From dea9b29b9429593a36199808eb753d5576a8d582 Mon Sep 17 00:00:00 2001 From: Cody Date: Thu, 6 Feb 2025 19:00:47 +0000 Subject: [PATCH 1/7] starter code --- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 6 ++++ .../barretenberg/dsl/acir_proofs/c_bind.hpp | 5 ++- barretenberg/exports.json | 14 +++++++++ barretenberg/ts/src/barretenberg/backend.ts | 5 +++ barretenberg/ts/src/barretenberg_api/index.ts | 31 +++++++++++++++++++ .../src/wasm_client_ivc_integration.test.ts | 5 +++ 6 files changed, 65 insertions(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index a3e037af23f4..990543c0749c 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -445,3 +445,9 @@ WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_ std::vector vkey_as_fields = verification_key->to_field_elements(); *out_vkey = to_heap_buffer(vkey_as_fields); } + +// STARTER +WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint32_t** totals) +{ + // return a pointer total such that total[i][0] is the finalized size of the ith circuit in a acir_stack +} diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index 64debff164ef..eb2d0cbed7b0 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -113,4 +113,7 @@ WASM_EXPORT void acir_proof_as_fields_ultra_honk(uint8_t const* proof_buf, fr::v WASM_EXPORT void acir_vk_as_fields_ultra_honk(uint8_t const* vk_buf, fr::vec_out_buf out_vkey); -WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_buf out_vkey); \ No newline at end of file +WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_buf out_vkey); + +// STARTER +WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint32_t** totals) \ No newline at end of file diff --git a/barretenberg/exports.json b/barretenberg/exports.json index 83b2a64ec71e..8d1e83bdf9d6 100644 --- a/barretenberg/exports.json +++ b/barretenberg/exports.json @@ -530,6 +530,20 @@ ], "isAsync": false }, + { + "functionName": "acir_gates_client_ivc", + "inArgs": [ + { + "name": "acir_stack", + "type": "const uint8_t *" + }, + { + "name": "totals", + "type": "uint32_t **" + } + ], + "isAsync": false + }, { "functionName": "acir_new_acir_composer", "inArgs": [ diff --git a/barretenberg/ts/src/barretenberg/backend.ts b/barretenberg/ts/src/barretenberg/backend.ts index c04d362d048b..4cc0e51af9a7 100644 --- a/barretenberg/ts/src/barretenberg/backend.ts +++ b/barretenberg/ts/src/barretenberg/backend.ts @@ -389,6 +389,11 @@ export class AztecClientBackend { return this.api.acirProveAndVerifyAztecClient(this.acirMsgpack, witnessMsgpack); } + // STARTER + async gates(): Promise { + // call funciton on API + } + async destroy(): Promise { if (!this.api) { return; diff --git a/barretenberg/ts/src/barretenberg_api/index.ts b/barretenberg/ts/src/barretenberg_api/index.ts index 90d9952ab7b2..946e084f02b5 100644 --- a/barretenberg/ts/src/barretenberg_api/index.ts +++ b/barretenberg/ts/src/barretenberg_api/index.ts @@ -357,6 +357,21 @@ export class BarretenbergApi { return out as [number, number]; } + // STARTER + async acirGatesAztecClient( // cf acirProveAztecClient + acirVec: Uint8Array[] + ): Promise { + const inArgs = [acirVec].map(serializeBufferable); + const outTypes: OutputType[] = [NumberDeserializer(), NumberDeserializer()/* TODO: need to determine this number at runtime or set a max */]; + const result = await this.wasm.callWasmExport( + 'acir_gates_aztec_client', + inArgs, + outTypes.map(t => t.SIZE_IN_BYTES), + ); + const out = result.map((r, i) => outTypes[i].fromBuffer(r)); + return out as [number, number]; + } + async acirNewAcirComposer(sizeHint: number): Promise { const inArgs = [sizeHint].map(serializeBufferable); const outTypes: OutputType[] = [Ptr]; @@ -1059,6 +1074,22 @@ export class BarretenbergApiSync { return out as any; } + acirGatesMegaHonk( + constraintSystemBuf: Uint8Array, + recursive: boolean, + honkRecursion: boolean, + ): [number, number, number] { + const inArgs = [constraintSystemBuf, recursive, honkRecursion].map(serializeBufferable); + const outTypes: OutputType[] = [NumberDeserializer(), NumberDeserializer()]; + const result = this.wasm.callWasmExport( + 'acir_gate_mega_honk', + inArgs, + outTypes.map(t => t.SIZE_IN_BYTES), + ); + const out = result.map((r, i) => outTypes[i].fromBuffer(r)); + return out as any; + } + acirNewAcirComposer(sizeHint: number): Ptr { const inArgs = [sizeHint].map(serializeBufferable); const outTypes: OutputType[] = [Ptr]; diff --git a/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts b/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts index f6402e91cb34..719aec11dab1 100644 --- a/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts +++ b/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts @@ -65,6 +65,11 @@ describe('Client IVC Integration', () => { MockPrivateKernelInitCircuit.bytecode, MockPrivateKernelTailCircuit.bytecode, ]; + + // STARTER: add a test here instantiate an AztecClientBackend with the above bytecodes, call gates, and check they're correct (maybe just + // eyeball against logs to start... better is to make another test that actually pins the sizes since the mock protocol circuits are + // intended not to change, though for sure there will be some friction, and such test should actually just be located in barretenberg/ts) + logger.debug('built bytecode array'); const witnessStack = [appWitnessGenResult.witness, initWitnessGenResult.witness, tailWitnessGenResult.witness]; logger.debug('built witness stack'); From d52d9a3e581c4e18c8043a003df5aded7076a190 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 10 Feb 2025 15:23:23 +0000 Subject: [PATCH 2/7] first steps --- barretenberg/cpp/src/barretenberg/bb/main.cpp | 6 +++--- .../dsl/acir_format/acir_format.cpp | 2 +- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 19 +++++++++++++++++++ .../barretenberg/dsl/acir_proofs/c_bind.hpp | 2 +- barretenberg/ts/src/barretenberg/backend.ts | 4 +++- .../src/wasm_client_ivc_integration.test.ts | 14 +++++++++++++- 6 files changed, 40 insertions(+), 7 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/bb/main.cpp b/barretenberg/cpp/src/barretenberg/bb/main.cpp index f9d45093549e..6eb81162b60c 100644 --- a/barretenberg/cpp/src/barretenberg/bb/main.cpp +++ b/barretenberg/cpp/src/barretenberg/bb/main.cpp @@ -81,7 +81,7 @@ std::string honk_vk_to_json(std::vector& data) * * @param bytecodePath Path to the file containing the serialized circuit * @param witnessPath Path to the file containing the serialized witness - * @param recursive Whether to use recursive proof generation of non-recursive + * @param recursive Whether to use recursive proof generation or non-recursive * @return true if the proof is valid * @return false if the proof is invalid */ @@ -214,7 +214,7 @@ void prove_tube(const std::string& output_path) std::string vkPath = output_path + "/client_ivc_vk"; std::string proofPath = output_path + "/client_ivc_proof"; - // Note: this could be decreased once we optimise the size of the ClientIVC recursiveve rifier + // Note: this could be decreased once we optimise the size of the ClientIVC recursive verifier init_bn254_crs(1 << 25); init_grumpkin_crs(1 << 18); @@ -223,7 +223,7 @@ void prove_tube(const std::string& output_path) auto vk = from_buffer(read_file(vkPath)); // We don't serialise and deserialise the Grumkin SRS so initialise with circuit_size + 1 to be able to recursively - // IPA. The + 1 is to satisfy IPA verification key requirements. + // verify IPA. The + 1 is to satisfy IPA verification key requirements. // TODO(https://github.com/AztecProtocol/barretenberg/issues/1025) vk.eccvm->pcs_verification_key = std::make_shared(vk.eccvm->circuit_size + 1); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 1789562498d8..a7a63bc2a853 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -487,7 +487,7 @@ void process_ivc_recursion_constraints(MegaCircuitBuilder& builder, ivc->instantiate_stdlib_verification_queue(builder, stdlib_verification_keys); // Connect the public_input witnesses in each constraint to the corresponding public input witnesses in the internal - // verification queue. This ensures that the witnesses utlized in constraints generated based on acir are properly + // verification queue. This ensures that the witnesses utilized in constraints generated based on acir are properly // connected to the constraints generated herein via the ivc scheme (e.g. recursive verifications). for (auto [constraint, queue_entry] : zip_view(constraints.ivc_recursion_constraints, ivc->stdlib_verification_queue)) { diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 990543c0749c..abd65b9049a2 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -447,7 +447,26 @@ WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_ } // STARTER +// Do I need the witness stack? WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint32_t** totals) { + using Program = acir_format::AcirProgram; + + std::vector> acirs = from_buffer>>(acir_stack); + + TraceSettings trace_settings{ E2E_FULL_TEST_STRUCTURE }; + auto ivc = std::make_shared(trace_settings); + const acir_format::ProgramMetadata metadata{ ivc }; + + size_t program_counter = 0; + for (auto& bincode : acirs) { + acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format( + from_buffer>(bincode), /*honk_recursion=*/0) }; + auto builder = acir_format::create_circuit(program, metadata); + builder.finalize_circuit(/*ensure_nonzero=*/true); + totals[program_counter][0] = htonl((uint32_t)builder.get_finalized_total_circuit_size()); + program_counter++; + } + // return a pointer total such that total[i][0] is the finalized size of the ith circuit in a acir_stack } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index eb2d0cbed7b0..b7a7ca278b4b 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -116,4 +116,4 @@ WASM_EXPORT void acir_vk_as_fields_ultra_honk(uint8_t const* vk_buf, fr::vec_out WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_buf out_vkey); // STARTER -WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint32_t** totals) \ No newline at end of file +WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint32_t** totals); \ No newline at end of file diff --git a/barretenberg/ts/src/barretenberg/backend.ts b/barretenberg/ts/src/barretenberg/backend.ts index 4cc0e51af9a7..10873dbf371f 100644 --- a/barretenberg/ts/src/barretenberg/backend.ts +++ b/barretenberg/ts/src/barretenberg/backend.ts @@ -391,7 +391,9 @@ export class AztecClientBackend { // STARTER async gates(): Promise { - // call funciton on API + // call function on API + await this.instantiate(); + return this.api.acirGatesAztecClient( this.acirMsgpack); } async destroy(): Promise { diff --git a/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts b/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts index 0ee01bd3f0f8..09fae51713e3 100644 --- a/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts +++ b/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts @@ -2,6 +2,7 @@ import { jest } from '@jest/globals'; /* eslint-disable camelcase */ import createDebug from 'debug'; +import { ungzip } from 'pako'; import { MOCK_MAX_COMMITMENTS_PER_TX, @@ -66,11 +67,19 @@ describe('Client IVC Integration', () => { MockPrivateKernelTailCircuit.bytecode, ]; + const { AztecClientBackend } = await import('@aztec/bb.js'); + const backend = new AztecClientBackend(bytecodes.map(base64ToUint8Array).map((arr: Uint8Array) => ungzip(arr))); + const gateNumbers = await backend.gates(); + + logger('Gate numbers for each circuit:'); + gateNumbers.forEach((gateCount, index) => { + logger(`Circuit ${index + 1}: ${gateCount} gates`); + }); // STARTER: add a test here instantiate an AztecClientBackend with the above bytecodes, call gates, and check they're correct (maybe just // eyeball against logs to start... better is to make another test that actually pins the sizes since the mock protocol circuits are // intended not to change, though for sure there will be some friction, and such test should actually just be located in barretenberg/ts) - logger.debug('built bytecode array'); + logger('built bytecode array'); const witnessStack = [appWitnessGenResult.witness, initWitnessGenResult.witness, tailWitnessGenResult.witness]; logger('built witness stack'); @@ -147,3 +156,6 @@ describe('Client IVC Integration', () => { expect(verifyResult).toEqual(true); }); }); +function base64ToUint8Array(base64: string): Uint8Array { + return Uint8Array.from(atob(base64), c => c.charCodeAt(0)); +} From 9c7b6ab52ebe5b999e96cfd276620bfd24dd1ba5 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 12 Feb 2025 12:37:43 +0000 Subject: [PATCH 3/7] something's working --- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 15 ++++++--------- .../barretenberg/dsl/acir_proofs/c_bind.hpp | 2 +- barretenberg/ts/src/barretenberg/backend.ts | 3 +++ barretenberg/ts/src/barretenberg_api/index.ts | 19 +++++++++++++++---- .../src/wasm_client_ivc_integration.test.ts | 11 ++++------- 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index abd65b9049a2..ad4c29c5e2f9 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -448,25 +448,22 @@ WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_ // STARTER // Do I need the witness stack? -WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint32_t** totals) +WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint8_t** out) { - using Program = acir_format::AcirProgram; std::vector> acirs = from_buffer>>(acir_stack); + std::vector totals; TraceSettings trace_settings{ E2E_FULL_TEST_STRUCTURE }; auto ivc = std::make_shared(trace_settings); const acir_format::ProgramMetadata metadata{ ivc }; - - size_t program_counter = 0; for (auto& bincode : acirs) { - acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format( - from_buffer>(bincode), /*honk_recursion=*/0) }; + acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format(bincode, /*honk_recursion=*/0) }; auto builder = acir_format::create_circuit(program, metadata); builder.finalize_circuit(/*ensure_nonzero=*/true); - totals[program_counter][0] = htonl((uint32_t)builder.get_finalized_total_circuit_size()); - program_counter++; + totals.push_back(static_cast(builder.get_finalized_total_circuit_size())); } + auto totalsBytes = to_buffer(totals); - // return a pointer total such that total[i][0] is the finalized size of the ith circuit in a acir_stack + *out = to_heap_buffer(totals); } diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index b7a7ca278b4b..0bb567600f56 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -116,4 +116,4 @@ WASM_EXPORT void acir_vk_as_fields_ultra_honk(uint8_t const* vk_buf, fr::vec_out WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_buf out_vkey); // STARTER -WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint32_t** totals); \ No newline at end of file +WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint8_t** out); \ No newline at end of file diff --git a/barretenberg/ts/src/barretenberg/backend.ts b/barretenberg/ts/src/barretenberg/backend.ts index 10873dbf371f..91c98d4497fc 100644 --- a/barretenberg/ts/src/barretenberg/backend.ts +++ b/barretenberg/ts/src/barretenberg/backend.ts @@ -9,6 +9,9 @@ import { reconstructHonkProof, reconstructUltraPlonkProof, } from '../proof/index.js'; +import createDebug from 'debug'; + +const debug = createDebug('backend-ts'); export class UltraPlonkBackend { // These type assertions are used so that we don't diff --git a/barretenberg/ts/src/barretenberg_api/index.ts b/barretenberg/ts/src/barretenberg_api/index.ts index 79ca1d6b7ef8..4715cfd3a2da 100644 --- a/barretenberg/ts/src/barretenberg_api/index.ts +++ b/barretenberg/ts/src/barretenberg_api/index.ts @@ -12,6 +12,17 @@ import { OutputType, } from '../serialize/index.js'; import { Fr, Fq, Point, Buffer32, Buffer128, Ptr } from '../types/index.js'; +import createDebug from 'debug'; +const log = createDebug('index-ts'); + +function parseBigEndianU32Array(buffer: Uint8Array): number[] { + const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); + const out: number[] = []; + for (let i = 0; i < buffer.byteLength; i += 4) { + out.push(dv.getUint32(i, false)); // false -> big-endian + } + return out; +} export class BarretenbergApi { constructor(protected wasm: BarretenbergWasmWorker | BarretenbergWasmMain) {} @@ -362,14 +373,14 @@ export class BarretenbergApi { acirVec: Uint8Array[] ): Promise { const inArgs = [acirVec].map(serializeBufferable); - const outTypes: OutputType[] = [NumberDeserializer(), NumberDeserializer()/* TODO: need to determine this number at runtime or set a max */]; - const result = await this.wasm.callWasmExport( + const outTypes: OutputType[] = [BufferDeserializer()]; + const resultBuffer = await this.wasm.callWasmExport( 'acir_gates_aztec_client', inArgs, outTypes.map(t => t.SIZE_IN_BYTES), ); - const out = result.map((r, i) => outTypes[i].fromBuffer(r)); - return out as [number, number]; + + return parseBigEndianU32Array(resultBuffer[0]); } async acirNewAcirComposer(sizeHint: number): Promise { diff --git a/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts b/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts index 09fae51713e3..8a7cbe25571f 100644 --- a/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts +++ b/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts @@ -1,3 +1,5 @@ +import { AztecClientBackend } from '@aztec/bb.js'; + import { jest } from '@jest/globals'; /* eslint-disable camelcase */ @@ -39,7 +41,7 @@ describe('Client IVC Integration', () => { // 1. Run a mock app that creates two commitments // 2. Run the init kernel to process the app run // 3. Run the tail kernel to finish the client IVC chain. - it.skip('Should generate a verifiable client IVC proof from a simple mock tx via bb.js', async () => { + it('Should generate a verifiable client IVC proof from a simple mock tx via bb.js', async () => { const tx = { number_of_calls: '0x1', }; @@ -67,14 +69,9 @@ describe('Client IVC Integration', () => { MockPrivateKernelTailCircuit.bytecode, ]; - const { AztecClientBackend } = await import('@aztec/bb.js'); const backend = new AztecClientBackend(bytecodes.map(base64ToUint8Array).map((arr: Uint8Array) => ungzip(arr))); const gateNumbers = await backend.gates(); - - logger('Gate numbers for each circuit:'); - gateNumbers.forEach((gateCount, index) => { - logger(`Circuit ${index + 1}: ${gateCount} gates`); - }); + logger('Gate numbers for each circuit:', gateNumbers); // STARTER: add a test here instantiate an AztecClientBackend with the above bytecodes, call gates, and check they're correct (maybe just // eyeball against logs to start... better is to make another test that actually pins the sizes since the mock protocol circuits are // intended not to change, though for sure there will be some friction, and such test should actually just be located in barretenberg/ts) From 147595eb9eea24f5ca577d6cf03b3137a4da4b95 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 12 Feb 2025 15:20:05 +0000 Subject: [PATCH 4/7] add a separate "test" for gates + remove num circuits prefix from circuit sizes --- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 2 -- .../barretenberg/dsl/acir_proofs/c_bind.hpp | 1 - barretenberg/ts/src/barretenberg_api/index.ts | 28 +++++++++++++------ .../src/wasm_client_ivc_integration.test.ts | 26 ++++++++++++----- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index ad4c29c5e2f9..b50b4f93d6c9 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -446,8 +446,6 @@ WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_ *out_vkey = to_heap_buffer(vkey_as_fields); } -// STARTER -// Do I need the witness stack? WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint8_t** out) { diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp index 0bb567600f56..033579e4515e 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -115,5 +115,4 @@ WASM_EXPORT void acir_vk_as_fields_ultra_honk(uint8_t const* vk_buf, fr::vec_out WASM_EXPORT void acir_vk_as_fields_mega_honk(uint8_t const* vk_buf, fr::vec_out_buf out_vkey); -// STARTER WASM_EXPORT void acir_gates_aztec_client(uint8_t const* acir_stack, uint8_t** out); \ No newline at end of file diff --git a/barretenberg/ts/src/barretenberg_api/index.ts b/barretenberg/ts/src/barretenberg_api/index.ts index 4715cfd3a2da..24d7dcb9e8fb 100644 --- a/barretenberg/ts/src/barretenberg_api/index.ts +++ b/barretenberg/ts/src/barretenberg_api/index.ts @@ -15,13 +15,25 @@ import { Fr, Fq, Point, Buffer32, Buffer128, Ptr } from '../types/index.js'; import createDebug from 'debug'; const log = createDebug('index-ts'); -function parseBigEndianU32Array(buffer: Uint8Array): number[] { - const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); - const out: number[] = []; - for (let i = 0; i < buffer.byteLength; i += 4) { - out.push(dv.getUint32(i, false)); // false -> big-endian - } - return out; +function parseBigEndianU32Array(buffer: Uint8Array, hasSizePrefix = false): number[] { + const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); + + let offset = 0; + let count = buffer.byteLength >>> 2; // default is entire buffer length / 4 + + if (hasSizePrefix) { + // Read the first 4 bytes as the size (big-endian). + count = dv.getUint32(0, /* littleEndian= */ false); + offset = 4; + } + + const out: number[] = new Array(count); + for (let i = 0; i < count; i++) { + out[i] = dv.getUint32(offset, false); + offset += 4; + } + + return out; } export class BarretenbergApi { @@ -380,7 +392,7 @@ export class BarretenbergApi { outTypes.map(t => t.SIZE_IN_BYTES), ); - return parseBigEndianU32Array(resultBuffer[0]); + return parseBigEndianU32Array(resultBuffer[0], /*hasSizePrefix=*/ true); } async acirNewAcirComposer(sizeHint: number): Promise { diff --git a/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts b/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts index 8a7cbe25571f..9a13e21b7bba 100644 --- a/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts +++ b/yarn-project/ivc-integration/src/wasm_client_ivc_integration.test.ts @@ -69,13 +69,6 @@ describe('Client IVC Integration', () => { MockPrivateKernelTailCircuit.bytecode, ]; - const backend = new AztecClientBackend(bytecodes.map(base64ToUint8Array).map((arr: Uint8Array) => ungzip(arr))); - const gateNumbers = await backend.gates(); - logger('Gate numbers for each circuit:', gateNumbers); - // STARTER: add a test here instantiate an AztecClientBackend with the above bytecodes, call gates, and check they're correct (maybe just - // eyeball against logs to start... better is to make another test that actually pins the sizes since the mock protocol circuits are - // intended not to change, though for sure there will be some friction, and such test should actually just be located in barretenberg/ts) - logger('built bytecode array'); const witnessStack = [appWitnessGenResult.witness, initWitnessGenResult.witness, tailWitnessGenResult.witness]; logger('built witness stack'); @@ -86,6 +79,25 @@ describe('Client IVC Integration', () => { expect(verifyResult).toEqual(true); }); + it('Should generate an array of gate numbers for the stack of programs being proved by ClientIVC', async () => { + // Create ACIR bytecodes + const bytecodes = [ + MockAppCreatorCircuit.bytecode, + MockPrivateKernelInitCircuit.bytecode, + MockPrivateKernelTailCircuit.bytecode, + ]; + + // Initialize AztecClientBackend with the given bytecodes + const backend = new AztecClientBackend(bytecodes.map(base64ToUint8Array).map((arr: Uint8Array) => ungzip(arr))); + + // Compute the numbers of gates in each circuit + const gateNumbers = await backend.gates(); + await backend.destroy(); + logger('Gate numbers for each circuit:', gateNumbers); + // STARTER: add a test here instantiate an AztecClientBackend with the above bytecodes, call gates, and check they're correct (maybe just + // eyeball against logs to start... better is to make another test that actually pins the sizes since the mock protocol circuits are + // intended not to change, though for sure there will be some friction, and such test should actually just be located in barretenberg/ts) + }); // This test will verify a client IVC proof of a more complex tx: // 1. Run a mock app that creates two commitments // 2. Run the init kernel to process the app run From 99c6ccc93c123b02cdfe8d097984aa8755af4c4c Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 12 Feb 2025 16:01:53 +0000 Subject: [PATCH 5/7] exports corrected --- barretenberg/exports.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/exports.json b/barretenberg/exports.json index 8d1e83bdf9d6..ec246bb837b2 100644 --- a/barretenberg/exports.json +++ b/barretenberg/exports.json @@ -539,7 +539,7 @@ }, { "name": "totals", - "type": "uint32_t **" + "type": "uint8_t **" } ], "isAsync": false From b5c2c902ca9f31643a99456f07ed6e0d200ae756 Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Mon, 17 Feb 2025 10:23:39 +0000 Subject: [PATCH 6/7] minor changes --- barretenberg/ts/src/barretenberg/backend.ts | 6 +-- barretenberg/ts/src/barretenberg_api/index.ts | 39 +++++++++---------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/barretenberg/ts/src/barretenberg/backend.ts b/barretenberg/ts/src/barretenberg/backend.ts index 91c98d4497fc..4ee2546f23c9 100644 --- a/barretenberg/ts/src/barretenberg/backend.ts +++ b/barretenberg/ts/src/barretenberg/backend.ts @@ -9,9 +9,6 @@ import { reconstructHonkProof, reconstructUltraPlonkProof, } from '../proof/index.js'; -import createDebug from 'debug'; - -const debug = createDebug('backend-ts'); export class UltraPlonkBackend { // These type assertions are used so that we don't @@ -392,11 +389,10 @@ export class AztecClientBackend { return this.api.acirProveAndVerifyAztecClient(this.acirMsgpack, witnessMsgpack); } - // STARTER async gates(): Promise { // call function on API await this.instantiate(); - return this.api.acirGatesAztecClient( this.acirMsgpack); + return this.api.acirGatesAztecClient(this.acirMsgpack); } async destroy(): Promise { diff --git a/barretenberg/ts/src/barretenberg_api/index.ts b/barretenberg/ts/src/barretenberg_api/index.ts index 24d7dcb9e8fb..135bed351253 100644 --- a/barretenberg/ts/src/barretenberg_api/index.ts +++ b/barretenberg/ts/src/barretenberg_api/index.ts @@ -12,29 +12,28 @@ import { OutputType, } from '../serialize/index.js'; import { Fr, Fq, Point, Buffer32, Buffer128, Ptr } from '../types/index.js'; -import createDebug from 'debug'; -const log = createDebug('index-ts'); - function parseBigEndianU32Array(buffer: Uint8Array, hasSizePrefix = false): number[] { - const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); + const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); - let offset = 0; - let count = buffer.byteLength >>> 2; // default is entire buffer length / 4 + let offset = 0; + let count = buffer.byteLength >>> 2; // default is entire buffer length / 4 - if (hasSizePrefix) { - // Read the first 4 bytes as the size (big-endian). - count = dv.getUint32(0, /* littleEndian= */ false); - offset = 4; - } + if (hasSizePrefix) { + // Read the first 4 bytes as the size (big-endian). + count = dv.getUint32(0, /* littleEndian= */ false); + offset = 4; + } - const out: number[] = new Array(count); - for (let i = 0; i < count; i++) { - out[i] = dv.getUint32(offset, false); - offset += 4; - } + const out: number[] = new Array(count); + for (let i = 0; i < count; i++) { + out[i] = dv.getUint32(offset, false); + offset += 4; + } - return out; + return out; } +import createDebug from 'debug'; +const log = createDebug('index-ts'); export class BarretenbergApi { constructor(protected wasm: BarretenbergWasmWorker | BarretenbergWasmMain) {} @@ -380,9 +379,9 @@ export class BarretenbergApi { return out as [number, number]; } - // STARTER - async acirGatesAztecClient( // cf acirProveAztecClient - acirVec: Uint8Array[] + async acirGatesAztecClient( + // cf acirProveAztecClient + acirVec: Uint8Array[], ): Promise { const inArgs = [acirVec].map(serializeBufferable); const outTypes: OutputType[] = [BufferDeserializer()]; From 62b953ce3ef73955851da12322e1ffebfe0f898c Mon Sep 17 00:00:00 2001 From: iakovenkos Date: Wed, 19 Feb 2025 10:25:12 +0000 Subject: [PATCH 7/7] removed acirGatesMegaHonk starter code --- barretenberg/ts/src/barretenberg_api/index.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/barretenberg/ts/src/barretenberg_api/index.ts b/barretenberg/ts/src/barretenberg_api/index.ts index 135bed351253..523d1899a152 100644 --- a/barretenberg/ts/src/barretenberg_api/index.ts +++ b/barretenberg/ts/src/barretenberg_api/index.ts @@ -1095,22 +1095,6 @@ export class BarretenbergApiSync { return out as any; } - acirGatesMegaHonk( - constraintSystemBuf: Uint8Array, - recursive: boolean, - honkRecursion: boolean, - ): [number, number, number] { - const inArgs = [constraintSystemBuf, recursive, honkRecursion].map(serializeBufferable); - const outTypes: OutputType[] = [NumberDeserializer(), NumberDeserializer()]; - const result = this.wasm.callWasmExport( - 'acir_gate_mega_honk', - inArgs, - outTypes.map(t => t.SIZE_IN_BYTES), - ); - const out = result.map((r, i) => outTypes[i].fromBuffer(r)); - return out as any; - } - acirNewAcirComposer(sizeHint: number): Ptr { const inArgs = [sizeHint].map(serializeBufferable); const outTypes: OutputType[] = [Ptr];