Skip to content

Commit

Permalink
WitnessTester.compute supports multiple output signals (#104)
Browse files Browse the repository at this point in the history
* WitnessTester.compute supports multiple output signals

* Missed test circuit source
  • Loading branch information
numtel authored Dec 1, 2024
1 parent 98725e6 commit 49ab4c8
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/testers/witnessTester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ export class WitnessTester<IN extends readonly string[] = [], OUT extends readon
// non-main signals have an additional `.` in them after `main.symbol`
const signalDotCount = dotCount(signal) + 1; // +1 for the dot in `main.`
const signalLength = signal.length + 5; // +5 for prefix `main.`
const symbolNames = Object.keys(this.symbols!).filter(s => signalDotCount === dotCount(s));
const symbolNames = Object.keys(this.symbols!).filter(s =>
s.startsWith(`main.${signal}`) && signalDotCount === dotCount(s));

// get the symbol values from symbol names, ignoring `main.` prefix
// the matched symbols must exactly equal the signal
Expand Down
24 changes: 24 additions & 0 deletions tests/circuits/multiout.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
pragma circom 2.0.0;

template Multiout(N) {
signal input a[N];
signal input b[N];
var newSize = N + N - 1;
signal output cOut[N];
signal output aOut[newSize];
signal output bOut[newSize];

var a1[newSize];
var b1[newSize];
var c1[N];
for(var i = 0; i<N; i++) {
a1[i] = a[i] * i;
b1[i] = b[i] * i;
c1[i] = a[i] * b[i];
}

cOut <== c1;
aOut <== a1;
bOut <== b1;
}

37 changes: 36 additions & 1 deletion tests/witnessTester.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import {prepareMultiplier} from './common';
// TODO: add C tester

describe('witness tester', () => {
let circomkit: Circomkit;
let circuit: WitnessTester<['in'], ['out']>;
const {
circuit: {name, config, size, exact},
signals,
} = prepareMultiplier(4);

beforeAll(async () => {
const circomkit = new Circomkit({
circomkit = new Circomkit({
verbose: false,
logLevel: 'silent',
circuits: './tests/circuits.json',
Expand Down Expand Up @@ -46,6 +47,40 @@ describe('witness tester', () => {
expect(output.out).toEqual(BigInt(signals.output.out));
});

it('should compute correctly with multiple output signals', async () => {
const N = 167;
const newSize = N + N - 1;
const a = 2;
const b = 3;
const aOut = Array(newSize).fill(0).map((_, i) => BigInt(i < N ? a * i : 0));
const bOut = Array(newSize).fill(0).map((_, i) => BigInt(i < N ? b * i : 0));
const cOut = Array(N).fill(BigInt(a * b));

const circuit2 = await circomkit.WitnessTester('multiout', {
file: 'multiout',
template: 'Multiout',
params: [N],
});

const input = {
a: Array(N).fill(a),
b: Array(N).fill(b),
};
const output = await circuit2.compute(input, ['aOut', 'bOut', 'cOut']);

expect(output).toHaveProperty('aOut');
expect(output).toHaveProperty('bOut');
expect(output).toHaveProperty('cOut');
expect(output.aOut).toHaveLength(newSize);
expect(output.bOut).toHaveLength(newSize);
expect(output.cOut).toHaveLength(N);
expect(output.aOut).toEqual(aOut);
expect(output.bOut).toEqual(bOut);
expect(output.cOut).toEqual(cOut);

await circuit2.expectPass(input, output);
});

it('should read witness correctly', async () => {
const witness = await circuit.calculateWitness(signals.input);
const symbol = 'main.out';
Expand Down

0 comments on commit 49ab4c8

Please sign in to comment.