From 3454bb71777304cc453272092e4004f65da7f801 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 1 May 2024 20:53:37 +0000 Subject: [PATCH 1/4] initial testing of noir js running an acir program with multiple circuits --- tooling/noir_js/scripts/compile_test_programs.sh | 2 ++ tooling/noir_js/test/node/execute.test.ts | 14 ++++++++++++++ .../fold_fibonacci/Nargo.toml | 7 +++++++ .../fold_fibonacci/src/main.nr | 12 ++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 tooling/noir_js/test/noir_compiled_examples/fold_fibonacci/Nargo.toml create mode 100644 tooling/noir_js/test/noir_compiled_examples/fold_fibonacci/src/main.nr diff --git a/tooling/noir_js/scripts/compile_test_programs.sh b/tooling/noir_js/scripts/compile_test_programs.sh index 5257aaae696..23a4cffc072 100755 --- a/tooling/noir_js/scripts/compile_test_programs.sh +++ b/tooling/noir_js/scripts/compile_test_programs.sh @@ -3,3 +3,5 @@ rm -rf ./test/noir_compiled_examples/**/target nargo --program-dir ./test/noir_compiled_examples/assert_lt compile --force nargo --program-dir ./test/noir_compiled_examples/assert_msg_runtime compile --force +nargo --program-dir ./test/noir_compiled_examples/fold_fibonacci compile --force + diff --git a/tooling/noir_js/test/node/execute.test.ts b/tooling/noir_js/test/node/execute.test.ts index 491bcb0dfc4..8c02ac90a3d 100644 --- a/tooling/noir_js/test/node/execute.test.ts +++ b/tooling/noir_js/test/node/execute.test.ts @@ -1,11 +1,13 @@ import assert_lt_json from '../noir_compiled_examples/assert_lt/target/assert_lt.json' assert { type: 'json' }; import assert_msg_json from '../noir_compiled_examples/assert_msg_runtime/target/assert_msg_runtime.json' assert { type: 'json' }; +import fold_fibonacci_json from '../noir_compiled_examples/fold_fibonacci/target/fold_fibonacci.json' assert { type: 'json' }; import { Noir } from '@noir-lang/noir_js'; import { CompiledCircuit } from '@noir-lang/types'; import { expect } from 'chai'; const assert_lt_program = assert_lt_json as CompiledCircuit; const assert_msg_runtime = assert_msg_json as CompiledCircuit; +const fold_fibonacci_program = fold_fibonacci_json as CompiledCircuit; it('returns the return value of the circuit', async () => { const inputs = { @@ -29,3 +31,15 @@ it('circuit with a dynamic assert message should fail on an assert failure not t expect(knownError.message).to.equal('Circuit execution failed: Error: Cannot satisfy constraint'); } }); + +it('successfully executes a program with multiple acir circuits', async () => { + const inputs = { + x: '10', + }; + try { + await new Noir(fold_fibonacci_program).execute(inputs); + } catch (error) { + const knownError = error as Error; + expect(knownError.message).to.equal('Circuit execution failed: Error: Cannot satisfy constraint'); + } +}); diff --git a/tooling/noir_js/test/noir_compiled_examples/fold_fibonacci/Nargo.toml b/tooling/noir_js/test/noir_compiled_examples/fold_fibonacci/Nargo.toml new file mode 100644 index 00000000000..6d8214689b0 --- /dev/null +++ b/tooling/noir_js/test/noir_compiled_examples/fold_fibonacci/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "fold_fibonacci" +type = "bin" +authors = [""] +compiler_version = ">=0.28.0" + +[dependencies] \ No newline at end of file diff --git a/tooling/noir_js/test/noir_compiled_examples/fold_fibonacci/src/main.nr b/tooling/noir_js/test/noir_compiled_examples/fold_fibonacci/src/main.nr new file mode 100644 index 00000000000..e150a586086 --- /dev/null +++ b/tooling/noir_js/test/noir_compiled_examples/fold_fibonacci/src/main.nr @@ -0,0 +1,12 @@ +fn main(x: u32) { + assert(fibonacci(x) == 55); +} + +#[fold] +fn fibonacci(x: u32) -> u32 { + if x <= 1 { + x + } else { + fibonacci(x - 1) + fibonacci(x - 2) + } +} From 6f52320d15cb55a403440f8eec909c91677fa35f Mon Sep 17 00:00:00 2001 From: vezenovm Date: Thu, 2 May 2024 20:55:33 +0000 Subject: [PATCH 2/4] switch to executeProgramWithBlackBoxSolver and add a couple tests --- tooling/noir_js/src/program.ts | 9 ++++---- tooling/noir_js/src/witness_generation.ts | 8 +++---- tooling/noir_js/test/node/e2e.test.ts | 26 +++++++++++++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/tooling/noir_js/src/program.ts b/tooling/noir_js/src/program.ts index 8d80ec3a247..86aa0f60ddf 100644 --- a/tooling/noir_js/src/program.ts +++ b/tooling/noir_js/src/program.ts @@ -2,7 +2,7 @@ import { Backend, CompiledCircuit, ProofData } from '@noir-lang/types'; import { generateWitness } from './witness_generation.js'; import initAbi, { abiDecode, InputMap, InputValue } from '@noir-lang/noirc_abi'; -import initACVM, { compressWitness, ForeignCallHandler } from '@noir-lang/acvm_js'; +import initACVM, { compressWitnessStack, ForeignCallHandler } from '@noir-lang/acvm_js'; export class Noir { constructor( @@ -55,9 +55,10 @@ export class Noir { foreignCallHandler?: ForeignCallHandler, ): Promise<{ witness: Uint8Array; returnValue: InputValue }> { await this.init(); - const witness = await generateWitness(this.circuit, inputs, foreignCallHandler); - const { return_value: returnValue } = abiDecode(this.circuit.abi, witness); - return { witness: compressWitness(witness), returnValue }; + const witness_stack = await generateWitness(this.circuit, inputs, foreignCallHandler); + const main_witness = witness_stack[0].witness; + const { return_value: returnValue } = abiDecode(this.circuit.abi, main_witness); + return { witness: compressWitnessStack(witness_stack), returnValue }; } /** diff --git a/tooling/noir_js/src/witness_generation.ts b/tooling/noir_js/src/witness_generation.ts index cef1d817d9b..67dcc774288 100644 --- a/tooling/noir_js/src/witness_generation.ts +++ b/tooling/noir_js/src/witness_generation.ts @@ -1,12 +1,12 @@ import { abiEncode, InputMap } from '@noir-lang/noirc_abi'; import { base64Decode } from './base64_decode.js'; import { - WitnessMap, + WitnessStack, ForeignCallHandler, ForeignCallInput, createBlackBoxSolver, WasmBlackBoxFunctionSolver, - executeCircuitWithBlackBoxSolver, + executeProgramWithBlackBoxSolver, } from '@noir-lang/acvm_js'; import { CompiledCircuit } from '@noir-lang/types'; @@ -41,14 +41,14 @@ export async function generateWitness( compiledProgram: CompiledCircuit, inputs: InputMap, foreignCallHandler: ForeignCallHandler = defaultForeignCallHandler, -): Promise { +): Promise { // Throws on ABI encoding error const witnessMap = abiEncode(compiledProgram.abi, inputs); // Execute the circuit to generate the rest of the witnesses and serialize // them into a Uint8Array. try { - const solvedWitness = await executeCircuitWithBlackBoxSolver( + const solvedWitness = await executeProgramWithBlackBoxSolver( await getSolver(), base64Decode(compiledProgram.bytecode), witnessMap, diff --git a/tooling/noir_js/test/node/e2e.test.ts b/tooling/noir_js/test/node/e2e.test.ts index 979841c47e6..e206b7d4295 100644 --- a/tooling/noir_js/test/node/e2e.test.ts +++ b/tooling/noir_js/test/node/e2e.test.ts @@ -1,10 +1,12 @@ import { expect } from 'chai'; import assert_lt_json from '../noir_compiled_examples/assert_lt/target/assert_lt.json' assert { type: 'json' }; +import fold_fibonacci_json from '../noir_compiled_examples/fold_fibonacci/target/fold_fibonacci.json' assert { type: 'json' }; import { Noir } from '@noir-lang/noir_js'; import { BarretenbergBackend as Backend, BarretenbergVerifier as Verifier } from '@noir-lang/backend_barretenberg'; import { CompiledCircuit } from '@noir-lang/types'; const assert_lt_program = assert_lt_json as CompiledCircuit; +const fold_fibonacci_program = fold_fibonacci_json as CompiledCircuit; it('end-to-end proof creation and verification (outer)', async () => { // Noir.Js part @@ -93,6 +95,7 @@ it('end-to-end proof creation and verification (inner)', async () => { }); it('end-to-end proving and verification with different instances', async () => { + console.log('got here'); // Noir.Js part const inputs = { x: '2', @@ -105,8 +108,10 @@ it('end-to-end proving and verification with different instances', async () => { // bb.js part const prover = new Backend(assert_lt_program); + console.log('got prover'); const proof = await prover.generateProof(witness); + console.log('got proof'); const verifier = new Backend(assert_lt_program); const proof_is_valid = await verifier.verifyProof(proof); @@ -149,3 +154,24 @@ it('[BUG] -- bb.js null function or function signature mismatch (outer-inner) ', const isValidInner = await prover.verifyProof(_proofInner); expect(isValidInner).to.be.true; }); + +it('end-to-end ACIR program proof creation and verification (inner)', async () => { + // Noir.Js part + const inputs = { + x: '10', + }; + + const program = new Noir(fold_fibonacci_program); + + const { witness } = await program.execute(inputs); + + // bb.js part + // + // Proof creation + const backend = new Backend(fold_fibonacci_program); + const proof = await backend.generateProof(witness); + + // Proof verification + const isValid = await backend.verifyProof(proof); + expect(isValid).to.be.true; +}); From c60509ae88e9c2c44b8a5976946c8b8c4e01c841 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Thu, 2 May 2024 21:00:45 +0000 Subject: [PATCH 3/4] remove console log --- tooling/noir_js/test/node/e2e.test.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/tooling/noir_js/test/node/e2e.test.ts b/tooling/noir_js/test/node/e2e.test.ts index e206b7d4295..3b96db1b7cf 100644 --- a/tooling/noir_js/test/node/e2e.test.ts +++ b/tooling/noir_js/test/node/e2e.test.ts @@ -95,7 +95,6 @@ it('end-to-end proof creation and verification (inner)', async () => { }); it('end-to-end proving and verification with different instances', async () => { - console.log('got here'); // Noir.Js part const inputs = { x: '2', @@ -108,10 +107,8 @@ it('end-to-end proving and verification with different instances', async () => { // bb.js part const prover = new Backend(assert_lt_program); - console.log('got prover'); const proof = await prover.generateProof(witness); - console.log('got proof'); const verifier = new Backend(assert_lt_program); const proof_is_valid = await verifier.verifyProof(proof); From 1c2efd99df77b8f4893979360ebabcd04856bc26 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 3 May 2024 13:21:27 +0000 Subject: [PATCH 4/4] update test name --- tooling/noir_js/test/node/e2e.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/noir_js/test/node/e2e.test.ts b/tooling/noir_js/test/node/e2e.test.ts index 3b96db1b7cf..dbb9abcc964 100644 --- a/tooling/noir_js/test/node/e2e.test.ts +++ b/tooling/noir_js/test/node/e2e.test.ts @@ -152,7 +152,7 @@ it('[BUG] -- bb.js null function or function signature mismatch (outer-inner) ', expect(isValidInner).to.be.true; }); -it('end-to-end ACIR program proof creation and verification (inner)', async () => { +it('end-to-end proof creation and verification for multiple ACIR circuits (inner)', async () => { // Noir.Js part const inputs = { x: '10',