From 43329d0cc3388da6cb2c009e89c7f781705a9eb0 Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Tue, 1 Apr 2025 16:37:32 +0000 Subject: [PATCH 01/11] remove the dependence of the recursive flag for adding the pairing point object --- .../cpp/src/barretenberg/dsl/acir_format/acir_format.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 b44595f6b3c3..33577c2a6857 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -266,7 +266,7 @@ void build_constraints(Builder& builder, AcirProgram& program, const ProgramMeta !constraint_system.avm_recursion_constraints.empty()) { ASSERT(metadata.honk_recursion != 0); builder.add_pairing_point_accumulator(current_aggregation_object); - } else if (metadata.honk_recursion != 0 && builder.is_recursive_circuit) { + } else if (metadata.honk_recursion != 0) { // Make sure the verification key records the public input indices of the // final recursion output. builder.add_pairing_point_accumulator(current_aggregation_object); From 0eef23f7d46ab85c3d35ae5e31e34475f7ec4f78 Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Wed, 2 Apr 2025 22:01:30 +0000 Subject: [PATCH 02/11] remove all references to recursive from api_ultra_honk --- barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp index 702eb7229a7f..0053b58af2c5 100644 --- a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp +++ b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp @@ -34,7 +34,7 @@ Circuit _compute_circuit(const std::string& bytecode_path, // TODO(https://github.com/AztecProtocol/barretenberg/issues/1180): Don't init grumpkin crs when unnecessary. init_grumpkin_crs(1 << CONST_ECCVM_LOG_N); - const acir_format::ProgramMetadata metadata{ .recursive = init_kzg_accumulator, .honk_recursion = honk_recursion }; + const acir_format::ProgramMetadata metadata{ .honk_recursion = honk_recursion }; acir_format::AcirProgram program{ get_constraint_system(bytecode_path, metadata.honk_recursion) }; if (!witness_path.empty()) { @@ -235,7 +235,7 @@ void UltraHonkAPI::write_vk(const Flags& flags, void UltraHonkAPI::gates([[maybe_unused]] const Flags& flags, [[maybe_unused]] const std::filesystem::path& bytecode_path) { - gate_count(bytecode_path, flags.recursive, flags.honk_recursion, flags.include_gates_per_opcode); + gate_count(bytecode_path, /*useless=*/, flags.honk_recursion, flags.include_gates_per_opcode); } void UltraHonkAPI::write_solidity_verifier(const Flags& flags, @@ -273,7 +273,7 @@ void write_recursion_inputs_ultra_honk(const std::string& bytecode_path, init_grumpkin_crs(1 << CONST_ECCVM_LOG_N); ipa_accumulation = true; } - const acir_format::ProgramMetadata metadata{ .recursive = true, .honk_recursion = honk_recursion }; + const acir_format::ProgramMetadata metadata{ .honk_recursion = honk_recursion }; acir_format::AcirProgram program; program.constraints = get_constraint_system(bytecode_path, metadata.honk_recursion); From 6523e4fc0927002544008bcb881ad6ae71289b7a Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Wed, 2 Apr 2025 22:31:51 +0000 Subject: [PATCH 03/11] fix build --- barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp index 0053b58af2c5..8b85ca512334 100644 --- a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp +++ b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp @@ -235,7 +235,7 @@ void UltraHonkAPI::write_vk(const Flags& flags, void UltraHonkAPI::gates([[maybe_unused]] const Flags& flags, [[maybe_unused]] const std::filesystem::path& bytecode_path) { - gate_count(bytecode_path, /*useless=*/, flags.honk_recursion, flags.include_gates_per_opcode); + gate_count(bytecode_path, /*useless=*/false, flags.honk_recursion, flags.include_gates_per_opcode); } void UltraHonkAPI::write_solidity_verifier(const Flags& flags, From 3a151d4164af5969a859269244d63aa977c64c22 Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Wed, 2 Apr 2025 22:51:53 +0000 Subject: [PATCH 04/11] remove --recursive usages in c_bind and main.ts --- .../barretenberg/dsl/acir_proofs/c_bind.cpp | 36 +++----- .../barretenberg/dsl/acir_proofs/c_bind.hpp | 23 +---- barretenberg/ts/src/barretenberg_api/index.ts | 66 ++++--------- barretenberg/ts/src/main.ts | 92 +++++-------------- 4 files changed, 59 insertions(+), 158 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 28b6171c4654..1458d9205e88 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -64,12 +64,9 @@ WASM_EXPORT void acir_create_proof( *out = to_heap_buffer(proof_data); } -WASM_EXPORT void acir_prove_and_verify_ultra_honk(uint8_t const* acir_vec, - bool const* recursive, - uint8_t const* witness_vec, - bool* result) +WASM_EXPORT void acir_prove_and_verify_ultra_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, bool* result) { - const acir_format::ProgramMetadata metadata{ .recursive = *recursive, .honk_recursion = 1 }; + const acir_format::ProgramMetadata metadata{ .honk_recursion = 1 }; acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format(from_buffer>(acir_vec), metadata.honk_recursion), acir_format::witness_buf_to_witness_data(from_buffer>(witness_vec)) @@ -87,12 +84,9 @@ WASM_EXPORT void acir_prove_and_verify_ultra_honk(uint8_t const* acir_vec, info("verified: ", *result); } -WASM_EXPORT void acir_prove_and_verify_mega_honk(uint8_t const* acir_vec, - bool const* recursive, - uint8_t const* witness_vec, - bool* result) +WASM_EXPORT void acir_prove_and_verify_mega_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, bool* result) { - const acir_format::ProgramMetadata metadata{ .recursive = *recursive, .honk_recursion = 0 }; + const acir_format::ProgramMetadata metadata{ .honk_recursion = 0 }; acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format(from_buffer>(acir_vec), metadata.honk_recursion), @@ -309,14 +303,11 @@ WASM_EXPORT void acir_verify_aztec_client(uint8_t const* proof_buf, uint8_t cons *result = ClientIVC::verify(proof, vk); } -WASM_EXPORT void acir_prove_ultra_honk(uint8_t const* acir_vec, - bool const* recursive, - uint8_t const* witness_vec, - uint8_t** out) +WASM_EXPORT void acir_prove_ultra_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out) { // Lambda function to ensure things get freed before proving. UltraProver prover = [&] { - const acir_format::ProgramMetadata metadata{ .recursive = *recursive, .honk_recursion = 1 }; + const acir_format::ProgramMetadata metadata{ .honk_recursion = 1 }; acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format( from_buffer>(acir_vec), metadata.honk_recursion), acir_format::witness_buf_to_witness_data( @@ -330,14 +321,11 @@ WASM_EXPORT void acir_prove_ultra_honk(uint8_t const* acir_vec, *out = to_heap_buffer(to_buffer(proof)); } -WASM_EXPORT void acir_prove_ultra_keccak_honk(uint8_t const* acir_vec, - bool const* recursive, - uint8_t const* witness_vec, - uint8_t** out) +WASM_EXPORT void acir_prove_ultra_keccak_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out) { // Lambda function to ensure things get freed before proving. UltraKeccakProver prover = [&] { - const acir_format::ProgramMetadata metadata{ .recursive = *recursive, .honk_recursion = 1 }; + const acir_format::ProgramMetadata metadata{ .honk_recursion = 1 }; acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format( from_buffer>(acir_vec), metadata.honk_recursion), acir_format::witness_buf_to_witness_data( @@ -380,13 +368,13 @@ WASM_EXPORT void acir_verify_ultra_keccak_honk(uint8_t const* proof_buf, uint8_t *result = verifier.verify_proof(proof); } -WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, bool const* recursive, uint8_t** out) +WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, uint8_t** out) { using DeciderProvingKey = DeciderProvingKey_; using VerificationKey = UltraFlavor::VerificationKey; // lambda to free the builder DeciderProvingKey proving_key = [&] { - const acir_format::ProgramMetadata metadata{ .recursive = *recursive, .honk_recursion = 1 }; + const acir_format::ProgramMetadata metadata{ .honk_recursion = 1 }; acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format( from_buffer>(acir_vec), metadata.honk_recursion) }; auto builder = acir_format::create_circuit(program, metadata); @@ -397,14 +385,14 @@ WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, bool const* r *out = to_heap_buffer(to_buffer(vk)); } -WASM_EXPORT void acir_write_vk_ultra_keccak_honk(uint8_t const* acir_vec, bool const* recursive, uint8_t** out) +WASM_EXPORT void acir_write_vk_ultra_keccak_honk(uint8_t const* acir_vec uint8_t** out) { using DeciderProvingKey = DeciderProvingKey_; using VerificationKey = UltraKeccakFlavor::VerificationKey; // lambda to free the builder DeciderProvingKey proving_key = [&] { - const acir_format::ProgramMetadata metadata{ .recursive = *recursive, .honk_recursion = 1 }; + const acir_format::ProgramMetadata metadata{ .honk_recursion = 1 }; acir_format::AcirProgram program{ acir_format::circuit_buf_to_acir_format( from_buffer>(acir_vec), metadata.honk_recursion) }; auto builder = acir_format::create_circuit(program, metadata); 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 033579e4515e..d5c23142107d 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -60,15 +60,6 @@ WASM_EXPORT void acir_prove_aztec_client(uint8_t const* acir_stack, WASM_EXPORT void acir_verify_aztec_client(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result); -/** - * @brief Fold and verify a set of circuits using ClientIvc - * - */ -WASM_EXPORT void acir_fold_and_verify_program_stack(uint8_t const* constraint_system_buf, - bool const* recursive, - uint8_t const* witness_buf, - bool* result); - WASM_EXPORT void acir_load_verification_key(in_ptr acir_composer_ptr, uint8_t const* vk_buf); WASM_EXPORT void acir_init_verification_key(in_ptr acir_composer_ptr); @@ -94,20 +85,14 @@ WASM_EXPORT void acir_serialize_verification_key_into_fields(in_ptr acir_compose fr::vec_out_buf out_vkey, fr::out_buf out_key_hash); -WASM_EXPORT void acir_prove_ultra_honk(uint8_t const* acir_vec, - bool const* recursive, - uint8_t const* witness_vec, - uint8_t** out); -WASM_EXPORT void acir_prove_ultra_keccak_honk(uint8_t const* acir_vec, - bool const* recursive, - uint8_t const* witness_vec, - uint8_t** out); +WASM_EXPORT void acir_prove_ultra_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out); +WASM_EXPORT void acir_prove_ultra_keccak_honk(uint8_t const* acir_vec, uint8_t const* witness_vec, uint8_t** out); WASM_EXPORT void acir_verify_ultra_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result); WASM_EXPORT void acir_verify_ultra_keccak_honk(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result); -WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, bool const* recursive, uint8_t** out); -WASM_EXPORT void acir_write_vk_ultra_keccak_honk(uint8_t const* acir_vec, bool const* recursive, uint8_t** out); +WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, uint8_t** out); +WASM_EXPORT void acir_write_vk_ultra_keccak_honk(uint8_t const* acir_vec, uint8_t** out); WASM_EXPORT void acir_proof_as_fields_ultra_honk(uint8_t const* proof_buf, fr::vec_out_buf out); diff --git a/barretenberg/ts/src/barretenberg_api/index.ts b/barretenberg/ts/src/barretenberg_api/index.ts index 55a7e72377f9..e08ab1f9bd0f 100644 --- a/barretenberg/ts/src/barretenberg_api/index.ts +++ b/barretenberg/ts/src/barretenberg_api/index.ts @@ -447,10 +447,9 @@ export class BarretenbergApi { async acirProveAndVerifyUltraHonk( constraintSystemBuf: Uint8Array, - recursive: boolean, witnessBuf: Uint8Array, ): Promise { - const inArgs = [constraintSystemBuf, recursive, witnessBuf].map(serializeBufferable); + const inArgs = [constraintSystemBuf, witnessBuf].map(serializeBufferable); const outTypes: OutputType[] = [BoolDeserializer()]; const result = await this.wasm.callWasmExport( 'acir_prove_and_verify_ultra_honk', @@ -463,10 +462,9 @@ export class BarretenbergApi { async acirProveAndVerifyMegaHonk( constraintSystemBuf: Uint8Array, - recursive: boolean, witnessBuf: Uint8Array, ): Promise { - const inArgs = [constraintSystemBuf, recursive, witnessBuf].map(serializeBufferable); + const inArgs = [constraintSystemBuf, witnessBuf].map(serializeBufferable); const outTypes: OutputType[] = [BoolDeserializer()]; const result = await this.wasm.callWasmExport( 'acir_prove_and_verify_mega_honk', @@ -477,22 +475,6 @@ export class BarretenbergApi { return out[0]; } - async acirFoldAndVerifyProgramStack( - constraintSystemBuf: Uint8Array, - recursive: boolean, - witnessBuf: Uint8Array, - ): Promise { - const inArgs = [constraintSystemBuf, recursive, witnessBuf].map(serializeBufferable); - const outTypes: OutputType[] = [BoolDeserializer()]; - const result = await this.wasm.callWasmExport( - 'acir_fold_and_verify_program_stack', - inArgs, - outTypes.map(t => t.SIZE_IN_BYTES), - ); - const out = result.map((r, i) => outTypes[i].fromBuffer(r)); - return out[0]; - } - async acirLoadVerificationKey(acirComposerPtr: Ptr, vkBuf: Uint8Array): Promise { const inArgs = [acirComposerPtr, vkBuf].map(serializeBufferable); const outTypes: OutputType[] = []; @@ -629,8 +611,8 @@ export class BarretenbergApi { return out[0]; } - async acirProveUltraHonk(acirVec: Uint8Array, recursive: boolean, witnessVec: Uint8Array): Promise { - const inArgs = [acirVec, recursive, witnessVec].map(serializeBufferable); + async acirProveUltraHonk(acirVec: Uint8Array, witnessVec: Uint8Array): Promise { + const inArgs = [acirVec, witnessVec].map(serializeBufferable); const outTypes: OutputType[] = [BufferDeserializer()]; const result = await this.wasm.callWasmExport( 'acir_prove_ultra_honk', @@ -641,8 +623,8 @@ export class BarretenbergApi { return out[0]; } - async acirProveUltraKeccakHonk(acirVec: Uint8Array, recursive: boolean, witnessVec: Uint8Array): Promise { - const inArgs = [acirVec, recursive, witnessVec].map(serializeBufferable); + async acirProveUltraKeccakHonk(acirVec: Uint8Array, witnessVec: Uint8Array): Promise { + const inArgs = [acirVec, witnessVec].map(serializeBufferable); const outTypes: OutputType[] = [BufferDeserializer()]; const result = await this.wasm.callWasmExport( 'acir_prove_ultra_keccak_honk', @@ -677,8 +659,8 @@ export class BarretenbergApi { return out[0]; } - async acirWriteVkUltraHonk(acirVec: Uint8Array, recursive: boolean): Promise { - const inArgs = [acirVec, recursive].map(serializeBufferable); + async acirWriteVkUltraHonk(acirVec: Uint8Array): Promise { + const inArgs = [acirVec].map(serializeBufferable); const outTypes: OutputType[] = [BufferDeserializer()]; const result = await this.wasm.callWasmExport( 'acir_write_vk_ultra_honk', @@ -689,8 +671,8 @@ export class BarretenbergApi { return out[0]; } - async acirWriteVkUltraKeccakHonk(acirVec: Uint8Array, recursive: boolean): Promise { - const inArgs = [acirVec, recursive].map(serializeBufferable); + async acirWriteVkUltraKeccakHonk(acirVec: Uint8Array): Promise { + const inArgs = [acirVec].map(serializeBufferable); const outTypes: OutputType[] = [BufferDeserializer()]; const result = await this.wasm.callWasmExport( 'acir_write_vk_ultra_keccak_honk', @@ -1146,8 +1128,8 @@ export class BarretenbergApiSync { return out[0]; } - acirProveAndVerifyUltraHonk(constraintSystemBuf: Uint8Array, recursive: boolean, witnessBuf: Uint8Array): boolean { - const inArgs = [constraintSystemBuf, recursive, witnessBuf].map(serializeBufferable); + acirProveAndVerifyUltraHonk(constraintSystemBuf: Uint8Array, witnessBuf: Uint8Array): boolean { + const inArgs = [constraintSystemBuf, witnessBuf].map(serializeBufferable); const outTypes: OutputType[] = [BoolDeserializer()]; const result = this.wasm.callWasmExport( 'acir_prove_and_verify_ultra_honk', @@ -1158,8 +1140,8 @@ export class BarretenbergApiSync { return out[0]; } - acirProveAndVerifyMegaHonk(constraintSystemBuf: Uint8Array, recursive: boolean, witnessBuf: Uint8Array): boolean { - const inArgs = [constraintSystemBuf, recursive, witnessBuf].map(serializeBufferable); + acirProveAndVerifyMegaHonk(constraintSystemBuf: Uint8Array, witnessBuf: Uint8Array): boolean { + const inArgs = [constraintSystemBuf, witnessBuf].map(serializeBufferable); const outTypes: OutputType[] = [BoolDeserializer()]; const result = this.wasm.callWasmExport( 'acir_prove_and_verify_mega_honk', @@ -1170,18 +1152,6 @@ export class BarretenbergApiSync { return out[0]; } - acirFoldAndVerifyProgramStack(constraintSystemBuf: Uint8Array, recursive: boolean, witnessBuf: Uint8Array): boolean { - const inArgs = [constraintSystemBuf, recursive, witnessBuf].map(serializeBufferable); - const outTypes: OutputType[] = [BoolDeserializer()]; - const result = this.wasm.callWasmExport( - 'acir_fold_and_verify_program_stack', - inArgs, - outTypes.map(t => t.SIZE_IN_BYTES), - ); - const out = result.map((r, i) => outTypes[i].fromBuffer(r)); - return out[0]; - } - acirLoadVerificationKey(acirComposerPtr: Ptr, vkBuf: Uint8Array): void { const inArgs = [acirComposerPtr, vkBuf].map(serializeBufferable); const outTypes: OutputType[] = []; @@ -1278,8 +1248,8 @@ export class BarretenbergApiSync { return out as any; } - acirProveUltraHonk(acirVec: Uint8Array, recursive: boolean, witnessVec: Uint8Array): Uint8Array { - const inArgs = [acirVec, recursive, witnessVec].map(serializeBufferable); + acirProveUltraHonk(acirVec: Uint8Array, witnessVec: Uint8Array): Uint8Array { + const inArgs = [acirVec, witnessVec].map(serializeBufferable); const outTypes: OutputType[] = [BufferDeserializer()]; const result = this.wasm.callWasmExport( 'acir_prove_ultra_honk', @@ -1302,8 +1272,8 @@ export class BarretenbergApiSync { return out[0]; } - acirWriteVkUltraHonk(acirVec: Uint8Array, recursive: boolean): Uint8Array { - const inArgs = [acirVec, recursive].map(serializeBufferable); + acirWriteVkUltraHonk(acirVec: Uint8Array): Uint8Array { + const inArgs = [acirVec].map(serializeBufferable); const outTypes: OutputType[] = [BufferDeserializer()]; const result = this.wasm.callWasmExport( 'acir_write_vk_ultra_honk', diff --git a/barretenberg/ts/src/main.ts b/barretenberg/ts/src/main.ts index 3938f5688b3a..7dd6c6d78e37 100755 --- a/barretenberg/ts/src/main.ts +++ b/barretenberg/ts/src/main.ts @@ -108,12 +108,13 @@ async function initUltraPlonk( return { api, acirComposer, circuitSize, subgroupSize }; } -async function initUltraHonk(bytecodePath: string, recursive: boolean, crsPath: string) { +async function initUltraHonk(bytecodePath: string, crsPath: string) { const api = await Barretenberg.new({ threads }); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1248): Get rid of this call to avoid building the circuit twice. // TODO(https://github.com/AztecProtocol/barretenberg/issues/1126): use specific UltraHonk function - const circuitSize = await getGatesUltra(bytecodePath, recursive, /*honkRecursion=*/ true, api); + // recursive here is useless for UH, as it does not affect anything + const circuitSize = await getGatesUltra(bytecodePath, /*recursive=*/ false, /*honkRecursion=*/ true, api); // TODO(https://github.com/AztecProtocol/barretenberg/issues/811): remove subgroupSizeOverride hack for goblin const dyadicCircuitSize = Math.pow(2, Math.ceil(Math.log2(circuitSize))); @@ -185,17 +186,16 @@ export async function proveAndVerify(bytecodePath: string, recursive: boolean, w export async function proveAndVerifyUltraHonk( bytecodePath: string, - recursive: boolean, witnessPath: string, crsPath: string, ) { /* eslint-disable camelcase */ - const { api } = await initUltraHonk(bytecodePath, false, crsPath); + const { api } = await initUltraHonk(bytecodePath, crsPath); try { const bytecode = getBytecode(bytecodePath); const witness = getWitness(witnessPath); - const verified = await api.acirProveAndVerifyUltraHonk(bytecode, recursive, witness); + const verified = await api.acirProveAndVerifyUltraHonk(bytecode, witness); return verified; } finally { await api.destroy(); @@ -205,7 +205,6 @@ export async function proveAndVerifyUltraHonk( export async function proveAndVerifyMegaHonk( bytecodePath: string, - recursive: boolean, witnessPath: string, crsPath: string, ) { @@ -215,7 +214,7 @@ export async function proveAndVerifyMegaHonk( const bytecode = getBytecode(bytecodePath); const witness = getWitness(witnessPath); - const verified = await api.acirProveAndVerifyMegaHonk(bytecode, recursive, witness); + const verified = await api.acirProveAndVerifyMegaHonk(bytecode, witness); return verified; } finally { await api.destroy(); @@ -239,27 +238,6 @@ export async function proveAndVerifyAztecClient(bytecodePath: string, witnessPat /* eslint-enable camelcase */ } -export async function foldAndVerifyProgram( - bytecodePath: string, - recursive: boolean, - witnessPath: string, - crsPath: string, -) { - /* eslint-disable camelcase */ - const { api } = await initClientIVC(crsPath); - try { - const bytecode = getBytecode(bytecodePath); - const witness = getWitness(witnessPath); - - const verified = await api.acirFoldAndVerifyProgramStack(bytecode, recursive, witness); - debug(`Verification ${verified ? 'successful' : 'failed'}`); - return verified; - } finally { - await api.destroy(); - } - /* eslint-enable camelcase */ -} - export async function prove( bytecodePath: string, recursive: boolean, @@ -335,7 +313,7 @@ export async function contract(outputPath: string, vkPath: string, crsPath: stri } export async function contractUltraHonk(bytecodePath: string, vkPath: string, crsPath: string, outputPath: string) { - const { api } = await initUltraHonk(bytecodePath, false, crsPath); + const { api } = await initUltraHonk(bytecodePath, crsPath); try { debug(`Creating UltraHonk verifier contract bytecode=${bytecodePath} vk=${vkPath}`); const bytecode = getBytecode(bytecodePath); @@ -444,22 +422,21 @@ export async function vkAsFields(vkPath: string, vkeyOutputPath: string, crsPath export async function proveUltraHonk( bytecodePath: string, - recursive: boolean, witnessPath: string, crsPath: string, outputPath: string, options?: UltraHonkBackendOptions, ) { - const { api } = await initUltraHonk(bytecodePath, recursive, crsPath); + const { api } = await initUltraHonk(bytecodePath, crsPath); try { - debug(`Creating UltraHonk proof bytecode=${bytecodePath} recursive=${recursive}`); + debug(`Creating UltraHonk proof bytecode=${bytecodePath}`); const bytecode = getBytecode(bytecodePath); const witness = getWitness(witnessPath); const acirProveUltraHonk = options?.keccak ? api.acirProveUltraKeccakHonk.bind(api) : api.acirProveUltraHonk.bind(api); - const proof = await acirProveUltraHonk(bytecode, recursive, witness); + const proof = await acirProveUltraHonk(bytecode, witness); if (outputPath === '-') { process.stdout.write(proof); @@ -475,20 +452,19 @@ export async function proveUltraHonk( export async function writeVkUltraHonk( bytecodePath: string, - recursive: boolean, crsPath: string, outputPath: string, options?: UltraHonkBackendOptions, ) { - const { api } = await initUltraHonk(bytecodePath, recursive, crsPath); + const { api } = await initUltraHonk(bytecodePath, crsPath); try { const bytecode = getBytecode(bytecodePath); - debug(`Initializing UltraHonk verification key bytecode=${bytecodePath} recursive=${recursive}`); + debug(`Initializing UltraHonk verification key bytecode=${bytecodePath}`); const acirWriteVkUltraHonk = options?.keccak ? api.acirWriteVkUltraKeccakHonk.bind(api) : api.acirWriteVkUltraHonk.bind(api); - const vk = await acirWriteVkUltraHonk(bytecode, recursive); + const vk = await acirWriteVkUltraHonk(bytecode); if (outputPath === '-') { process.stdout.write(vk); @@ -592,11 +568,10 @@ program .command('prove_and_verify_ultra_honk') .description('Generate an UltraHonk proof and verify it. Process exits with success or failure code.') .option('-b, --bytecode-path ', 'Specify the bytecode path', './target/program.json') - .option('-r, --recursive', 'Whether to use a SNARK friendly proof', false) .option('-w, --witness-path ', 'Specify the witness path', './target/witness.gz') - .action(async ({ bytecodePath, recursive, witnessPath }) => { + .action(async ({ bytecodePath, witnessPath }) => { const { crsPath } = handleGlobalOptions(); - const result = await proveAndVerifyUltraHonk(bytecodePath, recursive, witnessPath, crsPath); + const result = await proveAndVerifyUltraHonk(bytecodePath, witnessPath, crsPath); process.exit(result ? 0 : 1); }); @@ -604,11 +579,10 @@ program .command('prove_and_verify_mega_honk') .description('Generate a MegaHonk proof and verify it. Process exits with success or failure code.') .option('-b, --bytecode-path ', 'Specify the bytecode path', './target/program.json') - .option('-r, --recursive', 'Whether to use a SNARK friendly proof', false) .option('-w, --witness-path ', 'Specify the witness path', './target/witness.gz') - .action(async ({ bytecodePath, recursive, witnessPath }) => { + .action(async ({ bytecodePath, witnessPath }) => { const { crsPath } = handleGlobalOptions(); - const result = await proveAndVerifyMegaHonk(bytecodePath, recursive, witnessPath, crsPath); + const result = await proveAndVerifyMegaHonk(bytecodePath, witnessPath, crsPath); process.exit(result ? 0 : 1); }); @@ -623,18 +597,6 @@ program process.exit(result ? 0 : 1); }); -program - .command('fold_and_verify_program') - .description('Accumulate a set of circuits using ClientIvc then verify. Process exits with success or failure code.') - .option('-b, --bytecode-path ', 'Specify the bytecode path', './target/program.json') - .option('-r, --recursive', 'Create a SNARK friendly proof', false) - .option('-w, --witness-path ', 'Specify the witness path', './target/witness.gz') - .action(async ({ bytecodePath, recursive, witnessPath }) => { - const { crsPath } = handleGlobalOptions(); - const result = await foldAndVerifyProgram(bytecodePath, recursive, witnessPath, crsPath); - process.exit(result ? 0 : 1); - }); - program .command('prove') .description('Generate a proof and write it to a file.') @@ -738,46 +700,42 @@ program .command('prove_ultra_honk') .description('Generate a proof and write it to a file.') .option('-b, --bytecode-path ', 'Specify the bytecode path', './target/program.json') - .option('-r, --recursive', 'Create a SNARK friendly proof', false) .option('-w, --witness-path ', 'Specify the witness path', './target/witness.gz') .option('-o, --output-path ', 'Specify the proof output path', './proofs/proof') - .action(async ({ bytecodePath, recursive, witnessPath, outputPath }) => { + .action(async ({ bytecodePath, witnessPath, outputPath }) => { const { crsPath } = handleGlobalOptions(); - await proveUltraHonk(bytecodePath, recursive, witnessPath, crsPath, outputPath); + await proveUltraHonk(bytecodePath, witnessPath, crsPath, outputPath); }); program .command('prove_ultra_keccak_honk') .description('Generate a proof and write it to a file.') .option('-b, --bytecode-path ', 'Specify the bytecode path', './target/program.json') - .option('-r, --recursive', 'Create a SNARK friendly proof', false) .option('-w, --witness-path ', 'Specify the witness path', './target/witness.gz') .option('-o, --output-path ', 'Specify the proof output path', './proofs/proof') - .action(async ({ bytecodePath, recursive, witnessPath, outputPath, crsPath }) => { + .action(async ({ bytecodePath, witnessPath, outputPath, crsPath }) => { handleGlobalOptions(); - await proveUltraHonk(bytecodePath, recursive, witnessPath, crsPath, outputPath, { keccak: true }); + await proveUltraHonk(bytecodePath, witnessPath, crsPath, outputPath, { keccak: true }); }); program .command('write_vk_ultra_honk') .description('Output verification key.') .option('-b, --bytecode-path ', 'Specify the bytecode path', './target/program.json') - .option('-r, --recursive', 'Create a SNARK friendly proof', false) .requiredOption('-o, --output-path ', 'Specify the path to write the key') - .action(async ({ bytecodePath, recursive, outputPath }) => { + .action(async ({ bytecodePath, outputPath }) => { const { crsPath } = handleGlobalOptions(); - await writeVkUltraHonk(bytecodePath, recursive, crsPath, outputPath); + await writeVkUltraHonk(bytecodePath, crsPath, outputPath); }); program .command('write_vk_ultra_keccak_honk') .description('Output verification key.') .option('-b, --bytecode-path ', 'Specify the bytecode path', './target/program.json') - .option('-r, --recursive', 'Create a SNARK friendly proof', false) .requiredOption('-o, --output-path ', 'Specify the path to write the key') - .action(async ({ bytecodePath, recursive, outputPath, crsPath }) => { + .action(async ({ bytecodePath, outputPath, crsPath }) => { handleGlobalOptions(); - await writeVkUltraHonk(bytecodePath, recursive, crsPath, outputPath, { keccak: true }); + await writeVkUltraHonk(bytecodePath, crsPath, outputPath, { keccak: true }); }); program From 4af2e0df1405af3a0bf609a4713dc508a375b62a Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Wed, 2 Apr 2025 23:08:15 +0000 Subject: [PATCH 05/11] just go crazy trying to remove things --- barretenberg/acir_tests/bootstrap.sh | 4 ++-- barretenberg/acir_tests/flows/sol_honk.sh | 1 - barretenberg/acir_tests/flows/sol_honk_zk.sh | 1 - barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp | 4 +--- barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp | 2 +- barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp | 2 -- noir-projects/scripts/generate_vk_json.js | 4 +--- 7 files changed, 5 insertions(+), 13 deletions(-) diff --git a/barretenberg/acir_tests/bootstrap.sh b/barretenberg/acir_tests/bootstrap.sh index 1a1e6f36b369..03816b07306c 100755 --- a/barretenberg/acir_tests/bootstrap.sh +++ b/barretenberg/acir_tests/bootstrap.sh @@ -179,8 +179,8 @@ function test_cmds_internal { for t in $honk_tests; do echo SYS=ultra_honk FLOW=prove_then_verify $run_test $(basename $t) done - echo SYS=ultra_honk FLOW=prove_then_verify RECURSIVE=true $run_test assert_statement - echo SYS=ultra_honk FLOW=prove_then_verify RECURSIVE=true $run_test double_verify_honk_proof + echo SYS=ultra_honk FLOW=prove_then_verify $run_test assert_statement + echo SYS=ultra_honk FLOW=prove_then_verify $run_test double_verify_honk_proof echo SYS=ultra_honk FLOW=prove_then_verify HASH=keccak $run_test assert_statement echo SYS=ultra_honk FLOW=prove_then_verify ROLLUP=true $run_test verify_rollup_honk_proof diff --git a/barretenberg/acir_tests/flows/sol_honk.sh b/barretenberg/acir_tests/flows/sol_honk.sh index 3f961e75d72a..eeec6940b08c 100755 --- a/barretenberg/acir_tests/flows/sol_honk.sh +++ b/barretenberg/acir_tests/flows/sol_honk.sh @@ -4,7 +4,6 @@ set -eu VFLAG=${VERBOSE:+-v} BFLAG="-b ./target/program.json" FLAGS="-c $CRS_PATH $VFLAG --scheme ultra_honk" -[ "${RECURSIVE}" = "true" ] && FLAGS+=" --recursive" PROVE_FLAGS="$FLAGS $BFLAG --oracle_hash keccak --output_format bytes_and_fields --write_vk --input_type single_circuit" VERIFY_FLAGS="$FLAGS --oracle_hash keccak" diff --git a/barretenberg/acir_tests/flows/sol_honk_zk.sh b/barretenberg/acir_tests/flows/sol_honk_zk.sh index a7c25f7a4853..d2cb24543aee 100755 --- a/barretenberg/acir_tests/flows/sol_honk_zk.sh +++ b/barretenberg/acir_tests/flows/sol_honk_zk.sh @@ -4,7 +4,6 @@ set -eux VFLAG=${VERBOSE:+-v} BFLAG="-b ./target/program.json" FLAGS="-c $CRS_PATH $VFLAG --scheme ultra_honk --zk" -[ "${RECURSIVE}" = "true" ] && FLAGS+=" --recursive" PROTOCOL_FLAGS=" --honk_recursion 1 --oracle_hash keccak" outdir=$(mktemp -d) diff --git a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp index 8b85ca512334..c40d59e13944 100644 --- a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp +++ b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp @@ -20,9 +20,7 @@ namespace bb { extern std::string CRS_PATH; template -Circuit _compute_circuit(const std::string& bytecode_path, - const std::string& witness_path, - const bool init_kzg_accumulator) +Circuit _compute_circuit(const std::string& bytecode_path, const std::string& witness_path) { uint32_t honk_recursion = 0; if constexpr (IsAnyOf) { 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 1458d9205e88..7bdfb595d0ca 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -385,7 +385,7 @@ WASM_EXPORT void acir_write_vk_ultra_honk(uint8_t const* acir_vec, uint8_t** out *out = to_heap_buffer(to_buffer(vk)); } -WASM_EXPORT void acir_write_vk_ultra_keccak_honk(uint8_t const* acir_vec uint8_t** out) +WASM_EXPORT void acir_write_vk_ultra_keccak_honk(uint8_t const* acir_vec, uint8_t** out) { using DeciderProvingKey = DeciderProvingKey_; using VerificationKey = UltraKeccakFlavor::VerificationKey; 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 d5c23142107d..ac6303fc9405 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.hpp @@ -36,7 +36,6 @@ WASM_EXPORT void acir_create_proof(in_ptr acir_composer_ptr, * */ WASM_EXPORT void acir_prove_and_verify_ultra_honk(uint8_t const* constraint_system_buf, - bool const* recursive, uint8_t const* witness_buf, bool* result); @@ -45,7 +44,6 @@ WASM_EXPORT void acir_prove_and_verify_ultra_honk(uint8_t const* constraint_syst * @deprecated */ WASM_EXPORT void acir_prove_and_verify_mega_honk(uint8_t const* constraint_system_buf, - bool const* recursive, uint8_t const* witness_buf, bool* result); diff --git a/noir-projects/scripts/generate_vk_json.js b/noir-projects/scripts/generate_vk_json.js index 64a819a29fe4..3fb3575ca42f 100644 --- a/noir-projects/scripts/generate_vk_json.js +++ b/noir-projects/scripts/generate_vk_json.js @@ -157,9 +157,7 @@ async function generateVKData( honk_recursion = 1; } - const writeVkCommand = `${BB_BIN_PATH} ${write_vk_flow} -h ${honk_recursion} -b "${artifactPath}" -o "${binaryVkPath}" ${ - isRecursive ? "--recursive" : "" - }`; + const writeVkCommand = `${BB_BIN_PATH} ${write_vk_flow} -h ${honk_recursion} -b "${artifactPath}" -o "${binaryVkPath}"`; console.log("WRITE VK CMD: ", writeVkCommand); From 61237134f31f6212ca35d881cf761c40019c079f Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Thu, 3 Apr 2025 01:01:12 +0000 Subject: [PATCH 06/11] more eliminating --- .../src/barretenberg/api/api_ultra_honk.cpp | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp index c40d59e13944..ab39fd488a1f 100644 --- a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp +++ b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp @@ -42,11 +42,9 @@ Circuit _compute_circuit(const std::string& bytecode_path, const std::string& wi } template -UltraProver_ _compute_prover(const std::string& bytecode_path, - const std::string& witness_path, - const bool init_kzg_accumulator) +UltraProver_ _compute_prover(const std::string& bytecode_path, const std::string& witness_path) { - auto prover = UltraProver_{ _compute_circuit(bytecode_path, witness_path, init_kzg_accumulator) }; + auto prover = UltraProver_{ _compute_circuit(bytecode_path, witness_path) }; size_t required_crs_size = prover.proving_key->proving_key.circuit_size; if constexpr (Flavor::HasZK) { @@ -57,11 +55,10 @@ UltraProver_ _compute_prover(const std::string& bytecode_path, } template -PubInputsProofAndKey _compute_vk(const bool init_kzg_accumulator, - const std::filesystem::path& bytecode_path, +PubInputsProofAndKey _compute_vk(const std::filesystem::path& bytecode_path, const std::filesystem::path& witness_path) { - auto prover = _compute_prover(bytecode_path.string(), witness_path.string(), init_kzg_accumulator); + auto prover = _compute_prover(bytecode_path.string(), witness_path.string()); return { PublicInputsVector{}, HonkProof{}, std::make_shared(prover.proving_key->proving_key) }; } @@ -71,7 +68,7 @@ PubInputsProofAndKey _prove(const bool compute_vk, const std::filesystem::path& bytecode_path, const std::filesystem::path& witness_path) { - auto prover = _compute_prover(bytecode_path.string(), witness_path.string(), init_kzg_accumulator); + auto prover = _compute_prover(bytecode_path.string(), witness_path.string()); HonkProof concat_pi_and_proof = prover.construct_proof(); size_t num_inner_public_inputs = prover.proving_key->proving_key.num_public_inputs; if (init_kzg_accumulator) { @@ -215,16 +212,14 @@ void UltraHonkAPI::write_vk(const Flags& flags, { const auto _write = [&](auto&& _prove_output) { write(_prove_output, flags.output_format, "vk", output_path); }; - const bool init = flags.init_kzg_accumulator; - if (flags.ipa_accumulation) { - _write(_compute_vk(init, bytecode_path, "")); + _write(_compute_vk(bytecode_path, "")); } else if (flags.oracle_hash_type == "poseidon2") { - _write(_compute_vk(init, bytecode_path, "")); + _write(_compute_vk(bytecode_path, "")); } else if (flags.oracle_hash_type == "keccak" && !flags.zk) { - _write(_compute_vk(init, bytecode_path, "")); + _write(_compute_vk(bytecode_path, "")); } else if (flags.oracle_hash_type == "keccak" && flags.zk) { - _write(_compute_vk(init, bytecode_path, "")); + _write(_compute_vk(bytecode_path, "")); } else { throw_or_abort("Invalid proving options specified in _prove"); } From 582b317f212e05f23638c7c9113d2b1f0cb9566b Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Thu, 3 Apr 2025 14:57:46 +0000 Subject: [PATCH 07/11] get things to compile and remove generateProofForAggregation --- barretenberg/ts/src/barretenberg/backend.ts | 59 ++++----------------- barretenberg/ts/src/proof/index.ts | 4 +- yarn-project/noir-bb-bench/src/index.ts | 2 +- 3 files changed, 14 insertions(+), 51 deletions(-) diff --git a/barretenberg/ts/src/barretenberg/backend.ts b/barretenberg/ts/src/barretenberg/backend.ts index ffe15fce9869..42ae6e125add 100644 --- a/barretenberg/ts/src/barretenberg/backend.ts +++ b/barretenberg/ts/src/barretenberg/backend.ts @@ -9,6 +9,7 @@ import { reconstructHonkProof, reconstructUltraPlonkProof, splitHonkProof, + AGGREGATION_OBJECT_LENGTH, } from '../proof/index.js'; export class AztecClientBackendError extends Error { @@ -202,61 +203,22 @@ export class UltraHonkBackend { ? this.api.acirProveUltraKeccakHonk.bind(this.api) : this.api.acirProveUltraHonk.bind(this.api); - const proofWithPublicInputs = await proveUltraHonk( - this.acirUncompressedBytecode, - this.circuitOptions.recursive, - gunzip(compressedWitness), - ); + const proofWithPublicInputs = await proveUltraHonk(this.acirUncompressedBytecode, gunzip(compressedWitness)); // Write VK to get the number of public inputs const writeVKUltraHonk = options?.keccak ? this.api.acirWriteVkUltraKeccakHonk.bind(this.api) : this.api.acirWriteVkUltraHonk.bind(this.api); - const vk = await writeVKUltraHonk(this.acirUncompressedBytecode, this.circuitOptions.recursive); + const vk = await writeVKUltraHonk(this.acirUncompressedBytecode); const vkAsFields = await this.api.acirVkAsFieldsUltraHonk(new RawBuffer(vk)); // Item at index 1 in VK is the number of public inputs - const numPublicInputs = Number(vkAsFields[1].toString()); - - const { proof, publicInputs: publicInputsBytes } = splitHonkProof(proofWithPublicInputs, numPublicInputs); - const publicInputs = deflattenFields(publicInputsBytes); - - return { proof, publicInputs }; - } - - async generateProofForRecursiveAggregation( - compressedWitness: Uint8Array, - options?: UltraHonkBackendOptions, - ): Promise { - await this.instantiate(); - - const proveUltraHonk = options?.keccak - ? this.api.acirProveUltraKeccakHonk.bind(this.api) - : this.api.acirProveUltraHonk.bind(this.api); - - const proofWithPublicInputs = await proveUltraHonk( - this.acirUncompressedBytecode, - this.circuitOptions.recursive, - gunzip(compressedWitness), - ); - // Write VK to get the number of public inputs - const writeVKUltraHonk = options?.keccak - ? this.api.acirWriteVkUltraKeccakHonk.bind(this.api) - : this.api.acirWriteVkUltraHonk.bind(this.api); - - const vk = await writeVKUltraHonk(this.acirUncompressedBytecode, this.circuitOptions.recursive); - const vkAsFields = await this.api.acirVkAsFieldsUltraHonk(new RawBuffer(vk)); - - // some public inputs are handled specially - const numKZGAccumulatorFieldElements = 16; const publicInputsSizeIndex = 1; // index into VK for numPublicInputs - const numPublicInputs = Number(vkAsFields[publicInputsSizeIndex].toString()) - numKZGAccumulatorFieldElements; - - const { proof: proofBytes, publicInputs: publicInputsBytes } = splitHonkProof(proofWithPublicInputs, numPublicInputs); + const numPublicInputs = Number(vkAsFields[publicInputsSizeIndex].toString()) - AGGREGATION_OBJECT_LENGTH; + const { proof, publicInputs: publicInputsBytes } = splitHonkProof(proofWithPublicInputs, numPublicInputs); const publicInputs = deflattenFields(publicInputsBytes); - const proof = deflattenFields(proofBytes); return { proof, publicInputs }; } @@ -273,22 +235,21 @@ export class UltraHonkBackend { ? this.api.acirVerifyUltraKeccakHonk.bind(this.api) : this.api.acirVerifyUltraHonk.bind(this.api); - const vkBuf = await writeVkUltraHonk(this.acirUncompressedBytecode, this.circuitOptions.recursive); + const vkBuf = await writeVkUltraHonk(this.acirUncompressedBytecode); return await verifyUltraHonk(proof, new RawBuffer(vkBuf)); } async getVerificationKey(options?: UltraHonkBackendOptions): Promise { await this.instantiate(); return options?.keccak - ? await this.api.acirWriteVkUltraKeccakHonk(this.acirUncompressedBytecode, this.circuitOptions.recursive) - : await this.api.acirWriteVkUltraHonk(this.acirUncompressedBytecode, this.circuitOptions.recursive); + ? await this.api.acirWriteVkUltraKeccakHonk(this.acirUncompressedBytecode) + : await this.api.acirWriteVkUltraHonk(this.acirUncompressedBytecode); } /** @description Returns a solidity verifier */ async getSolidityVerifier(vk?: Uint8Array): Promise { await this.instantiate(); - const vkBuf = - vk ?? (await this.api.acirWriteVkUltraKeccakHonk(this.acirUncompressedBytecode, this.circuitOptions.recursive)); + const vkBuf = vk ?? (await this.api.acirWriteVkUltraKeccakHonk(this.acirUncompressedBytecode)); return await this.api.acirHonkSolidityVerifier(this.acirUncompressedBytecode, new RawBuffer(vkBuf)); } @@ -310,7 +271,7 @@ export class UltraHonkBackend { // TODO: perhaps we should put this in the init function. Need to benchmark // TODO how long it takes. - const vkBuf = await this.api.acirWriteVkUltraHonk(this.acirUncompressedBytecode, this.circuitOptions.recursive); + const vkBuf = await this.api.acirWriteVkUltraHonk(this.acirUncompressedBytecode); const vk = await this.api.acirVkAsFieldsUltraHonk(vkBuf); return { diff --git a/barretenberg/ts/src/proof/index.ts b/barretenberg/ts/src/proof/index.ts index 36b93978245e..cc3f9e7f3e2a 100644 --- a/barretenberg/ts/src/proof/index.ts +++ b/barretenberg/ts/src/proof/index.ts @@ -1,4 +1,4 @@ -import { numToUInt32BE } from "../serialize/serialize.js"; +import { numToUInt32BE } from '../serialize/serialize.js'; /** * @description @@ -11,6 +11,8 @@ export type ProofData = { proof: Uint8Array; }; +export const AGGREGATION_OBJECT_LENGTH = 16; + /** * @description * The representation of a proof diff --git a/yarn-project/noir-bb-bench/src/index.ts b/yarn-project/noir-bb-bench/src/index.ts index 108b3899a97d..1c6009a9a563 100644 --- a/yarn-project/noir-bb-bench/src/index.ts +++ b/yarn-project/noir-bb-bench/src/index.ts @@ -67,7 +67,7 @@ export async function proveCircuit1( const backend = new UltraHonkBackend(bytecode, { threads: threads }, { recursive: true }); try { logger(`proving...`); - const proverOutput = await backend.generateProofForRecursiveAggregation(witness); + const proverOutput = await backend.generateProof(witness); logger(`done generating recursive proof artifacts.`); return { proof: proverOutput.proof as FixedLengthArray, From c519bbb0046c83a83d61b7a14e711855513d5edd Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Thu, 3 Apr 2025 20:16:47 +0000 Subject: [PATCH 08/11] clean up index.js --- barretenberg/acir_tests/sol-test/src/index.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/barretenberg/acir_tests/sol-test/src/index.js b/barretenberg/acir_tests/sol-test/src/index.js index b966ab4b72ff..3d4948895d57 100644 --- a/barretenberg/acir_tests/sol-test/src/index.js +++ b/barretenberg/acir_tests/sol-test/src/index.js @@ -225,19 +225,11 @@ try { const proof = readFileSync(proofPath); proofStr = proof.toString("hex"); - let publicInputsAsFieldsPath; // PUBLIC_INPUTS_AS_FIELDS is not defined for bb plonk, but is for bb honk and bbjs honk. - try { - publicInputsAsFieldsPath = getEnvVar("PUBLIC_INPUTS_AS_FIELDS"); - } catch (e) { - // noop - } + let publicInputsAsFieldsPath = getEnvVarCanBeUndefined( + "PUBLIC_INPUTS_AS_FIELDS" + ); // PUBLIC_INPUTS_AS_FIELDS is not defined for bb plonk, but is for bb honk and bbjs honk. var publicInputs; - let proofAsFieldsPath; // PROOF_AS_FIELDS is not defined for bbjs, but is for bb plonk and bb honk. - try { - proofAsFieldsPath = getEnvVar("PROOF_AS_FIELDS"); - } catch (e) { - // noop - } + let proofAsFieldsPath = getEnvVar("PROOF_AS_FIELDS"); // PROOF_AS_FIELDS is not defined for bbjs, but is for bb plonk and bb honk. let numExtraPublicInputs = 0; let extraPublicInputs = []; if (proofAsFieldsPath) { From 27774359f42dae9a99ba2061b332e8d22512c0e7 Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Fri, 4 Apr 2025 14:31:02 +0000 Subject: [PATCH 09/11] try changing proof lengths to 456 --- barretenberg/acir_tests/bbjs-test/src/index.ts | 4 ++-- barretenberg/acir_tests/flows/bb_prove_bbjs_verify.sh | 3 ++- barretenberg/acir_tests/flows/bbjs_prove_bb_verify.sh | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/barretenberg/acir_tests/bbjs-test/src/index.ts b/barretenberg/acir_tests/bbjs-test/src/index.ts index 18420da2a368..31cd4ccdd3bf 100644 --- a/barretenberg/acir_tests/bbjs-test/src/index.ts +++ b/barretenberg/acir_tests/bbjs-test/src/index.ts @@ -7,7 +7,7 @@ import assert from "assert"; createDebug.enable("*"); const debug = createDebug("bbjs-test"); -const UH_PROOF_FIELDS_LENGTH = 440; +const UH_PROOF_FIELDS_LENGTH = 456; const BYTES_PER_FIELD = 32; const UH_PROOF_LENGTH_IN_BYTES = UH_PROOF_FIELDS_LENGTH * BYTES_PER_FIELD; @@ -75,7 +75,7 @@ async function verifyProof({ directory }: { directory: string }) { const proof = await fs.readFile(proofPath(directory)); assert( proof.length === UH_PROOF_LENGTH_IN_BYTES, - `Unexpected proof length ${proof.length}` + `Unexpected proof length ${proof.length}, expected ${UH_PROOF_LENGTH_IN_BYTES}` ); const publicInputs = JSON.parse( diff --git a/barretenberg/acir_tests/flows/bb_prove_bbjs_verify.sh b/barretenberg/acir_tests/flows/bb_prove_bbjs_verify.sh index 843bad92880a..aa75f7b42a4b 100755 --- a/barretenberg/acir_tests/flows/bb_prove_bbjs_verify.sh +++ b/barretenberg/acir_tests/flows/bb_prove_bbjs_verify.sh @@ -34,8 +34,9 @@ $BIN write_vk \ # Save public inputs as a separate file (first NUM_PUBLIC_INPUTS fields of proof_fields.json) PROOF_FIELDS_LENGTH=$(jq 'length' $output_dir/proof_fields.json) -UH_PROOF_FIELDS_LENGTH=440 +UH_PROOF_FIELDS_LENGTH=456 NUM_PUBLIC_INPUTS=$((PROOF_FIELDS_LENGTH - UH_PROOF_FIELDS_LENGTH)) +echo $NUM_PUBLIC_INPUTS jq ".[:$NUM_PUBLIC_INPUTS]" $output_dir/proof_fields.json > $output_dir/public_inputs_fields.json # Remove public inputs from the proof (first NUM_PUBLIC_INPUTS*32 bytes) diff --git a/barretenberg/acir_tests/flows/bbjs_prove_bb_verify.sh b/barretenberg/acir_tests/flows/bbjs_prove_bb_verify.sh index 403e0864fe0c..f2b4609a6189 100755 --- a/barretenberg/acir_tests/flows/bbjs_prove_bb_verify.sh +++ b/barretenberg/acir_tests/flows/bbjs_prove_bb_verify.sh @@ -25,7 +25,7 @@ node ../../bbjs-test prove \ # this will not be needed after #11024 NUM_PUBLIC_INPUTS=$(cat $output_dir/public_inputs_fields.json | jq 'length') -UH_PROOF_FIELDS_LENGTH=440 +UH_PROOF_FIELDS_LENGTH=456 PROOF_LENGTH_IN_FIELDS=$((UH_PROOF_FIELDS_LENGTH)) PI_LENGTH_IN_FIELDS=$((NUM_PUBLIC_INPUTS)) # First 4 bytes is PROOF_AND_PI_LENGTH_IN_FIELDS From 6191a58f61af4f950d2d0a73c10cd8fe44f7d135 Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Fri, 4 Apr 2025 16:49:15 +0000 Subject: [PATCH 10/11] fix bbjs sol test --- barretenberg/acir_tests/bbjs-test/src/index.ts | 8 +++++++- barretenberg/acir_tests/flows/bbjs_prove_sol_verify.sh | 1 + barretenberg/acir_tests/sol-test/src/index.js | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/barretenberg/acir_tests/bbjs-test/src/index.ts b/barretenberg/acir_tests/bbjs-test/src/index.ts index 3f8be295825d..7a50b1a1c787 100644 --- a/barretenberg/acir_tests/bbjs-test/src/index.ts +++ b/barretenberg/acir_tests/bbjs-test/src/index.ts @@ -12,6 +12,7 @@ const BYTES_PER_FIELD = 32; const UH_PROOF_LENGTH_IN_BYTES = UH_PROOF_FIELDS_LENGTH * BYTES_PER_FIELD; const proofPath = (dir: string) => path.join(dir, "proof"); +const proofAsFieldsPath = (dir: string) => path.join(dir, "proof_fields.json"); const publicInputsAsFieldsPath = (dir: string) => path.join(dir, "public_inputs_fields.json"); const vkeyPath = (dir: string) => path.join(dir, "vk"); @@ -29,7 +30,7 @@ async function generateProof({ oracleHash?: string; multiThreaded?: boolean; }) { - const { UltraHonkBackend } = await import("@aztec/bb.js"); + const { UltraHonkBackend, deflattenFields } = await import("@aztec/bb.js"); debug(`Generating proof for ${bytecodePath}...`); const circuitArtifact = await fs.readFile(bytecodePath); @@ -58,6 +59,11 @@ async function generateProof({ "Public inputs written to " + publicInputsAsFieldsPath(outputDirectory) ); + await fs.writeFile( + proofAsFieldsPath(outputDirectory), + JSON.stringify(deflattenFields(proof.proof)) + ); + const verificationKey = await backend.getVerificationKey({ keccak: oracleHash === "keccak", }); diff --git a/barretenberg/acir_tests/flows/bbjs_prove_sol_verify.sh b/barretenberg/acir_tests/flows/bbjs_prove_sol_verify.sh index 0d4a9fb5f301..fb85352d9959 100755 --- a/barretenberg/acir_tests/flows/bbjs_prove_sol_verify.sh +++ b/barretenberg/acir_tests/flows/bbjs_prove_sol_verify.sh @@ -31,6 +31,7 @@ $BIN write_solidity_verifier --scheme ultra_honk -k $VK -o $VERIFIER_PATH # Verify the proof using the solidity verifier export PROOF=$output_dir/proof +export PROOF_AS_FIELDS=$output_dir/proof_fields.json export PUBLIC_INPUTS_AS_FIELDS=$output_dir/public_inputs_fields.json export TEST_PATH=$(realpath "../../sol-test/HonkTest.sol") export TESTING_HONK="true" diff --git a/barretenberg/acir_tests/sol-test/src/index.js b/barretenberg/acir_tests/sol-test/src/index.js index a73595bccc09..ff568a3c0415 100644 --- a/barretenberg/acir_tests/sol-test/src/index.js +++ b/barretenberg/acir_tests/sol-test/src/index.js @@ -229,7 +229,7 @@ try { "PUBLIC_INPUTS_AS_FIELDS" ); // PUBLIC_INPUTS_AS_FIELDS is not defined for bb plonk, but is for bb honk and bbjs honk. var publicInputs; - let proofAsFieldsPath = getEnvVar("PROOF_AS_FIELDS"); // PROOF_AS_FIELDS is not defined for bbjs, but is for bb plonk and bb honk. + let proofAsFieldsPath = getEnvVarCanBeUndefined("PROOF_AS_FIELDS"); // PROOF_AS_FIELDS is not defined for bbjs, but is for bb plonk and bb honk. let numExtraPublicInputs = 0; let extraPublicInputs = []; if (proofAsFieldsPath) { From d0cf8c4f0dc975657c64345ea05c95da8b4875b1 Mon Sep 17 00:00:00 2001 From: lucasxia01 Date: Fri, 4 Apr 2025 16:49:30 +0000 Subject: [PATCH 11/11] other cleanup --- .../cpp/src/barretenberg/api/api_ultra_honk.cpp | 17 ++++++----------- barretenberg/ts/src/barretenberg/backend.ts | 1 - barretenberg/ts/src/index.ts | 2 +- barretenberg/ts/src/proof/index.ts | 11 ----------- 4 files changed, 7 insertions(+), 24 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp index 5e18552979a3..3ec7ea54d932 100644 --- a/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp +++ b/barretenberg/cpp/src/barretenberg/api/api_ultra_honk.cpp @@ -64,17 +64,14 @@ PubInputsProofAndKey _compute_vk(const std::filesystem::path& bytecode_path, template PubInputsProofAndKey _prove(const bool compute_vk, - const bool init_kzg_accumulator, const std::filesystem::path& bytecode_path, const std::filesystem::path& witness_path) { auto prover = _compute_prover(bytecode_path.string(), witness_path.string()); HonkProof concat_pi_and_proof = prover.construct_proof(); size_t num_inner_public_inputs = prover.proving_key->proving_key.num_public_inputs; - if (init_kzg_accumulator) { - ASSERT(num_inner_public_inputs >= PAIRING_POINT_ACCUMULATOR_SIZE); - num_inner_public_inputs -= PAIRING_POINT_ACCUMULATOR_SIZE; - } + ASSERT(num_inner_public_inputs >= PAIRING_POINT_ACCUMULATOR_SIZE); + num_inner_public_inputs -= PAIRING_POINT_ACCUMULATOR_SIZE; if constexpr (HasIPAAccumulator) { ASSERT(num_inner_public_inputs >= IPA_CLAIM_SIZE); num_inner_public_inputs -= IPA_CLAIM_SIZE; @@ -162,16 +159,14 @@ void UltraHonkAPI::prove(const Flags& flags, write(_prove_output, flags.output_format, flags.write_vk ? "proof_and_vk" : "proof", output_dir); }; - const bool init = flags.init_kzg_accumulator; - if (flags.ipa_accumulation) { - _write(_prove(flags.write_vk, init, bytecode_path, witness_path)); + _write(_prove(flags.write_vk, bytecode_path, witness_path)); } else if (flags.oracle_hash_type == "poseidon2") { - _write(_prove(flags.write_vk, init, bytecode_path, witness_path)); + _write(_prove(flags.write_vk, bytecode_path, witness_path)); } else if (flags.oracle_hash_type == "keccak" && !flags.zk) { - _write(_prove(flags.write_vk, init, bytecode_path, witness_path)); + _write(_prove(flags.write_vk, bytecode_path, witness_path)); } else if (flags.oracle_hash_type == "keccak" && flags.zk) { - _write(_prove(flags.write_vk, init, bytecode_path, witness_path)); + _write(_prove(flags.write_vk, bytecode_path, witness_path)); } else { throw_or_abort("Invalid proving options specified in _prove"); } diff --git a/barretenberg/ts/src/barretenberg/backend.ts b/barretenberg/ts/src/barretenberg/backend.ts index 42ae6e125add..2aee4496bcdf 100644 --- a/barretenberg/ts/src/barretenberg/backend.ts +++ b/barretenberg/ts/src/barretenberg/backend.ts @@ -5,7 +5,6 @@ import { deflattenFields, flattenFieldsAsArray, ProofData, - ProofDataForRecursion, reconstructHonkProof, reconstructUltraPlonkProof, splitHonkProof, diff --git a/barretenberg/ts/src/index.ts b/barretenberg/ts/src/index.ts index 23159ba7ff9f..b07efdb217b6 100644 --- a/barretenberg/ts/src/index.ts +++ b/barretenberg/ts/src/index.ts @@ -10,4 +10,4 @@ export { } from './barretenberg/index.js'; export { RawBuffer, Fr } from './types/index.js'; -export { splitHonkProof, reconstructHonkProof, ProofData } from './proof/index.js'; +export { splitHonkProof, reconstructHonkProof, deflattenFields, ProofData } from './proof/index.js'; diff --git a/barretenberg/ts/src/proof/index.ts b/barretenberg/ts/src/proof/index.ts index b79e4a12b24e..5cd9df43c931 100644 --- a/barretenberg/ts/src/proof/index.ts +++ b/barretenberg/ts/src/proof/index.ts @@ -13,17 +13,6 @@ export type ProofData = { export const AGGREGATION_OBJECT_LENGTH = 16; -/** - * @description - * The representation of a proof - * */ -export type ProofDataForRecursion = { - /** @description Public inputs of a proof */ - publicInputs: string[]; - /** @description An byte array representing the proof */ - proof: string[]; -}; - // Fields are 32 bytes const fieldByteSize = 32;