From c8bf5f6696d840b20d4a76f445fa6e1644be2594 Mon Sep 17 00:00:00 2001 From: federicobarbacovi <171914500+federicobarbacovi@users.noreply.github.com> Date: Tue, 29 Jul 2025 09:12:23 +0000 Subject: [PATCH 1/6] Introduce InputCommitments --- .../stdlib/merge_verifier/merge_recursive_verifier.cpp | 7 ++++--- .../stdlib/merge_verifier/merge_recursive_verifier.hpp | 7 ++++++- .../cpp/src/barretenberg/ultra_honk/merge_verifier.cpp | 7 ++++--- .../cpp/src/barretenberg/ultra_honk/merge_verifier.hpp | 7 ++++++- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp index 710d838f942a..3c278ef5e319 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp @@ -71,7 +71,7 @@ template std::pair::PairingPoints, typename MergeRecursiveVerifier_::TableCommitments> MergeRecursiveVerifier_::verify_proof(const stdlib::Proof& proof, - const TableCommitments& t_commitments) + const InputCommitments& input_commitments) { using Claims = typename ShplonkVerifier_::LinearCombinationOfClaims; @@ -86,8 +86,9 @@ MergeRecursiveVerifier_::verify_proof(const stdlib::Prooftemplate receive_from_prover("T_PREV_" + std::to_string(idx)); - auto left_table = settings == MergeSettings::PREPEND ? t_commitments[idx] : T_prev_commitment; - auto right_table = settings == MergeSettings::PREPEND ? T_prev_commitment : t_commitments[idx]; + auto left_table = settings == MergeSettings::PREPEND ? input_commitments.t_commitments[idx] : T_prev_commitment; + auto right_table = + settings == MergeSettings::PREPEND ? T_prev_commitment : input_commitments.t_commitments[idx]; table_commitments.emplace_back(left_table); table_commitments.emplace_back(right_table); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp index 984a7bac7712..8598b5b6c656 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp @@ -32,12 +32,17 @@ template class MergeRecursiveVerifier_ { static constexpr size_t NUM_WIRES = MegaExecutionTraceBlocks::NUM_WIRES; using TableCommitments = std::array; // Commitments to the subtables and the merged table + struct InputCommitments { + TableCommitments t_commitments; + TableCommitments T_prev_commitments; + }; + explicit MergeRecursiveVerifier_(CircuitBuilder* builder, const MergeSettings settings = MergeSettings::PREPEND, const std::shared_ptr& transcript = std::make_shared()); [[nodiscard("Pairing points should be accumulated")]] std::pair verify_proof( - const stdlib::Proof& proof, const TableCommitments& t_commitments); + const stdlib::Proof& proof, const InputCommitments& input_commitments); }; } // namespace bb::stdlib::recursion::goblin diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp index 96f4637fb15f..1ff281189940 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp @@ -61,7 +61,7 @@ MergeVerifier::MergeVerifier(const MergeSettings settings, const std::shared_ptr * read from the proof */ std::pair MergeVerifier::verify_proof( - const HonkProof& proof, const TableCommitments& t_commitments) + const HonkProof& proof, const InputCommitments& input_commitments) { using Claims = typename ShplonkVerifier_::LinearCombinationOfClaims; @@ -76,8 +76,9 @@ std::pair MergeVerifier::verify_ for (size_t idx = 0; idx < NUM_WIRES; ++idx) { // TODO(https://github.com/AztecProtocol/barretenberg/issues/1473): remove receiving commitment to T_prev auto T_prev_commitment = transcript->template receive_from_prover("T_PREV_" + std::to_string(idx)); - auto left_table = settings == MergeSettings::PREPEND ? t_commitments[idx] : T_prev_commitment; - auto right_table = settings == MergeSettings::PREPEND ? T_prev_commitment : t_commitments[idx]; + auto left_table = settings == MergeSettings::PREPEND ? input_commitments.t_commitments[idx] : T_prev_commitment; + auto right_table = + settings == MergeSettings::PREPEND ? T_prev_commitment : input_commitments.t_commitments[idx]; table_commitments.emplace_back(left_table); table_commitments.emplace_back(right_table); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp index 906b8d98036e..0557e67de376 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp @@ -34,12 +34,17 @@ class MergeVerifier { using Commitment = typename Curve::AffineElement; using TableCommitments = std::array; // Commitments to the subtables and the merged table + struct InputCommitments { + TableCommitments t_commitments; + TableCommitments T_prev_commitments; + }; + std::shared_ptr transcript; MergeSettings settings; explicit MergeVerifier(const MergeSettings settings = MergeSettings::PREPEND, const std::shared_ptr& transcript = std::make_shared()); - std::pair verify_proof(const HonkProof& proof, const TableCommitments& t_commitments); + std::pair verify_proof(const HonkProof& proof, const InputCommitments& input_commitments); }; } // namespace bb From eb64778a8b4222043e375c0d24f620e0eb51a826 Mon Sep 17 00:00:00 2001 From: federicobarbacovi <171914500+federicobarbacovi@users.noreply.github.com> Date: Tue, 29 Jul 2025 11:32:16 +0000 Subject: [PATCH 2/6] Update interfaces --- .../graph_description_goblin.test.cpp | 31 ++--- .../cpp/src/barretenberg/goblin/goblin.cpp | 11 +- .../cpp/src/barretenberg/goblin/goblin.hpp | 22 +-- .../goblin_recursive_verifier.cpp | 12 +- .../goblin_recursive_verifier.hpp | 8 +- .../goblin_recursive_verifier.test.cpp | 131 +++++++----------- .../merge_recursive_verifier.cpp | 7 +- .../merge_recursive_verifier.hpp | 1 + .../merge_verifier/merge_verifier.test.cpp | 25 ++-- .../ultra_honk/mega_honk.test.cpp | 9 +- .../ultra_honk/merge_verifier.cpp | 7 +- .../ultra_honk/merge_verifier.hpp | 1 + 12 files changed, 110 insertions(+), 155 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_goblin.test.cpp b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_goblin.test.cpp index 7161cc078c28..0519337ebe81 100644 --- a/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_goblin.test.cpp +++ b/barretenberg/cpp/src/barretenberg/boomerang_value_detection/graph_description_goblin.test.cpp @@ -23,17 +23,16 @@ class BoomerangGoblinRecursiveVerifierTests : public testing::Test { using OuterDeciderProvingKey = DeciderProvingKey_; using Commitment = MergeVerifier::Commitment; - using TableCommitment = MergeVerifier::TableCommitments; + using MergeCommitments = MergeVerifier::InputCommitments; using RecursiveCommitment = GoblinRecursiveVerifier::MergeVerifier::Commitment; - using RecursiveTableCommitment = GoblinRecursiveVerifier::MergeVerifier::TableCommitments; + using RecursiveMergeCommitments = GoblinRecursiveVerifier::MergeVerifier::InputCommitments; static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); } struct ProverOutput { GoblinProof proof; Goblin::VerificationKey verifier_input; - TableCommitment t_commitments; - TableCommitment T_prev_commitments; + MergeCommitments merge_commitments; }; /** @@ -60,21 +59,19 @@ class BoomerangGoblinRecursiveVerifierTests : public testing::Test { GoblinMockCircuits::construct_simple_circuit(builder); goblin_final.op_queue->merge(); // Subtable values and commitments - needed for (Recursive)MergeVerifier - TableCommitment t_commitments; - TableCommitment T_prev_commitments; + MergeCommitments merge_commitments; auto t_current = goblin_final.op_queue->construct_current_ultra_ops_subtable_columns(); auto T_prev = goblin_final.op_queue->construct_previous_ultra_ops_table_columns(); CommitmentKey pcs_commitment_key(goblin_final.op_queue->get_ultra_ops_table_num_rows()); for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) { - t_commitments[idx] = pcs_commitment_key.commit(t_current[idx]); - T_prev_commitments[idx] = pcs_commitment_key.commit(T_prev[idx]); + merge_commitments.t_commitments[idx] = pcs_commitment_key.commit(t_current[idx]); + merge_commitments.T_prev_commitments[idx] = pcs_commitment_key.commit(T_prev[idx]); } // Output is a goblin proof plus ECCVM/Translator verification keys return { goblin_final.prove(), { std::make_shared(), std::make_shared() }, - t_commitments, - T_prev_commitments }; + merge_commitments }; } }; @@ -84,21 +81,21 @@ class BoomerangGoblinRecursiveVerifierTests : public testing::Test { */ TEST_F(BoomerangGoblinRecursiveVerifierTests, graph_description_basic) { - auto [proof, verifier_input, t_commitments, T_prev_commitments] = create_goblin_prover_output(); + auto [proof, verifier_input, merge_commitments] = create_goblin_prover_output(); Builder builder; // Merge commitments - RecursiveTableCommitment recursive_t_commitments; - RecursiveTableCommitment recursive_T_prev_commitments; + RecursiveMergeCommitments recursive_merge_commitments; for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) { - recursive_t_commitments[idx] = RecursiveCommitment::from_witness(&builder, t_commitments[idx]); - recursive_T_prev_commitments[idx] = RecursiveCommitment::from_witness(&builder, T_prev_commitments[idx]); + recursive_merge_commitments.t_commitments[idx] = + RecursiveCommitment::from_witness(&builder, merge_commitments.t_commitments[idx]); + recursive_merge_commitments.T_prev_commitments[idx] = + RecursiveCommitment::from_witness(&builder, merge_commitments.T_prev_commitments[idx]); } GoblinRecursiveVerifier verifier{ &builder, verifier_input }; - GoblinRecursiveVerifierOutput output = - verifier.verify(proof, recursive_t_commitments, recursive_T_prev_commitments); + GoblinRecursiveVerifierOutput output = verifier.verify(proof, recursive_merge_commitments); output.points_accumulator.set_public(); // Construct and verify a proof for the Goblin Recursive Verifier circuit { diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.cpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.cpp index 3612d66e0ba2..01b3d713ec9d 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.cpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.cpp @@ -76,8 +76,7 @@ GoblinProof Goblin::prove() std::pair Goblin::recursively_verify_merge( MegaBuilder& builder, - const RecursiveTableCommitments& t_commitments, - const RecursiveTableCommitments& T_prev_commitments, + const RecursiveMergeCommitments& merge_commitments, const std::shared_ptr& transcript) { ASSERT(!merge_verification_queue.empty()); @@ -87,7 +86,7 @@ std::pair Goblin::recu MergeRecursiveVerifier merge_verifier{ &builder, MergeSettings::PREPEND, transcript }; auto [pairing_points, merged_table_commitments] = - merge_verifier.verify_proof(stdlib_merge_proof, t_commitments, T_prev_commitments); + merge_verifier.verify_proof(stdlib_merge_proof, merge_commitments); merge_verification_queue.pop_front(); // remove the processed proof from the queue @@ -95,13 +94,11 @@ std::pair Goblin::recu } bool Goblin::verify(const GoblinProof& proof, - const TableCommitments& t_commitments, - const TableCommitments& T_prev_commitments, + const MergeCommitments& merge_commitments, const std::shared_ptr& transcript) { MergeVerifier merge_verifier(MergeSettings::PREPEND, transcript); - auto [merge_verified, merged_table_commitments] = - merge_verifier.verify_proof(proof.merge_proof, t_commitments, T_prev_commitments); + auto [merge_verified, merged_table_commitments] = merge_verifier.verify_proof(proof.merge_proof, merge_commitments); ECCVMVerifier eccvm_verifier(transcript); bool eccvm_verified = eccvm_verifier.verify_proof(proof.eccvm_proof); diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index 83eb1a78a761..77ccc0d8c693 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -40,6 +40,8 @@ class Goblin { using PairingPoints = MergeRecursiveVerifier::PairingPoints; using TableCommitments = MergeVerifier::TableCommitments; using RecursiveTableCommitments = MergeRecursiveVerifier::TableCommitments; + using MergeCommitments = MergeVerifier::InputCommitments; + using RecursiveMergeCommitments = MergeRecursiveVerifier::InputCommitments; using RecursiveCommitment = MergeRecursiveVerifier::Commitment; using RecursiveTranscript = bb::BaseTranscript>; @@ -94,25 +96,26 @@ class Goblin { * @details Proofs are verified in a FIFO manner * * @param builder The circuit in which the recursive verification will be performed. - * @param subtable_commitments The subtable commitments data, containing the commitments to t_j read from the - * transcript by the PG verifier with which the Merge verifier shares a transcript - * @param T_prev_commitments The full op_queue table commitments after the previous iteration of merge + * @param inputs_commitments Commitments used by the verifier to run the verification algorithm. They contain the + * subtable commitments data, containing the commitments to t_j read from the transcript by the PG verifier with + * which the Merge verifier shares a transcript, and the commitments to the full op_queue table after the previous + * iteration of merge * @param transcript The transcript to be passed to the MergeRecursiveVerifier. * @return Pair of PairingPoints and commitments to the merged tables as read from the proof by the Merge verifier */ std::pair recursively_verify_merge( MegaBuilder& builder, - const RecursiveTableCommitments& t_commitments, - const RecursiveTableCommitments& T_prev_commitments, + const RecursiveMergeCommitments& merge_commitments, const std::shared_ptr& transcript); /** * @brief Verify a full Goblin proof (ECCVM, Translator, merge) * * @param proof - * @param subtable_commitments The subtable commitments data, containing the commitments to t_j read from the - * transcript by the PG verifier with which the Merge verifier shares a transcript - * @param T_prev_commitments The full op_queue table commitments after the previous iteration of merge + * @param inputs_commitments Commitments used by the verifier to run the verification algorithm. They contain the + * subtable commitments data, containing the commitments to t_j read from the transcript by the PG verifier with + * which the Merge verifier shares a transcript, and the commitments to the full op_queue table after the previous + * iteration of merge * @param merged_table_commitment The commitment to the merged table as read from the proof * @param transcript * @@ -120,8 +123,7 @@ class Goblin { * verifier */ static bool verify(const GoblinProof& proof, - const TableCommitments& t_commitments, - const TableCommitments& T_prev_commitments, + const MergeCommitments& merge_commitments, const std::shared_ptr& transcript); }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.cpp index 5f2b61806c1a..d21dc8cb43d6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.cpp @@ -16,11 +16,10 @@ namespace bb::stdlib::recursion::honk { * */ GoblinRecursiveVerifierOutput GoblinRecursiveVerifier::verify(const GoblinProof& proof, - const TableCommitments& t_commitments, - const TableCommitments& T_prev_commitments) + const MergeCommitments& merge_commitments) { StdlibProof stdlib_proof(*builder, proof); - return verify(stdlib_proof, t_commitments, T_prev_commitments); + return verify(stdlib_proof, merge_commitments); } /** @@ -30,16 +29,13 @@ GoblinRecursiveVerifierOutput GoblinRecursiveVerifier::verify(const GoblinProof& * @param t_commitments The commitments to the subtable for the merge being verified * */ -// TODO(https://github.com/AztecProtocol/barretenberg/issues/1492): Modify Merge verifier API and package inputs in a -// single struct GoblinRecursiveVerifierOutput GoblinRecursiveVerifier::verify(const StdlibProof& proof, - const TableCommitments& t_commitments, - const TableCommitments& T_prev_commitments) + const MergeCommitments& merge_commitments) { // Verify the final merge step MergeVerifier merge_verifier{ builder, MergeSettings::PREPEND, transcript }; auto [merge_pairing_points, merged_table_commitments] = - merge_verifier.verify_proof(proof.merge_proof, t_commitments, T_prev_commitments); + merge_verifier.verify_proof(proof.merge_proof, merge_commitments); // Run the ECCVM recursive verifier ECCVMVerifier eccvm_verifier{ builder, verification_keys.eccvm_verification_key, transcript }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.hpp index c753d8a3a54d..e2d567681c73 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.hpp @@ -15,9 +15,7 @@ namespace bb::stdlib::recursion::honk { struct GoblinRecursiveVerifierOutput { using Builder = UltraCircuitBuilder; using Curve = grumpkin; - using Transcript = bb::BaseTranscript>; using PairingAccumulator = PairingPoints; - using TableCommitments = goblin::MergeRecursiveVerifier_::TableCommitments; PairingAccumulator points_accumulator; OpeningClaim opening_claim; stdlib::Proof ipa_proof; @@ -40,7 +38,7 @@ class GoblinRecursiveVerifier { using VerificationKey = Goblin::VerificationKey; // Merge commitments - using TableCommitments = MergeVerifier::TableCommitments; + using MergeCommitments = MergeVerifier::InputCommitments; struct StdlibProof { using StdlibHonkProof = bb::stdlib::Proof; @@ -66,9 +64,9 @@ class GoblinRecursiveVerifier { , transcript(transcript){}; [[nodiscard("IPA claim and Pairing points should be accumulated")]] GoblinRecursiveVerifierOutput verify( - const GoblinProof&, const TableCommitments& t_commitments, const TableCommitments& T_prev_commitments); + const GoblinProof&, const MergeCommitments& merge_commitments); [[nodiscard("IPA claim and Pairing points should be accumulated")]] GoblinRecursiveVerifierOutput verify( - const StdlibProof&, const TableCommitments& t_commitments, const TableCommitments& T_prev_commitments); + const StdlibProof&, const MergeCommitments& merge_commitments); private: Builder* builder; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.test.cpp index b65cae81f648..2fcca300bdb5 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursive_verifier.test.cpp @@ -23,18 +23,16 @@ class GoblinRecursiveVerifierTests : public testing::Test { using Commitment = MergeVerifier::Commitment; using RecursiveCommitment = GoblinRecursiveVerifier::MergeVerifier::Commitment; - using TableCommitments = MergeVerifier::TableCommitments; - using RecursiveTableCommitments = GoblinRecursiveVerifier::MergeVerifier::TableCommitments; + using MergeCommitments = MergeVerifier::InputCommitments; + using RecursiveMergeCommitments = GoblinRecursiveVerifier::MergeVerifier::InputCommitments; static void SetUpTestSuite() { bb::srs::init_file_crs_factory(bb::srs::bb_crs_path()); } struct ProverOutput { GoblinProof proof; Goblin::VerificationKey verifier_input; - TableCommitments t_commitments; - TableCommitments T_prev_commitments; - RecursiveTableCommitments recursive_t_commitments; - RecursiveTableCommitments recursive_T_prev_commitments; + MergeCommitments merge_commitments; + RecursiveMergeCommitments recursive_merge_commitments; }; /** @@ -63,30 +61,30 @@ class GoblinRecursiveVerifierTests : public testing::Test { goblin_final.op_queue->merge(); // Subtable values and commitments - needed for (Recursive)MergeVerifier - TableCommitments t_commitments; - TableCommitments T_prev_commitments; + MergeCommitments merge_commitments; auto t_current = goblin_final.op_queue->construct_current_ultra_ops_subtable_columns(); auto T_prev = goblin_final.op_queue->construct_previous_ultra_ops_table_columns(); CommitmentKey pcs_commitment_key(goblin_final.op_queue->get_ultra_ops_table_num_rows()); for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) { - t_commitments[idx] = pcs_commitment_key.commit(t_current[idx]); - T_prev_commitments[idx] = pcs_commitment_key.commit(T_prev[idx]); + merge_commitments.t_commitments[idx] = pcs_commitment_key.commit(t_current[idx]); + merge_commitments.T_prev_commitments[idx] = pcs_commitment_key.commit(T_prev[idx]); } - RecursiveTableCommitments recursive_t_commitments; - RecursiveTableCommitments recursive_T_prev_commitments; + RecursiveMergeCommitments recursive_merge_commitments; if (outer_builder != nullptr) { for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) { - recursive_t_commitments[idx] = RecursiveCommitment::from_witness(outer_builder, t_commitments[idx]); - recursive_T_prev_commitments[idx] = - RecursiveCommitment::from_witness(outer_builder, T_prev_commitments[idx]); + recursive_merge_commitments.t_commitments[idx] = + RecursiveCommitment::from_witness(outer_builder, merge_commitments.t_commitments[idx]); + recursive_merge_commitments.T_prev_commitments[idx] = + RecursiveCommitment::from_witness(outer_builder, merge_commitments.T_prev_commitments[idx]); } } // Output is a goblin proof plus ECCVM/Translator verification keys - return { goblin_final.prove(), { std::make_shared(), std::make_shared() }, - t_commitments, T_prev_commitments, - recursive_t_commitments, recursive_T_prev_commitments }; + return { goblin_final.prove(), + { std::make_shared(), std::make_shared() }, + merge_commitments, + recursive_merge_commitments }; } }; @@ -96,16 +94,11 @@ class GoblinRecursiveVerifierTests : public testing::Test { */ TEST_F(GoblinRecursiveVerifierTests, NativeVerification) { - auto [proof, - verifier_input, - t_commitments, - T_prev_commitments, - _recursive_t_commitments, - _recursive_T_prev_commitments] = create_goblin_prover_output(); + auto [proof, verifier_input, merge_commitments, _] = create_goblin_prover_output(); std::shared_ptr verifier_transcript = std::make_shared(); - EXPECT_TRUE(Goblin::verify(proof, t_commitments, T_prev_commitments, verifier_transcript)); + EXPECT_TRUE(Goblin::verify(proof, merge_commitments, verifier_transcript)); } /** @@ -116,16 +109,11 @@ TEST_F(GoblinRecursiveVerifierTests, Basic) { Builder builder; - auto [proof, - verifier_input, - t_commitments, - T_prev_commitments, - recursive_t_commitments, - recursive_T_prev_commitments] = create_goblin_prover_output(&builder); + auto [proof, verifier_input, merge_commitments, recursive_merge_commitments] = + create_goblin_prover_output(&builder); GoblinRecursiveVerifier verifier{ &builder, verifier_input }; - GoblinRecursiveVerifierOutput output = - verifier.verify(proof, recursive_t_commitments, recursive_T_prev_commitments); + GoblinRecursiveVerifierOutput output = verifier.verify(proof, recursive_merge_commitments); output.points_accumulator.set_public(); info("Recursive Verifier: num gates = ", builder.num_gates); @@ -155,16 +143,11 @@ TEST_F(GoblinRecursiveVerifierTests, IndependentVKHash) -> std::tuple> { Builder builder; - auto [proof, - verifier_input, - t_commitments, - T_prev_commitments, - recursive_t_commitments, - recursive_T_prev_commitments] = create_goblin_prover_output(&builder, inner_size); + auto [proof, verifier_input, merge_commitments, recursive_merge_commitments] = + create_goblin_prover_output(&builder, inner_size); GoblinRecursiveVerifier verifier{ &builder, verifier_input }; - GoblinRecursiveVerifierOutput output = - verifier.verify(proof, recursive_t_commitments, recursive_T_prev_commitments); + GoblinRecursiveVerifierOutput output = verifier.verify(proof, recursive_merge_commitments); output.points_accumulator.set_public(); info("Recursive Verifier: num gates = ", builder.num_gates); @@ -193,12 +176,8 @@ TEST_F(GoblinRecursiveVerifierTests, ECCVMFailure) { Builder builder; - auto [proof, - verifier_input, - t_commitments, - T_prev_commitments, - recursive_t_commitments, - recursive_T_prev_commitments] = create_goblin_prover_output(&builder); + auto [proof, verifier_input, merge_commitments, recursive_merge_commitments] = + create_goblin_prover_output(&builder); // Tamper with the ECCVM proof for (auto& val : proof.eccvm_proof.pre_ipa_proof) { @@ -209,8 +188,7 @@ TEST_F(GoblinRecursiveVerifierTests, ECCVMFailure) } GoblinRecursiveVerifier verifier{ &builder, verifier_input }; - GoblinRecursiveVerifierOutput goblin_rec_verifier_output = - verifier.verify(proof, recursive_t_commitments, recursive_T_prev_commitments); + GoblinRecursiveVerifierOutput goblin_rec_verifier_output = verifier.verify(proof, recursive_merge_commitments); srs::init_file_crs_factory(bb::srs::bb_crs_path()); auto crs_factory = srs::get_grumpkin_crs_factory(); @@ -231,12 +209,7 @@ TEST_F(GoblinRecursiveVerifierTests, ECCVMFailure) */ TEST_F(GoblinRecursiveVerifierTests, TranslatorFailure) { - auto [proof, - verifier_input, - t_commitments, - T_prev_commitments, - _recursive_t_commitments, - _recursive_T_prev_commitments] = create_goblin_prover_output(); + auto [proof, verifier_input, merge_commitments, _] = create_goblin_prover_output(); // Tamper with the Translator proof preamble { @@ -250,16 +223,16 @@ TEST_F(GoblinRecursiveVerifierTests, TranslatorFailure) Builder builder; - RecursiveTableCommitments recursive_t_commitments; - RecursiveTableCommitments recursive_T_prev_commitments; + RecursiveMergeCommitments recursive_merge_commitments; for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) { - recursive_t_commitments[idx] = RecursiveCommitment::from_witness(&builder, t_commitments[idx]); - recursive_T_prev_commitments[idx] = RecursiveCommitment::from_witness(&builder, T_prev_commitments[idx]); + recursive_merge_commitments.t_commitments[idx] = + RecursiveCommitment::from_witness(&builder, merge_commitments.t_commitments[idx]); + recursive_merge_commitments.T_prev_commitments[idx] = + RecursiveCommitment::from_witness(&builder, merge_commitments.T_prev_commitments[idx]); } GoblinRecursiveVerifier verifier{ &builder, verifier_input }; - [[maybe_unused]] auto goblin_rec_verifier_output = - verifier.verify(tampered_proof, recursive_t_commitments, recursive_T_prev_commitments); + [[maybe_unused]] auto goblin_rec_verifier_output = verifier.verify(tampered_proof, recursive_merge_commitments); EXPECT_FALSE(CircuitChecker::check(builder)); } // Tamper with the Translator proof non-preamble values @@ -277,16 +250,16 @@ TEST_F(GoblinRecursiveVerifierTests, TranslatorFailure) Builder builder; - RecursiveTableCommitments recursive_t_commitments; - RecursiveTableCommitments recursive_T_prev_commitments; + RecursiveMergeCommitments recursive_merge_commitments; for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) { - recursive_t_commitments[idx] = RecursiveCommitment::from_witness(&builder, t_commitments[idx]); - recursive_T_prev_commitments[idx] = RecursiveCommitment::from_witness(&builder, T_prev_commitments[idx]); + recursive_merge_commitments.t_commitments[idx] = + RecursiveCommitment::from_witness(&builder, merge_commitments.t_commitments[idx]); + recursive_merge_commitments.T_prev_commitments[idx] = + RecursiveCommitment::from_witness(&builder, merge_commitments.T_prev_commitments[idx]); } GoblinRecursiveVerifier verifier{ &builder, verifier_input }; - [[maybe_unused]] auto goblin_rec_verifier_output = - verifier.verify(tampered_proof, recursive_t_commitments, recursive_T_prev_commitments); + [[maybe_unused]] auto goblin_rec_verifier_output = verifier.verify(tampered_proof, recursive_merge_commitments); EXPECT_FALSE(CircuitChecker::check(builder)); } } @@ -299,12 +272,8 @@ TEST_F(GoblinRecursiveVerifierTests, TranslationEvaluationsFailure) { Builder builder; - auto [proof, - verifier_input, - t_commitments, - T_prev_commitments, - recursive_t_commitments, - recursive_T_prev_commitments] = create_goblin_prover_output(&builder); + auto [proof, verifier_input, merge_commitments, recursive_merge_commitments] = + create_goblin_prover_output(&builder); // Tamper with the evaluation of `op` witness. The index is computed manually. // TODO(https://github.com/AztecProtocol/barretenberg/issues/1298): @@ -313,8 +282,7 @@ TEST_F(GoblinRecursiveVerifierTests, TranslationEvaluationsFailure) proof.eccvm_proof.pre_ipa_proof[op_limb_index] += 1; GoblinRecursiveVerifier verifier{ &builder, verifier_input }; - [[maybe_unused]] auto goblin_rec_verifier_output = - verifier.verify(proof, recursive_t_commitments, recursive_T_prev_commitments); + [[maybe_unused]] auto goblin_rec_verifier_output = verifier.verify(proof, recursive_merge_commitments); EXPECT_FALSE(CircuitChecker::check(builder)); } @@ -333,17 +301,13 @@ TEST_F(GoblinRecursiveVerifierTests, TranslatorMergeConsistencyFailure) Builder builder; - auto [proof, - verifier_input, - t_commitments, - T_prev_commitments, - recursive_t_commitments, - recursive_T_prev_commitments] = create_goblin_prover_output(&builder); + auto [proof, verifier_input, merge_commitments, recursive_merge_commitments] = + create_goblin_prover_output(&builder); std::shared_ptr verifier_transcript = std::make_shared(); // Check natively that the proof is correct. - EXPECT_TRUE(Goblin::verify(proof, t_commitments, T_prev_commitments, verifier_transcript)); + EXPECT_TRUE(Goblin::verify(proof, merge_commitments, verifier_transcript)); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1298): // Better recursion testing - create more flexible proof tampering tests. @@ -370,8 +334,7 @@ TEST_F(GoblinRecursiveVerifierTests, TranslatorMergeConsistencyFailure) // Construct and check the Goblin Recursive Verifier circuit GoblinRecursiveVerifier verifier{ &builder, verifier_input }; - [[maybe_unused]] auto goblin_rec_verifier_output = - verifier.verify(proof, recursive_t_commitments, recursive_T_prev_commitments); + [[maybe_unused]] auto goblin_rec_verifier_output = verifier.verify(proof, recursive_merge_commitments); EXPECT_FALSE(CircuitChecker::check(builder)); } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp index 959f93331f8c..9c13e4792eaa 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp @@ -62,9 +62,10 @@ MergeRecursiveVerifier_::MergeRecursiveVerifier_(CircuitBuilder* * @param proof * @param subtable_commitments The subtable commitments data, containing the commitments to t_j read from the transcript * by the PG verifier with which the Merge verifier shares a transcript - * @param t_commitments The subtable commitments data, containing the commitments to t_j read from the transcript - * by the PG verifier with which the Merge verifier shares a transcript - * @param T_prev_commitments The full op_queue table commitments after the previous iteration of merge + * @param inputs_commitments Commitments used by the verifier to run the verification algorithm. They contain the + * subtable commitments data, containing the commitments to t_j read from the transcript by the PG verifier with which + * the Merge verifier shares a transcript, and the commitments to the full op_queue table after the previous iteration + * of merge * @return std::pair Pair of the pairing inputs for final verification and the * commitments to the merged tables as read from the proof */ diff --git a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp index 8598b5b6c656..9ab146168d9e 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp @@ -32,6 +32,7 @@ template class MergeRecursiveVerifier_ { static constexpr size_t NUM_WIRES = MegaExecutionTraceBlocks::NUM_WIRES; using TableCommitments = std::array; // Commitments to the subtables and the merged table + // Commitments used by the Merge verifier to perfom merge verification struct InputCommitments { TableCommitments t_commitments; TableCommitments T_prev_commitments; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_verifier.test.cpp index edffb8a1fee7..a7551555ec35 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_verifier.test.cpp @@ -23,6 +23,7 @@ template class RecursiveMergeVerifierTest : public test // Types for recursive verifier circuit using RecursiveMergeVerifier = MergeRecursiveVerifier_; using RecursiveTableCommitments = MergeRecursiveVerifier_::TableCommitments; + using RecursiveMergeCommitments = MergeRecursiveVerifier_::InputCommitments; // Define types relevant for inner circuit using InnerFlavor = MegaFlavor; @@ -35,6 +36,7 @@ template class RecursiveMergeVerifierTest : public test using VerifierCommitmentKey = bb::VerifierCommitmentKey; using MergeProof = MergeProver::MergeProof; using TableCommitments = MergeVerifier::TableCommitments; + using MergeCommitments = MergeVerifier::InputCommitments; enum class TamperProofMode { None, Shift, MCommitment, LEval }; @@ -86,19 +88,17 @@ template class RecursiveMergeVerifierTest : public test tamper_with_proof(merge_proof, tampering_mode); // Subtable values and commitments - needed for (Recursive)MergeVerifier - TableCommitments t_commitments; - TableCommitments T_prev_commitments; - RecursiveTableCommitments recursive_t_commitments; - RecursiveTableCommitments recursive_T_prev_commitments; + MergeCommitments merge_commitments; + RecursiveMergeCommitments recursive_merge_commitments; auto t_current = op_queue->construct_current_ultra_ops_subtable_columns(); auto T_prev = op_queue->construct_previous_ultra_ops_table_columns(); for (size_t idx = 0; idx < InnerFlavor::NUM_WIRES; idx++) { - t_commitments[idx] = merge_prover.pcs_commitment_key.commit(t_current[idx]); - T_prev_commitments[idx] = merge_prover.pcs_commitment_key.commit(T_prev[idx]); - recursive_t_commitments[idx] = - RecursiveMergeVerifier::Commitment::from_witness(&outer_circuit, t_commitments[idx]); - recursive_T_prev_commitments[idx] = - RecursiveMergeVerifier::Commitment::from_witness(&outer_circuit, T_prev_commitments[idx]); + merge_commitments.t_commitments[idx] = merge_prover.pcs_commitment_key.commit(t_current[idx]); + merge_commitments.T_prev_commitments[idx] = merge_prover.pcs_commitment_key.commit(T_prev[idx]); + recursive_merge_commitments.t_commitments[idx] = + RecursiveMergeVerifier::Commitment::from_witness(&outer_circuit, merge_commitments.t_commitments[idx]); + recursive_merge_commitments.T_prev_commitments[idx] = RecursiveMergeVerifier::Commitment::from_witness( + &outer_circuit, recursive_merge_commitments.T_prev_commitments[idx]); } // Create a recursive merge verification circuit for the merge proof @@ -106,7 +106,7 @@ template class RecursiveMergeVerifierTest : public test verifier.transcript->enable_manifest(); const stdlib::Proof stdlib_merge_proof(outer_circuit, merge_proof); auto [pairing_points, recursive_merged_table_commitments] = - verifier.verify_proof(stdlib_merge_proof, recursive_t_commitments, recursive_T_prev_commitments); + verifier.verify_proof(stdlib_merge_proof, recursive_merge_commitments); // Check for a failure flag in the recursive verifier circuit EXPECT_EQ(outer_circuit.failed(), !expected) << outer_circuit.err(); @@ -115,8 +115,7 @@ template class RecursiveMergeVerifierTest : public test // verifier and check that the result agrees. MergeVerifier native_verifier{ settings }; native_verifier.transcript->enable_manifest(); - auto [verified_native, merged_table_commitments] = - native_verifier.verify_proof(merge_proof, t_commitments, T_prev_commitments); + auto [verified_native, merged_table_commitments] = native_verifier.verify_proof(merge_proof, merge_commitments); VerifierCommitmentKey pcs_verification_key; bool verified_recursive = pcs_verification_key.pairing_check(pairing_points.P0.get_value(), pairing_points.P1.get_value()); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/mega_honk.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/mega_honk.test.cpp index 3d15dafbcb30..a47d70e5564e 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/mega_honk.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/mega_honk.test.cpp @@ -83,16 +83,15 @@ template class MegaHonkTests : public ::testing::Test { auto merge_proof = merge_prover.construct_proof(); // Construct Merge commitments - MergeVerifier::TableCommitments t_commitments; - MergeVerifier::TableCommitments T_prev_commitments; + MergeVerifier::InputCommitments merge_commitments; auto t_current = op_queue->construct_current_ultra_ops_subtable_columns(); auto T_prev = op_queue->construct_previous_ultra_ops_table_columns(); for (size_t idx = 0; idx < Flavor::NUM_WIRES; idx++) { - t_commitments[idx] = merge_prover.pcs_commitment_key.commit(t_current[idx]); - T_prev_commitments[idx] = merge_prover.pcs_commitment_key.commit(T_prev[idx]); + merge_commitments.t_commitments[idx] = merge_prover.pcs_commitment_key.commit(t_current[idx]); + merge_commitments.T_prev_commitments[idx] = merge_prover.pcs_commitment_key.commit(T_prev[idx]); } - auto [verified, _] = merge_verifier.verify_proof(merge_proof, t_commitments, T_prev_commitments); + auto [verified, _] = merge_verifier.verify_proof(merge_proof, merge_commitments); return verified; } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp index 292975868de4..b296438c88cb 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp @@ -55,9 +55,10 @@ MergeVerifier::MergeVerifier(const MergeSettings settings, const std::shared_ptr * - \f$l_j = T_{prev,j}, r_j = t_j, m_j = T_j\f$ if we are appending the subtable * * @param proof - * @param t_commitments The subtable commitments data, containing the commitments to t_j read from the transcript - * by the PG verifier with which the Merge verifier shares a transcript - * @param T_prev_commitments The full op_queue table commitments after the previous iteration of merge + * @param inputs_commitments Commitments used by the verifier to run the verification algorithm. They contain the + * subtable commitments data, containing the commitments to t_j read from the transcript by the PG verifier with which + * the Merge verifier shares a transcript, and the commitments to the full op_queue table after the previous iteration + * of merge * @return std::pair Pair of verification result and the commitments to the merged tables as * read from the proof */ diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp index 0557e67de376..725d082b2ce6 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp @@ -34,6 +34,7 @@ class MergeVerifier { using Commitment = typename Curve::AffineElement; using TableCommitments = std::array; // Commitments to the subtables and the merged table + // Commitments used by the Merge verifier to perfom merge verification struct InputCommitments { TableCommitments t_commitments; TableCommitments T_prev_commitments; From 315a3cfaaa1a1d215845f92ca48bf4aff892ea34 Mon Sep 17 00:00:00 2001 From: federicobarbacovi <171914500+federicobarbacovi@users.noreply.github.com> Date: Tue, 29 Jul 2025 11:43:33 +0000 Subject: [PATCH 3/6] Update CIVC and Goblin --- .../barretenberg/client_ivc/client_ivc.cpp | 40 ++++++++++--------- .../client_ivc_recursive_verifier.cpp | 16 ++++---- .../goblin_avm_recursive_verifier.hpp | 9 +++-- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index a43e9d345210..e8b45b3515b0 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -98,15 +98,15 @@ std::pair ClientIVC:: const TableCommitments& T_prev_commitments, const std::shared_ptr& accumulation_recursive_transcript) { + using MergeCommitments = Goblin::MergeRecursiveVerifier::InputCommitments; + // Witness commitments and public inputs corresponding to the incoming instance WitnessCommitments witness_commitments; std::vector public_inputs; - // Commitments to the previous status of the op_queue, to be finalized according to the recursive verification we - // are performing - // TODO(https://github.com/AztecProtocol/barretenberg/issues/1492): Change Merge verifier API and improve the name - // of the following variable. - TableCommitments finalised_T_prev_commitments = T_prev_commitments; + // Input commitments to be passed to the merge recursive verification + MergeCommitments merge_commitments; + merge_commitments.T_prev_commitments = T_prev_commitments; switch (verifier_inputs.type) { case QUEUE_TYPE::PG: { @@ -146,7 +146,7 @@ std::pair ClientIVC:: public_inputs = std::move(verifier.public_inputs); // T_prev = 0 in the first recursive verification - finalised_T_prev_commitments = HidingKernelIO::empty_ecc_op_tables(circuit); + merge_commitments.T_prev_commitments = HidingKernelIO::empty_ecc_op_tables(circuit); break; } @@ -173,7 +173,7 @@ std::pair ClientIVC:: // T_prev is read by the public input of the previous kernel K_{i-1} at the beginning of the recursive // verification of of the folding of K_{i-1} (kernel), A_{i,1} (app), .., A_{i, n} (app). This verification // happens in K_{i} - finalised_T_prev_commitments = kernel_input.ecc_op_tables; + merge_commitments.T_prev_commitments = kernel_input.ecc_op_tables; // Perform databus consistency checks kernel_input.kernel_return_data.assert_equal(witness_commitments.calldata); @@ -192,11 +192,11 @@ std::pair ClientIVC:: } // Extract the commitments to the subtable corresponding to the incoming circuit - TableCommitments t_commitments = witness_commitments.get_ecc_op_wires().get_copy(); + merge_commitments.t_commitments = witness_commitments.get_ecc_op_wires().get_copy(); // Recursively verify the corresponding merge proof - auto [pairing_points, merged_table_commitments] = goblin.recursively_verify_merge( - circuit, t_commitments, finalised_T_prev_commitments, accumulation_recursive_transcript); + auto [pairing_points, merged_table_commitments] = + goblin.recursively_verify_merge(circuit, merge_commitments, accumulation_recursive_transcript); pairing_points.aggregate(nested_pairing_points); @@ -381,6 +381,8 @@ std::pair ClientIVC::comp const std::shared_ptr& stdlib_vk_and_hash, ClientCircuit& circuit) { + using MergeCommitments = Goblin::MergeRecursiveVerifier::InputCommitments; + // Shared transcript between PG and Merge // TODO(https://github.com/AztecProtocol/barretenberg/issues/1453): Investigate whether Decider/PG/Merge need to // share a transcript @@ -421,13 +423,13 @@ std::pair ClientIVC::comp kernel_input.app_return_data.assert_equal(witness_commitments.secondary_calldata); // Extract the commitments to the subtable corresponding to the incoming circuit - TableCommitments t_commitments = witness_commitments.get_ecc_op_wires().get_copy(); + MergeCommitments merge_commitments; + merge_commitments.t_commitments = witness_commitments.get_ecc_op_wires().get_copy(); + merge_commitments.T_prev_commitments = std::move( + kernel_input.ecc_op_tables); // Commitment to the status of the op_queue before folding the tail kernel // Perform recursive verification of the last merge proof - auto [points_accumulator, merged_table_commitments] = goblin.recursively_verify_merge( - circuit, - t_commitments, - kernel_input.ecc_op_tables, // Commitment to the status of the op_queue before folding the tail kernel - pg_merge_transcript); + auto [points_accumulator, merged_table_commitments] = + goblin.recursively_verify_merge(circuit, merge_commitments, pg_merge_transcript); points_accumulator.aggregate(kernel_input.pairing_inputs); @@ -509,6 +511,7 @@ ClientIVC::Proof ClientIVC::prove() bool ClientIVC::verify(const Proof& proof, const VerificationKey& vk) { + using TableCommitments = Goblin::TableCommitments; // Create a transcript to be shared by MegaZK-, Merge-, ECCVM-, and Translator- Verifiers. std::shared_ptr civc_verifier_transcript = std::make_shared(); // Verify the hiding circuit proof @@ -517,12 +520,11 @@ bool ClientIVC::verify(const Proof& proof, const VerificationKey& vk) vinfo("Mega verified: ", mega_verified); // Extract the commitments to the subtable corresponding to the incoming circuit - MergeVerifier::TableCommitments t_commitments = - verifier.verification_key->witness_commitments.get_ecc_op_wires().get_copy(); + TableCommitments t_commitments = verifier.verification_key->witness_commitments.get_ecc_op_wires().get_copy(); // Goblin verification (final merge, eccvm, translator) bool goblin_verified = - Goblin::verify(proof.goblin_proof, t_commitments, T_prev_commitments, civc_verifier_transcript); + Goblin::verify(proof.goblin_proof, { t_commitments, T_prev_commitments }, civc_verifier_transcript); vinfo("Goblin verified: ", goblin_verified); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1396): State tracking in CIVC verifiers. diff --git a/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp index 005f948db729..4f520a124c82 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp @@ -16,7 +16,7 @@ namespace bb::stdlib::recursion::honk { */ ClientIVCRecursiveVerifier::Output ClientIVCRecursiveVerifier::verify(const StdlibProof& proof) { - using TableCommitments = GoblinVerifier::MergeVerifier::TableCommitments; + using MergeCommitments = GoblinVerifier::MergeVerifier::InputCommitments; std::shared_ptr civc_rec_verifier_transcript(std::make_shared()); // Construct stdlib Mega verification key auto stdlib_mega_vk_and_hash = std::make_shared(*builder, ivc_verification_key.mega); @@ -27,14 +27,14 @@ ClientIVCRecursiveVerifier::Output ClientIVCRecursiveVerifier::verify(const Stdl // Perform Goblin recursive verification GoblinVerificationKey goblin_verification_key{}; - TableCommitments t_commitments = verifier.key->witness_commitments.get_ecc_op_wires() - .get_copy(); // Commitments to subtables added by the hiding kernel + MergeCommitments merge_commitments; + merge_commitments.t_commitments = verifier.key->witness_commitments.get_ecc_op_wires() + .get_copy(); // Commitments to subtables added by the hiding kernel + merge_commitments.T_prev_commitments = std::move( + mega_output + .ecc_op_tables); // Commitments to the state of the ecc op_queue as computed insided the hiding kernel GoblinVerifier goblin_verifier{ builder.get(), goblin_verification_key, civc_rec_verifier_transcript }; - GoblinRecursiveVerifierOutput output = goblin_verifier.verify( - proof.goblin_proof, - t_commitments, - mega_output.ecc_op_tables // Commitments to the state of the ecc op_queue as computed insided the hiding kernel - ); + GoblinRecursiveVerifierOutput output = goblin_verifier.verify(proof.goblin_proof, merge_commitments); output.points_accumulator.aggregate(mega_output.points_accumulator); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1396): State tracking in CIVC verifiers return { output }; diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp index e5b635ee1801..cb4d03fb9b96 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp @@ -117,7 +117,7 @@ class AvmGoblinRecursiveVerifier { using MegaRecursiveVerifier = stdlib::recursion::honk::UltraRecursiveVerifier_; using GoblinRecursiveVerifier = stdlib::recursion::honk::GoblinRecursiveVerifier; using GoblinRecursiveVerifierOutput = stdlib::recursion::honk::GoblinRecursiveVerifierOutput; - using TableCommitments = GoblinRecursiveVerifier::MergeVerifier::TableCommitments; + using MergeCommitments = GoblinRecursiveVerifier::MergeVerifier::InputCommitments; using FF = MegaRecursiveFlavor::FF; // Construct hash buffer containing the AVM proof, public inputs, and VK @@ -138,13 +138,14 @@ class AvmGoblinRecursiveVerifier { auto mega_verifier_output = mega_verifier.verify_proof(mega_proof); // Recursively verify the goblin proof\pi_G in the Ultra circuit - TableCommitments t_commitments = mega_verifier.key->witness_commitments.get_ecc_op_wires().get_copy(); - TableCommitments T_prev_commitments = + MergeCommitments merge_commitments; + merge_commitments.t_commitments = mega_verifier.key->witness_commitments.get_ecc_op_wires().get_copy(); + merge_commitments.T_prev_commitments = stdlib::recursion::honk::HidingKernelIO::empty_ecc_op_tables( ultra_builder); // Empty ecc op tables because there is only one layer of Goblin GoblinRecursiveVerifier goblin_verifier{ &ultra_builder, inner_output.goblin_vk, transcript }; GoblinRecursiveVerifierOutput goblin_verifier_output = - goblin_verifier.verify(inner_output.goblin_proof, t_commitments, T_prev_commitments); + goblin_verifier.verify(inner_output.goblin_proof, merge_commitments); goblin_verifier_output.points_accumulator.aggregate(mega_verifier_output.points_accumulator); // Validate the consistency of the AVM2 verifier inputs {\pi, pub_inputs, VK}_{AVM2} between the inner (Mega) From 36421a738ae402862849ab2d27045836a732fdaa Mon Sep 17 00:00:00 2001 From: federicobarbacovi <171914500+federicobarbacovi@users.noreply.github.com> Date: Tue, 29 Jul 2025 11:48:03 +0000 Subject: [PATCH 4/6] Fix --- .../barretenberg/stdlib/merge_verifier/merge_verifier.test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_verifier.test.cpp index a7551555ec35..b82513b9df7e 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_verifier.test.cpp @@ -98,7 +98,7 @@ template class RecursiveMergeVerifierTest : public test recursive_merge_commitments.t_commitments[idx] = RecursiveMergeVerifier::Commitment::from_witness(&outer_circuit, merge_commitments.t_commitments[idx]); recursive_merge_commitments.T_prev_commitments[idx] = RecursiveMergeVerifier::Commitment::from_witness( - &outer_circuit, recursive_merge_commitments.T_prev_commitments[idx]); + &outer_circuit, merge_commitments.T_prev_commitments[idx]); } // Create a recursive merge verification circuit for the merge proof From cbab4d7c77cedc0d1424b9b9cc712cd7594f27d2 Mon Sep 17 00:00:00 2001 From: federicobarbacovi <171914500+federicobarbacovi@users.noreply.github.com> Date: Wed, 30 Jul 2025 13:54:27 +0000 Subject: [PATCH 5/6] Address comments --- barretenberg/cpp/src/barretenberg/goblin/goblin.hpp | 10 ++-------- .../client_ivc_recursive_verifier.cpp | 12 ++++++------ .../merge_verifier/merge_recursive_verifier.cpp | 7 +------ .../merge_verifier/merge_recursive_verifier.hpp | 7 ++++++- .../src/barretenberg/ultra_honk/merge_verifier.cpp | 5 +---- .../src/barretenberg/ultra_honk/merge_verifier.hpp | 7 ++++++- .../recursion/goblin_avm_recursive_verifier.hpp | 13 +++++++------ 7 files changed, 29 insertions(+), 32 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index 77ccc0d8c693..46cbf6fdf18f 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -96,10 +96,7 @@ class Goblin { * @details Proofs are verified in a FIFO manner * * @param builder The circuit in which the recursive verification will be performed. - * @param inputs_commitments Commitments used by the verifier to run the verification algorithm. They contain the - * subtable commitments data, containing the commitments to t_j read from the transcript by the PG verifier with - * which the Merge verifier shares a transcript, and the commitments to the full op_queue table after the previous - * iteration of merge + * @param inputs_commitments The commitment used by the Merge verifier * @param transcript The transcript to be passed to the MergeRecursiveVerifier. * @return Pair of PairingPoints and commitments to the merged tables as read from the proof by the Merge verifier */ @@ -112,10 +109,7 @@ class Goblin { * @brief Verify a full Goblin proof (ECCVM, Translator, merge) * * @param proof - * @param inputs_commitments Commitments used by the verifier to run the verification algorithm. They contain the - * subtable commitments data, containing the commitments to t_j read from the transcript by the PG verifier with - * which the Merge verifier shares a transcript, and the commitments to the full op_queue table after the previous - * iteration of merge + * @param inputs_commitments The commitments used by the Merge verifier * @param merged_table_commitment The commitment to the merged table as read from the proof * @param transcript * diff --git a/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp index 4f520a124c82..bdda5fbecb33 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/client_ivc_verifier/client_ivc_recursive_verifier.cpp @@ -27,12 +27,12 @@ ClientIVCRecursiveVerifier::Output ClientIVCRecursiveVerifier::verify(const Stdl // Perform Goblin recursive verification GoblinVerificationKey goblin_verification_key{}; - MergeCommitments merge_commitments; - merge_commitments.t_commitments = verifier.key->witness_commitments.get_ecc_op_wires() - .get_copy(); // Commitments to subtables added by the hiding kernel - merge_commitments.T_prev_commitments = std::move( - mega_output - .ecc_op_tables); // Commitments to the state of the ecc op_queue as computed insided the hiding kernel + MergeCommitments merge_commitments{ + .t_commitments = verifier.key->witness_commitments.get_ecc_op_wires() + .get_copy(), // Commitments to subtables added by the hiding kernel + .T_prev_commitments = std::move(mega_output.ecc_op_tables) // Commitments to the state of the ecc op_queue as + // computed insided the hiding kernel + }; GoblinVerifier goblin_verifier{ builder.get(), goblin_verification_key, civc_rec_verifier_transcript }; GoblinRecursiveVerifierOutput output = goblin_verifier.verify(proof.goblin_proof, merge_commitments); output.points_accumulator.aggregate(mega_output.points_accumulator); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp index 9c13e4792eaa..50f3720b5449 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.cpp @@ -60,12 +60,7 @@ MergeRecursiveVerifier_::MergeRecursiveVerifier_(CircuitBuilder* * * @tparam CircuitBuilder * @param proof - * @param subtable_commitments The subtable commitments data, containing the commitments to t_j read from the transcript - * by the PG verifier with which the Merge verifier shares a transcript - * @param inputs_commitments Commitments used by the verifier to run the verification algorithm. They contain the - * subtable commitments data, containing the commitments to t_j read from the transcript by the PG verifier with which - * the Merge verifier shares a transcript, and the commitments to the full op_queue table after the previous iteration - * of merge + * @param inputs_commitments The commitments used by the Merge verifier * @return std::pair Pair of the pairing inputs for final verification and the * commitments to the merged tables as read from the proof */ diff --git a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp index 9ab146168d9e..2f951e01b9d1 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/merge_verifier/merge_recursive_verifier.hpp @@ -32,7 +32,12 @@ template class MergeRecursiveVerifier_ { static constexpr size_t NUM_WIRES = MegaExecutionTraceBlocks::NUM_WIRES; using TableCommitments = std::array; // Commitments to the subtables and the merged table - // Commitments used by the Merge verifier to perfom merge verification + /** + * Commitments used by the verifier to run the verification algorithm. They contain: + * - `t_commitments`: the subtable commitments data, containing the commitments to t_j read from the transcript by + * the PG verifier with which the Merge verifier shares a transcript + * - `T_prev_commitments`: the commitments to the full op_queue table after the previous iteration of merge + */ struct InputCommitments { TableCommitments t_commitments; TableCommitments T_prev_commitments; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp index b296438c88cb..00271caa7321 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.cpp @@ -55,10 +55,7 @@ MergeVerifier::MergeVerifier(const MergeSettings settings, const std::shared_ptr * - \f$l_j = T_{prev,j}, r_j = t_j, m_j = T_j\f$ if we are appending the subtable * * @param proof - * @param inputs_commitments Commitments used by the verifier to run the verification algorithm. They contain the - * subtable commitments data, containing the commitments to t_j read from the transcript by the PG verifier with which - * the Merge verifier shares a transcript, and the commitments to the full op_queue table after the previous iteration - * of merge + * @param inputs_commitments The commitments used by the Merge verifier * @return std::pair Pair of verification result and the commitments to the merged tables as * read from the proof */ diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp index 725d082b2ce6..3fb4468c4c70 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_verifier.hpp @@ -34,7 +34,12 @@ class MergeVerifier { using Commitment = typename Curve::AffineElement; using TableCommitments = std::array; // Commitments to the subtables and the merged table - // Commitments used by the Merge verifier to perfom merge verification + /** + * Commitments used by the verifier to run the verification algorithm. They contain: + * - `t_commitments`: the subtable commitments data, containing the commitments to t_j read from the transcript by + * the PG verifier with which the Merge verifier shares a transcript + * - `T_prev_commitments`: the commitments to the full op_queue table after the previous iteration of merge + */ struct InputCommitments { TableCommitments t_commitments; TableCommitments T_prev_commitments; diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp index cb4d03fb9b96..37bd7a8199a6 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp @@ -119,6 +119,7 @@ class AvmGoblinRecursiveVerifier { using GoblinRecursiveVerifierOutput = stdlib::recursion::honk::GoblinRecursiveVerifierOutput; using MergeCommitments = GoblinRecursiveVerifier::MergeVerifier::InputCommitments; using FF = MegaRecursiveFlavor::FF; + using IO = stdlib::recursion::honk::HidingKernelIO; // Construct hash buffer containing the AVM proof, public inputs, and VK std::vector hash_buffer; @@ -138,11 +139,11 @@ class AvmGoblinRecursiveVerifier { auto mega_verifier_output = mega_verifier.verify_proof(mega_proof); // Recursively verify the goblin proof\pi_G in the Ultra circuit - MergeCommitments merge_commitments; - merge_commitments.t_commitments = mega_verifier.key->witness_commitments.get_ecc_op_wires().get_copy(); - merge_commitments.T_prev_commitments = - stdlib::recursion::honk::HidingKernelIO::empty_ecc_op_tables( - ultra_builder); // Empty ecc op tables because there is only one layer of Goblin + MergeCommitments merge_commitments{ + .t_commitments = mega_verifier.key->witness_commitments.get_ecc_op_wires().get_copy(), + .T_prev_commitments = + IO::empty_ecc_op_tables(ultra_builder) // Empty ecc op tables because there is only one layer of Goblin + }; GoblinRecursiveVerifier goblin_verifier{ &ultra_builder, inner_output.goblin_vk, transcript }; GoblinRecursiveVerifierOutput goblin_verifier_output = goblin_verifier.verify(inner_output.goblin_proof, merge_commitments); @@ -219,7 +220,7 @@ class AvmGoblinRecursiveVerifier { inputs.pairing_inputs = points_accumulator; // TODO(https://github.com/AztecProtocol/barretenberg/issues/1489): Can we avoid paying for these public inputs // given that they are not used? - inputs.ecc_op_tables = stdlib::recursion::honk::HidingKernelIO::default_ecc_op_tables( + inputs.ecc_op_tables = IO::default_ecc_op_tables( mega_builder); // There is only one layer of Goblin, so the verifier will set T_prev // to the empty table and disregard this value inputs.set_public(); From 59f804410dada187a3ead02c253c2e19a5f9474d Mon Sep 17 00:00:00 2001 From: federicobarbacovi <171914500+federicobarbacovi@users.noreply.github.com> Date: Wed, 30 Jul 2025 14:00:48 +0000 Subject: [PATCH 6/6] Fix --- .../recursion/goblin_avm_recursive_verifier.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp index 37bd7a8199a6..c1d64523aa14 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/vm2/constraining/recursion/goblin_avm_recursive_verifier.hpp @@ -220,9 +220,9 @@ class AvmGoblinRecursiveVerifier { inputs.pairing_inputs = points_accumulator; // TODO(https://github.com/AztecProtocol/barretenberg/issues/1489): Can we avoid paying for these public inputs // given that they are not used? - inputs.ecc_op_tables = IO::default_ecc_op_tables( - mega_builder); // There is only one layer of Goblin, so the verifier will set T_prev - // to the empty table and disregard this value + inputs.ecc_op_tables = + IO::default_ecc_op_tables(mega_builder); // There is only one layer of Goblin, so the verifier will set + // T_prev to the empty table and disregard this value inputs.set_public(); // All prover components share a single transcript