diff --git a/README.md b/README.md index 5e1c995..7c7fdbb 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ The repository follows an _opinionated file structure_ shown below, abstracting circom-ts-starter ├── circuits # where you write templates │ ├── main # where you instantiate components -│ │ │── foo-bar.circom +│ │ │── foo-main.circom │ │ └── ... │ │── foo.circom │ └── ... @@ -25,18 +25,18 @@ circom-ts-starter │ ├── powersOfTau28_hez_final_12.ptau │ └── ... └── build # artifacts, .gitignore'd - │── foo-bar - │ │── foo-bar_js # artifacts of compilation + │── foo-main + │ │── foo-main_js # artifacts of compilation │ │ │── generate_witness.js │ │ │── witness_calculator.js - │ │ └── foo-bar.wasm + │ │ └── foo-main.wasm │ │── input-name # artifacts of witness & proof generation │ │ │── proof.json # proof object │ │ │── public.json # public signals │ │ └── witness.wtns │ │── ... # folders for other inputs - │ │── foo-bar.r1cs - │ │── foo-bar.sym + │ │── foo-main.r1cs + │ │── foo-main.sym │ │── prover_key.zkey │ └── verification_key.json └── ... diff --git a/inputs/sudoku9/foo.json b/inputs/sudoku9/foo.json index 428ee62..d676d14 100644 --- a/inputs/sudoku9/foo.json +++ b/inputs/sudoku9/foo.json @@ -1,24 +1,24 @@ { "solution": [ - ["1", "9", "4", "8", "6", "5", "2", "3", "7"], - ["7", "3", "5", "4", "1", "2", "9", "6", "8"], - ["8", "6", "2", "3", "9", "7", "1", "4", "5"], - ["9", "2", "1", "7", "4", "8", "3", "5", "6"], - ["6", "7", "8", "5", "3", "1", "4", "2", "9"], - ["4", "5", "3", "9", "2", "6", "8", "7", "1"], - ["3", "8", "9", "6", "5", "4", "7", "1", "2"], - ["2", "4", "6", "1", "7", "9", "5", "8", "3"], - ["5", "1", "7", "2", "8", "3", "6", "9", "4"] + [1, 9, 4, 8, 6, 5, 2, 3, 7], + [7, 3, 5, 4, 1, 2, 9, 6, 8], + [8, 6, 2, 3, 9, 7, 1, 4, 5], + [9, 2, 1, 7, 4, 8, 3, 5, 6], + [6, 7, 8, 5, 3, 1, 4, 2, 9], + [4, 5, 3, 9, 2, 6, 8, 7, 1], + [3, 8, 9, 6, 5, 4, 7, 1, 2], + [2, 4, 6, 1, 7, 9, 5, 8, 3], + [5, 1, 7, 2, 8, 3, 6, 9, 4] ], "puzzle": [ - ["0", "0", "0", "8", "6", "0", "2", "3", "0"], - ["7", "0", "5", "0", "0", "0", "9", "0", "8"], - ["0", "6", "0", "3", "0", "7", "0", "4", "0"], - ["0", "2", "0", "7", "0", "8", "0", "5", "0"], - ["0", "7", "8", "5", "0", "0", "0", "0", "0"], - ["4", "0", "0", "9", "0", "6", "0", "7", "0"], - ["3", "0", "9", "0", "5", "0", "7", "0", "2"], - ["0", "4", "0", "1", "0", "9", "0", "8", "0"], - ["5", "0", "7", "0", "8", "0", "0", "9", "4"] + [0, 0, 0, 8, 6, 0, 2, 3, 0], + [7, 0, 5, 0, 0, 0, 9, 0, 8], + [0, 6, 0, 3, 0, 7, 0, 4, 0], + [0, 2, 0, 7, 0, 8, 0, 5, 0], + [0, 7, 8, 5, 0, 0, 0, 0, 0], + [4, 0, 0, 9, 0, 6, 0, 7, 0], + [3, 0, 9, 0, 5, 0, 7, 0, 2], + [0, 4, 0, 1, 0, 9, 0, 8, 0], + [5, 0, 7, 0, 8, 0, 0, 9, 4] ] } diff --git a/tests/multiplier.test.ts b/tests/multiplier.test.ts index c79d21b..51112a9 100644 --- a/tests/multiplier.test.ts +++ b/tests/multiplier.test.ts @@ -1,25 +1,28 @@ import {compileCircuit} from '../utils'; import {Circuit} from '../utils/circuit'; -import type {FullProof} from '../types/circuit'; +import type {CircuitSignals, FullProof} from '../types/circuit'; import type {WasmTester} from '../types/wasmTester'; import {assert, expect} from 'chai'; +// read inputs from file +import input80 from '../inputs/multiplier3/80.json'; const CIRCUIT_NAME = 'multiplier3'; describe(CIRCUIT_NAME, () => { - const INPUT = { - in: [2n, 4n, 6n], - }; + const INPUT: CircuitSignals = input80; describe('functionality', () => { let circuit: WasmTester; before(async () => { - circuit = await compileCircuit('../circuits/main/' + CIRCUIT_NAME + '.circom'); + circuit = await compileCircuit('./circuits/main/' + CIRCUIT_NAME + '.circom'); + await circuit.loadConstraints(); + console.log('#constraints:', circuit.constraints!.length); }); it('should compute correctly', async () => { // compute witness const witness = await circuit.calculateWitness(INPUT, true); + console.log(witness); // witness should have valid constraints await circuit.checkConstraints(witness); @@ -54,7 +57,7 @@ describe(CIRCUIT_NAME, () => { }); }); - describe.skip('validation', () => { + describe('validation', () => { let fullProof: FullProof; const circuit = new Circuit(CIRCUIT_NAME); diff --git a/tests/sudoku.test.ts b/tests/sudoku.test.ts index 0122739..1d01c7e 100644 --- a/tests/sudoku.test.ts +++ b/tests/sudoku.test.ts @@ -1,74 +1,30 @@ import {compileCircuit} from '../utils'; import {Circuit} from '../utils/circuit'; -import type {FullProof} from '../types/circuit'; +import type {CircuitSignals, FullProof} from '../types/circuit'; import type {WasmTester} from '../types/wasmTester'; import {assert, expect} from 'chai'; +// read inputs from file +import inputfoo from '../inputs/sudoku9/foo.json'; -const CIRCUIT_NAME = 'sudoku'; +const CIRCUIT_NAME = 'sudoku9'; describe(CIRCUIT_NAME, () => { - const INPUT = { - solution: [ - ['1', '9', '4', '8', '6', '5', '2', '3', '7'], - ['7', '3', '5', '4', '1', '2', '9', '6', '8'], - ['8', '6', '2', '3', '9', '7', '1', '4', '5'], - ['9', '2', '1', '7', '4', '8', '3', '5', '6'], - ['6', '7', '8', '5', '3', '1', '4', '2', '9'], - ['4', '5', '3', '9', '2', '6', '8', '7', '1'], - ['3', '8', '9', '6', '5', '4', '7', '1', '2'], - ['2', '4', '6', '1', '7', '9', '5', '8', '3'], - ['5', '1', '7', '2', '8', '3', '6', '9', '4'], - ], - puzzle: [ - ['0', '0', '0', '8', '6', '0', '2', '3', '0'], - ['7', '0', '5', '0', '0', '0', '9', '0', '8'], - ['0', '6', '0', '3', '0', '7', '0', '4', '0'], - ['0', '2', '0', '7', '0', '8', '0', '5', '0'], - ['0', '7', '8', '5', '0', '0', '0', '0', '0'], - ['4', '0', '0', '9', '0', '6', '0', '7', '0'], - ['3', '0', '9', '0', '5', '0', '7', '0', '2'], - ['0', '4', '0', '1', '0', '9', '0', '8', '0'], - ['5', '0', '7', '0', '8', '0', '0', '9', '4'], - ], - }; + const INPUT: CircuitSignals = inputfoo; describe('functionality', () => { let circuit: WasmTester; before(async () => { - circuit = await compileCircuit(CIRCUIT_NAME); + circuit = await compileCircuit('./circuits/main/' + CIRCUIT_NAME + '.circom'); + await circuit.loadConstraints(); + console.log('#constraints:', circuit.constraints!.length); }); it('should compute correctly', async () => { // compute witness - const witness = await circuit.calculateWitness(INPUT, true); + const witness = await circuit.calculateWitness(inputfoo, true); // witness should have valid constraints await circuit.checkConstraints(witness); - - // witness should have correct output - // await circuit.assertOut(witness, { - // main: INPUT.puzzle, - // }); - }); - }); - - describe('validation', () => { - let fullProof: FullProof; - - const circuit = new Circuit(CIRCUIT_NAME); - - before(async () => { - fullProof = await circuit.prove(INPUT); - }); - - it('should verify', async () => { - expect(await circuit.verify(fullProof.proof, fullProof.publicSignals)).to.be.true; - }); - - it('should NOT verify a wrong puzzle', async () => { - // just give a prime number, assuming there are no factors of 1 - // TODO; provide wrong answer - expect(await circuit.verify(fullProof.proof, ['13'])).to.be.false; }); }); }); diff --git a/types/circuit.ts b/types/circuit.ts index eeb79ca..609da2e 100644 --- a/types/circuit.ts +++ b/types/circuit.ts @@ -14,5 +14,5 @@ export type WitnessType = bigint[]; */ export type FullProof = { proof: object; - publicSignals: CircuitSignals; + publicSignals: string[]; }; diff --git a/utils/circuit.ts b/utils/circuit.ts index e38b3ae..4e63a23 100644 --- a/utils/circuit.ts +++ b/utils/circuit.ts @@ -42,7 +42,7 @@ export class Circuit { * @param publicSignals public signals for the circuit * @returns `true` if proof verifies, `false` otherwise */ - async verify(proof: object, publicSignals: bigint[]): Promise { + async verify(proof: object, publicSignals: string[]): Promise { return await snarkjs.groth16.verify(this.verificationKey, publicSignals, proof); } }