From 3b7779ac956379090b04c7f33b646ae2909a7fc1 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Mon, 10 Mar 2025 19:55:14 +0000 Subject: [PATCH 1/9] Rough moving of merge in main verification queue --- .../barretenberg/client_ivc/client_ivc.cpp | 68 ++++---- .../barretenberg/client_ivc/client_ivc.hpp | 15 +- .../acir_format/ivc_recursion_constraint.cpp | 5 +- .../cpp/src/barretenberg/goblin/goblin.hpp | 71 ++++---- .../stdlib/goblin_verifier/goblin.test.cpp | 57 +++---- .../goblin_verifier/goblin_recursion.test.cpp | 78 ++++----- .../goblin_recursive_verifier.cpp | 3 +- .../merge_recursive_verifier.cpp | 5 +- .../merge_recursive_verifier.hpp | 2 +- .../goblin_verifier/merge_verifier.test.cpp | 4 +- .../ultra_vanilla_client_ivc.test.cpp | 156 +++++++++--------- 11 files changed, 230 insertions(+), 234 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 48ae5a5bce37..54c2581e6d96 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -23,15 +23,16 @@ void ClientIVC::instantiate_stdlib_verification_queue( } size_t key_idx = 0; - for (auto& [proof, vkey, type] : verification_queue) { + for (auto& [proof, merge_proof, vkey, type] : verification_queue) { // Construct stdlib proof directly from the internal native queue data auto stdlib_proof = bb::convert_native_proof_to_stdlib(&circuit, proof); + auto stdlib_merge_proof = bb::convert_native_proof_to_stdlib(&circuit, merge_proof); // Use the provided stdlib vkey if present, otherwise construct one from the internal native queue auto stdlib_vkey = vkeys_provided ? input_keys[key_idx++] : std::make_shared(&circuit, vkey); - stdlib_verification_queue.push_back({ stdlib_proof, stdlib_vkey, type }); + stdlib_verification_queue.push_back({ stdlib_proof, stdlib_merge_proof, stdlib_vkey, type }); } verification_queue.clear(); // the native data is not needed beyond this point } @@ -49,11 +50,14 @@ void ClientIVC::instantiate_stdlib_verification_queue( * @param type The type of the proof (equivalently, the type of the verifier) */ void ClientIVC::perform_recursive_verification_and_databus_consistency_checks( - ClientCircuit& circuit, - const StdlibProof& proof, - const std::shared_ptr& vkey, - const QUEUE_TYPE type) + ClientCircuit& circuit, const StdlibVerifierInputs& verifier_inputs) { + + const StdlibProof& proof = verifier_inputs.proof; + const StdlibProof& merge_proof = verifier_inputs.merge_proof; + const std::shared_ptr& vkey = verifier_inputs.honk_verification_key; + const QUEUE_TYPE type = verifier_inputs.type; + // Store the decider vk for the incoming circuit; its data is used in the databus consistency checks below std::shared_ptr decider_vk; @@ -93,6 +97,9 @@ void ClientIVC::perform_recursive_verification_and_databus_consistency_checks( } } + // Recursively verify the merge proof for the present circuit + goblin.verify_merge(circuit, merge_proof); + // Set the return data commitment to be propagated on the public inputs of the present kernel and perform // consistency checks between the calldata commitments and the return data commitments contained within the public // inputs @@ -104,20 +111,6 @@ void ClientIVC::perform_recursive_verification_and_databus_consistency_checks( decider_vk->verification_key->databus_propagation_data); } -/** - * @brief Perform recursive merge verification for each merge proof in the queue - * - * @param circuit - */ -void ClientIVC::process_recursive_merge_verification_queue(ClientCircuit& circuit) -{ - // Recusively verify all merge proofs in queue - for (auto& proof : merge_verification_queue) { - goblin.verify_merge(circuit, proof); - } - merge_verification_queue.clear(); -} - /** * @brief Append logic to complete a kernel circuit * @details A kernel circuit may contain some combination of PG recursive verification, merge recursive @@ -135,17 +128,14 @@ void ClientIVC::complete_kernel_circuit_logic(ClientCircuit& circuit) instantiate_stdlib_verification_queue(circuit); } - // Peform recursive verification and databus consistency checks for each entry in the verification queue - for (auto& [proof, vkey, type] : stdlib_verification_queue) { - perform_recursive_verification_and_databus_consistency_checks(circuit, proof, vkey, type); + // Perform recursive verification and databus consistency checks for each entry in the verification queue + for (auto& verifier_input : stdlib_verification_queue) { + perform_recursive_verification_and_databus_consistency_checks(circuit, verifier_input); } stdlib_verification_queue.clear(); // Propagate return data commitments via the public inputs for use in databus consistency checks bus_depot.propagate_return_data_commitments(circuit); - - // Perform recursive merge verification for every merge proof in the queue - process_recursive_merge_verification_queue(circuit); } /** @@ -166,7 +156,6 @@ void ClientIVC::accumulate(ClientCircuit& circuit, { // Construct merge proof for the present circuit and add to merge verification queue MergeProof merge_proof = goblin.prove_merge(circuit); - merge_verification_queue.emplace_back(merge_proof); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1069): Do proper aggregation with merge recursive // verifier. @@ -221,8 +210,8 @@ void ClientIVC::accumulate(ClientCircuit& circuit, fold_output.accumulator = proving_key; // initialize the prover accum with the completed key // Add oink proof and corresponding verification key to the verification queue - verification_queue.push_back( - bb::ClientIVC::VerifierInputs{ oink_prover.transcript->proof_data, honk_vk, QUEUE_TYPE::OINK }); + verification_queue.push_back(bb::ClientIVC::VerifierInputs{ + oink_prover.transcript->proof_data, merge_proof, honk_vk, QUEUE_TYPE::OINK }); initialized = true; } else { // Otherwise, fold the new key into the accumulator @@ -232,7 +221,8 @@ void ClientIVC::accumulate(ClientCircuit& circuit, vinfo("constructed folding proof"); // Add fold proof and corresponding verification key to the verification queue - verification_queue.push_back(bb::ClientIVC::VerifierInputs{ fold_output.proof, honk_vk, QUEUE_TYPE::PG }); + verification_queue.push_back( + bb::ClientIVC::VerifierInputs{ fold_output.proof, merge_proof, honk_vk, QUEUE_TYPE::PG }); } } @@ -243,11 +233,10 @@ void ClientIVC::accumulate(ClientCircuit& circuit, * @details The aim of this intermediate stage is to reduce the cost of producing a zero-knowledge ClientIVCProof. * @return HonkProof - a Mega proof */ -HonkProof ClientIVC::construct_and_prove_hiding_circuit() +std::pair ClientIVC::construct_and_prove_hiding_circuit() { trace_usage_tracker.print(); // print minimum structured sizes for each block ASSERT(verification_queue.size() == 1); - ASSERT(merge_verification_queue.size() == 1); // ensure only a single merge proof remains in the queue FoldProof& fold_proof = verification_queue[0].proof; HonkProof decider_proof = decider_prove(); @@ -267,7 +256,9 @@ HonkProof ClientIVC::construct_and_prove_hiding_circuit() builder.add_public_variable(fold_proof[i + offset]); } - process_recursive_merge_verification_queue(builder); + const StdlibProof stdlib_merge_proof = + bb::convert_native_proof_to_stdlib(&builder, verification_queue[0].merge_proof); + goblin.verify_merge(builder, stdlib_merge_proof); // Construct stdlib accumulator, decider vkey and folding proof auto stdlib_verifier_accumulator = @@ -291,7 +282,6 @@ HonkProof ClientIVC::construct_and_prove_hiding_circuit() // Construct the last merge proof for the present circuit and add to merge verification queue MergeProof merge_proof = goblin.prove_merge(builder); - merge_verification_queue.emplace_back(merge_proof); auto decider_pk = std::make_shared(builder, TraceSettings(), bn254_commitment_key); honk_vk = std::make_shared(decider_pk->proving_key); @@ -299,7 +289,7 @@ HonkProof ClientIVC::construct_and_prove_hiding_circuit() HonkProof proof = prover.construct_proof(); - return proof; + return { proof, merge_proof }; } /** @@ -309,12 +299,14 @@ HonkProof ClientIVC::construct_and_prove_hiding_circuit() */ ClientIVC::Proof ClientIVC::prove() { + MergeProof merge_proof; if (!one_circuit) { - mega_proof = construct_and_prove_hiding_circuit(); - ASSERT(merge_verification_queue.size() == 1); // ensure only a single merge proof remains in the queue + auto [mega_proof, merge_proof_hiding] = construct_and_prove_hiding_circuit(); + merge_proof = merge_proof_hiding; + } else { + merge_proof = verification_queue[0].merge_proof; } - MergeProof& merge_proof = merge_verification_queue[0]; return { mega_proof, goblin.prove(merge_proof) }; }; diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp index 441efc43bfd2..c33d0308a64d 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp @@ -86,6 +86,7 @@ class ClientIVC { // An entry in the native verification queue struct VerifierInputs { std::vector proof; // oink or PG + std::vector merge_proof; std::shared_ptr honk_verification_key; QUEUE_TYPE type; }; @@ -94,6 +95,7 @@ class ClientIVC { // An entry in the stdlib verification queue struct StdlibVerifierInputs { StdlibProof proof; // oink or PG + StdlibProof merge_proof; std::shared_ptr honk_verification_key; QUEUE_TYPE type; }; @@ -117,8 +119,6 @@ class ClientIVC { VerificationQueue verification_queue; // Set of tuples {stdlib_proof, stdlib_verification_key, type} corresponding to the native verification queue StdlibVerificationQueue stdlib_verification_queue; - // Set of merge proofs to be recursively verified - std::vector merge_verification_queue; // Management of linking databus commitments between circuits in the IVC DataBusDepot bus_depot; @@ -148,13 +148,8 @@ class ClientIVC { void instantiate_stdlib_verification_queue( ClientCircuit& circuit, const std::vector>& input_keys = {}); - void perform_recursive_verification_and_databus_consistency_checks( - ClientCircuit& circuit, - const StdlibProof& proof, - const std::shared_ptr& vkey, - const QUEUE_TYPE type); - - void process_recursive_merge_verification_queue(ClientCircuit& circuit); + void perform_recursive_verification_and_databus_consistency_checks(ClientCircuit& circuit, + const StdlibVerifierInputs& verifier_inputs); // Complete the logic of a kernel circuit (e.g. PG/merge recursive verification, databus consistency checks) void complete_kernel_circuit_logic(ClientCircuit& circuit); @@ -174,7 +169,7 @@ class ClientIVC { Proof prove(); - HonkProof construct_and_prove_hiding_circuit(); + std::pair construct_and_prove_hiding_circuit(); static bool verify(const Proof& proof, const VerificationKey& vk); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp index 4d77b3fbce11..f54ce346c4fc 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ivc_recursion_constraint.cpp @@ -77,7 +77,6 @@ void mock_ivc_accumulation(const std::shared_ptr& ivc, ClientIVC::QUE ClientIVC::VerifierInputs entry = acir_format::create_mock_verification_queue_entry(type, ivc->trace_settings, is_kernel); ivc->verification_queue.emplace_back(entry); - ivc->merge_verification_queue.emplace_back(acir_format::create_dummy_merge_proof()); ivc->initialized = true; } @@ -123,7 +122,9 @@ ClientIVC::VerifierInputs create_mock_verification_queue_entry(const ClientIVC:: verification_key->databus_propagation_data = bb::DatabusPropagationData::kernel_default(); } - return ClientIVC::VerifierInputs{ proof, verification_key, verification_type }; + std::vector merge_proof = create_dummy_merge_proof(); + + return ClientIVC::VerifierInputs{ proof, merge_proof, verification_key, verification_type }; } /** diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index 7fa5281e65b1..f8212a1af80b 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -77,40 +77,43 @@ class GoblinProver { commitment_key = bn254_commitment_key ? bn254_commitment_key : nullptr; GoblinMockCircuits::perform_op_queue_interactions_for_mock_first_circuit(op_queue); } - /** - * @brief Construct a MegaHonk proof and a merge proof for the present circuit. - * @details If there is a previous merge proof, recursively verify it. - * - * @param circuit_builder - */ - GoblinAccumulationOutput accumulate(MegaBuilder& circuit_builder) - { - // Complete the circuit logic by recursively verifying previous merge proof if it exists - if (merge_proof_exists) { - RecursiveMergeVerifier merge_verifier{ &circuit_builder }; - [[maybe_unused]] auto pairing_points = merge_verifier.verify_proof(merge_proof); - } - - // Construct a Honk proof for the main circuit - auto proving_key = std::make_shared(circuit_builder); - MegaProver prover(proving_key); - auto ultra_proof = prover.construct_proof(); - auto verification_key = std::make_shared(proving_key->proving_key); - - // Construct and store the merge proof to be recursively verified on the next call to accumulate - MergeProver merge_prover{ circuit_builder.op_queue }; - merge_proof = merge_prover.construct_proof(); - - if (!merge_proof_exists) { - merge_proof_exists = true; - } - - return { ultra_proof, verification_key }; - }; + // /** + // * @brief Construct a MegaHonk proof and a merge proof for the present circuit. + // * @details If there is a previous merge proof, recursively verify it. + // * + // * @param circuit_builder + // */ + // GoblinAccumulationOutput accumulate(MegaBuilder& circuit_builder) + // { + // // Complete the circuit logic by recursively verifying previous merge proof if it exists + // if (merge_proof_exists) { + // RecursiveMergeVerifier merge_verifier{ &circuit_builder }; + // StdlibProof stdlib_merge_proof = + // bb::convert_native_proof_to_stdlib(&circuit_builder, merge_proof); + // [[maybe_unused]] auto pairing_points = merge_verifier.verify_proof(stdlib_merge_proof); + // } + + // // Construct a Honk proof for the main circuit + // auto proving_key = std::make_shared(circuit_builder); + // MegaProver prover(proving_key); + // auto ultra_proof = prover.construct_proof(); + // auto verification_key = std::make_shared(proving_key->proving_key); + + // // Construct and store the merge proof to be recursively verified on the next call to accumulate + // MergeProver merge_prover{ circuit_builder.op_queue }; + // merge_proof = merge_prover.construct_proof(); + + // if (!merge_proof_exists) { + // merge_proof_exists = true; + // } + + // return { ultra_proof, verification_key }; + // }; /** * @brief Add a recursive merge verifier to input circuit and construct a merge proof for the updated op queue - * @details When this method is used, the "prover" functionality of the IVC scheme must be performed explicitly, but + * @details When this method is used, the "prover" functionality of the IVC scheme must be performed explicitly, + but * this method has to be called first so that the recursive merge verifier can be "appended" to the circuit being * accumulated * @@ -120,7 +123,9 @@ class GoblinProver { { // Append a recursive merge verification of the merge proof if (merge_proof_exists) { - [[maybe_unused]] auto pairing_points = verify_merge(circuit_builder, merge_proof); + StdlibProof stdlib_merge_proof = + bb::convert_native_proof_to_stdlib(&circuit_builder, merge_proof); + [[maybe_unused]] auto pairing_points = verify_merge(circuit_builder, stdlib_merge_proof); } // Construct a merge proof for the present circuit @@ -133,7 +138,7 @@ class GoblinProver { * @param circuit_builder * @return PairingPoints */ - PairingPoints verify_merge(MegaBuilder& circuit_builder, MergeProof& proof) const + PairingPoints verify_merge(MegaBuilder& circuit_builder, const StdlibProof& proof) const { PROFILE_THIS_NAME("Goblin::merge"); RecursiveMergeVerifier merge_verifier{ &circuit_builder }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp index 14d4ffbad4ae..d4d699f01fd8 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp @@ -28,33 +28,34 @@ class GoblinTests : public ::testing::Test { } }; -/** - * @brief A simple test demonstrating goblin proof construction / verification based on operations from a collection of - * circuits - * - */ -TEST_F(GoblinTests, MultipleCircuits) -{ - GoblinProver goblin; - - // Construct and accumulate multiple circuits - size_t NUM_CIRCUITS = 3; - for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { - auto circuit = construct_mock_circuit(goblin.op_queue); - goblin.merge(circuit); // appends a recurisve merge verifier if a merge proof exists - } - - // Construct a goblin proof which consists of a merge proof and ECCVM/Translator proofs - GoblinProof proof = goblin.prove(); - - // Verify the goblin proof (eccvm, translator, merge); (Construct ECCVM/Translator verification keys from their - // respective proving keys) - auto eccvm_vkey = std::make_shared(goblin.get_eccvm_proving_key()); - auto translator_vkey = std::make_shared(goblin.get_translator_proving_key()); - GoblinVerifier goblin_verifier{ eccvm_vkey, translator_vkey }; - bool verified = goblin_verifier.verify(proof); - - EXPECT_TRUE(verified); -} +// /** +// * @brief A simple test demonstrating goblin proof construction / verification based on operations from a collection +// of +// * circuits +// * +// */ +// TEST_F(GoblinTests, MultipleCircuits) +// { +// GoblinProver goblin; + +// // Construct and accumulate multiple circuits +// size_t NUM_CIRCUITS = 3; +// for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { +// auto circuit = construct_mock_circuit(goblin.op_queue); +// goblin.merge(circuit); // appends a recurisve merge verifier if a merge proof exists +// } + +// // Construct a goblin proof which consists of a merge proof and ECCVM/Translator proofs +// GoblinProof proof = goblin.prove(); + +// // Verify the goblin proof (eccvm, translator, merge); (Construct ECCVM/Translator verification keys from their +// // respective proving keys) +// auto eccvm_vkey = std::make_shared(goblin.get_eccvm_proving_key()); +// auto translator_vkey = std::make_shared(goblin.get_translator_proving_key()); +// GoblinVerifier goblin_verifier{ eccvm_vkey, translator_vkey }; +// bool verified = goblin_verifier.verify(proof); + +// EXPECT_TRUE(verified); +// } // TODO(https://github.com/AztecProtocol/barretenberg/issues/787) Expand these tests. diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp index 18ca69a5d789..508e34d5daae 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp @@ -34,49 +34,49 @@ class GoblinRecursionTests : public ::testing::Test { } }; -/** - * @brief Test illustrating a Goblin-based IVC scheme - * @details Goblin is usd to accumulate recursive verifications of the MegaHonk proving system. - */ -TEST_F(GoblinRecursionTests, Vanilla) -{ - GoblinProver goblin; +// /** +// * @brief Test illustrating a Goblin-based IVC scheme +// * @details Goblin is usd to accumulate recursive verifications of the MegaHonk proving system. +// */ +// TEST_F(GoblinRecursionTests, Vanilla) +// { +// GoblinProver goblin; - GoblinAccumulationOutput kernel_accum; +// GoblinAccumulationOutput kernel_accum; - size_t NUM_CIRCUITS = 2; - for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { +// size_t NUM_CIRCUITS = 2; +// for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { - // Construct and accumulate a mock function circuit containing both arbitrary arithmetic gates and goblin - // ecc op gates to make it a meaningful test - MegaCircuitBuilder function_circuit{ goblin.op_queue }; - MockCircuits::construct_arithmetic_circuit(function_circuit, /*target_log2_dyadic_size=*/8); - MockCircuits::construct_goblin_ecc_op_circuit(function_circuit); - goblin.merge(function_circuit); - function_circuit.add_pairing_point_accumulator( - stdlib::recursion::init_default_agg_obj_indices(function_circuit)); - auto function_accum = construct_accumulator(function_circuit); +// // Construct and accumulate a mock function circuit containing both arbitrary arithmetic gates and goblin +// // ecc op gates to make it a meaningful test +// MegaCircuitBuilder function_circuit{ goblin.op_queue }; +// MockCircuits::construct_arithmetic_circuit(function_circuit, /*target_log2_dyadic_size=*/8); +// MockCircuits::construct_goblin_ecc_op_circuit(function_circuit); +// goblin.merge(function_circuit); +// function_circuit.add_pairing_point_accumulator( +// stdlib::recursion::init_default_agg_obj_indices(function_circuit)); +// auto function_accum = construct_accumulator(function_circuit); - // Construct and accumulate the mock kernel circuit (no kernel accum in first round) - MegaCircuitBuilder kernel_circuit{ goblin.op_queue }; - GoblinMockCircuits::construct_mock_kernel_small(kernel_circuit, - { function_accum.proof, function_accum.verification_key }, - { kernel_accum.proof, kernel_accum.verification_key }); - goblin.merge(kernel_circuit); - kernel_circuit.add_pairing_point_accumulator(stdlib::recursion::init_default_agg_obj_indices(kernel_circuit)); - kernel_accum = construct_accumulator(kernel_circuit); - } +// // Construct and accumulate the mock kernel circuit (no kernel accum in first round) +// MegaCircuitBuilder kernel_circuit{ goblin.op_queue }; +// GoblinMockCircuits::construct_mock_kernel_small(kernel_circuit, +// { function_accum.proof, function_accum.verification_key }, +// { kernel_accum.proof, kernel_accum.verification_key }); +// goblin.merge(kernel_circuit); +// kernel_circuit.add_pairing_point_accumulator(stdlib::recursion::init_default_agg_obj_indices(kernel_circuit)); +// kernel_accum = construct_accumulator(kernel_circuit); +// } - GoblinProof proof = goblin.prove(); - // Verify the final ultra proof - MegaVerifier ultra_verifier{ kernel_accum.verification_key }; - bool ultra_verified = ultra_verifier.verify_proof(kernel_accum.proof); - // Verify the goblin proof (eccvm, translator, merge) - auto eccvm_vkey = std::make_shared(goblin.get_eccvm_proving_key()); - auto translator_vkey = std::make_shared(goblin.get_translator_proving_key()); - GoblinVerifier goblin_verifier{ eccvm_vkey, translator_vkey }; - bool verified = goblin_verifier.verify(proof); - EXPECT_TRUE(ultra_verified && verified); -} +// GoblinProof proof = goblin.prove(); +// // Verify the final ultra proof +// MegaVerifier ultra_verifier{ kernel_accum.verification_key }; +// bool ultra_verified = ultra_verifier.verify_proof(kernel_accum.proof); +// // Verify the goblin proof (eccvm, translator, merge) +// auto eccvm_vkey = std::make_shared(goblin.get_eccvm_proving_key()); +// auto translator_vkey = std::make_shared(goblin.get_translator_proving_key()); +// GoblinVerifier goblin_verifier{ eccvm_vkey, translator_vkey }; +// bool verified = goblin_verifier.verify(proof); +// EXPECT_TRUE(ultra_verified && verified); +// } // TODO(https://github.com/AztecProtocol/barretenberg/issues/787) Expand these tests. 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 19278f0ea8a3..deb50225a8da 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 @@ -37,7 +37,8 @@ GoblinRecursiveVerifierOutput GoblinRecursiveVerifier::verify(const GoblinProof& translator_verifier.verify_translation(translation_evaluations, eccvm_verifier.translation_masking_term_eval); MergeVerifier merge_verifier{ builder }; - merge_verifier.verify_proof(proof.merge_proof); + StdlibProof stdlib_merge_proof = bb::convert_native_proof_to_stdlib(builder, proof.merge_proof); + merge_verifier.verify_proof(stdlib_merge_proof); return { opening_claim, ipa_transcript }; } } // namespace bb::stdlib::recursion::honk diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.cpp index 41fa0356b542..4c375f3d1885 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.cpp @@ -24,11 +24,10 @@ MergeRecursiveVerifier_::MergeRecursiveVerifier_(CircuitBuilder* */ template std::array::Element, 2> MergeRecursiveVerifier_::verify_proof( - const HonkProof& proof) + const StdlibProof& proof) { // Transform proof into a stdlib object - StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof); - transcript = std::make_shared(stdlib_proof); + transcript = std::make_shared(proof); FF subtable_size = transcript->template receive_from_prover("subtable_size"); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.hpp index 8ba6af11ffbd..cf54f9c5d837 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_recursive_verifier.hpp @@ -23,7 +23,7 @@ template class MergeRecursiveVerifier_ { explicit MergeRecursiveVerifier_(CircuitBuilder* builder); - PairingPoints verify_proof(const HonkProof& proof); + PairingPoints verify_proof(const StdlibProof& proof); }; } // namespace bb::stdlib::recursion::goblin diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_verifier.test.cpp index 7f3f302ad449..764ae5830280 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/merge_verifier.test.cpp @@ -59,7 +59,9 @@ template class RecursiveMergeVerifierTest : public test // Create a recursive merge verification circuit for the merge proof RecursiveBuilder outer_circuit; RecursiveMergeVerifier verifier{ &outer_circuit }; - auto pairing_points = verifier.verify_proof(merge_proof); + const StdlibProof stdlib_merge_proof = + bb::convert_native_proof_to_stdlib(&outer_circuit, merge_proof); + auto pairing_points = verifier.verify_proof(stdlib_merge_proof); // Check for a failure flag in the recursive verifier circuit EXPECT_EQ(outer_circuit.failed(), false) << outer_circuit.err(); diff --git a/barretenberg/cpp/src/barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.test.cpp index 21656305671b..92a2d825d299 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.test.cpp @@ -1,93 +1,93 @@ -#include "barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.hpp" -#include "barretenberg/goblin/goblin.hpp" -#include "barretenberg/goblin/mock_circuits.hpp" -#include "barretenberg/protogalaxy/folding_test_utils.hpp" -#include "barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp" -#include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp" -#include +// #include "barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.hpp" +// #include "barretenberg/goblin/goblin.hpp" +// #include "barretenberg/goblin/mock_circuits.hpp" +// #include "barretenberg/protogalaxy/folding_test_utils.hpp" +// #include "barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp" +// #include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp" +// #include -using namespace bb; +// using namespace bb; -class UltraVanillaClientIVCTests : public ::testing::Test { - protected: - static void SetUpTestSuite() - { - srs::init_crs_factory("../srs_db/ignition"); - srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); - } +// class UltraVanillaClientIVCTests : public ::testing::Test { +// protected: +// static void SetUpTestSuite() +// { +// srs::init_crs_factory("../srs_db/ignition"); +// srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); +// } - using Flavor = UltraVanillaClientIVC::Flavor; - using Builder = UltraCircuitBuilder; - using FF = typename Flavor::FF; - using VK = Flavor::VerificationKey; - using PK = DeciderProvingKey_; +// using Flavor = UltraVanillaClientIVC::Flavor; +// using Builder = UltraCircuitBuilder; +// using FF = typename Flavor::FF; +// using VK = Flavor::VerificationKey; +// using PK = DeciderProvingKey_; - class MockCircuitSource : public CircuitSource { - std::vector _sizes; - std::vector> _vks; - uint32_t step{ 0 }; +// class MockCircuitSource : public CircuitSource { +// std::vector _sizes; +// std::vector> _vks; +// uint32_t step{ 0 }; - public: - MockCircuitSource(const std::vector& sizes) - : _sizes(sizes) - { - std::fill_n(std::back_inserter(_vks), sizes.size(), nullptr); - } +// public: +// MockCircuitSource(const std::vector& sizes) +// : _sizes(sizes) +// { +// std::fill_n(std::back_inserter(_vks), sizes.size(), nullptr); +// } - MockCircuitSource(const MockCircuitSource& source_without_sizes, std::vector> vks) - : _sizes(source_without_sizes._sizes) - , _vks(vks) - {} +// MockCircuitSource(const MockCircuitSource& source_without_sizes, std::vector> vks) +// : _sizes(source_without_sizes._sizes) +// , _vks(vks) +// {} - Output next() override - { - Builder circuit; - MockCircuits::construct_arithmetic_circuit(circuit, _sizes[step]); - const auto& vk = _vks[step]; - ++step; - return { circuit, vk }; - } +// Output next() override +// { +// Builder circuit; +// MockCircuits::construct_arithmetic_circuit(circuit, _sizes[step]); +// const auto& vk = _vks[step]; +// ++step; +// return { circuit, vk }; +// } - size_t num_circuits() const override - { - ASSERT(_sizes.size() == _vks.size()); - return _sizes.size(); - } - }; -}; +// size_t num_circuits() const override +// { +// ASSERT(_sizes.size() == _vks.size()); +// return _sizes.size(); +// } +// }; +// }; -TEST_F(UltraVanillaClientIVCTests, TwoCircuits) -{ - static constexpr size_t LOG_SIZE = 10; - UltraVanillaClientIVC ivc(1 << LOG_SIZE); - MockCircuitSource circuit_source{ { LOG_SIZE, LOG_SIZE } }; - EXPECT_TRUE(ivc.prove_and_verify(circuit_source)); -}; +// TEST_F(UltraVanillaClientIVCTests, TwoCircuits) +// { +// static constexpr size_t LOG_SIZE = 10; +// UltraVanillaClientIVC ivc(1 << LOG_SIZE); +// MockCircuitSource circuit_source{ { LOG_SIZE, LOG_SIZE } }; +// EXPECT_TRUE(ivc.prove_and_verify(circuit_source)); +// }; -TEST_F(UltraVanillaClientIVCTests, ThreeCircuits) -{ - static constexpr size_t LOG_SIZE = 10; - UltraVanillaClientIVC ivc(1 << LOG_SIZE); - MockCircuitSource circuit_source{ { LOG_SIZE, LOG_SIZE, LOG_SIZE } }; - EXPECT_TRUE(ivc.prove_and_verify(circuit_source)); -}; +// TEST_F(UltraVanillaClientIVCTests, ThreeCircuits) +// { +// static constexpr size_t LOG_SIZE = 10; +// UltraVanillaClientIVC ivc(1 << LOG_SIZE); +// MockCircuitSource circuit_source{ { LOG_SIZE, LOG_SIZE, LOG_SIZE } }; +// EXPECT_TRUE(ivc.prove_and_verify(circuit_source)); +// }; -/** - * @brief Prove and verify accumulation of an arbitrary set of circuits using precomputed verification keys - * @details The test precomputes the keys via one pass of the ivc prover, then it uses them in a second pass. - */ -TEST_F(UltraVanillaClientIVCTests, PrecomputedVerificationKeys) -{ +// /** +// * @brief Prove and verify accumulation of an arbitrary set of circuits using precomputed verification keys +// * @details The test precomputes the keys via one pass of the ivc prover, then it uses them in a second pass. +// */ +// TEST_F(UltraVanillaClientIVCTests, PrecomputedVerificationKeys) +// { - static constexpr size_t LOG_SIZE = 10; +// static constexpr size_t LOG_SIZE = 10; - UltraVanillaClientIVC ivc_1(1 << LOG_SIZE); - MockCircuitSource circuit_source_no_vks{ { LOG_SIZE, LOG_SIZE } }; - auto vks = ivc_1.compute_vks(circuit_source_no_vks); +// UltraVanillaClientIVC ivc_1(1 << LOG_SIZE); +// MockCircuitSource circuit_source_no_vks{ { LOG_SIZE, LOG_SIZE } }; +// auto vks = ivc_1.compute_vks(circuit_source_no_vks); - UltraVanillaClientIVC ivc_2(1 << LOG_SIZE); // need to refactor accumulator_value use to reuse ivc_1 - MockCircuitSource circuit_source_with_vks{ circuit_source_no_vks, vks }; - EXPECT_TRUE(ivc_2.prove_and_verify(circuit_source_with_vks)); -}; +// UltraVanillaClientIVC ivc_2(1 << LOG_SIZE); // need to refactor accumulator_value use to reuse ivc_1 +// MockCircuitSource circuit_source_with_vks{ circuit_source_no_vks, vks }; +// EXPECT_TRUE(ivc_2.prove_and_verify(circuit_source_with_vks)); +// }; -// TODO(https://github.com/AztecProtocol/barretenberg/issues/1177) Implement failure tests +// // TODO(https://github.com/AztecProtocol/barretenberg/issues/1177) Implement failure tests From 1b8ca2412bbf5e60784764443ff23797c1b61b55 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Mon, 10 Mar 2025 21:09:31 +0000 Subject: [PATCH 2/9] bug fix and reinstate tests --- .../barretenberg/client_ivc/client_ivc.cpp | 5 +- .../cpp/src/barretenberg/goblin/goblin.hpp | 36 --------- .../stdlib/goblin_verifier/goblin.test.cpp | 57 +++++++------- .../goblin_verifier/goblin_recursion.test.cpp | 78 +++++++++---------- 4 files changed, 71 insertions(+), 105 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 54c2581e6d96..449ef23f694b 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -299,11 +299,14 @@ std::pair ClientIVC::construct_and_prove_hiding_circuit() */ ClientIVC::Proof ClientIVC::prove() { + HonkProof mega_proof; MergeProof merge_proof; if (!one_circuit) { - auto [mega_proof, merge_proof_hiding] = construct_and_prove_hiding_circuit(); + auto [mega_proof_hiding, merge_proof_hiding] = construct_and_prove_hiding_circuit(); + mega_proof = mega_proof_hiding; merge_proof = merge_proof_hiding; } else { + mega_proof = verification_queue[0].proof; merge_proof = verification_queue[0].merge_proof; } diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index f8212a1af80b..6a5526b4d97e 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -40,10 +40,6 @@ class GoblinProver { using MergeProver = MergeProver_; using VerificationKey = MegaFlavor::VerificationKey; using MergeProof = std::vector; - /** - * @brief Output of goblin::accumulate; an Ultra proof and the corresponding verification key - * - */ std::shared_ptr op_queue = std::make_shared(); std::shared_ptr> commitment_key; @@ -77,38 +73,6 @@ class GoblinProver { commitment_key = bn254_commitment_key ? bn254_commitment_key : nullptr; GoblinMockCircuits::perform_op_queue_interactions_for_mock_first_circuit(op_queue); } - // /** - // * @brief Construct a MegaHonk proof and a merge proof for the present circuit. - // * @details If there is a previous merge proof, recursively verify it. - // * - // * @param circuit_builder - // */ - // GoblinAccumulationOutput accumulate(MegaBuilder& circuit_builder) - // { - // // Complete the circuit logic by recursively verifying previous merge proof if it exists - // if (merge_proof_exists) { - // RecursiveMergeVerifier merge_verifier{ &circuit_builder }; - // StdlibProof stdlib_merge_proof = - // bb::convert_native_proof_to_stdlib(&circuit_builder, merge_proof); - // [[maybe_unused]] auto pairing_points = merge_verifier.verify_proof(stdlib_merge_proof); - // } - - // // Construct a Honk proof for the main circuit - // auto proving_key = std::make_shared(circuit_builder); - // MegaProver prover(proving_key); - // auto ultra_proof = prover.construct_proof(); - // auto verification_key = std::make_shared(proving_key->proving_key); - - // // Construct and store the merge proof to be recursively verified on the next call to accumulate - // MergeProver merge_prover{ circuit_builder.op_queue }; - // merge_proof = merge_prover.construct_proof(); - - // if (!merge_proof_exists) { - // merge_proof_exists = true; - // } - - // return { ultra_proof, verification_key }; - // }; /** * @brief Add a recursive merge verifier to input circuit and construct a merge proof for the updated op queue diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp index d4d699f01fd8..14d4ffbad4ae 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp @@ -28,34 +28,33 @@ class GoblinTests : public ::testing::Test { } }; -// /** -// * @brief A simple test demonstrating goblin proof construction / verification based on operations from a collection -// of -// * circuits -// * -// */ -// TEST_F(GoblinTests, MultipleCircuits) -// { -// GoblinProver goblin; - -// // Construct and accumulate multiple circuits -// size_t NUM_CIRCUITS = 3; -// for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { -// auto circuit = construct_mock_circuit(goblin.op_queue); -// goblin.merge(circuit); // appends a recurisve merge verifier if a merge proof exists -// } - -// // Construct a goblin proof which consists of a merge proof and ECCVM/Translator proofs -// GoblinProof proof = goblin.prove(); - -// // Verify the goblin proof (eccvm, translator, merge); (Construct ECCVM/Translator verification keys from their -// // respective proving keys) -// auto eccvm_vkey = std::make_shared(goblin.get_eccvm_proving_key()); -// auto translator_vkey = std::make_shared(goblin.get_translator_proving_key()); -// GoblinVerifier goblin_verifier{ eccvm_vkey, translator_vkey }; -// bool verified = goblin_verifier.verify(proof); - -// EXPECT_TRUE(verified); -// } +/** + * @brief A simple test demonstrating goblin proof construction / verification based on operations from a collection of + * circuits + * + */ +TEST_F(GoblinTests, MultipleCircuits) +{ + GoblinProver goblin; + + // Construct and accumulate multiple circuits + size_t NUM_CIRCUITS = 3; + for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { + auto circuit = construct_mock_circuit(goblin.op_queue); + goblin.merge(circuit); // appends a recurisve merge verifier if a merge proof exists + } + + // Construct a goblin proof which consists of a merge proof and ECCVM/Translator proofs + GoblinProof proof = goblin.prove(); + + // Verify the goblin proof (eccvm, translator, merge); (Construct ECCVM/Translator verification keys from their + // respective proving keys) + auto eccvm_vkey = std::make_shared(goblin.get_eccvm_proving_key()); + auto translator_vkey = std::make_shared(goblin.get_translator_proving_key()); + GoblinVerifier goblin_verifier{ eccvm_vkey, translator_vkey }; + bool verified = goblin_verifier.verify(proof); + + EXPECT_TRUE(verified); +} // TODO(https://github.com/AztecProtocol/barretenberg/issues/787) Expand these tests. diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp index 508e34d5daae..18ca69a5d789 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp @@ -34,49 +34,49 @@ class GoblinRecursionTests : public ::testing::Test { } }; -// /** -// * @brief Test illustrating a Goblin-based IVC scheme -// * @details Goblin is usd to accumulate recursive verifications of the MegaHonk proving system. -// */ -// TEST_F(GoblinRecursionTests, Vanilla) -// { -// GoblinProver goblin; +/** + * @brief Test illustrating a Goblin-based IVC scheme + * @details Goblin is usd to accumulate recursive verifications of the MegaHonk proving system. + */ +TEST_F(GoblinRecursionTests, Vanilla) +{ + GoblinProver goblin; -// GoblinAccumulationOutput kernel_accum; + GoblinAccumulationOutput kernel_accum; -// size_t NUM_CIRCUITS = 2; -// for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { + size_t NUM_CIRCUITS = 2; + for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { -// // Construct and accumulate a mock function circuit containing both arbitrary arithmetic gates and goblin -// // ecc op gates to make it a meaningful test -// MegaCircuitBuilder function_circuit{ goblin.op_queue }; -// MockCircuits::construct_arithmetic_circuit(function_circuit, /*target_log2_dyadic_size=*/8); -// MockCircuits::construct_goblin_ecc_op_circuit(function_circuit); -// goblin.merge(function_circuit); -// function_circuit.add_pairing_point_accumulator( -// stdlib::recursion::init_default_agg_obj_indices(function_circuit)); -// auto function_accum = construct_accumulator(function_circuit); + // Construct and accumulate a mock function circuit containing both arbitrary arithmetic gates and goblin + // ecc op gates to make it a meaningful test + MegaCircuitBuilder function_circuit{ goblin.op_queue }; + MockCircuits::construct_arithmetic_circuit(function_circuit, /*target_log2_dyadic_size=*/8); + MockCircuits::construct_goblin_ecc_op_circuit(function_circuit); + goblin.merge(function_circuit); + function_circuit.add_pairing_point_accumulator( + stdlib::recursion::init_default_agg_obj_indices(function_circuit)); + auto function_accum = construct_accumulator(function_circuit); -// // Construct and accumulate the mock kernel circuit (no kernel accum in first round) -// MegaCircuitBuilder kernel_circuit{ goblin.op_queue }; -// GoblinMockCircuits::construct_mock_kernel_small(kernel_circuit, -// { function_accum.proof, function_accum.verification_key }, -// { kernel_accum.proof, kernel_accum.verification_key }); -// goblin.merge(kernel_circuit); -// kernel_circuit.add_pairing_point_accumulator(stdlib::recursion::init_default_agg_obj_indices(kernel_circuit)); -// kernel_accum = construct_accumulator(kernel_circuit); -// } + // Construct and accumulate the mock kernel circuit (no kernel accum in first round) + MegaCircuitBuilder kernel_circuit{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_kernel_small(kernel_circuit, + { function_accum.proof, function_accum.verification_key }, + { kernel_accum.proof, kernel_accum.verification_key }); + goblin.merge(kernel_circuit); + kernel_circuit.add_pairing_point_accumulator(stdlib::recursion::init_default_agg_obj_indices(kernel_circuit)); + kernel_accum = construct_accumulator(kernel_circuit); + } -// GoblinProof proof = goblin.prove(); -// // Verify the final ultra proof -// MegaVerifier ultra_verifier{ kernel_accum.verification_key }; -// bool ultra_verified = ultra_verifier.verify_proof(kernel_accum.proof); -// // Verify the goblin proof (eccvm, translator, merge) -// auto eccvm_vkey = std::make_shared(goblin.get_eccvm_proving_key()); -// auto translator_vkey = std::make_shared(goblin.get_translator_proving_key()); -// GoblinVerifier goblin_verifier{ eccvm_vkey, translator_vkey }; -// bool verified = goblin_verifier.verify(proof); -// EXPECT_TRUE(ultra_verified && verified); -// } + GoblinProof proof = goblin.prove(); + // Verify the final ultra proof + MegaVerifier ultra_verifier{ kernel_accum.verification_key }; + bool ultra_verified = ultra_verifier.verify_proof(kernel_accum.proof); + // Verify the goblin proof (eccvm, translator, merge) + auto eccvm_vkey = std::make_shared(goblin.get_eccvm_proving_key()); + auto translator_vkey = std::make_shared(goblin.get_translator_proving_key()); + GoblinVerifier goblin_verifier{ eccvm_vkey, translator_vkey }; + bool verified = goblin_verifier.verify(proof); + EXPECT_TRUE(ultra_verified && verified); +} // TODO(https://github.com/AztecProtocol/barretenberg/issues/787) Expand these tests. From 0fd22227a124d643be625b31f51c0436c0631d53 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Mon, 10 Mar 2025 21:51:39 +0000 Subject: [PATCH 3/9] uncommment test suite --- .../ultra_vanilla_client_ivc.test.cpp | 156 +++++++++--------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.test.cpp index 92a2d825d299..21656305671b 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.test.cpp @@ -1,93 +1,93 @@ -// #include "barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.hpp" -// #include "barretenberg/goblin/goblin.hpp" -// #include "barretenberg/goblin/mock_circuits.hpp" -// #include "barretenberg/protogalaxy/folding_test_utils.hpp" -// #include "barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp" -// #include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp" -// #include +#include "barretenberg/ultra_vanilla_client_ivc/ultra_vanilla_client_ivc.hpp" +#include "barretenberg/goblin/goblin.hpp" +#include "barretenberg/goblin/mock_circuits.hpp" +#include "barretenberg/protogalaxy/folding_test_utils.hpp" +#include "barretenberg/stdlib_circuit_builders/mega_circuit_builder.hpp" +#include "barretenberg/stdlib_circuit_builders/ultra_circuit_builder.hpp" +#include -// using namespace bb; +using namespace bb; -// class UltraVanillaClientIVCTests : public ::testing::Test { -// protected: -// static void SetUpTestSuite() -// { -// srs::init_crs_factory("../srs_db/ignition"); -// srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); -// } +class UltraVanillaClientIVCTests : public ::testing::Test { + protected: + static void SetUpTestSuite() + { + srs::init_crs_factory("../srs_db/ignition"); + srs::init_grumpkin_crs_factory("../srs_db/grumpkin"); + } -// using Flavor = UltraVanillaClientIVC::Flavor; -// using Builder = UltraCircuitBuilder; -// using FF = typename Flavor::FF; -// using VK = Flavor::VerificationKey; -// using PK = DeciderProvingKey_; + using Flavor = UltraVanillaClientIVC::Flavor; + using Builder = UltraCircuitBuilder; + using FF = typename Flavor::FF; + using VK = Flavor::VerificationKey; + using PK = DeciderProvingKey_; -// class MockCircuitSource : public CircuitSource { -// std::vector _sizes; -// std::vector> _vks; -// uint32_t step{ 0 }; + class MockCircuitSource : public CircuitSource { + std::vector _sizes; + std::vector> _vks; + uint32_t step{ 0 }; -// public: -// MockCircuitSource(const std::vector& sizes) -// : _sizes(sizes) -// { -// std::fill_n(std::back_inserter(_vks), sizes.size(), nullptr); -// } + public: + MockCircuitSource(const std::vector& sizes) + : _sizes(sizes) + { + std::fill_n(std::back_inserter(_vks), sizes.size(), nullptr); + } -// MockCircuitSource(const MockCircuitSource& source_without_sizes, std::vector> vks) -// : _sizes(source_without_sizes._sizes) -// , _vks(vks) -// {} + MockCircuitSource(const MockCircuitSource& source_without_sizes, std::vector> vks) + : _sizes(source_without_sizes._sizes) + , _vks(vks) + {} -// Output next() override -// { -// Builder circuit; -// MockCircuits::construct_arithmetic_circuit(circuit, _sizes[step]); -// const auto& vk = _vks[step]; -// ++step; -// return { circuit, vk }; -// } + Output next() override + { + Builder circuit; + MockCircuits::construct_arithmetic_circuit(circuit, _sizes[step]); + const auto& vk = _vks[step]; + ++step; + return { circuit, vk }; + } -// size_t num_circuits() const override -// { -// ASSERT(_sizes.size() == _vks.size()); -// return _sizes.size(); -// } -// }; -// }; + size_t num_circuits() const override + { + ASSERT(_sizes.size() == _vks.size()); + return _sizes.size(); + } + }; +}; -// TEST_F(UltraVanillaClientIVCTests, TwoCircuits) -// { -// static constexpr size_t LOG_SIZE = 10; -// UltraVanillaClientIVC ivc(1 << LOG_SIZE); -// MockCircuitSource circuit_source{ { LOG_SIZE, LOG_SIZE } }; -// EXPECT_TRUE(ivc.prove_and_verify(circuit_source)); -// }; +TEST_F(UltraVanillaClientIVCTests, TwoCircuits) +{ + static constexpr size_t LOG_SIZE = 10; + UltraVanillaClientIVC ivc(1 << LOG_SIZE); + MockCircuitSource circuit_source{ { LOG_SIZE, LOG_SIZE } }; + EXPECT_TRUE(ivc.prove_and_verify(circuit_source)); +}; -// TEST_F(UltraVanillaClientIVCTests, ThreeCircuits) -// { -// static constexpr size_t LOG_SIZE = 10; -// UltraVanillaClientIVC ivc(1 << LOG_SIZE); -// MockCircuitSource circuit_source{ { LOG_SIZE, LOG_SIZE, LOG_SIZE } }; -// EXPECT_TRUE(ivc.prove_and_verify(circuit_source)); -// }; +TEST_F(UltraVanillaClientIVCTests, ThreeCircuits) +{ + static constexpr size_t LOG_SIZE = 10; + UltraVanillaClientIVC ivc(1 << LOG_SIZE); + MockCircuitSource circuit_source{ { LOG_SIZE, LOG_SIZE, LOG_SIZE } }; + EXPECT_TRUE(ivc.prove_and_verify(circuit_source)); +}; -// /** -// * @brief Prove and verify accumulation of an arbitrary set of circuits using precomputed verification keys -// * @details The test precomputes the keys via one pass of the ivc prover, then it uses them in a second pass. -// */ -// TEST_F(UltraVanillaClientIVCTests, PrecomputedVerificationKeys) -// { +/** + * @brief Prove and verify accumulation of an arbitrary set of circuits using precomputed verification keys + * @details The test precomputes the keys via one pass of the ivc prover, then it uses them in a second pass. + */ +TEST_F(UltraVanillaClientIVCTests, PrecomputedVerificationKeys) +{ -// static constexpr size_t LOG_SIZE = 10; + static constexpr size_t LOG_SIZE = 10; -// UltraVanillaClientIVC ivc_1(1 << LOG_SIZE); -// MockCircuitSource circuit_source_no_vks{ { LOG_SIZE, LOG_SIZE } }; -// auto vks = ivc_1.compute_vks(circuit_source_no_vks); + UltraVanillaClientIVC ivc_1(1 << LOG_SIZE); + MockCircuitSource circuit_source_no_vks{ { LOG_SIZE, LOG_SIZE } }; + auto vks = ivc_1.compute_vks(circuit_source_no_vks); -// UltraVanillaClientIVC ivc_2(1 << LOG_SIZE); // need to refactor accumulator_value use to reuse ivc_1 -// MockCircuitSource circuit_source_with_vks{ circuit_source_no_vks, vks }; -// EXPECT_TRUE(ivc_2.prove_and_verify(circuit_source_with_vks)); -// }; + UltraVanillaClientIVC ivc_2(1 << LOG_SIZE); // need to refactor accumulator_value use to reuse ivc_1 + MockCircuitSource circuit_source_with_vks{ circuit_source_no_vks, vks }; + EXPECT_TRUE(ivc_2.prove_and_verify(circuit_source_with_vks)); +}; -// // TODO(https://github.com/AztecProtocol/barretenberg/issues/1177) Implement failure tests +// TODO(https://github.com/AztecProtocol/barretenberg/issues/1177) Implement failure tests From 3a8b0c1686e78d563ad41fc93e2df6ae93a0374f Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Mon, 10 Mar 2025 22:32:53 +0000 Subject: [PATCH 4/9] dont run nonsensical ivc tests --- barretenberg/acir_tests/bootstrap.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/barretenberg/acir_tests/bootstrap.sh b/barretenberg/acir_tests/bootstrap.sh index b8767bc21fae..a62c76193e46 100755 --- a/barretenberg/acir_tests/bootstrap.sh +++ b/barretenberg/acir_tests/bootstrap.sh @@ -125,10 +125,10 @@ function test_cmds_internal { 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 - # barretenberg-acir-tests-bb-client-ivc: - echo FLOW=prove_then_verify_client_ivc $run_test 6_array - echo FLOW=prove_then_verify_client_ivc $run_test databus - echo FLOW=prove_then_verify_client_ivc $run_test databus_two_calldata + # # barretenberg-acir-tests-bb-client-ivc: + # echo FLOW=prove_then_verify_client_ivc $run_test 6_array + # echo FLOW=prove_then_verify_client_ivc $run_test databus + # echo FLOW=prove_then_verify_client_ivc $run_test databus_two_calldata } function ultra_honk_wasm_memory { From f74245eb4780208a2770fd60b6d9585d4cfbed43 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Mon, 10 Mar 2025 22:48:01 +0000 Subject: [PATCH 5/9] clean out goblin a bit --- .../barretenberg/client_ivc/client_ivc.cpp | 13 ++-- .../cpp/src/barretenberg/goblin/goblin.hpp | 63 ++++++------------- .../stdlib/goblin_verifier/goblin.test.cpp | 2 +- .../goblin_verifier/goblin_recursion.test.cpp | 4 +- .../goblin_recursive_verifier.test.cpp | 6 +- .../barretenberg/ultra_honk/oink_prover.cpp | 4 +- .../barretenberg/ultra_honk/oink_prover.hpp | 2 +- 7 files changed, 35 insertions(+), 59 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 449ef23f694b..35dde3bc1e05 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -97,8 +97,8 @@ void ClientIVC::perform_recursive_verification_and_databus_consistency_checks( } } - // Recursively verify the merge proof for the present circuit - goblin.verify_merge(circuit, merge_proof); + // Recursively verify the merge proof for the circuit being recursively verified + [[maybe_unused]] auto pairing_points = GoblinVerifier::recursive_verify_merge(circuit, merge_proof); // Set the return data commitment to be propagated on the public inputs of the present kernel and perform // consistency checks between the calldata commitments and the return data commitments contained within the public @@ -201,7 +201,7 @@ void ClientIVC::accumulate(ClientCircuit& circuit, // proof MegaOinkProver oink_prover{ proving_key }; vinfo("computing oink proof..."); - oink_prover.prove(); + HonkProof oink_proof = oink_prover.prove(); vinfo("oink proof constructed"); proving_key->is_accumulator = true; // indicate to PG that it should not run oink on this key // Initialize the gate challenges to zero for use in first round of folding @@ -210,8 +210,8 @@ void ClientIVC::accumulate(ClientCircuit& circuit, fold_output.accumulator = proving_key; // initialize the prover accum with the completed key // Add oink proof and corresponding verification key to the verification queue - verification_queue.push_back(bb::ClientIVC::VerifierInputs{ - oink_prover.transcript->proof_data, merge_proof, honk_vk, QUEUE_TYPE::OINK }); + verification_queue.push_back( + bb::ClientIVC::VerifierInputs{ oink_proof, merge_proof, honk_vk, QUEUE_TYPE::OINK }); initialized = true; } else { // Otherwise, fold the new key into the accumulator @@ -258,7 +258,8 @@ std::pair ClientIVC::construct_and_prove_hiding_circuit() const StdlibProof stdlib_merge_proof = bb::convert_native_proof_to_stdlib(&builder, verification_queue[0].merge_proof); - goblin.verify_merge(builder, stdlib_merge_proof); + + [[maybe_unused]] auto pairing_points = GoblinVerifier::recursive_verify_merge(builder, stdlib_merge_proof); // Construct stdlib accumulator, decider vkey and folding proof auto stdlib_verifier_accumulator = diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index 6a5526b4d97e..1341dd7832a6 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -35,8 +35,7 @@ class GoblinProver { using ECCVMProvingKey = ECCVMFlavor::ProvingKey; using TranslationEvaluations = ECCVMProver::TranslationEvaluations; using TranslatorBuilder = TranslatorCircuitBuilder; - using RecursiveMergeVerifier = stdlib::recursion::goblin::MergeRecursiveVerifier_; - using PairingPoints = RecursiveMergeVerifier::PairingPoints; + using MergeProver = MergeProver_; using VerificationKey = MegaFlavor::VerificationKey; using MergeProof = std::vector; @@ -47,9 +46,6 @@ class GoblinProver { MergeProof merge_proof; GoblinProof goblin_proof; - // on the first call to accumulate there is no merge proof to verify - bool merge_proof_exists{ false }; - std::shared_ptr get_eccvm_proving_key() const { return eccvm_key; } std::shared_ptr get_translator_proving_key() const { @@ -74,47 +70,12 @@ class GoblinProver { GoblinMockCircuits::perform_op_queue_interactions_for_mock_first_circuit(op_queue); } - /** - * @brief Add a recursive merge verifier to input circuit and construct a merge proof for the updated op queue - * @details When this method is used, the "prover" functionality of the IVC scheme must be performed explicitly, - but - * this method has to be called first so that the recursive merge verifier can be "appended" to the circuit being - * accumulated - * - * @param circuit_builder - */ - void merge(MegaBuilder& circuit_builder) - { - // Append a recursive merge verification of the merge proof - if (merge_proof_exists) { - StdlibProof stdlib_merge_proof = - bb::convert_native_proof_to_stdlib(&circuit_builder, merge_proof); - [[maybe_unused]] auto pairing_points = verify_merge(circuit_builder, stdlib_merge_proof); - } - - // Construct a merge proof for the present circuit - merge_proof = prove_merge(circuit_builder); - }; - - /** - * @brief Append recursive verification of a merge proof to a provided circuit - * - * @param circuit_builder - * @return PairingPoints - */ - PairingPoints verify_merge(MegaBuilder& circuit_builder, const StdlibProof& proof) const - { - PROFILE_THIS_NAME("Goblin::merge"); - RecursiveMergeVerifier merge_verifier{ &circuit_builder }; - return merge_verifier.verify_proof(proof); - }; - /** * @brief Construct a merge proof for the goblin ECC ops in the provided circuit * * @param circuit_builder */ - MergeProof prove_merge(MegaBuilder& circuit_builder) + MergeProof prove_merge(MegaBuilder& circuit_builder) const { PROFILE_THIS_NAME("Goblin::merge"); // TODO(https://github.com/AztecProtocol/barretenberg/issues/993): Some circuits (particularly on the first call @@ -126,10 +87,6 @@ class GoblinProver { MockCircuits::construct_goblin_ecc_op_circuit(circuit_builder); // Add some arbitrary goblin ECC ops } - if (!merge_proof_exists) { - merge_proof_exists = true; - } - MergeProver merge_prover{ circuit_builder.op_queue, commitment_key }; return merge_prover.construct_proof(); }; @@ -226,6 +183,9 @@ class GoblinVerifier { using ECCVMVerificationKey = ECCVMFlavor::VerificationKey; using TranslatorVerificationKey = bb::TranslatorFlavor::VerificationKey; using MergeVerifier = bb::MergeVerifier_; + using Builder = MegaCircuitBuilder; + using RecursiveMergeVerifier = stdlib::recursion::goblin::MergeRecursiveVerifier_; + using PairingPoints = RecursiveMergeVerifier::PairingPoints; struct VerifierInput { std::shared_ptr eccvm_verification_key; @@ -248,6 +208,19 @@ class GoblinVerifier { , translator_verification_key(input.translator_verification_key) {} + /** + * @brief Append recursive verification of a merge proof to a provided circuit + * + * @param circuit_builder + * @return PairingPoints + */ + static PairingPoints recursive_verify_merge(Builder& circuit_builder, const StdlibProof& proof) + { + PROFILE_THIS_NAME("Goblin::merge"); + RecursiveMergeVerifier merge_verifier{ &circuit_builder }; + return merge_verifier.verify_proof(proof); + }; + /** * @brief Verify a full Goblin proof (ECCVM, Translator, merge) * diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp index 14d4ffbad4ae..c003a5208107 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp @@ -41,7 +41,7 @@ TEST_F(GoblinTests, MultipleCircuits) size_t NUM_CIRCUITS = 3; for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { auto circuit = construct_mock_circuit(goblin.op_queue); - goblin.merge(circuit); // appends a recurisve merge verifier if a merge proof exists + goblin.prove_merge(circuit); // appends a recurisve merge verifier if a merge proof exists } // Construct a goblin proof which consists of a merge proof and ECCVM/Translator proofs diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp index 18ca69a5d789..a52668f08544 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin_recursion.test.cpp @@ -52,7 +52,7 @@ TEST_F(GoblinRecursionTests, Vanilla) MegaCircuitBuilder function_circuit{ goblin.op_queue }; MockCircuits::construct_arithmetic_circuit(function_circuit, /*target_log2_dyadic_size=*/8); MockCircuits::construct_goblin_ecc_op_circuit(function_circuit); - goblin.merge(function_circuit); + goblin.prove_merge(function_circuit); function_circuit.add_pairing_point_accumulator( stdlib::recursion::init_default_agg_obj_indices(function_circuit)); auto function_accum = construct_accumulator(function_circuit); @@ -62,7 +62,7 @@ TEST_F(GoblinRecursionTests, Vanilla) GoblinMockCircuits::construct_mock_kernel_small(kernel_circuit, { function_accum.proof, function_accum.verification_key }, { kernel_accum.proof, kernel_accum.verification_key }); - goblin.merge(kernel_circuit); + goblin.prove_merge(kernel_circuit); kernel_circuit.add_pairing_point_accumulator(stdlib::recursion::init_default_agg_obj_indices(kernel_circuit)); kernel_accum = construct_accumulator(kernel_circuit); } 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 87d9b3889572..c79193dee36e 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 @@ -42,14 +42,14 @@ class GoblinRecursiveVerifierTests : public testing::Test { * * @return ProverOutput */ - ProverOutput create_goblin_prover_output(const size_t NUM_CIRCUITS = 3) + static ProverOutput create_goblin_prover_output(const size_t NUM_CIRCUITS = 3) { GoblinProver goblin; // Construct and accumulate multiple circuits for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { auto circuit = construct_mock_circuit(goblin.op_queue); - goblin.merge(circuit); // appends a recurisve merge verifier if a merge proof exists + goblin.prove_merge(circuit); // appends a recurisve merge verifier if a merge proof exists } // Output is a goblin proof plus ECCVM/Translator verification keys @@ -107,7 +107,7 @@ TEST_F(GoblinRecursiveVerifierTests, Basic) TEST_F(GoblinRecursiveVerifierTests, IndependentVKHash) { // Retrieves the trace blocks (each consisting of a specific gate) from the recursive verifier circuit - auto get_blocks = [this](size_t inner_size) + auto get_blocks = [](size_t inner_size) -> std::tuple> { auto [proof, verifier_input] = create_goblin_prover_output(inner_size); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp index e15fc8911c54..c599aa9f5a83 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.cpp @@ -12,7 +12,7 @@ namespace bb { * @tparam Flavor * @return OinkProverOutput */ -template void OinkProver::prove() +template HonkProof OinkProver::prove() { if (proving_key->proving_key.commitment_key == nullptr) { proving_key->proving_key.commitment_key = @@ -63,6 +63,8 @@ template void OinkProver::prove() // Free the commitment key proving_key->proving_key.commitment_key = nullptr; // #endif + + return transcript->proof_data; } /** diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.hpp index 5009c33e92e7..9db80c57049e 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/oink_prover.hpp @@ -56,7 +56,7 @@ template class OinkProver { , trace_usage_tracker(trace_usage_tracker) {} - void prove(); + HonkProof prove(); void execute_preamble_round(); void execute_wire_commitments_round(); void execute_sorted_list_accumulator_round(); From f4e92ebe82ccf62e32b73136a966db914291da64 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Tue, 11 Mar 2025 18:44:59 +0000 Subject: [PATCH 6/9] store merge proof in goblin for use in tests --- .../cpp/src/barretenberg/client_ivc/client_ivc.cpp | 3 ++- .../cpp/src/barretenberg/client_ivc/client_ivc.hpp | 2 +- barretenberg/cpp/src/barretenberg/goblin/goblin.hpp | 7 ++++--- .../cpp/src/barretenberg/ultra_honk/merge_prover.cpp | 2 +- .../cpp/src/barretenberg/ultra_honk/merge_prover.hpp | 4 +++- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 35dde3bc1e05..4dc011819a0d 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -232,8 +232,9 @@ void ClientIVC::accumulate(ClientCircuit& circuit, * * @details The aim of this intermediate stage is to reduce the cost of producing a zero-knowledge ClientIVCProof. * @return HonkProof - a Mega proof + * @return MergeProof - a Merge proof */ -std::pair ClientIVC::construct_and_prove_hiding_circuit() +std::pair ClientIVC::construct_and_prove_hiding_circuit() { trace_usage_tracker.print(); // print minimum structured sizes for each block ASSERT(verification_queue.size() == 1); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp index c33d0308a64d..7a444218fd50 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp @@ -169,7 +169,7 @@ class ClientIVC { Proof prove(); - std::pair construct_and_prove_hiding_circuit(); + std::pair construct_and_prove_hiding_circuit(); static bool verify(const Proof& proof, const VerificationKey& vk); diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index 1341dd7832a6..ec62293ddb26 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -38,7 +38,7 @@ class GoblinProver { using MergeProver = MergeProver_; using VerificationKey = MegaFlavor::VerificationKey; - using MergeProof = std::vector; + using MergeProof = MergeProver::MergeProof; std::shared_ptr op_queue = std::make_shared(); std::shared_ptr> commitment_key; @@ -75,7 +75,7 @@ class GoblinProver { * * @param circuit_builder */ - MergeProof prove_merge(MegaBuilder& circuit_builder) const + MergeProof prove_merge(MegaBuilder& circuit_builder) { PROFILE_THIS_NAME("Goblin::merge"); // TODO(https://github.com/AztecProtocol/barretenberg/issues/993): Some circuits (particularly on the first call @@ -88,7 +88,8 @@ class GoblinProver { } MergeProver merge_prover{ circuit_builder.op_queue, commitment_key }; - return merge_prover.construct_proof(); + merge_proof = merge_prover.construct_proof(); + return merge_proof; }; /** diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.cpp index 7d872aec97f3..0127e9ec6047 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.cpp @@ -32,7 +32,7 @@ MergeProver_::MergeProver_(const std::shared_ptr& op_queue, * * @return honk::proof */ -template HonkProof MergeProver_::construct_proof() +template MergeProver_::MergeProof MergeProver_::construct_proof() { transcript = std::make_shared(); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp index 9a265698c096..2abab06f3865 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/merge_prover.hpp @@ -25,12 +25,14 @@ template class MergeProver_ { using Transcript = NativeTranscript; public: + using MergeProof = std::vector; + std::shared_ptr transcript; explicit MergeProver_(const std::shared_ptr& op_queue, std::shared_ptr commitment_key = nullptr); - BB_PROFILE HonkProof construct_proof(); + BB_PROFILE MergeProof construct_proof(); private: std::shared_ptr op_queue; From c93e6e25c8f5212bf608bcab44496e61bd815780 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Tue, 11 Mar 2025 20:33:17 +0000 Subject: [PATCH 7/9] clean out stuff related to one_circuit functionality --- barretenberg/acir_tests/bootstrap.sh | 5 ---- .../barretenberg/client_ivc/client_ivc.cpp | 28 ++----------------- .../barretenberg/client_ivc/client_ivc.hpp | 4 --- 3 files changed, 3 insertions(+), 34 deletions(-) diff --git a/barretenberg/acir_tests/bootstrap.sh b/barretenberg/acir_tests/bootstrap.sh index a62c76193e46..0ee8858d8427 100755 --- a/barretenberg/acir_tests/bootstrap.sh +++ b/barretenberg/acir_tests/bootstrap.sh @@ -124,11 +124,6 @@ function test_cmds_internal { echo SYS=ultra_honk FLOW=prove_then_verify RECURSIVE=true $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 - - # # barretenberg-acir-tests-bb-client-ivc: - # echo FLOW=prove_then_verify_client_ivc $run_test 6_array - # echo FLOW=prove_then_verify_client_ivc $run_test databus - # echo FLOW=prove_then_verify_client_ivc $run_test databus_two_calldata } function ultra_honk_wasm_memory { diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 4dc011819a0d..7380cea9e714 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -150,7 +150,7 @@ void ClientIVC::complete_kernel_circuit_logic(ClientCircuit& circuit) * @param precomputed_vk */ void ClientIVC::accumulate(ClientCircuit& circuit, - const bool _one_circuit, + [[maybe_unused]] const bool _one_circuit, const std::shared_ptr& precomputed_vk, const bool mock_vk) { @@ -183,20 +183,7 @@ void ClientIVC::accumulate(ClientCircuit& circuit, vinfo("set honk vk metadata"); } - if (_one_circuit) { - // The initial stack consisted of only one circuit, so construct a proof for it. - one_circuit = _one_circuit; - MegaProver prover{ proving_key }; - vinfo("computing mega proof..."); - mega_proof = prover.prove(); - vinfo("mega proof computed"); - - proving_key->is_accumulator = true; // indicate to PG that it should not run oink on this key - // Initialize the gate challenges to zero for use in first round of folding - proving_key->gate_challenges = std::vector(CONST_PG_LOG_N, 0); - - fold_output.accumulator = proving_key; - } else if (!initialized) { + if (!initialized) { // If this is the first circuit in the IVC, use oink to complete the decider proving key and generate an oink // proof MegaOinkProver oink_prover{ proving_key }; @@ -301,16 +288,7 @@ std::pair ClientIVC::construct_and_prove_hidin */ ClientIVC::Proof ClientIVC::prove() { - HonkProof mega_proof; - MergeProof merge_proof; - if (!one_circuit) { - auto [mega_proof_hiding, merge_proof_hiding] = construct_and_prove_hiding_circuit(); - mega_proof = mega_proof_hiding; - merge_proof = merge_proof_hiding; - } else { - mega_proof = verification_queue[0].proof; - merge_proof = verification_queue[0].merge_proof; - } + auto [mega_proof, merge_proof] = construct_and_prove_hiding_circuit(); return { mega_proof, goblin.prove(merge_proof) }; }; diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp index 7a444218fd50..6dde08538abf 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp @@ -130,10 +130,6 @@ class ClientIVC { GoblinProver goblin; - // We dynamically detect whether the input stack consists of one circuit, in which case we do not construct the - // hiding circuit and instead simply prove the single input circuit. - bool one_circuit = false; - bool initialized = false; // Is the IVC accumulator initialized ClientIVC(TraceSettings trace_settings = {}) From 60f68c261ffc536ac6d30490d6b02206159bb7fd Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Tue, 11 Mar 2025 20:57:11 +0000 Subject: [PATCH 8/9] minor cleanup and tagging todos --- .../cpp/src/barretenberg/client_ivc/client_ivc.cpp | 8 ++++---- .../barretenberg/stdlib/goblin_verifier/goblin.test.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 7380cea9e714..b6dedc5d72e1 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -98,6 +98,7 @@ void ClientIVC::perform_recursive_verification_and_databus_consistency_checks( } // Recursively verify the merge proof for the circuit being recursively verified + // TODO(https://github.com/AztecProtocol/barretenberg/issues/950): handle pairing point accumulation [[maybe_unused]] auto pairing_points = GoblinVerifier::recursive_verify_merge(circuit, merge_proof); // Set the return data commitment to be propagated on the public inputs of the present kernel and perform @@ -197,8 +198,7 @@ void ClientIVC::accumulate(ClientCircuit& circuit, fold_output.accumulator = proving_key; // initialize the prover accum with the completed key // Add oink proof and corresponding verification key to the verification queue - verification_queue.push_back( - bb::ClientIVC::VerifierInputs{ oink_proof, merge_proof, honk_vk, QUEUE_TYPE::OINK }); + verification_queue.push_back(VerifierInputs{ oink_proof, merge_proof, honk_vk, QUEUE_TYPE::OINK }); initialized = true; } else { // Otherwise, fold the new key into the accumulator @@ -208,8 +208,7 @@ void ClientIVC::accumulate(ClientCircuit& circuit, vinfo("constructed folding proof"); // Add fold proof and corresponding verification key to the verification queue - verification_queue.push_back( - bb::ClientIVC::VerifierInputs{ fold_output.proof, merge_proof, honk_vk, QUEUE_TYPE::PG }); + verification_queue.push_back(VerifierInputs{ fold_output.proof, merge_proof, honk_vk, QUEUE_TYPE::PG }); } } @@ -247,6 +246,7 @@ std::pair ClientIVC::construct_and_prove_hidin const StdlibProof stdlib_merge_proof = bb::convert_native_proof_to_stdlib(&builder, verification_queue[0].merge_proof); + // TODO(https://github.com/AztecProtocol/barretenberg/issues/950): handle pairing point accumulation [[maybe_unused]] auto pairing_points = GoblinVerifier::recursive_verify_merge(builder, stdlib_merge_proof); // Construct stdlib accumulator, decider vkey and folding proof diff --git a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp index c003a5208107..eb2d92442d98 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/goblin_verifier/goblin.test.cpp @@ -41,7 +41,7 @@ TEST_F(GoblinTests, MultipleCircuits) size_t NUM_CIRCUITS = 3; for (size_t idx = 0; idx < NUM_CIRCUITS; ++idx) { auto circuit = construct_mock_circuit(goblin.op_queue); - goblin.prove_merge(circuit); // appends a recurisve merge verifier if a merge proof exists + goblin.prove_merge(circuit); // appends a recursive merge verifier if a merge proof exists } // Construct a goblin proof which consists of a merge proof and ECCVM/Translator proofs From 2c184507b7df1be0d08e0b0bc35e8df5c4b994a4 Mon Sep 17 00:00:00 2001 From: ledwards2225 Date: Tue, 11 Mar 2025 21:43:08 +0000 Subject: [PATCH 9/9] use verifier inputs directly --- .../barretenberg/client_ivc/client_ivc.cpp | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index b6dedc5d72e1..138c9bd569b5 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -44,31 +44,23 @@ void ClientIVC::instantiate_stdlib_verification_queue( * case, the verifier accumulator is updated in place via the verification algorithm. Databus commitment consistency * checks are performed on the witness commitments and public inputs extracted from the proof by the verifier. * - * @param circuit The circuit to which the constraints are appended - * @param proof A stdlib proof to be recursively verified (either oink or PG) - * @param vkey The stdlib verification key associated with the proof - * @param type The type of the proof (equivalently, the type of the verifier) + * @param circuit + * @param verifier_inputs {proof, merge_proof, vkey, type (Oink/PG)} A set of inputs for recursive verification */ void ClientIVC::perform_recursive_verification_and_databus_consistency_checks( ClientCircuit& circuit, const StdlibVerifierInputs& verifier_inputs) { - - const StdlibProof& proof = verifier_inputs.proof; - const StdlibProof& merge_proof = verifier_inputs.merge_proof; - const std::shared_ptr& vkey = verifier_inputs.honk_verification_key; - const QUEUE_TYPE type = verifier_inputs.type; - // Store the decider vk for the incoming circuit; its data is used in the databus consistency checks below std::shared_ptr decider_vk; - switch (type) { + switch (verifier_inputs.type) { case QUEUE_TYPE::PG: { // Construct stdlib verifier accumulator from the native counterpart computed on a previous round auto stdlib_verifier_accum = std::make_shared(&circuit, verifier_accumulator); // Perform folding recursive verification to update the verifier accumulator - FoldingRecursiveVerifier verifier{ &circuit, stdlib_verifier_accum, { vkey } }; - auto verifier_accum = verifier.verify_folding_proof(proof); + FoldingRecursiveVerifier verifier{ &circuit, stdlib_verifier_accum, { verifier_inputs.honk_verification_key } }; + auto verifier_accum = verifier.verify_folding_proof(verifier_inputs.proof); // Extract native verifier accumulator from the stdlib accum for use on the next round verifier_accumulator = std::make_shared(verifier_accum->get_value()); @@ -79,11 +71,12 @@ void ClientIVC::perform_recursive_verification_and_databus_consistency_checks( } case QUEUE_TYPE::OINK: { // Construct an incomplete stdlib verifier accumulator from the corresponding stdlib verification key - auto verifier_accum = std::make_shared(&circuit, vkey); + auto verifier_accum = + std::make_shared(&circuit, verifier_inputs.honk_verification_key); // Perform oink recursive verification to complete the initial verifier accumulator OinkRecursiveVerifier oink{ &circuit, verifier_accum }; - oink.verify_proof(proof); + oink.verify_proof(verifier_inputs.proof); verifier_accum->is_accumulator = true; // indicate to PG that it should not run oink // Extract native verifier accumulator from the stdlib accum for use on the next round @@ -99,7 +92,7 @@ void ClientIVC::perform_recursive_verification_and_databus_consistency_checks( // Recursively verify the merge proof for the circuit being recursively verified // TODO(https://github.com/AztecProtocol/barretenberg/issues/950): handle pairing point accumulation - [[maybe_unused]] auto pairing_points = GoblinVerifier::recursive_verify_merge(circuit, merge_proof); + [[maybe_unused]] auto pairing_points = GoblinVerifier::recursive_verify_merge(circuit, verifier_inputs.merge_proof); // Set the return data commitment to be propagated on the public inputs of the present kernel and perform // consistency checks between the calldata commitments and the return data commitments contained within the public