From eebe8854fba5e8ebaf1f2b7c997a9bb0bba8cdb5 Mon Sep 17 00:00:00 2001 From: maramihali Date: Fri, 16 Feb 2024 10:26:13 +0000 Subject: [PATCH 01/15] moved to new branch --- .../benchmark/ivc_bench/ivc.bench.cpp | 29 +- .../protogalaxy_bench/protogalaxy.bench.cpp | 2 +- .../protogalaxy_rounds.bench.cpp | 2 +- .../benchmark/ultra_bench/mock_proofs.hpp | 4 +- .../barretenberg/client_ivc/client_ivc.cpp | 42 +- .../barretenberg/client_ivc/client_ivc.hpp | 19 +- .../client_ivc/client_ivc.test.cpp | 111 ++++-- .../client_ivc/mock_kernel_pinning.test.cpp | 21 +- .../src/barretenberg/goblin/CMakeLists.txt | 2 +- .../cpp/src/barretenberg/goblin/goblin.hpp | 10 +- .../goblin/goblin_recursion.test.cpp | 7 +- .../src/barretenberg/goblin/mock_circuits.hpp | 56 +-- .../goblin/mock_circuits_pinning.test.cpp | 4 +- .../protogalaxy/decider_prover.cpp | 48 --- .../protogalaxy/decider_verifier.cpp | 109 ++--- .../protogalaxy/decider_verifier.hpp | 5 +- .../protogalaxy/protogalaxy_prover.cpp | 211 ++++------ .../protogalaxy/protogalaxy_prover.hpp | 47 +-- .../protogalaxy/protogalaxy_verifier.cpp | 162 ++------ .../protogalaxy/protogalaxy_verifier.hpp | 8 +- .../recursion/honk/transcript/transcript.hpp | 4 +- .../verifier/decider_recursive_verifier.cpp | 58 +-- .../verifier/decider_recursive_verifier.hpp | 9 +- .../honk/verifier/goblin_verifier.test.cpp | 38 +- .../honk/verifier/merge_verifier.test.cpp | 5 +- .../protogalaxy_recursive_verifier.cpp | 178 ++------- .../protogalaxy_recursive_verifier.hpp | 20 +- .../protogalaxy_recursive_verifier.test.cpp | 373 +++++++++--------- .../honk/verifier/recursive_instances.hpp | 44 +++ .../verifier/recursive_verifier_instance.hpp | 140 +++++++ .../recursion/honk/verifier/verifier.test.cpp | 36 +- .../sumcheck/instance/instances.hpp | 8 +- .../sumcheck/instance/prover_instance.hpp | 2 +- .../src/barretenberg/sumcheck/sumcheck.hpp | 2 +- .../ultra_honk/databus_composer.test.cpp | 5 +- .../ultra_honk/goblin_ultra_composer.test.cpp | 5 +- .../goblin_ultra_transcript.test.cpp | 12 +- .../ultra_honk/protogalaxy.test.cpp | 163 ++++---- .../ultra_honk/relation_correctness.test.cpp | 4 +- .../barretenberg/ultra_honk/sumcheck.test.cpp | 2 +- .../ultra_honk/ultra_composer.cpp | 41 +- .../ultra_honk/ultra_composer.hpp | 37 +- .../ultra_honk/ultra_composer.test.cpp | 12 +- .../barretenberg/ultra_honk/ultra_prover.cpp | 2 +- .../ultra_honk/ultra_transcript.test.cpp | 12 +- 45 files changed, 1044 insertions(+), 1067 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp create mode 100644 barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp index 95eeb7d5b94..2e1cacf27a1 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp @@ -33,44 +33,57 @@ class IvcBench : public benchmark::Fixture { /** * @brief Perform a specified number of function circuit accumulation rounds - * @details Each round "accumulates" a mock function circuit and a mock kernel circuit. Each round thus consists of + * @details Each round "accumulates" a mock function circuit and a mock kernel circuit. Each round thus consists + of * the generation of two circuits, two folding proofs and two Merge proofs. To match the sizes called out in the * spec * (https://github.com/AztecProtocol/aztec-packages/blob/master/yellow-paper/docs/cryptography/performance-targets.md) - * we set the size of the function circuit to be 2^17. The first one should be 2^19 but we can't currently support + * we set the size of the function circuit to be 2^17. The first one should be 2^19 but we can't currently + support * folding circuits of unequal size. * */ static void perform_ivc_accumulation_rounds(State& state, ClientIVC& ivc) { + static_cast(state); + static_cast(ivc); // Initialize IVC with function circuit Builder function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(function_circuit); ivc.initialize(function_circuit); + auto kernel_verifier_accum = ivc.get_verifier_accumulator(); // Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet) Builder kernel_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(kernel_circuit); auto kernel_fold_proof = ivc.accumulate(kernel_circuit); + auto kernel_verifier_inst = ivc.get_verifier_instance(); auto NUM_CIRCUITS = static_cast(state.range(0)); - NUM_CIRCUITS -= 1; // Subtract one to account for the "initialization" round above + // Subtract one to account for the "initialization" round above + NUM_CIRCUITS -= 1; for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { - - // Accumulate function circuit Builder function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(function_circuit); auto function_fold_proof = ivc.accumulate(function_circuit); + auto fnct_verifier_inst = ivc.get_verifier_instance(); // Accumulate kernel circuit Builder kernel_circuit{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, function_fold_proof, kernel_fold_proof); - auto kernel_fold_proof = ivc.accumulate(kernel_circuit); + kernel_verifier_accum = GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, + kernel_fold_proof, + function_fold_proof, + kernel_verifier_inst, + fnct_verifier_inst, + kernel_verifier_accum); + + kernel_fold_proof = ivc.accumulate(kernel_circuit); + kernel_verifier_inst = ivc.get_verifier_instance(); } } }; -/** +/**ch * @brief Benchmark the prover work for the full PG-Goblin IVC protocol * */ diff --git a/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_bench/protogalaxy.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_bench/protogalaxy.bench.cpp index 61c46dc2493..0b5c2403cc5 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_bench/protogalaxy.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_bench/protogalaxy.bench.cpp @@ -30,7 +30,7 @@ template void fold_one(State& state) noexcept static_assert(std::same_as); bb::mock_proofs::generate_basic_arithmetic_circuit(builder, log2_num_gates); } - return composer.create_instance(builder); + return composer.create_prover_instance(builder); }; std::shared_ptr instance_1 = construct_instance(); diff --git a/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp index 626ab82bc1f..8369b995d9a 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp @@ -28,7 +28,7 @@ void _bench_round(::benchmark::State& state, static_assert(std::same_as); bb::mock_proofs::generate_basic_arithmetic_circuit(builder, log2_num_gates); } - return composer.create_instance(builder); + return composer.create_prover_instance(builder); }; std::shared_ptr instance_1 = construct_instance(); diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ultra_bench/mock_proofs.hpp b/barretenberg/cpp/src/barretenberg/benchmark/ultra_bench/mock_proofs.hpp index 1c0a1ed43ba..29ff2fb135e 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ultra_bench/mock_proofs.hpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ultra_bench/mock_proofs.hpp @@ -54,7 +54,7 @@ inline UltraProver get_prover(UltraComposer& composer, { UltraComposer::CircuitBuilder builder; test_circuit_function(builder, num_iterations); - std::shared_ptr instance = composer.create_instance(builder); + std::shared_ptr instance = composer.create_prover_instance(builder); return composer.create_prover(instance); } @@ -64,7 +64,7 @@ inline GoblinUltraProver get_prover(GoblinUltraComposer& composer, { GoblinUltraComposer::CircuitBuilder builder; test_circuit_function(builder, num_iterations); - std::shared_ptr instance = composer.create_instance(builder); + std::shared_ptr instance = composer.create_prover_instance(builder); return composer.create_prover(instance); } diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 92db4e2aaca..2cae9315c09 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -18,7 +18,7 @@ void ClientIVC::initialize(ClientCircuit& circuit) { goblin.merge(circuit); // Construct new merge proof Composer composer; - fold_output.accumulator = composer.create_instance(circuit); + prover_fold_output.accumulator = composer.create_prover_instance(circuit); } /** @@ -32,11 +32,10 @@ ClientIVC::FoldProof ClientIVC::accumulate(ClientCircuit& circuit) { goblin.merge(circuit); // Add recursive merge verifier and construct new merge proof Composer composer; - auto instance = composer.create_instance(circuit); - std::vector> instances{ fold_output.accumulator, instance }; - auto folding_prover = composer.create_folding_prover(instances); - fold_output = folding_prover.fold_instances(); - return fold_output.folding_data; + prover_instance = composer.create_prover_instance(circuit); + auto folding_prover = composer.create_folding_prover({ prover_fold_output.accumulator, prover_instance }); + prover_fold_output = folding_prover.fold_instances(); + return prover_fold_output.folding_data; } /** @@ -46,7 +45,7 @@ ClientIVC::FoldProof ClientIVC::accumulate(ClientCircuit& circuit) */ ClientIVC::Proof ClientIVC::prove() { - return { fold_output.folding_data, decider_prove(), goblin.prove() }; + return { prover_fold_output.folding_data, decider_prove(), goblin.prove() }; } /** @@ -55,19 +54,19 @@ ClientIVC::Proof ClientIVC::prove() * @param proof * @return bool */ -bool ClientIVC::verify(Proof& proof) +bool ClientIVC::verify(Proof& proof, const std::vector& verifier_instances) { // Goblin verification (merge, eccvm, translator) bool goblin_verified = goblin.verify(proof.goblin_proof); // Decider verification Composer composer; - auto folding_verifier = composer.create_folding_verifier(); - bool folding_verified = folding_verifier.verify_folding_proof(proof.fold_proof); + auto folding_verifier = composer.create_folding_verifier({ verifier_instances[0], verifier_instances[1] }); + auto verifier_accumulator = folding_verifier.verify_folding_proof(proof.fold_proof); // NOTE: Use of member accumulator here will go away with removal of vkey from ProverInstance - auto decider_verifier = composer.create_decider_verifier(fold_output.accumulator); + auto decider_verifier = composer.create_decider_verifier(verifier_accumulator); bool decision = decider_verifier.verify_proof(proof.decider_proof); - return goblin_verified && folding_verified && decision; + return goblin_verified && decision; } /** @@ -78,8 +77,25 @@ bool ClientIVC::verify(Proof& proof) HonkProof ClientIVC::decider_prove() const { Composer composer; - auto decider_prover = composer.create_decider_prover(fold_output.accumulator); + auto decider_prover = composer.create_decider_prover(prover_fold_output.accumulator); return decider_prover.construct_proof(); } +std::shared_ptr ClientIVC::get_verifier_instance() +{ + Composer composer; + composer.compute_commitment_key(prover_instance->instance_size); + auto verifier_instance = composer.create_verifier_instance(prover_instance); + return verifier_instance; +} + +ClientIVC::VerifierAccumulator ClientIVC::get_verifier_accumulator() +{ + Composer composer; + auto prover_accumulator = prover_fold_output.accumulator; + composer.compute_commitment_key(prover_accumulator->instance_size); + auto verifier_accumulator = composer.create_verifier_instance(prover_accumulator); + return verifier_accumulator; +} + } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp index cd3b82b4d6d..15d24ddce85 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp @@ -18,7 +18,10 @@ class ClientIVC { using Flavor = GoblinUltraFlavor; using FF = Flavor::FF; using FoldProof = std::vector; - using Accumulator = std::shared_ptr>; + using ProverAccumulator = std::shared_ptr>; + using VerifierAccumulator = std::shared_ptr>; + using VerifierInstance = VerifierInstance_; + using ProverInstance = ProverInstance_; using ClientCircuit = GoblinUltraCircuitBuilder; // can only be GoblinUltra // A full proof for the IVC scheme @@ -29,13 +32,16 @@ class ClientIVC { }; private: - using FoldingOutput = FoldingResult; - using Instance = ProverInstance_; + using ProverFoldOutput = FoldingResult; using Composer = GoblinUltraComposer; public: Goblin goblin; - FoldingOutput fold_output; + ProverFoldOutput prover_fold_output; + ProverAccumulator prover_accumulator; + + // keep the instance or instances around if we're folding more of them so we can compute the verification key + std::shared_ptr prover_instance; ClientIVC(); @@ -45,8 +51,11 @@ class ClientIVC { Proof prove(); - bool verify(Proof& proof); + bool verify(Proof& proof, const std::vector& verifier_instances); HonkProof decider_prove() const; + + VerifierAccumulator get_verifier_accumulator(); + std::shared_ptr get_verifier_instance(); }; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp index 2924188f87d..d767f1c7e56 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp @@ -21,23 +21,28 @@ class ClientIVCTests : public ::testing::Test { using FF = typename Flavor::FF; using Builder = ClientIVC::ClientCircuit; using Composer = GoblinUltraComposer; - using Accumulator = ClientIVC::Accumulator; + using ProverAccumulator = ClientIVC::ProverAccumulator; + using VerifierAccumulator = ClientIVC::VerifierAccumulator; + using VerifierInstance = std::shared_ptr; using FoldProof = ClientIVC::FoldProof; using GURecursiveFlavor = GoblinUltraRecursiveFlavor_; - using RecursiveVerifierInstances = ::bb::VerifierInstances_; + using RecursiveVerifierInstance = ::bb::stdlib::recursion::honk::RecursiveVerifierInstance_; + using RecursiveVerifierAccumulator = std::shared_ptr; + using RecursiveVerifierInstances = ::bb::stdlib::recursion::honk::RecursiveVerifierInstances_; using FoldingRecursiveVerifier = bb::stdlib::recursion::honk::ProtoGalaxyRecursiveVerifier_; /** * @brief Construct mock circuit with arithmetic gates and goblin ops - * @details Currently default sized to 2^16 to match kernel. (Note: op gates will bump size to next power of 2) + * @details Currently default sized to 2^16 to match kernel. (Note: op gates will bump size to next power of + 2) * */ - static Builder create_mock_circuit(ClientIVC& ivc, size_t log2_num_gates = 15) + static Builder create_mock_circuit(ClientIVC& ivc, size_t num_gates = 1 << 15) { Builder circuit{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_arithmetic_circuit(circuit, log2_num_gates); + GoblinMockCircuits::construct_arithmetic_circuit(circuit, num_gates); GoblinMockCircuits::construct_goblin_ecc_op_circuit(circuit); return circuit; } @@ -49,36 +54,50 @@ class ClientIVCTests : public ::testing::Test { * @param fctn_fold_proof * @param kernel_fold_proof */ - static void construct_mock_folding_kernel(Builder& builder, - FoldProof& fctn_fold_proof, - FoldProof& kernel_fold_proof) + static VerifierAccumulator construct_mock_folding_kernel(Builder& builder, + FoldProof& fold_proof_1, + FoldProof& fold_proof_2, + VerifierInstance& verifier_inst_1, + VerifierInstance& verifier_inst_2, + VerifierAccumulator& prev_kernel_accum) { - FoldingRecursiveVerifier verifier_1{ &builder }; - verifier_1.verify_folding_proof(fctn_fold_proof); - FoldingRecursiveVerifier verifier_2{ &builder }; - verifier_2.verify_folding_proof(kernel_fold_proof); + FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { verifier_inst_1->verification_key } }; + auto fctn_verifier_accum = verifier_1.verify_folding_proof(fold_proof_1); + auto native_acc = std::make_shared(fctn_verifier_accum->get_value()); + FoldingRecursiveVerifier verifier_2{ &builder, native_acc, { verifier_inst_2->verification_key } }; + auto kernel_verifier_accum = verifier_2.verify_folding_proof(fold_proof_2); + return std::make_shared(kernel_verifier_accum->get_value()); } + /** + * @brief Construct mock kernel consisting of two recursive folding verifiers + * + * @param builder + * @param fctn_fold_proof + * @param kernel_fold_proof + */ + /** * @brief Perform native fold verification and run decider prover/verifier * */ - static void EXPECT_FOLDING_AND_DECIDING_VERIFIED(const Accumulator& accumulator, const FoldProof& fold_proof) - { - // Verify fold proof - Composer composer; - auto folding_verifier = composer.create_folding_verifier(); - bool folding_verified = folding_verifier.verify_folding_proof(fold_proof); - EXPECT_TRUE(folding_verified); - - // Run decider - auto decider_prover = composer.create_decider_prover(accumulator); - auto decider_verifier = composer.create_decider_verifier(accumulator); - auto decider_proof = decider_prover.construct_proof(); - bool decision = decider_verifier.verify_proof(decider_proof); - EXPECT_TRUE(decision); - } + // static VerifierAccumulator native_folding(const ProverAccumulator& prover_accumulator, + // const std::vector>& + // verifier_instances, const FoldProof& fold_proof) + // { + // // Verify fold proof + // Composer composer; + // auto folding_verifier = composer.create_folding_verifier(verifier_instances); + // auto verifier_accumulator = folding_verifier.verify_folding_proof(fold_proof); + + // // Run decider + // auto decider_prover = composer.create_decider_prover(prover_accumulator); + // auto decider_verifier = composer.create_decider_verifier(verifier_accumulator); + // auto decider_proof = decider_prover.construct_proof(); + // bool decision = decider_verifier.verify_proof(decider_proof); + // EXPECT_TRUE(decision); + // } }; /** @@ -90,31 +109,41 @@ TEST_F(ClientIVCTests, Full) ClientIVC ivc; // Initialize IVC with function circuit - Builder function_circuit = create_mock_circuit(ivc); - ivc.initialize(function_circuit); + Builder function_circuit_1 = create_mock_circuit(ivc); + ivc.initialize(function_circuit_1); + VerifierAccumulator kernel_verifier_accum = + ivc.get_verifier_accumulator(); // fake accumulator, just a function circuit for the first round - // Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet) Builder kernel_circuit = create_mock_circuit(ivc); FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); - EXPECT_FOLDING_AND_DECIDING_VERIFIED(ivc.fold_output.accumulator, kernel_fold_proof); - - size_t NUM_CIRCUITS = 1; + auto kernel_verifier_inst = ivc.get_verifier_instance(); + size_t NUM_CIRCUITS = 2; for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { // Accumulate function circuit Builder function_circuit = create_mock_circuit(ivc); FoldProof function_fold_proof = ivc.accumulate(function_circuit); - EXPECT_FOLDING_AND_DECIDING_VERIFIED(ivc.fold_output.accumulator, function_fold_proof); + auto fnct_verifier_inst = ivc.get_verifier_instance(); // Accumulate kernel circuit Builder kernel_circuit{ ivc.goblin.op_queue }; - construct_mock_folding_kernel(kernel_circuit, function_fold_proof, kernel_fold_proof); - FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); - EXPECT_FOLDING_AND_DECIDING_VERIFIED(ivc.fold_output.accumulator, kernel_fold_proof); + + kernel_verifier_accum = construct_mock_folding_kernel(kernel_circuit, + kernel_fold_proof, + function_fold_proof, + kernel_verifier_inst, + fnct_verifier_inst, + kernel_verifier_accum); + + kernel_fold_proof = ivc.accumulate(kernel_circuit); + kernel_verifier_inst = ivc.get_verifier_instance(); } - // Constuct four proofs: merge, eccvm, translator, decider + // // Constuct four proofs: merge, eccvm, translator, decider, last folding proof auto proof = ivc.prove(); - // Verify all four proofs - EXPECT_TRUE(ivc.verify(proof)); -} \ No newline at end of file + // // Verify all four proofs + auto verifier_instances = std::vector{ kernel_verifier_accum, kernel_verifier_inst }; + auto res = ivc.verify(proof, verifier_instances); + + EXPECT_TRUE(res); +}; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp index 6ff29a1293e..a857bd913f2 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp @@ -24,19 +24,36 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) GoblinUltraCircuitBuilder circuit_1{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_1); ivc.initialize(circuit_1); + auto verifier_acc = ivc.get_verifier_accumulator(); GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_2); auto fold_proof_1 = ivc.accumulate(circuit_2); + auto verifier_inst_1 = ivc.get_verifier_instance(); GoblinUltraCircuitBuilder circuit_3{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_3); auto fold_proof_2 = ivc.accumulate(circuit_3); + auto verifier_inst_2 = ivc.get_verifier_instance(); // Construct kernel circuit GoblinUltraCircuitBuilder kernel_circuit{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, fold_proof_1, fold_proof_2); + auto new_acc = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, fold_proof_1, fold_proof_2, verifier_inst_1, verifier_inst_2, verifier_acc); + + auto fold_proof_3 = ivc.accumulate(kernel_circuit); + auto verifier_inst_3 = ivc.get_verifier_instance(); + EXPECT_EQ(ivc.prover_instance->log_instance_size, 17); + + GoblinUltraCircuitBuilder circuit_4{ ivc.goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(circuit_4); + auto fold_proof_4 = ivc.accumulate(circuit_4); + auto verifier_inst_4 = ivc.get_verifier_instance(); + + GoblinUltraCircuitBuilder new_kernel_circuit = GoblinUltraCircuitBuilder{ ivc.goblin.op_queue }; + new_acc = GoblinMockCircuits::construct_mock_folding_kernel( + new_kernel_circuit, fold_proof_3, fold_proof_4, verifier_inst_3, verifier_inst_4, new_acc); GoblinUltraComposer composer; - auto instance = composer.create_instance(kernel_circuit); + auto instance = composer.create_prover_instance(new_kernel_circuit); EXPECT_EQ(instance->proving_key->log_circuit_size, 17); } \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/goblin/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/goblin/CMakeLists.txt index 60ba6aa607c..ee4b04affe8 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/goblin/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(goblin stdlib_recursion ultra_honk eccvm translator_vm stdlib_sha256 crypto_merkle_tree stdlib_primitives) \ No newline at end of file +barretenberg_module(goblin stdlib_recursion ultra_honk eccvm translator_vm stdlib_sha256 stdlib_merkle_tree stdlib_primitives) \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp index 1fde752ccec..fdfed9ef41d 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin.hpp @@ -104,7 +104,8 @@ class Goblin { // Construct a Honk proof for the main circuit GoblinUltraComposer composer; - auto instance = composer.create_instance(circuit_builder); + auto instance = composer.create_prover_instance(circuit_builder); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); auto ultra_proof = prover.construct_proof(); @@ -116,7 +117,7 @@ class Goblin { merge_proof_exists = true; } - return { ultra_proof, instance->verification_key }; + return { ultra_proof, verification_key }; }; /** @@ -229,11 +230,12 @@ class Goblin { // Construct a Honk proof for the main circuit GoblinUltraComposer composer; - auto instance = composer.create_instance(circuit_builder); + auto instance = composer.create_prover_instance(circuit_builder); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); auto ultra_proof = prover.construct_proof(); - accumulator = { ultra_proof, instance->verification_key }; + accumulator = { ultra_proof, verification_key }; // TODO(https://github.com/AztecProtocol/barretenberg/issues/811): no merge prover for now since we're not // mocking the first set of ecc ops diff --git a/barretenberg/cpp/src/barretenberg/goblin/goblin_recursion.test.cpp b/barretenberg/cpp/src/barretenberg/goblin/goblin_recursion.test.cpp index dc0facdb60a..c731722d755 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/goblin_recursion.test.cpp +++ b/barretenberg/cpp/src/barretenberg/goblin/goblin_recursion.test.cpp @@ -24,10 +24,11 @@ class GoblinRecursionTests : public ::testing::Test { static Goblin::AccumulationOutput construct_accumulator(GoblinUltraBuilder& builder) { GoblinUltraComposer composer; - auto instance = composer.create_instance(builder); - auto prover = composer.create_prover(instance); + auto prover_instance = composer.create_prover_instance(builder); + auto verifier_instance = composer.create_verifier_instance(prover_instance); + auto prover = composer.create_prover(prover_instance); auto ultra_proof = prover.construct_proof(); - return { ultra_proof, instance->verification_key }; + return { ultra_proof, verifier_instance->verification_key }; } }; diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 02500ee75b5..e32e475197d 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -30,6 +30,9 @@ class GoblinMockCircuits { using RecursiveFlavor = bb::GoblinUltraRecursiveFlavor_; using RecursiveVerifier = bb::stdlib::recursion::honk::UltraRecursiveVerifier_; using KernelInput = Goblin::AccumulationOutput; + using VerifierInstance = bb::VerifierInstance_; + using RecursiveVerifierInstance = ::bb::stdlib::recursion::honk::RecursiveVerifierInstance_; + using RecursiveVerifierAccumulator = std::shared_ptr; static constexpr size_t NUM_OP_QUEUE_COLUMNS = Flavor::NUM_WIRES; /** @@ -38,9 +41,8 @@ class GoblinMockCircuits { * @param builder * @param num_gates */ - static void construct_arithmetic_circuit(GoblinUltraBuilder& builder, size_t log2_num_gates = 0) + static void construct_arithmetic_circuit(GoblinUltraBuilder& builder, size_t num_gates = 1) { - size_t num_gates = 1 << log2_num_gates; // For good measure, include a gate with some public inputs { FF a = FF::random_element(); @@ -54,18 +56,17 @@ class GoblinMockCircuits { builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, FF(1), FF(1), FF(1), FF(-1), FF(0) }); } - // Add arbitrary arithmetic gates to obtain a total of num_gates-many gates - FF a = FF::random_element(); - FF b = FF::random_element(); - FF c = FF::random_element(); - FF d = a + b + c; - uint32_t a_idx = builder.add_variable(a); - uint32_t b_idx = builder.add_variable(b); - uint32_t c_idx = builder.add_variable(c); - uint32_t d_idx = builder.add_variable(d); - for (size_t i = 0; i < num_gates - 1; ++i) { + FF a = FF::random_element(); + FF b = FF::random_element(); + FF c = FF::random_element(); + FF d = a + b + c; + uint32_t a_idx = builder.add_variable(a); + uint32_t b_idx = builder.add_variable(b); + uint32_t c_idx = builder.add_variable(c); + uint32_t d_idx = builder.add_variable(d); + builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, FF(1), FF(1), FF(1), FF(-1), FF(0) }); } } @@ -199,6 +200,7 @@ class GoblinMockCircuits { RecursiveVerifier verifier2{ &builder, prev_kernel_accum.verification_key }; verifier2.verify_proof(prev_kernel_accum.proof); } + info(builder.get_num_gates()); } /** @@ -212,29 +214,35 @@ class GoblinMockCircuits { * @param function_fold_proof * @param kernel_fold_proof */ - static void construct_mock_folding_kernel(GoblinUltraBuilder& builder, - const std::vector& function_fold_proof, - const std::vector& kernel_fold_proof) + static std::shared_ptr construct_mock_folding_kernel( + GoblinUltraBuilder& builder, + const std::vector& fold_proof_1, + const std::vector& fold_proof_2, + std::shared_ptr& verifier_inst_1, + std::shared_ptr& verifier_inst_2, + std::shared_ptr& prev_kernel_accum) { using GURecursiveFlavor = GoblinUltraRecursiveFlavor_; - using RecursiveVerifierInstances = ::bb::VerifierInstances_; + using RecursiveVerifierInstances = + bb::stdlib::recursion::honk::RecursiveVerifierInstances_; using FoldingRecursiveVerifier = bb::stdlib::recursion::honk::ProtoGalaxyRecursiveVerifier_; - // Add operations representing general kernel logic e.g. state updates. Note: these are structured to make the - // kernel "full" within the dyadic size 2^17 (130914 gates) - const size_t NUM_MERKLE_CHECKS = 20; + // Add operations representing general kernel logic e.g. state updates. Note: these are structured to make + // the kernel "full" within the dyadic size 2^17 (130914 gates) + const size_t NUM_MERKLE_CHECKS = 35; const size_t NUM_ECDSA_VERIFICATIONS = 1; const size_t NUM_SHA_HASHES = 1; stdlib::generate_merkle_membership_test_circuit(builder, NUM_MERKLE_CHECKS); stdlib::generate_ecdsa_verification_test_circuit(builder, NUM_ECDSA_VERIFICATIONS); stdlib::generate_sha256_test_circuit(builder, NUM_SHA_HASHES); - FoldingRecursiveVerifier verifier_1{ &builder }; - verifier_1.verify_folding_proof(function_fold_proof); - - FoldingRecursiveVerifier verifier_2{ &builder }; - verifier_2.verify_folding_proof(kernel_fold_proof); + FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { verifier_inst_1->verification_key } }; + auto fctn_verifier_accum = verifier_1.verify_folding_proof(fold_proof_1); + auto native_acc = std::make_shared(fctn_verifier_accum->get_value()); + FoldingRecursiveVerifier verifier_2{ &builder, native_acc, { verifier_inst_2->verification_key } }; + auto kernel_verifier_accum = verifier_2.verify_folding_proof(fold_proof_2); + return std::make_shared(kernel_verifier_accum->get_value()); } /** diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp index 2f52c964eab..db0fc69b80d 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits_pinning.test.cpp @@ -23,7 +23,7 @@ TEST_F(MockCircuits, PinFunctionSizes) GoblinUltraCircuitBuilder app_circuit{ goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(app_circuit, large); GoblinUltraComposer composer; - auto instance = composer.create_instance(app_circuit); + auto instance = composer.create_prover_instance(app_circuit); if (large) { EXPECT_EQ(instance->proving_key->log_circuit_size, 19); } else { @@ -47,7 +47,7 @@ TEST_F(MockCircuits, PinRecursionKernelSizes) GoblinUltraCircuitBuilder kernel_circuit{ goblin.op_queue }; GoblinMockCircuits::construct_mock_recursion_kernel_circuit(kernel_circuit, function_accum, kernel_accum); GoblinUltraComposer composer; - auto instance = composer.create_instance(kernel_circuit); + auto instance = composer.create_prover_instance(kernel_circuit); if (large) { EXPECT_EQ(instance->proving_key->log_circuit_size, 17); } else { diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.cpp index 51d55e9766a..ccac06c7928 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.cpp @@ -20,51 +20,6 @@ DeciderProver_::DeciderProver_(const std::shared_ptr& inst, , commitment_key(commitment_key) {} -/** - * @brief Add ϕ, \vec{β}, e to the transcript. These are produced in the last round of folding that was carried out - * before deciding. - */ -template void DeciderProver_::execute_preamble_round() -{ - const auto accumulator_size = static_cast(accumulator->instance_size); - const auto num_public_inputs = static_cast(accumulator->public_inputs.size()); - transcript->send_to_verifier("accumulator_size", accumulator_size); - transcript->send_to_verifier("public_input_size", num_public_inputs); - - for (size_t i = 0; i < accumulator->public_inputs.size(); ++i) { - auto public_input_i = accumulator->public_inputs[i]; - transcript->send_to_verifier("public_input_" + std::to_string(i), public_input_i); - } - - transcript->send_to_verifier("eta", accumulator->relation_parameters.eta); - transcript->send_to_verifier("beta", accumulator->relation_parameters.beta); - transcript->send_to_verifier("gamma", accumulator->relation_parameters.gamma); - transcript->send_to_verifier("public_input_delta", accumulator->relation_parameters.public_input_delta); - transcript->send_to_verifier("lookup_grand_product_delta", - accumulator->relation_parameters.lookup_grand_product_delta); - size_t alpha_idx = 0; - for (auto alpha : accumulator->alphas) { - transcript->send_to_verifier("alpha_" + std::to_string(alpha_idx), alpha); - } - - transcript->send_to_verifier("target_sum", accumulator->target_sum); - for (size_t idx = 0; idx < accumulator->gate_challenges.size(); idx++) { - transcript->send_to_verifier("gate_challenge_" + std::to_string(idx), accumulator->gate_challenges[idx]); - } - - auto comm_view = accumulator->witness_commitments.get_all(); - auto witness_labels = accumulator->commitment_labels.get_witness(); - for (size_t idx = 0; idx < witness_labels.size(); idx++) { - transcript->send_to_verifier(witness_labels[idx], comm_view[idx]); - } - - auto vk_view = accumulator->verification_key->get_all(); - auto vk_labels = accumulator->commitment_labels.get_precomputed(); - for (size_t idx = 0; idx < vk_labels.size(); idx++) { - transcript->send_to_verifier(vk_labels[idx], vk_view[idx]); - } -} - /** * @brief Run Sumcheck to establish that ∑_i pow(\vec{β*})f_i(ω) = e*. This results in u = (u_1,...,u_d) sumcheck round * challenges and all evaluations at u being calculated. @@ -102,9 +57,6 @@ template HonkProof& DeciderProver_::export_proof( template HonkProof& DeciderProver_::construct_proof() { - // Add ϕ, \vec{β*}, e* to transcript - execute_preamble_round(); - // Run sumcheck subprotocol. execute_relation_check_rounds(); diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp index 1c6601613fb..197d739817e 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp @@ -8,8 +8,8 @@ namespace bb { template DeciderVerifier_::DeciderVerifier_(const std::shared_ptr& transcript, - const std::shared_ptr& verifier_key) - : key(verifier_key) + const std::shared_ptr& accumulator) + : accumulator(accumulator) , transcript(transcript) {} template @@ -25,68 +25,69 @@ DeciderVerifier_::DeciderVerifier_() */ template bool DeciderVerifier_::verify_proof(const HonkProof& proof) { - using FF = typename Flavor::FF; - using Commitment = typename Flavor::Commitment; + // using FF = typename Flavor::FF; + // using Commitment = typename Flavor::Commitment; using Curve = typename Flavor::Curve; using ZeroMorph = ZeroMorphVerifier_; - using Instance = VerifierInstance_; + // using Instance = VerifierInstance_; using VerifierCommitments = typename Flavor::VerifierCommitments; - static constexpr size_t NUM_SUBRELATIONS = Flavor::NUM_SUBRELATIONS; + // static constexpr size_t NUM_SUBRELATIONS = Flavor::NUM_SUBRELATIONS; transcript = std::make_shared(proof); - auto inst = std::make_unique(); - - inst->instance_size = transcript->template receive_from_prover("instance_size"); - inst->log_instance_size = static_cast(numeric::get_msb(inst->instance_size)); - inst->public_input_size = transcript->template receive_from_prover("public_input_size"); - - for (size_t i = 0; i < inst->public_input_size; ++i) { - auto public_input_i = transcript->template receive_from_prover("public_input_" + std::to_string(i)); - inst->public_inputs.emplace_back(public_input_i); - } - - auto eta = transcript->template receive_from_prover("eta"); - auto beta = transcript->template receive_from_prover("beta"); - auto gamma = transcript->template receive_from_prover("gamma"); - auto public_input_delta = transcript->template receive_from_prover("public_input_delta"); - auto lookup_grand_product_delta = transcript->template receive_from_prover("lookup_grand_product_delta"); - inst->relation_parameters = - RelationParameters{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta }; - - for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { - - inst->alphas[idx] = transcript->template receive_from_prover("alpha" + std::to_string(idx)); - } - - inst->target_sum = transcript->template receive_from_prover("target_sum"); - - inst->gate_challenges = std::vector(inst->log_instance_size); - for (size_t idx = 0; idx < inst->log_instance_size; idx++) { - inst->gate_challenges[idx] = - transcript->template receive_from_prover("gate_challenge_" + std::to_string(idx)); - } - auto comm_view = inst->witness_commitments.get_all(); - auto witness_labels = inst->commitment_labels.get_witness(); - for (size_t idx = 0; idx < witness_labels.size(); idx++) { - comm_view[idx] = transcript->template receive_from_prover(witness_labels[idx]); - } - - inst->verification_key = std::make_shared(inst->instance_size, inst->public_input_size); - auto vk_view = inst->verification_key->get_all(); - auto vk_labels = inst->commitment_labels.get_precomputed(); - for (size_t idx = 0; idx < vk_labels.size(); idx++) { - vk_view[idx] = transcript->template receive_from_prover(vk_labels[idx]); - } - - VerifierCommitments commitments{ inst->verification_key, inst->witness_commitments }; - - auto sumcheck = SumcheckVerifier(inst->log_instance_size, transcript, inst->target_sum); + // auto inst = std::make_unique(); + + // inst->instance_size = transcript->template receive_from_prover("instance_size"); + // inst->log_instance_size = static_cast(numeric::get_msb(inst->instance_size)); + // inst->public_input_size = transcript->template receive_from_prover("public_input_size"); + + // for (size_t i = 0; i < inst->public_input_size; ++i) { + // auto public_input_i = transcript->template receive_from_prover("public_input_" + std::to_string(i)); + // inst->public_inputs.emplace_back(public_input_i); + // } + + // auto eta = transcript->template receive_from_prover("eta"); + // auto beta = transcript->template receive_from_prover("beta"); + // auto gamma = transcript->template receive_from_prover("gamma"); + // auto public_input_delta = transcript->template receive_from_prover("public_input_delta"); + // auto lookup_grand_product_delta = transcript->template receive_from_prover("lookup_grand_product_delta"); + // inst->relation_parameters = + // RelationParameters{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta }; + + // for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { + + // inst->alphas[idx] = transcript->template receive_from_prover("alpha" + std::to_string(idx)); + // } + + // inst->target_sum = transcript->template receive_from_prover("target_sum"); + + // inst->gate_challenges = std::vector(inst->log_instance_size); + // for (size_t idx = 0; idx < inst->log_instance_size; idx++) { + // inst->gate_challenges[idx] = + // transcript->template receive_from_prover("gate_challenge_" + std::to_string(idx)); + // } + // auto comm_view = inst->witness_commitments.get_all(); + // auto witness_labels = inst->commitment_labels.get_witness(); + // for (size_t idx = 0; idx < witness_labels.size(); idx++) { + // comm_view[idx] = transcript->template receive_from_prover(witness_labels[idx]); + // } + + // inst->verification_key = std::make_shared(inst->instance_size, inst->public_input_size); + // auto vk_view = inst->verification_key->get_all(); + // auto vk_labels = inst->commitment_labels.get_precomputed(); + // for (size_t idx = 0; idx < vk_labels.size(); idx++) { + // vk_view[idx] = transcript->template receive_from_prover(vk_labels[idx]); + // } + + VerifierCommitments commitments{ accumulator->verification_key, accumulator->witness_commitments }; + + auto sumcheck = SumcheckVerifier(accumulator->log_instance_size, transcript, accumulator->target_sum); auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = - sumcheck.verify(inst->relation_parameters, inst->alphas, inst->gate_challenges); + sumcheck.verify(accumulator->relation_parameters, accumulator->alphas, accumulator->gate_challenges); // If Sumcheck did not verify, return false if (sumcheck_verified.has_value() && !sumcheck_verified.value()) { + info("here"); return false; } diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.hpp index 70ca2033617..3969b89d96c 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.hpp @@ -3,6 +3,7 @@ #include "barretenberg/flavor/ultra.hpp" #include "barretenberg/honk/proof_system/types/proof.hpp" #include "barretenberg/srs/global_crs.hpp" +#include "barretenberg/sumcheck/instance/verifier_instance.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" namespace bb { @@ -12,16 +13,18 @@ template class DeciderVerifier_ { using VerificationKey = typename Flavor::VerificationKey; using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; using Transcript = typename Flavor::Transcript; + using VerifierInstance = VerifierInstance_; public: explicit DeciderVerifier_(); explicit DeciderVerifier_(const std::shared_ptr& transcript, - const std::shared_ptr& verifier_key = nullptr); + const std::shared_ptr& accumulator = nullptr); bool verify_proof(const HonkProof& proof); std::shared_ptr key; std::map commitments; + std::shared_ptr accumulator; std::shared_ptr pcs_verification_key; std::shared_ptr transcript; }; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp index 372926ddafb..98930e72646 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp @@ -58,7 +58,7 @@ void ProtoGalaxyProver_::finalise_and_send_instance(std::shared auto eta = transcript->template get_challenge(domain_separator + "_eta"); instance->compute_sorted_accumulator_polynomials(eta); - // Commit to the sorted witness-table accumulator and the finalized (i.e. with memory records) fourth wire + // Commit to the sorted withness-table accumulator and the finalized (i.e. with memory records) fourth wire // polynomial witness_commitments.sorted_accum = commitment_key->commit(instance->prover_polynomials.sorted_accum); witness_commitments.w_4 = commitment_key->commit(instance->prover_polynomials.w_4); @@ -92,67 +92,69 @@ void ProtoGalaxyProver_::finalise_and_send_instance(std::shared instance->alphas[idx] = transcript->template get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); } - auto vk_view = instance->verification_key->get_all(); - auto labels = instance->commitment_labels.get_precomputed(); - for (size_t idx = 0; idx < labels.size(); idx++) { - transcript->send_to_verifier(domain_separator + "_" + labels[idx], vk_view[idx]); - } + // auto vk_view = instance->verification_key->get_all(); + // auto labels = instance->commitment_labels.get_precomputed(); + // for (size_t idx = 0; idx < labels.size(); idx++) { + // transcript->send_to_verifier(domain_separator + "_" + labels[idx], vk_view[idx]); + // } } -template -void ProtoGalaxyProver_::send_accumulator(std::shared_ptr instance, - const std::string& domain_separator) -{ - const auto instance_size = static_cast(instance->instance_size); - const auto num_public_inputs = static_cast(instance->public_inputs.size()); - transcript->send_to_verifier(domain_separator + "_instance_size", instance_size); - transcript->send_to_verifier(domain_separator + "_public_input_size", num_public_inputs); - - for (size_t i = 0; i < instance->public_inputs.size(); ++i) { - auto public_input_i = instance->public_inputs[i]; - transcript->send_to_verifier(domain_separator + "_public_input_" + std::to_string(i), public_input_i); - } - - transcript->send_to_verifier(domain_separator + "_eta", instance->relation_parameters.eta); - transcript->send_to_verifier(domain_separator + "_beta", instance->relation_parameters.beta); - transcript->send_to_verifier(domain_separator + "_gamma", instance->relation_parameters.gamma); - transcript->send_to_verifier(domain_separator + "_public_input_delta", - instance->relation_parameters.public_input_delta); - transcript->send_to_verifier(domain_separator + "_lookup_grand_product_delta", - instance->relation_parameters.lookup_grand_product_delta); - - for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { - transcript->send_to_verifier(domain_separator + "_alpha_" + std::to_string(idx), instance->alphas[idx]); - } - - transcript->send_to_verifier(domain_separator + "_target_sum", instance->target_sum); - for (size_t idx = 0; idx < instance->gate_challenges.size(); idx++) { - transcript->send_to_verifier(domain_separator + "_gate_challenge_" + std::to_string(idx), - instance->gate_challenges[idx]); - } - - auto comm_view = instance->witness_commitments.get_all(); - auto witness_labels = instance->commitment_labels.get_witness(); - for (size_t idx = 0; idx < witness_labels.size(); idx++) { - transcript->send_to_verifier(domain_separator + "_" + witness_labels[idx], comm_view[idx]); - } - - auto vk_view = instance->verification_key->get_all(); - auto vk_labels = instance->commitment_labels.get_precomputed(); - for (size_t idx = 0; idx < vk_labels.size(); idx++) { - transcript->send_to_verifier(domain_separator + "_" + vk_labels[idx], vk_view[idx]); - } -} +// template +// void ProtoGalaxyProver_::send_accumulator(std::shared_ptr instance, +// const std::string& domain_separator) +// { +// const auto instance_size = static_cast(instance->instance_size); +// const auto num_public_inputs = static_cast(instance->public_inputs.size()); +// transcript->send_to_verifier(domain_separator + "_instance_size", instance_size); +// transcript->send_to_verifier(domain_separator + "_public_input_size", num_public_inputs); + +// for (size_t i = 0; i < instance->public_inputs.size(); ++i) { +// auto public_input_i = instance->public_inputs[i]; +// transcript->send_to_verifier(domain_separator + "_public_input_" + std::to_string(i), public_input_i); +// } + +// transcript->send_to_verifier(domain_separator + "_eta", instance->relation_parameters.eta); +// transcript->send_to_verifier(domain_separator + "_beta", instance->relation_parameters.beta); +// transcript->send_to_verifier(domain_separator + "_gamma", instance->relation_parameters.gamma); +// transcript->send_to_verifier(domain_separator + "_public_input_delta", +// instance->relation_parameters.public_input_delta); +// transcript->send_to_verifier(domain_separator + "_lookup_grand_product_delta", +// instance->relation_parameters.lookup_grand_product_delta); + +// for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { +// transcript->send_to_verifier(domain_separator + "_alpha_" + std::to_string(idx), instance->alphas[idx]); +// } + +// transcript->send_to_verifier(domain_separator + "_target_sum", instance->target_sum); +// for (size_t idx = 0; idx < instance->gate_challenges.size(); idx++) { +// transcript->send_to_verifier(domain_separator + "_gate_challenge_" + std::to_string(idx), +// instance->gate_challenges[idx]); +// } + +// auto comm_view = instance->witness_commitments.get_all(); +// auto witness_labels = instance->commitment_labels.get_witness(); +// for (size_t idx = 0; idx < witness_labels.size(); idx++) { +// transcript->send_to_verifier(domain_separator + "_" + witness_labels[idx], comm_view[idx]); +// } + +// auto vk_view = instance->verification_key->get_all(); +// auto vk_labels = instance->commitment_labels.get_precomputed(); +// for (size_t idx = 0; idx < vk_labels.size(); idx++) { +// transcript->send_to_verifier(domain_separator + "_" + vk_labels[idx], vk_view[idx]); +// } +// } template void ProtoGalaxyProver_::prepare_for_folding() { auto idx = 0; auto instance = instances[0]; auto domain_separator = std::to_string(idx); - transcript->send_to_verifier(domain_separator + "is_accumulator", instance->is_accumulator); - if (instance->is_accumulator) { - send_accumulator(instance, domain_separator); - } else { + // transcript->send_to_verifier(domain_separator + "is_accumulator", instance->is_accumulator); + if (!instance->is_accumulator) + // { + // send_accumulator(instance, domain_separator); + // }else + { // This is the first round of folding and we need to generate some gate challenges. // TODO(https://github.com/AztecProtocol/barretenberg/issues/740): implement option 2 to make this more // efficient by avoiding the computation of the perturbator @@ -200,10 +202,6 @@ std::shared_ptr ProtoGalaxyProver_send_to_verifier("next_target_sum", next_target_sum); - for (size_t idx = 0; idx < instances.next_gate_challenges.size(); idx++) { - transcript->send_to_verifier("next_gate_challenge_" + std::to_string(idx), instances.next_gate_challenges[idx]); - } next_accumulator->target_sum = next_target_sum; next_accumulator->gate_challenges = instances.next_gate_challenges; @@ -225,20 +223,6 @@ std::shared_ptr ProtoGalaxyProver_prover_polynomials = std::move(acc_prover_polynomials); - // Fold the witness commtiments and send them to the verifier - auto witness_labels = next_accumulator->commitment_labels.get_witness(); - size_t comm_idx = 0; - for (auto& acc_comm : next_accumulator->witness_commitments.get_all()) { - acc_comm = Commitment::infinity(); - size_t inst_idx = 0; - for (auto& instance : instances) { - acc_comm = acc_comm + instance->witness_commitments.get_all()[comm_idx] * lagranges[inst_idx]; - inst_idx++; - } - transcript->send_to_verifier("next_" + witness_labels[comm_idx], acc_comm); - comm_idx++; - } - // Fold public data ϕ from all instances to produce ϕ* and add it to the transcript. As part of the folding // verification, the verifier will produce ϕ* as well and check it against what was sent by the prover. @@ -254,7 +238,6 @@ std::shared_ptr ProtoGalaxyProver_send_to_verifier("next_public_input_" + std::to_string(el_idx), el); el_idx++; } @@ -263,7 +246,6 @@ std::shared_ptr ProtoGalaxyProver_alphas; for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { folded_alphas[idx] = instances.alphas[idx].evaluate(challenge); - transcript->send_to_verifier("next_alpha_" + std::to_string(idx), folded_alphas[idx]); } // Evaluate each relation parameter univariate at challenge to obtain the folded relation parameters and send to @@ -276,87 +258,46 @@ std::shared_ptr ProtoGalaxyProver_send_to_verifier("next_eta", folded_relation_parameters.eta); - transcript->send_to_verifier("next_beta", folded_relation_parameters.beta); - transcript->send_to_verifier("next_gamma", folded_relation_parameters.gamma); - transcript->send_to_verifier("next_public_input_delta", folded_relation_parameters.public_input_delta); - transcript->send_to_verifier("next_lookup_grand_product_delta", - folded_relation_parameters.lookup_grand_product_delta); next_accumulator->relation_parameters = folded_relation_parameters; - - // Fold the verification key and send it to the verifier as this is part of ϕ as well - auto acc_vk = std::make_shared(instances[0]->prover_polynomials.get_polynomial_size(), - instances[0]->public_inputs.size()); - auto labels = next_accumulator->commitment_labels.get_precomputed(); - size_t vk_idx = 0; - for (auto& vk : acc_vk->get_all()) { - size_t inst = 0; - vk = Commitment::infinity(); - for (auto& instance : instances) { - vk = vk + (instance->verification_key->get_all()[vk_idx]) * lagranges[inst]; - inst++; - } - transcript->send_to_verifier("next_" + labels[vk_idx], vk); - vk_idx++; - } - next_accumulator->verification_key = acc_vk; return next_accumulator; } -template void ProtoGalaxyProver_::preparation_round() +template +FoldingResult ProtoGalaxyProver_::fold_instances() { prepare_for_folding(); -}; - -template void ProtoGalaxyProver_::perturbator_round() -{ - state.accumulator = get_accumulator(); FF delta = transcript->template get_challenge("delta"); - state.deltas = compute_round_challenge_pows(state.accumulator->log_instance_size, delta); - state.perturbator = compute_perturbator(state.accumulator, state.deltas); - for (size_t idx = 0; idx <= state.accumulator->log_instance_size; idx++) { - transcript->send_to_verifier("perturbator_" + std::to_string(idx), state.perturbator[idx]); - } -}; -template void ProtoGalaxyProver_::combiner_quotient_round() -{ + auto accumulator = get_accumulator(); + auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); + + auto perturbator = compute_perturbator(accumulator, deltas); + + for (size_t idx = 1; idx <= accumulator->log_instance_size; idx++) { + transcript->send_to_verifier("perturbator_" + std::to_string(idx), perturbator[idx]); + } auto perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); instances.next_gate_challenges = - update_gate_challenges(perturbator_challenge, state.accumulator->gate_challenges, state.deltas); + update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); combine_relation_parameters(instances); combine_alpha(instances); auto pow_polynomial = PowPolynomial(instances.next_gate_challenges); auto combiner = compute_combiner(instances, pow_polynomial); - state.compressed_perturbator = state.perturbator.evaluate(perturbator_challenge); - state.combiner_quotient = compute_combiner_quotient(state.compressed_perturbator, combiner); + auto compressed_perturbator = perturbator.evaluate(perturbator_challenge); + auto combiner_quotient = compute_combiner_quotient(compressed_perturbator, combiner); for (size_t idx = ProverInstances::NUM; idx < ProverInstances::BATCHED_EXTENDED_LENGTH; idx++) { - transcript->send_to_verifier("combiner_quotient_" + std::to_string(idx), state.combiner_quotient.value_at(idx)); + transcript->send_to_verifier("combiner_quotient_" + std::to_string(idx), combiner_quotient.value_at(idx)); } -}; - -template void ProtoGalaxyProver_::accumulator_update_round() -{ FF combiner_challenge = transcript->template get_challenge("combiner_quotient_challenge"); - std::shared_ptr next_accumulator = - compute_next_accumulator(instances, state.combiner_quotient, combiner_challenge, state.compressed_perturbator); - state.result.folding_data = transcript->proof_data; - state.result.accumulator = next_accumulator; -}; - -template -FoldingResult ProtoGalaxyProver_::fold_instances() -{ - preparation_round(); - perturbator_round(); - combiner_quotient_round(); - accumulator_update_round(); - return state.result; + FoldingResult res; + auto next_accumulator = + compute_next_accumulator(instances, combiner_quotient, combiner_challenge, compressed_perturbator); + res.folding_data = transcript->proof_data; + res.accumulator = next_accumulator; + return res; } template class ProtoGalaxyProver_>; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index cbe139eb37c..a566f399955 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -12,18 +12,6 @@ #include "barretenberg/sumcheck/instance/instances.hpp" namespace bb { -template struct ProtogalaxyProofConstructionState { - using FF = typename ProverInstances_::FF; - using Instance = typename ProverInstances_::Instance; - - std::shared_ptr accumulator; - Polynomial perturbator; - std::vector deltas; - Univariate combiner_quotient; - FF compressed_perturbator; - FoldingResult result; -}; - template class ProtoGalaxyProver_ { public: using ProverInstances = ProverInstances_; @@ -40,6 +28,7 @@ template class ProtoGalaxyProver_ { using VerificationKey = typename Flavor::VerificationKey; using CommitmentKey = typename Flavor::CommitmentKey; using WitnessCommitments = typename Flavor::WitnessCommitments; + using CommitmentLabels = typename Flavor::CommitmentLabels; using Commitment = typename Flavor::Commitment; using BaseUnivariate = Univariate; @@ -61,8 +50,8 @@ template class ProtoGalaxyProver_ { ProverInstances instances; std::shared_ptr transcript = std::make_shared(); + std::shared_ptr commitment_key; - ProtogalaxyProofConstructionState state; ProtoGalaxyProver_() = default; ProtoGalaxyProver_(const std::vector>& insts, @@ -85,7 +74,7 @@ template class ProtoGalaxyProver_ { * @param domain_separator separates the same type of data coming from difference instances by instance * index */ - void send_accumulator(std::shared_ptr, const std::string& domain_separator); + // void send_accumulator(std::shared_ptr, const std::string& domain_separator); /** * @brief For each instance produced by a circuit, prior to folding, we need to complete the computation of its @@ -155,33 +144,29 @@ template class ProtoGalaxyProver_ { const RelationParameters& relation_parameters) { auto instance_size = instance_polynomials.get_polynomial_size(); + FF linearly_dependent_contribution = FF(0); std::vector full_honk_evaluations(instance_size); - std::vector linearly_dependent_contributions(instance_size); - parallel_for(instance_size, [&](size_t row) { + for (size_t row = 0; row < instance_size; row++) { auto row_evaluations = instance_polynomials.get_row(row); RelationEvaluations relation_evaluations; Utils::zero_elements(relation_evaluations); - // Note that the evaluations are accumulated with the gate separation challenge - // being 1 at this stage, as this specific randomness is added later through the - // power polynomial univariate specific to ProtoGalaxy + // Note that the evaluations are accumulated with the gate separation challenge being 1 at this stage, as + // this specific randomness is added later through the power polynomial univariate specific to ProtoGalaxy Utils::template accumulate_relation_evaluations<>( row_evaluations, relation_evaluations, relation_parameters, FF(1)); auto output = FF(0); auto running_challenge = FF(1); - // Sum relation evaluations, batched by their corresponding relation separator challenge, to - // get the value of the full honk relation at a specific row - linearly_dependent_contributions[row] = 0; + // Sum relation evaluations, batched by their corresponding relation separator challenge, to get the value + // of the full honk relation at a specific row Utils::scale_and_batch_elements( - relation_evaluations, alpha, running_challenge, output, linearly_dependent_contributions[row]); - full_honk_evaluations[row] = output; - }); + relation_evaluations, alpha, running_challenge, output, linearly_dependent_contribution); - for (FF& linearly_dependent_contribution : linearly_dependent_contributions) { - full_honk_evaluations[0] += linearly_dependent_contribution; + full_honk_evaluations[row] = output; } + full_honk_evaluations[0] += linearly_dependent_contribution; return full_honk_evaluations; } @@ -463,10 +448,6 @@ template class ProtoGalaxyProver_ { Univariate& combiner_quotient, FF& challenge, const FF& compressed_perturbator); - - void preparation_round(); - void perturbator_round(); - void combiner_quotient_round(); - void accumulator_update_round(); }; -} // namespace bb \ No newline at end of file + +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 07b32554f34..818c02ca7d5 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -2,65 +2,6 @@ #include "barretenberg/proof_system/library/grand_product_delta.hpp" namespace bb { -template -void ProtoGalaxyVerifier_::receive_accumulator(const std::shared_ptr& inst, - const std::string& domain_separator) -{ - // Get circuit parameters - inst->instance_size = transcript->template receive_from_prover(domain_separator + "_instance_size"); - inst->log_instance_size = static_cast(numeric::get_msb(inst->instance_size)); - inst->public_input_size = - transcript->template receive_from_prover(domain_separator + "_public_input_size"); - - // Get folded public inputs - for (size_t i = 0; i < inst->public_input_size; ++i) { - auto public_input_i = - transcript->template receive_from_prover(domain_separator + "_public_input_" + std::to_string(i)); - inst->public_inputs.emplace_back(public_input_i); - } - - // Get folded relation parameters - auto eta = transcript->template receive_from_prover(domain_separator + "_eta"); - auto beta = transcript->template receive_from_prover(domain_separator + "_beta"); - auto gamma = transcript->template receive_from_prover(domain_separator + "_gamma"); - auto public_input_delta = transcript->template receive_from_prover(domain_separator + "_public_input_delta"); - auto lookup_grand_product_delta = - transcript->template receive_from_prover(domain_separator + "_lookup_grand_product_delta"); - inst->relation_parameters = - RelationParameters{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta }; - - // Get the folded relation separator challenges \vec{α} - for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { - inst->alphas[idx] = - transcript->template receive_from_prover(domain_separator + "_alpha_" + std::to_string(idx)); - } - - inst->target_sum = transcript->template receive_from_prover(domain_separator + "_target_sum"); - - // Get the folded gate challenges, \vec{β} in the paper - inst->gate_challenges = std::vector(inst->log_instance_size); - for (size_t idx = 0; idx < inst->log_instance_size; idx++) { - inst->gate_challenges[idx] = - transcript->template receive_from_prover(domain_separator + "_gate_challenge_" + std::to_string(idx)); - } - - // Get the folded commitments to all witness polynomials - auto comm_view = inst->witness_commitments.get_all(); - auto witness_labels = inst->commitment_labels.get_witness(); - for (size_t idx = 0; idx < witness_labels.size(); idx++) { - comm_view[idx] = - transcript->template receive_from_prover(domain_separator + "_" + witness_labels[idx]); - } - - // Get the folded commitments to selector polynomials - inst->verification_key = std::make_shared(inst->instance_size, inst->public_input_size); - auto vk_view = inst->verification_key->get_all(); - auto vk_labels = inst->commitment_labels.get_precomputed(); - for (size_t idx = 0; idx < vk_labels.size(); idx++) { - vk_view[idx] = transcript->template receive_from_prover(domain_separator + "_" + vk_labels[idx]); - } -} - template void ProtoGalaxyVerifier_::receive_and_finalise_instance(const std::shared_ptr& inst, const std::string& domain_separator) @@ -135,14 +76,6 @@ void ProtoGalaxyVerifier_::receive_and_finalise_instance(cons for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { inst->alphas[idx] = transcript->template get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); } - - // Get the commitments to the selector polynomials for the given instance - inst->verification_key = std::make_shared(inst->instance_size, inst->public_input_size); - auto vk_view = inst->verification_key->get_all(); - auto vk_labels = labels.get_precomputed(); - for (size_t idx = 0; idx < vk_labels.size(); idx++) { - vk_view[idx] = transcript->template receive_from_prover(domain_separator + "_" + vk_labels[idx]); - } } // TODO(https://github.com/AztecProtocol/barretenberg/issues/795): The rounds prior to actual verifying are common @@ -154,10 +87,10 @@ void ProtoGalaxyVerifier_::prepare_for_folding(const std::vec auto index = 0; auto inst = instances[0]; auto domain_separator = std::to_string(index); - inst->is_accumulator = transcript->template receive_from_prover(domain_separator + "is_accumulator"); - if (inst->is_accumulator) { - receive_accumulator(inst, domain_separator); - } else { + // auto is_accumulator = transcript->template receive_from_prover(domain_separator + "is_accumulator"); + if (!inst->is_accumulator) { + // receive_accumulator(inst, domain_separator); + // } else { // This is the first round of folding and we need to generate some gate challenges. // TODO(https://github.com/AztecProtocol/barretenberg/issues/740): implement option 2 to make this more // efficient by avoiding the computation of the perturbator @@ -181,7 +114,8 @@ void ProtoGalaxyVerifier_::prepare_for_folding(const std::vec } template -bool ProtoGalaxyVerifier_::verify_folding_proof(const std::vector& fold_data) +std::shared_ptr ProtoGalaxyVerifier_::verify_folding_proof( + const std::vector& fold_data) { prepare_for_folding(fold_data); @@ -190,14 +124,11 @@ bool ProtoGalaxyVerifier_::verify_folding_proof(const std::ve auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); std::vector perturbator_coeffs(accumulator->log_instance_size + 1); - for (size_t idx = 0; idx <= accumulator->log_instance_size; idx++) { + for (size_t idx = 1; idx <= accumulator->log_instance_size; idx++) { perturbator_coeffs[idx] = transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); } - if (perturbator_coeffs[0] != accumulator->target_sum) { - return false; - } - + perturbator_coeffs[0] = accumulator->target_sum; auto perturbator = Polynomial(perturbator_coeffs); FF perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); auto perturbator_at_challenge = perturbator.evaluate(perturbator_challenge); @@ -216,60 +147,56 @@ bool ProtoGalaxyVerifier_::verify_folding_proof(const std::ve auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); auto lagranges = std::vector{ FF(1) - combiner_challenge, combiner_challenge }; + auto next_accumulator = std::make_shared(); + next_accumulator->instance_size = accumulator->instance_size; + next_accumulator->log_instance_size = accumulator->log_instance_size; + next_accumulator->is_accumulator = true; // Compute next folding parameters and verify against the ones received from the prover - auto expected_next_target_sum = + next_accumulator->target_sum = perturbator_at_challenge * lagranges[0] + vanishing_polynomial_at_challenge * combiner_quotient_at_challenge; - auto next_target_sum = transcript->template receive_from_prover("next_target_sum"); - bool verified = (expected_next_target_sum == next_target_sum); - auto expected_betas_star = update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); - for (size_t idx = 0; idx < accumulator->log_instance_size; idx++) { - auto beta_star = transcript->template receive_from_prover("next_gate_challenge_" + std::to_string(idx)); - verified = verified & (expected_betas_star[idx] == beta_star); - } + next_accumulator->gate_challenges = + update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); // Compute ϕ and verify against the data received from the prover - WitnessCommitments acc_witness_commitments; + auto& acc_witness_commitments = next_accumulator->witness_commitments; auto witness_labels = commitment_labels.get_witness(); size_t comm_idx = 0; - for (auto& expected_comm : acc_witness_commitments.get_all()) { - expected_comm = Commitment::infinity(); + for (auto& comm : acc_witness_commitments.get_all()) { + comm = Commitment::infinity(); size_t inst = 0; for (auto& instance : instances) { - expected_comm = expected_comm + instance->witness_commitments.get_all()[comm_idx] * lagranges[inst]; + comm = comm + instance->witness_commitments.get_all()[comm_idx] * lagranges[inst]; inst++; } - auto comm = transcript->template receive_from_prover("next_" + witness_labels[comm_idx]); - verified = verified & (comm == expected_comm); comm_idx++; } - std::vector folded_public_inputs(instances[0]->public_inputs.size(), 0); - size_t el_idx = 0; - for (auto& expected_el : folded_public_inputs) { + next_accumulator->public_input_size = instances[0]->public_input_size; + next_accumulator->public_inputs = std::vector(next_accumulator->public_input_size, 0); + size_t public_input_idx = 0; + for (auto& public_input : next_accumulator->public_inputs) { size_t inst = 0; for (auto& instance : instances) { // TODO(https://github.com/AztecProtocol/barretenberg/issues/830) - if (instance->public_inputs.size() >= folded_public_inputs.size()) { - expected_el += instance->public_inputs[el_idx] * lagranges[inst]; + if (instance->public_inputs.size() >= next_accumulator->public_input_size) { + public_input += instance->public_inputs[public_input_idx] * lagranges[inst]; inst++; - }; + } } - auto el = transcript->template receive_from_prover("next_public_input" + std::to_string(el_idx)); - verified = verified & (el == expected_el); - el_idx++; + public_input_idx++; } - for (size_t alpha_idx = 0; alpha_idx < NUM_SUBRELATIONS - 1; alpha_idx++) { - FF alpha(0); + size_t alpha_idx = 0; + for (auto& alpha : next_accumulator->alphas) { + alpha = FF(0); size_t instance_idx = 0; for (auto& instance : instances) { alpha += instance->alphas[alpha_idx] * lagranges[instance_idx]; instance_idx++; } - auto next_alpha = transcript->template receive_from_prover("next_alpha_" + std::to_string(alpha_idx)); - verified = verified & (alpha == next_alpha); + alpha_idx++; } - auto expected_parameters = bb::RelationParameters{}; + auto& expected_parameters = next_accumulator->relation_parameters; for (size_t inst_idx = 0; inst_idx < VerifierInstances::NUM; inst_idx++) { auto instance = instances[inst_idx]; expected_parameters.eta += instance->relation_parameters.eta * lagranges[inst_idx]; @@ -281,38 +208,21 @@ bool ProtoGalaxyVerifier_::verify_folding_proof(const std::ve instance->relation_parameters.lookup_grand_product_delta * lagranges[inst_idx]; } - auto next_eta = transcript->template receive_from_prover("next_eta"); - verified = verified & (next_eta == expected_parameters.eta); - - auto next_beta = transcript->template receive_from_prover("next_beta"); - verified = verified & (next_beta == expected_parameters.beta); - - auto next_gamma = transcript->template receive_from_prover("next_gamma"); - verified = verified & (next_gamma == expected_parameters.gamma); - - auto next_public_input_delta = transcript->template receive_from_prover("next_public_input_delta"); - verified = verified & (next_public_input_delta == expected_parameters.public_input_delta); - - auto next_lookup_grand_product_delta = - transcript->template receive_from_prover("next_lookup_grand_product_delta"); - verified = verified & (next_lookup_grand_product_delta == expected_parameters.lookup_grand_product_delta); - - auto acc_vk = std::make_shared(instances[0]->instance_size, instances[0]->public_input_size); + next_accumulator->verification_key = + std::make_shared(instances[0]->instance_size, instances[0]->public_input_size); auto vk_labels = commitment_labels.get_precomputed(); size_t vk_idx = 0; - for (auto& expected_vk : acc_vk->get_all()) { + for (auto& expected_vk : next_accumulator->verification_key->get_all()) { size_t inst = 0; expected_vk = Commitment::infinity(); for (auto& instance : instances) { expected_vk = expected_vk + instance->verification_key->get_all()[vk_idx] * lagranges[inst]; inst++; } - auto vk = transcript->template receive_from_prover("next_" + vk_labels[vk_idx]); - verified = verified & (vk == expected_vk); vk_idx++; } - return verified; + return next_accumulator; } template class ProtoGalaxyVerifier_>; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.hpp index 5743a888a0f..05dae2fb4f1 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.hpp @@ -27,8 +27,8 @@ template class ProtoGalaxyVerifier_ { CommitmentLabels commitment_labels; - ProtoGalaxyVerifier_(VerifierInstances insts) - : instances(insts){}; + ProtoGalaxyVerifier_(const std::vector>& insts) + : instances(VerifierInstances(insts)){}; ~ProtoGalaxyVerifier_() = default; /** * @brief Given a new round challenge δ for each iteration of the full ProtoGalaxy protocol, compute the vector @@ -70,7 +70,7 @@ template class ProtoGalaxyVerifier_ { * @brief Instantiatied the accumulator (i.e. the relaxed instance) from the transcript. * */ - void receive_accumulator(const std::shared_ptr&, const std::string&); + // void receive_accumulator(const std::shared_ptr&, const std::string&); /** * @brief Process the public data ϕ for the Instances to be folded. @@ -83,7 +83,7 @@ template class ProtoGalaxyVerifier_ { * accumulator, received from the prover is the same as that produced by the verifier. * */ - bool verify_folding_proof(const std::vector&); + std::shared_ptr verify_folding_proof(const std::vector&); }; } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp index dcc23cdfa6a..9fef4b874f9 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp @@ -37,7 +37,7 @@ template struct StdlibTranscriptParams { } template static constexpr size_t calc_num_bn254_frs() { - return bb::stdlib::field_conversion::calc_num_bn254_frs(); + return bb::stdlib::field_conversion::calc_num_bn254_frs(); } template static inline T convert_from_bn254_frs(std::span frs) { @@ -48,7 +48,7 @@ template struct StdlibTranscriptParams { template static inline std::vector convert_to_bn254_frs(const T& element) { Builder* builder = element.get_context(); - return bb::stdlib::field_conversion::convert_to_bn254_frs(*builder, element); + return bb::stdlib::field_conversion::convert_to_bn254_frs(*builder, element); } }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp index 0ece406ee75..5dd711ae8f7 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp @@ -1,16 +1,10 @@ #include "barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.hpp" #include "barretenberg/commitment_schemes/zeromorph/zeromorph.hpp" #include "barretenberg/numeric/bitop/get_msb.hpp" -#include "barretenberg/sumcheck/instance/verifier_instance.hpp" #include "barretenberg/transcript/transcript.hpp" namespace bb::stdlib::recursion::honk { -template -DeciderRecursiveVerifier_::DeciderRecursiveVerifier_(Builder* builder) - : builder(builder) -{} - /** * @brief This function verifies an Ultra Honk proof for a given Flavor, produced for a relaxed instance (ϕ, \vec{β*}, * e*). @@ -24,60 +18,16 @@ std::array DeciderRecursiveVerifier_:: using ZeroMorph = ::bb::ZeroMorphVerifier_; using VerifierCommitments = typename Flavor::VerifierCommitments; using Transcript = typename Flavor::Transcript; - using Instance = VerifierInstance_; - static constexpr size_t NUM_SUBRELATIONS = Flavor::NUM_SUBRELATIONS; StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); transcript = std::make_shared(stdlib_proof); - auto inst = std::make_unique(); - - const auto instance_size = transcript->template receive_from_prover("instance_size"); - const auto public_input_size = transcript->template receive_from_prover("public_input_size"); - const auto log_instance_size = static_cast(numeric::get_msb(uint32_t(instance_size.get_value()))); - - for (size_t i = 0; i < uint32_t(public_input_size.get_value()); ++i) { - auto public_input_i = transcript->template receive_from_prover("public_input_" + std::to_string(i)); - inst->public_inputs.emplace_back(public_input_i); - } - - auto eta = transcript->template receive_from_prover("eta"); - auto beta = transcript->template receive_from_prover("beta"); - auto gamma = transcript->template receive_from_prover("gamma"); - auto public_input_delta = transcript->template receive_from_prover("public_input_delta"); - auto lookup_grand_product_delta = transcript->template receive_from_prover("lookup_grand_product_delta"); - inst->relation_parameters = - RelationParameters{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta }; - - for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { - inst->alphas[idx] = transcript->template receive_from_prover("alpha" + std::to_string(idx)); - } - - inst->target_sum = transcript->template receive_from_prover("target_sum"); - - inst->gate_challenges = std::vector(log_instance_size); - for (size_t idx = 0; idx < log_instance_size; idx++) { - inst->gate_challenges[idx] = - transcript->template receive_from_prover("gate_challenge_" + std::to_string(idx)); - } - auto comm_view = inst->witness_commitments.get_all(); - auto witness_labels = inst->commitment_labels.get_witness(); - for (size_t idx = 0; idx < witness_labels.size(); idx++) { - comm_view[idx] = transcript->template receive_from_prover(witness_labels[idx]); - } - - inst->verification_key = std::make_shared(inst->instance_size, inst->public_input_size); - auto vk_view = inst->verification_key->get_all(); - auto vk_labels = inst->commitment_labels.get_precomputed(); - for (size_t idx = 0; idx < vk_labels.size(); idx++) { - vk_view[idx] = transcript->template receive_from_prover(vk_labels[idx]); - } - VerifierCommitments commitments{ inst->verification_key, inst->witness_commitments }; + VerifierCommitments commitments{ accumulator->verification_key, accumulator->witness_commitments }; - auto sumcheck = Sumcheck(log_instance_size, transcript, inst->target_sum); + auto sumcheck = Sumcheck(accumulator->log_instance_size, transcript, accumulator->target_sum); auto [multivariate_challenge, claimed_evaluations, sumcheck_verified] = - sumcheck.verify(inst->relation_parameters, inst->alphas, inst->gate_challenges); + sumcheck.verify(accumulator->relation_parameters, accumulator->alphas, accumulator->gate_challenges); // Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description of the // unrolled protocol. @@ -91,6 +41,6 @@ std::array DeciderRecursiveVerifier_:: return pairing_points; } -template class DeciderRecursiveVerifier_>; +// template class DeciderRecursiveVerifier_>; template class DeciderRecursiveVerifier_>; } // namespace bb::stdlib::recursion::honk diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.hpp index 61f9a481420..829f47e99a5 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.hpp @@ -3,9 +3,11 @@ #include "barretenberg/flavor/ultra_recursive.hpp" #include "barretenberg/honk/proof_system/types/proof.hpp" #include "barretenberg/stdlib/recursion/honk/transcript/transcript.hpp" +#include "barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp" #include "barretenberg/sumcheck/sumcheck.hpp" namespace bb::stdlib::recursion::honk { template class DeciderRecursiveVerifier_ { + using NativeFlavor = typename Flavor::NativeFlavor; using FF = typename Flavor::FF; using Commitment = typename Flavor::Commitment; using GroupElement = typename Flavor::GroupElement; @@ -14,16 +16,21 @@ template class DeciderRecursiveVerifier_ { using Builder = typename Flavor::CircuitBuilder; using RelationSeparator = typename Flavor::RelationSeparator; using PairingPoints = std::array; + using Instance = RecursiveVerifierInstance_; + using NativeInstance = bb::VerifierInstance_; using Transcript = bb::BaseTranscript>; public: - explicit DeciderRecursiveVerifier_(Builder* builder); + explicit DeciderRecursiveVerifier_(Builder* builder, std::shared_ptr accumulator) + : builder(builder) + , accumulator(std::make_shared(builder, accumulator)){}; PairingPoints verify_proof(const HonkProof& proof); std::map commitments; std::shared_ptr pcs_verification_key; Builder* builder; + std::shared_ptr accumulator; std::shared_ptr transcript; }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/goblin_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/goblin_verifier.test.cpp index 9052d25c071..f74d18faccb 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/goblin_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/goblin_verifier.test.cpp @@ -148,21 +148,22 @@ template class GoblinRecursiveVerifierTest : public testi // Compute native verification key InnerComposer inner_composer; - auto instance = inner_composer.create_instance(inner_circuit); + auto instance = inner_composer.create_prover_instance(inner_circuit); + auto verification_key = inner_composer.compute_verification_key(instance); auto prover = inner_composer.create_prover(instance); // A prerequisite for computing VK // Instantiate the recursive verifier using the native verification key - RecursiveVerifier verifier{ &outer_circuit, instance->verification_key }; + RecursiveVerifier verifier{ &outer_circuit, verification_key }; // Spot check some values in the recursive VK to ensure it was constructed correctly - EXPECT_EQ(verifier.key->circuit_size, instance->verification_key->circuit_size); - EXPECT_EQ(verifier.key->log_circuit_size, instance->verification_key->log_circuit_size); - EXPECT_EQ(verifier.key->num_public_inputs, instance->verification_key->num_public_inputs); - EXPECT_EQ(verifier.key->q_m.get_value(), instance->verification_key->q_m); - EXPECT_EQ(verifier.key->q_r.get_value(), instance->verification_key->q_r); - EXPECT_EQ(verifier.key->sigma_1.get_value(), instance->verification_key->sigma_1); - EXPECT_EQ(verifier.key->id_3.get_value(), instance->verification_key->id_3); - EXPECT_EQ(verifier.key->lagrange_ecc_op.get_value(), instance->verification_key->lagrange_ecc_op); + EXPECT_EQ(verifier.key->circuit_size, verification_key->circuit_size); + EXPECT_EQ(verifier.key->log_circuit_size, verification_key->log_circuit_size); + EXPECT_EQ(verifier.key->num_public_inputs, verification_key->num_public_inputs); + EXPECT_EQ(verifier.key->q_m.get_value(), verification_key->q_m); + EXPECT_EQ(verifier.key->q_r.get_value(), verification_key->q_r); + EXPECT_EQ(verifier.key->sigma_1.get_value(), verification_key->sigma_1); + EXPECT_EQ(verifier.key->id_3.get_value(), verification_key->id_3); + EXPECT_EQ(verifier.key->lagrange_ecc_op.get_value(), verification_key->lagrange_ecc_op); } /** @@ -176,13 +177,14 @@ template class GoblinRecursiveVerifierTest : public testi // Generate a proof over the inner circuit InnerComposer inner_composer; - auto instance = inner_composer.create_instance(inner_circuit); + auto instance = inner_composer.create_prover_instance(inner_circuit); + auto verification_key = inner_composer.compute_verification_key(instance); auto inner_prover = inner_composer.create_prover(instance); auto inner_proof = inner_prover.construct_proof(); // Create a recursive verification circuit for the proof of the inner circuit OuterBuilder outer_circuit; - RecursiveVerifier verifier{ &outer_circuit, instance->verification_key }; + RecursiveVerifier verifier{ &outer_circuit, verification_key }; auto pairing_points = verifier.verify_proof(inner_proof); info("Recursive Verifier Goblin: num gates = ", outer_circuit.num_gates); @@ -191,7 +193,7 @@ template class GoblinRecursiveVerifierTest : public testi // Check 1: Perform native verification then perform the pairing on the outputs of the recursive // verifier and check that the result agrees. - auto native_verifier = inner_composer.create_verifier(instance); + auto native_verifier = inner_composer.create_verifier(verification_key); auto native_result = native_verifier.verify_proof(inner_proof); auto recursive_result = native_verifier.pcs_verification_key->pairing_check(pairing_points[0].get_value(), pairing_points[1].get_value()); @@ -208,9 +210,10 @@ template class GoblinRecursiveVerifierTest : public testi // Check 3: Construct and verify a proof of the recursive verifier circuit { auto composer = get_outer_composer(); - auto instance = composer.create_instance(outer_circuit); + auto instance = composer.create_prover_instance(outer_circuit); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); auto proof = prover.construct_proof(); bool verified = verifier.verify_proof(proof); @@ -231,7 +234,8 @@ template class GoblinRecursiveVerifierTest : public testi // Generate a proof over the inner circuit InnerComposer inner_composer; - auto instance = inner_composer.create_instance(inner_circuit); + auto instance = inner_composer.create_prover_instance(inner_circuit); + auto verification_key = inner_composer.compute_verification_key(instance); auto inner_prover = inner_composer.create_prover(instance); auto inner_proof = inner_prover.construct_proof(); @@ -243,7 +247,7 @@ template class GoblinRecursiveVerifierTest : public testi // Create a recursive verification circuit for the proof of the inner circuit OuterBuilder outer_circuit; - RecursiveVerifier verifier{ &outer_circuit, instance->verification_key }; + RecursiveVerifier verifier{ &outer_circuit, verification_key }; verifier.verify_proof(inner_proof); // We expect the circuit check to fail due to the bad proof diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_verifier.test.cpp index 8e6595a1b98..4b02a451818 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/merge_verifier.test.cpp @@ -82,9 +82,10 @@ class RecursiveMergeVerifierTest : public testing::Test { // Check 3: Construct and verify a (goblin) ultra honk proof of the Merge recursive verifier circuit { GoblinUltraComposer composer; - auto instance = composer.create_instance(outer_circuit); + auto instance = composer.create_prover_instance(outer_circuit); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); auto proof = prover.construct_proof(); bool verified = verifier.verify_proof(proof); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp index 047cfa4037e..9652935a9f1 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp @@ -1,69 +1,9 @@ #include "protogalaxy_recursive_verifier.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/proof_system/library/grand_product_delta.hpp" +#include "barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp" namespace bb::stdlib::recursion::honk { -template -void ProtoGalaxyRecursiveVerifier_::receive_accumulator(const std::shared_ptr& inst, - const std::string& domain_separator) -{ - // Get circuit parameters - const auto instance_size = transcript->template receive_from_prover(domain_separator + "_instance_size"); - const auto public_input_size = - transcript->template receive_from_prover(domain_separator + "_public_input_size"); - inst->instance_size = uint32_t(instance_size.get_value()); - inst->log_instance_size = uint32_t(numeric::get_msb(inst->instance_size)); - inst->public_input_size = uint32_t(public_input_size.get_value()); - - // Get folded public inputs - for (size_t i = 0; i < inst->public_input_size; ++i) { - auto public_input_i = - transcript->template receive_from_prover(domain_separator + "_public_input_" + std::to_string(i)); - inst->public_inputs.emplace_back(public_input_i); - } - - // Get folded relation parameters - auto eta = transcript->template receive_from_prover(domain_separator + "_eta"); - auto beta = transcript->template receive_from_prover(domain_separator + "_beta"); - auto gamma = transcript->template receive_from_prover(domain_separator + "_gamma"); - auto public_input_delta = transcript->template receive_from_prover(domain_separator + "_public_input_delta"); - auto lookup_grand_product_delta = - transcript->template receive_from_prover(domain_separator + "_lookup_grand_product_delta"); - inst->relation_parameters = - RelationParameters{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta }; - - // Get the folded relation separator challenges \vec{α} - for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { - inst->alphas[idx] = - transcript->template receive_from_prover(domain_separator + "_alpha_" + std::to_string(idx)); - } - - inst->target_sum = transcript->template receive_from_prover(domain_separator + "_target_sum"); - - // Get the folded gate challenges, \vec{β} in the paper - inst->gate_challenges = std::vector(inst->log_instance_size); - for (size_t idx = 0; idx < inst->log_instance_size; idx++) { - inst->gate_challenges[idx] = - transcript->template receive_from_prover(domain_separator + "_gate_challenge_" + std::to_string(idx)); - } - - // Get the folded commitments to all witness polynomials - auto comm_view = inst->witness_commitments.get_all(); - auto witness_labels = inst->commitment_labels.get_witness(); - for (size_t idx = 0; idx < witness_labels.size(); idx++) { - comm_view[idx] = - transcript->template receive_from_prover(domain_separator + "_" + witness_labels[idx]); - } - - // Get the folded commitments to selector polynomials - inst->verification_key = std::make_shared(inst->instance_size, inst->public_input_size); - auto vk_view = inst->verification_key->get_all(); - auto vk_labels = inst->commitment_labels.get_precomputed(); - for (size_t idx = 0; idx < vk_labels.size(); idx++) { - vk_view[idx] = transcript->template receive_from_prover(domain_separator + "_" + vk_labels[idx]); - } -} - template void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_instance( const std::shared_ptr& inst, const std::string& domain_separator) @@ -141,14 +81,6 @@ void ProtoGalaxyRecursiveVerifier_::receive_and_finalise_inst for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { inst->alphas[idx] = transcript->template get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); } - - // Get the commitments to the selector polynomials for the given instance - inst->verification_key = std::make_shared(inst->instance_size, inst->public_input_size); - auto vk_view = inst->verification_key->get_all(); - auto vk_labels = labels.get_precomputed(); - for (size_t idx = 0; idx < vk_labels.size(); idx++) { - vk_view[idx] = transcript->template receive_from_prover(domain_separator + "_" + vk_labels[idx]); - } } // TODO(https://github.com/AztecProtocol/barretenberg/issues/795): The rounds prior to actual verifying are common @@ -158,14 +90,7 @@ template void ProtoGalaxyRecursiveVerifier_template receive_from_prover(domain_separator + "is_accumulator"); - inst->is_accumulator = static_cast(is_accumulator.get_value()); - if (inst->is_accumulator) { - receive_accumulator(inst, domain_separator); - } else { - // This is the first round of folding and we need to generate some gate challenges. - // TODO(https://github.com/AztecProtocol/barretenberg/issues/740): implement option 2 to make this more - // efficient by avoiding the computation of the perturbator + if (!inst->is_accumulator) { receive_and_finalise_instance(inst, domain_separator); inst->target_sum = 0; auto beta = transcript->template get_challenge(domain_separator + "_initial_gate_challenge"); @@ -186,10 +111,10 @@ template void ProtoGalaxyRecursiveVerifier_ -void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(const HonkProof& proof) +std::shared_ptr ProtoGalaxyRecursiveVerifier_< + VerifierInstances>::verify_folding_proof(const HonkProof& proof) { using Transcript = typename Flavor::Transcript; - using ScalarNative = typename Flavor::Curve::ScalarFieldNative; StdlibProof stdlib_proof = bb::convert_proof_to_witness(builder, proof); transcript = std::make_shared(stdlib_proof); @@ -200,15 +125,11 @@ void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(cons auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); std::vector perturbator_coeffs(accumulator->log_instance_size + 1); - for (size_t idx = 0; idx <= accumulator->log_instance_size; idx++) { + for (size_t idx = 1; idx <= accumulator->log_instance_size; idx++) { perturbator_coeffs[idx] = transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); } - // TODO(https://github.com/AztecProtocol/barretenberg/issues/833): As currently the stdlib transcript is not - // creating proper constraints linked to Fiat-Shamir we add an additonal gate to ensure assert_equal is correct. - // This comparison to 0 can be removed here and below once we have merged the transcript. - auto zero = FF::from_witness(builder, ScalarNative(0)); - zero.assert_equal(accumulator->target_sum - perturbator_coeffs[0], "F(0) != e"); + perturbator_coeffs[0] = accumulator->target_sum; FF perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); @@ -227,24 +148,22 @@ void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(cons auto vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); auto lagranges = std::vector{ FF(1) - combiner_challenge, combiner_challenge }; + auto next_accumulator = std::make_shared(builder); + next_accumulator->instance_size = accumulator->instance_size; + next_accumulator->log_instance_size = accumulator->log_instance_size; + next_accumulator->is_accumulator = true; + // Compute next folding parameters and verify against the ones received from the prover - auto expected_next_target_sum = + next_accumulator->target_sum = perturbator_at_challenge * lagranges[0] + vanishing_polynomial_at_challenge * combiner_quotient_at_challenge; - auto next_target_sum = transcript->template receive_from_prover("next_target_sum"); - zero.assert_equal(expected_next_target_sum - next_target_sum, "next target sum mismatch"); - - auto expected_betas_star = update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); - for (size_t idx = 0; idx < accumulator->log_instance_size; idx++) { - auto beta_star = transcript->template receive_from_prover("next_gate_challenge_" + std::to_string(idx)); - zero.assert_equal(beta_star - expected_betas_star[idx], - " next gate challenge mismatch at: " + std::to_string(idx)); - } + next_accumulator->gate_challenges = + update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); // Compute ϕ and verify against the data received from the prover - WitnessCommitments acc_witness_commitments; + auto& acc_witness_commitments = next_accumulator->witness_commitments; auto witness_labels = commitment_labels.get_witness(); size_t comm_idx = 0; - for (auto& expected_comm : acc_witness_commitments.get_all()) { + for (auto& comm : acc_witness_commitments.get_all()) { std::vector scalars; std::vector commitments; size_t inst = 0; @@ -253,41 +172,36 @@ void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(cons commitments.emplace_back(instance->witness_commitments.get_all()[comm_idx]); inst++; } - expected_comm = Commitment::batch_mul(commitments, scalars); - auto comm = transcript->template receive_from_prover("next_" + witness_labels[comm_idx]); - comm.x.assert_equal(expected_comm.x); - comm.y.assert_equal(expected_comm.y); + comm = Commitment::batch_mul(commitments, scalars); comm_idx++; } - std::vector folded_public_inputs(instances[0]->public_inputs.size(), 0); + next_accumulator->public_input_size = instances[0]->public_input_size; + next_accumulator->public_inputs = std::vector(next_accumulator->public_input_size, 0); size_t public_input_idx = 0; - for (auto& expected_public_input : folded_public_inputs) { + for (auto& public_input : next_accumulator->public_inputs) { size_t inst = 0; for (auto& instance : instances) { - expected_public_input += instance->public_inputs[public_input_idx] * lagranges[inst]; - inst++; + if (instance->public_inputs.size() >= next_accumulator->public_inputs.size()) { + public_input += instance->public_inputs[public_input_idx] * lagranges[inst]; + inst++; + }; } - auto next_public_input = - transcript->template receive_from_prover("next_public_input" + std::to_string(public_input_idx)); - zero.assert_equal(expected_public_input - next_public_input, - "folded public input mismatch at: " + std::to_string(public_input_idx)); public_input_idx++; } - for (size_t alpha_idx = 0; alpha_idx < NUM_SUBRELATIONS - 1; alpha_idx++) { - FF expected_alpha(0); + size_t alpha_idx = 0; + for (auto& alpha : next_accumulator->alphas) { + alpha = FF(0); size_t instance_idx = 0; for (auto& instance : instances) { - expected_alpha += instance->alphas[alpha_idx] * lagranges[instance_idx]; + alpha += instance->alphas[alpha_idx] * lagranges[instance_idx]; instance_idx++; } - auto next_alpha = transcript->template receive_from_prover("next_alpha_" + std::to_string(alpha_idx)); - zero.assert_equal(expected_alpha - next_alpha, - "folded relation separator mismatch at: " + std::to_string(alpha_idx)); + alpha_idx++; } - auto expected_parameters = bb::RelationParameters{}; + auto& expected_parameters = next_accumulator->relation_parameters; for (size_t inst_idx = 0; inst_idx < VerifierInstances::NUM; inst_idx++) { auto instance = instances[inst_idx]; expected_parameters.eta += instance->relation_parameters.eta * lagranges[inst_idx]; @@ -299,28 +213,11 @@ void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(cons instance->relation_parameters.lookup_grand_product_delta * lagranges[inst_idx]; } - auto next_eta = transcript->template receive_from_prover("next_eta"); - zero.assert_equal(expected_parameters.eta - next_eta, "relation parameter eta mismatch"); - - auto next_beta = transcript->template receive_from_prover("next_beta"); - zero.assert_equal(expected_parameters.beta - next_beta, "relation parameter beta mismatch"); - - auto next_gamma = transcript->template receive_from_prover("next_gamma"); - zero.assert_equal(expected_parameters.gamma - next_gamma, "relation parameter gamma mismatch"); - - auto next_public_input_delta = transcript->template receive_from_prover("next_public_input_delta"); - zero.assert_equal(expected_parameters.public_input_delta - next_public_input_delta, - "relation parameter public input delta mismatch"); - - auto next_lookup_grand_product_delta = - transcript->template receive_from_prover("next_lookup_grand_product_delta"); - zero.assert_equal(expected_parameters.lookup_grand_product_delta - next_lookup_grand_product_delta, - "relation parameter lookup grand product delta mismatch"); - - auto acc_vk = std::make_shared(instances[0]->instance_size, instances[0]->public_input_size); + next_accumulator->verification_key = + std::make_shared(instances[0]->instance_size, instances[0]->public_input_size); auto vk_labels = commitment_labels.get_precomputed(); size_t vk_idx = 0; - for (auto& expected_vk : acc_vk->get_all()) { + for (auto& expected_vk : next_accumulator->verification_key->get_all()) { size_t inst = 0; std::vector scalars; std::vector commitments; @@ -330,14 +227,13 @@ void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(cons inst++; } expected_vk = Commitment::batch_mul(commitments, scalars); - auto vk = transcript->template receive_from_prover("next_" + vk_labels[vk_idx]); - vk.x.assert_equal(expected_vk.x); - vk.y.assert_equal(expected_vk.y); vk_idx++; } + return next_accumulator; } -template class ProtoGalaxyRecursiveVerifier_, 2>>; +// template class ProtoGalaxyRecursiveVerifier_, +// 2>>; template class ProtoGalaxyRecursiveVerifier_< - VerifierInstances_, 2>>; + RecursiveVerifierInstances_, 2>>; } // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp index 9bcc8a9c238..f413fb3b151 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp @@ -5,36 +5,42 @@ #include "barretenberg/honk/proof_system/types/proof.hpp" #include "barretenberg/protogalaxy/folding_result.hpp" #include "barretenberg/stdlib/recursion/honk/transcript/transcript.hpp" -#include "barretenberg/sumcheck/instance/instances.hpp" +#include "barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp" namespace bb::stdlib::recursion::honk { template class ProtoGalaxyRecursiveVerifier_ { public: using Flavor = typename VerifierInstances::Flavor; + using NativeFlavor = typename Flavor::NativeFlavor; using FF = typename Flavor::FF; using Commitment = typename Flavor::Commitment; using GroupElement = typename Flavor::GroupElement; using Instance = typename VerifierInstances::Instance; + using NativeInstance = bb::VerifierInstance_; using VerificationKey = typename Flavor::VerificationKey; + using NativeVerificationKey = typename Flavor::NativeVerificationKey; using WitnessCommitments = typename Flavor::WitnessCommitments; using CommitmentLabels = typename Flavor::CommitmentLabels; using Builder = typename Flavor::CircuitBuilder; using RelationSeparator = typename Flavor::RelationSeparator; using PairingPoints = std::array; + static constexpr size_t NUM = VerifierInstances::NUM; using Transcript = bb::BaseTranscript>; static constexpr size_t NUM_SUBRELATIONS = Flavor::NUM_SUBRELATIONS; - VerifierInstances instances; - CommitmentLabels commitment_labels; Builder* builder; std::shared_ptr transcript; + VerifierInstances instances; + + ProtoGalaxyRecursiveVerifier_(Builder* builder, + std::shared_ptr accumulator, + const std::vector> native_inst_vks) + : builder(builder) + , instances(VerifierInstances(builder, accumulator, native_inst_vks)){}; - explicit ProtoGalaxyRecursiveVerifier_(Builder* builder) - : instances(VerifierInstances()) - , builder(builder){}; /** * @brief Given a new round challenge δ for each iteration of the full ProtoGalaxy protocol, compute the vector * [δ, δ^2,..., δ^t] where t = logn and n is the size of the instance. @@ -92,7 +98,7 @@ template class ProtoGalaxyRecursiveVerifier_ { * by the prover, are expressed as constraints. */ - void verify_folding_proof(const HonkProof& proof); + std::shared_ptr verify_folding_proof(const HonkProof&); /** * @brief Evaluates the perturbator at a given scalar, in a sequential manner for the recursive setting. diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp index 0912edf91ce..19566c92d00 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp @@ -16,7 +16,9 @@ template class ProtoGalaxyRecursiveTests : public tes using InnerFlavor = typename RecursiveFlavor::NativeFlavor; using InnerComposer = ::bb::UltraComposer_; - using Instance = ::bb::ProverInstance_; + using ProverInstance = ::bb::ProverInstance_; + using VerifierInstance = ::bb::VerifierInstance_; + using RecursiveVerifierInstance = ::bb::stdlib::recursion::honk::RecursiveVerifierInstance_; using InnerBuilder = typename InnerComposer::CircuitBuilder; using InnerCurve = bn254; using Commitment = typename InnerFlavor::Commitment; @@ -26,7 +28,7 @@ template class ProtoGalaxyRecursiveTests : public tes using OuterBuilder = GoblinUltraCircuitBuilder; using OuterComposer = GoblinUltraComposer; - using RecursiveVerifierInstances = ::bb::VerifierInstances_; + using RecursiveVerifierInstances = ::bb::stdlib::recursion::honk::RecursiveVerifierInstances_; using FoldingRecursiveVerifier = ProtoGalaxyRecursiveVerifier_; using DeciderRecursiveVerifier = DeciderRecursiveVerifier_; using DeciderVerifier = DeciderVerifier_; @@ -55,7 +57,7 @@ template class ProtoGalaxyRecursiveTests : public tes * TODO(https://github.com/AztecProtocol/barretenberg/issues/744): make testing utility with functionality shared * amongst test files */ - static void create_inner_circuit(InnerBuilder& builder, size_t log_num_gates = 10) + static void create_inner_circuit(InnerBuilder& builder, size_t log_num_gates = 15) { using fr_ct = typename InnerCurve::ScalarField; using fq_ct = typename InnerCurve::BaseField; @@ -111,17 +113,17 @@ template class ProtoGalaxyRecursiveTests : public tes } }; - static std::shared_ptr fold_and_verify_native(const std::vector>& instances, - InnerComposer& composer) + static std::tuple, std::shared_ptr> fold_and_verify_native( + const std::vector>& prover_instances, + const std::vector>& verifier_instances, + InnerComposer& composer) { - auto folding_prover = composer.create_folding_prover(instances); - auto folding_verifier = composer.create_folding_verifier(); - - auto proof = folding_prover.fold_instances(); - auto next_accumulator = proof.accumulator; - auto res = folding_verifier.verify_folding_proof(proof.folding_data); - EXPECT_EQ(res, true); - return next_accumulator; + auto folding_prover = composer.create_folding_prover(prover_instances); + auto folding_verifier = composer.create_folding_verifier(verifier_instances); + + auto [prover_accumulator, folding_proof] = folding_prover.fold_instances(); + auto verifier_accumulator = folding_verifier.verify_folding_proof(folding_proof); + return { prover_accumulator, verifier_accumulator }; } /** @@ -165,39 +167,39 @@ template class ProtoGalaxyRecursiveTests : public tes }; /** - * @brief Tests a simple recursive fold that is valid works as expected. + * @brief Tests that a valid recursive fold works as expected. * */ static void test_recursive_folding() { // Create two arbitrary circuits for the first round of folding InnerBuilder builder1; - create_inner_circuit(builder1); InnerBuilder builder2; - builder2.add_public_variable(FF(1)); create_inner_circuit(builder2); InnerComposer inner_composer = InnerComposer(); - auto instance1 = inner_composer.create_instance(builder1); - auto instance2 = inner_composer.create_instance(builder2); - auto instances = std::vector>{ instance1, instance2 }; - + auto prover_instance_1 = inner_composer.create_prover_instance(builder1); + auto verifier_instance_1 = inner_composer.create_verifier_instance(prover_instance_1); + auto prover_instance_2 = inner_composer.create_prover_instance(builder2); + auto verifier_instance_2 = inner_composer.create_verifier_instance(prover_instance_2); // Generate a folding proof - auto inner_folding_prover = inner_composer.create_folding_prover(instances); + auto inner_folding_prover = inner_composer.create_folding_prover({ prover_instance_1, prover_instance_2 }); auto inner_folding_proof = inner_folding_prover.fold_instances(); // Create a recursive folding verifier circuit for the folding proof of the two instances OuterBuilder outer_folding_circuit; - FoldingRecursiveVerifier verifier{ &outer_folding_circuit }; - verifier.verify_folding_proof(inner_folding_proof.folding_data); + auto verifier = FoldingRecursiveVerifier( + &outer_folding_circuit, verifier_instance_1, { verifier_instance_2->verification_key }); + auto recursive_verifier_accumulator = verifier.verify_folding_proof(inner_folding_proof.folding_data); + auto acc = std::make_shared(recursive_verifier_accumulator->get_value()); info("Folding Recursive Verifier: num gates = ", outer_folding_circuit.num_gates); - // Perform native folding verification and ensure it returns the same result (either true or false) as calling - // check_circuit on the recursive folding verifier - auto native_folding_verifier = inner_composer.create_folding_verifier(); - auto native_folding_result = native_folding_verifier.verify_folding_proof(inner_folding_proof.folding_data); - EXPECT_EQ(native_folding_result, !outer_folding_circuit.failed()); + // Perform native folding verification and ensure it returns the same result (either true or false) as + // calling check_circuit on the recursive folding verifier + auto native_folding_verifier = + inner_composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); + auto verifier_accumulator = native_folding_verifier.verify_folding_proof(inner_folding_proof.folding_data); // Ensure that the underlying native and recursive folding verification algorithms agree by ensuring the // manifestsproduced by each agree. @@ -208,87 +210,31 @@ template class ProtoGalaxyRecursiveTests : public tes EXPECT_EQ(recursive_folding_manifest[i], native_folding_manifest[i]); } - // Check for a failure flag in the recursive verifier circuit - EXPECT_EQ(outer_folding_circuit.failed(), false) << outer_folding_circuit.err(); - - { - auto composer = OuterComposer(); - auto instance = composer.create_instance(outer_folding_circuit); - auto prover = composer.create_prover(instance); - auto verifier = composer.create_verifier(instance); - auto proof = prover.construct_proof(); - bool verified = verifier.verify_proof(proof); - - ASSERT(verified); - } - }; - - /** - * @brief Perform two rounds of folding valid circuits and then recursive verify the final decider proof, - * make sure the verifer circuits pass check_circuit(). Ensure that the algorithm of the recursive and native - * verifiers are identical by checking the manifests - */ - // TODO(https://github.com/AztecProtocol/barretenberg/issues/844): Fold the recursive folding verifier in tests once - // we can fold instances of different sizes. - static void test_full_protogalaxy_recursive() - { - // Create two arbitrary circuits for the first round of folding - InnerBuilder builder1; - - create_inner_circuit(builder1); - InnerBuilder builder2; - builder2.add_public_variable(FF(1)); - create_inner_circuit(builder2); - - InnerComposer inner_composer = InnerComposer(); - auto instance1 = inner_composer.create_instance(builder1); - auto instance2 = inner_composer.create_instance(builder2); - auto instances = std::vector>{ instance1, instance2 }; - - auto accumulator = fold_and_verify_native(instances, inner_composer); - - // Create another circuit to do a second round of folding - InnerBuilder builder3; - create_inner_circuit(builder3); - auto instance3 = inner_composer.create_instance(builder3); - instances = std::vector>{ accumulator, instance3 }; - - accumulator = fold_and_verify_native(instances, inner_composer); - - // Create a decider proof for the relaxed instance obtained through folding - auto inner_decider_prover = inner_composer.create_decider_prover(accumulator); + auto inner_decider_prover = inner_composer.create_decider_prover(inner_folding_proof.accumulator); auto inner_decider_proof = inner_decider_prover.construct_proof(); - // Create a decider verifier circuit for recursively verifying the decider proof OuterBuilder outer_decider_circuit; - DeciderRecursiveVerifier decider_verifier{ &outer_decider_circuit }; + DeciderRecursiveVerifier decider_verifier{ &outer_decider_circuit, acc }; auto pairing_points = decider_verifier.verify_proof(inner_decider_proof); info("Decider Recursive Verifier: num gates = ", outer_decider_circuit.num_gates); // Check for a failure flag in the recursive verifier circuit EXPECT_EQ(outer_decider_circuit.failed(), false) << outer_decider_circuit.err(); - // Perform native verification then perform the pairing on the outputs of the recursive - // decider verifier and check that the result agrees. - DeciderVerifier native_decider_verifier = inner_composer.create_decider_verifier(accumulator); + // Check for a failure flag in the recursive verifier circuit + EXPECT_EQ(outer_folding_circuit.failed(), false) << outer_folding_circuit.err(); + + DeciderVerifier native_decider_verifier = inner_composer.create_decider_verifier(verifier_accumulator); auto native_result = native_decider_verifier.verify_proof(inner_decider_proof); auto recursive_result = native_decider_verifier.pcs_verification_key->pairing_check( pairing_points[0].get_value(), pairing_points[1].get_value()); EXPECT_EQ(native_result, recursive_result); - // Ensure that the underlying native and recursive decider verification algorithms agree by ensuring - // the manifests produced are the same. - auto recursive_decider_manifest = decider_verifier.transcript->get_manifest(); - auto native_decider_manifest = native_decider_verifier.transcript->get_manifest(); - for (size_t i = 0; i < recursive_decider_manifest.size(); ++i) { - EXPECT_EQ(recursive_decider_manifest[i], native_decider_manifest[i]); - } - - // Construct and verify a proof of the recursive decider verifier circuit { auto composer = OuterComposer(); - auto instance = composer.create_instance(outer_decider_circuit); + auto instance = composer.create_prover_instance(outer_folding_circuit); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); auto proof = prover.construct_proof(); bool verified = verifier.verify_proof(proof); @@ -296,80 +242,153 @@ template class ProtoGalaxyRecursiveTests : public tes } }; - static void test_tampered_decider_proof() - { - // Create two arbitrary circuits for the first round of folding - InnerBuilder builder1; - - create_inner_circuit(builder1); - InnerBuilder builder2; - builder2.add_public_variable(FF(1)); - create_inner_circuit(builder2); - - InnerComposer inner_composer = InnerComposer(); - auto instance1 = inner_composer.create_instance(builder1); - auto instance2 = inner_composer.create_instance(builder2); - auto instances = std::vector>{ instance1, instance2 }; - - auto accumulator = fold_and_verify_native(instances, inner_composer); - - // Tamper with the accumulator by changing the target sum - accumulator->target_sum = FF::random_element(); - - // Create a decider proof for the relaxed instance obtained through folding - auto inner_decider_prover = inner_composer.create_decider_prover(accumulator); - auto inner_decider_proof = inner_decider_prover.construct_proof(); - - // Create a decider verifier circuit for recursively verifying the decider proof - OuterBuilder outer_decider_circuit; - DeciderRecursiveVerifier decider_verifier{ &outer_decider_circuit }; - decider_verifier.verify_proof(inner_decider_proof); - info("Decider Recursive Verifier: num gates = ", outer_decider_circuit.num_gates); - - // We expect the decider circuit check to fail due to the bad proof - EXPECT_FALSE(outer_decider_circuit.check_circuit()); - }; - - static void test_tampered_accumulator() - { - // Create two arbitrary circuits for the first round of folding - InnerBuilder builder1; - - create_inner_circuit(builder1); - InnerBuilder builder2; - builder2.add_public_variable(FF(1)); - create_inner_circuit(builder2); - - InnerComposer inner_composer = InnerComposer(); - auto instance1 = inner_composer.create_instance(builder1); - auto instance2 = inner_composer.create_instance(builder2); - auto instances = std::vector>{ instance1, instance2 }; - - auto accumulator = fold_and_verify_native(instances, inner_composer); - - // Create another circuit to do a second round of folding - InnerBuilder builder3; - create_inner_circuit(builder3); - auto instance3 = inner_composer.create_instance(builder3); - - // Tamper with the accumulator - instances = std::vector>{ accumulator, instance3 }; - accumulator->prover_polynomials.w_l[1] = FF::random_element(); - - // Generate a folding proof - auto inner_folding_prover = inner_composer.create_folding_prover(instances); - auto inner_folding_proof = inner_folding_prover.fold_instances(); - - // Create a recursive folding verifier circuit for the folding proof of the two instances - OuterBuilder outer_folding_circuit; - FoldingRecursiveVerifier verifier{ &outer_folding_circuit }; - verifier.verify_folding_proof(inner_folding_proof.folding_data); - EXPECT_EQ(outer_folding_circuit.check_circuit(), false); - }; + /** + * @brief Perform two rounds of folding valid circuits and then recursive verify the final decider proof, + * make sure the verifer circuits pass check_circuit(). Ensure that the algorithm of the recursive and native + * verifiers are identical by checking the manifests + */ + // TODO(https://github.com/AztecProtocol/barretenberg/issues/844): Fold the recursive folding verifier in + // tests once + // we can fold instances of different sizes. + // static void test_full_protogalaxy_recursive() + // { + // // Create two arbitrary circuits for the first round of folding + // InnerBuilder builder1; + + // create_inner_circuit(builder1); + // InnerBuilder builder2; + // builder2.add_public_variable(FF(1)); + // create_inner_circuit(builder2); + + // InnerComposer inner_composer = InnerComposer(); + // auto prover_instance_1 = inner_composer.create_prover_instance(builder1); + // auto verifier_instance_1 = inner_composer.create_verifier_instance(prover_instance_1); + // auto prover_instance_2 = inner_composer.create_prover_instance(builder2); + // auto verifier_instance_2 = inner_composer.create_verifier_instance(prover_instance_2); + + // auto [prover_accumulator, verifier_accumulator] = fold_and_verify_native( + // { prover_instance_1, prover_instance_2 }, { verifier_instance_1, verifier_instance_2 }, + // tinner_composer); + + // // Create another circuit to do a second round of folding + // InnerBuilder builder3; + // create_inner_circuit(builder3); + // auto prover_instance_3 = inner_composer.create_prover_instance(builder3); + // auto verifier_instance_3 = inner_composer.create_verifier_instance(prover_instance_3); + + // auto [prover_accumulator_2, verifier_accumulator_2] = fold_and_verify_native( + // { prover_accumulator, prover_instance_3 }, { verifier_accumulator, verifier_instance_3 }, + // inner_composer); + + // // Create a decider proof for the relaxed instance obtained through folding + // auto inner_decider_prover = inner_composer.create_decider_prover(prover_accumulator_2); + // auto inner_decider_proof = inner_decider_prover.construct_proof(); + + // // Create a decider verifier circuit for recursively verifying the decider proof + // OuterBuilder outer_decider_circuit; + // DeciderRecursiveVerifier decider_verifier{ &outer_decider_circuit }; + // auto pairing_points = decider_verifier.verify_proof(inner_decider_proof); + // info("Decider Recursive Verifier: num gates = ", outer_decider_circuit.num_gates); + // // Check for a failure flag in the recursive verifier circuit + // EXPECT_EQ(outer_decider_circuit.failed(), false) << outer_decider_circuit.err(); + + // // Perform native verification then perform the pairing on the outputs of the recursive + // // decider verifier and check that the result agrees. + + // // Ensure that the underlying native and recursive decider verification algorithms agree by ensuring + // // the manifests produced are the same. + // auto recursive_decider_manifest = decider_verifier.transcript->get_manifest(); + // auto native_decider_manifest = native_decider_verifier.transcript->get_manifest(); + // for (size_t i = 0; i < recursive_decider_manifest.size(); ++i) { + // EXPECT_EQ(recursive_decider_manifest[i], native_decider_manifest[i]); + // } + + // // Construct and verify a proof of the recursive decider verifier circuit + // { + // auto composer = OuterComposer(); + // auto instance = composer.create_prover_instance(outer_decider_circuit); + // auto prover = composer.create_prover(instance); + // auto verifier = composer.create_verifier(instance); + // auto proof = prover.construct_proof(); + // bool verified = verifier.verify_proof(proof); + + // ASSERT(verified); + // } + // }; + + // static void test_tampered_decider_proof() + // { + // // Create two arbitrary circuits for the first round of folding + // InnerBuilder builder1; + + // create_inner_circuit(builder1); + // InnerBuilder builder2; + // builder2.add_public_variable(FF(1)); + // create_inner_circuit(builder2); + + // InnerComposer inner_composer = InnerComposer(); + // auto prover_instance_1 = inner_composer.create_prover_instance(builder1); + // auto prover_instance_2 = inner_composer.create_prover_instance(builder2); + // auto instances = std::vector>{ prover_instance_1, prover_instance_2 }; + + // auto accumulator = fold_and_verify_native(instances, inner_composer); + + // // Tamper with the accumulator by changing the target sum + // accumulator->target_sum = FF::random_element(); + + // // Create a decider proof for the relaxed instance obtained through folding + // auto inner_decider_prover = inner_composer.create_decider_prover(accumulator); + // auto inner_decider_proof = inner_decider_prover.construct_proof(); + + // // Create a decider verifier circuit for recursively verifying the decider proof + // OuterBuilder outer_decider_circuit; + // DeciderRecursiveVerifier decider_verifier{ &outer_decider_circuit }; + // decider_verifier.verify_proof(inner_decider_proof); + // info("Decider Recursive Verifier: num gates = ", outer_decider_circuit.num_gates); + + // // We expect the decider circuit check to fail due to the bad proof + // EXPECT_FALSE(outer_decider_circuit.check_circuit()); + // }; + + // static void test_tampered_accumulator() + // { + // // Create two arbitrary circuits for the first round of folding + // InnerBuilder builder1; + + // create_inner_circuit(builder1); + // InnerBuilder builder2; + // builder2.add_public_variable(FF(1)); + // create_inner_circuit(builder2); + + // InnerComposer inner_composer = InnerComposer(); + // auto prover_instance_1 = inner_composer.create_prover_instance(builder1); + // auto prover_instance_2 = inner_composer.create_prover_instance(builder2); + // auto instances = std::vector>{ prover_instance_1, prover_instance_2 }; + + // auto accumulator = fold_and_verify_native(instances, inner_composer); + + // // Create another circuit to do a second round of folding + // InnerBuilder builder3; + // create_inner_circuit(builder3); + // auto instance3 = inner_composer.create_prover_instance(builder3); + + // // Tamper with the accumulator + // instances = std::vector>{ accumulator, instance3 }; + // accumulator->prover_polynomials.w_l[1] = FF::random_element(); + + // // Generate a folding proof + // auto inner_folding_prover = inner_composer.create_folding_prover(instances); + // auto inner_folding_proof = inner_folding_prover.fold_instances(); + + // // Create a recursive folding verifier circuit for the folding proof of the two instances + // OuterBuilder outer_folding_circuit; + // FoldingRecursiveVerifier verifier{ &outer_folding_circuit }; + // verifier.verify_folding_proof(inner_folding_proof.folding_data); + // EXPECT_EQ(outer_folding_circuit.check_circuit(), false); + // }; }; -using FlavorTypes = testing::Types, - UltraRecursiveFlavor_>; +using FlavorTypes = testing::Types>; TYPED_TEST_SUITE(ProtoGalaxyRecursiveTests, FlavorTypes); TYPED_TEST(ProtoGalaxyRecursiveTests, InnerCircuit) @@ -387,20 +406,20 @@ TYPED_TEST(ProtoGalaxyRecursiveTests, RecursiveFoldingTest) TestFixture::test_recursive_folding(); } -TYPED_TEST(ProtoGalaxyRecursiveTests, FullProtogalaxyRecursiveTest) -{ +// TYPED_TEST(ProtoGalaxyRecursiveTests, FullProtogalaxyRecursiveTest) +// { - TestFixture::test_full_protogalaxy_recursive(); -} +// TestFixture::test_full_protogalaxy_recursive(); +// } -TYPED_TEST(ProtoGalaxyRecursiveTests, TamperedDeciderProof) -{ - TestFixture::test_tampered_decider_proof(); -} +// TYPED_TEST(ProtoGalaxyRecursiveTests, TamperedDeciderProof) +// { +// TestFixture::test_tampered_decider_proof(); +// } -TYPED_TEST(ProtoGalaxyRecursiveTests, TamperedAccumulator) -{ - TestFixture::test_tampered_accumulator(); -} +// TYPED_TEST(ProtoGalaxyRecursiveTests, TamperedAccumulator) +// { +// TestFixture::test_tampered_accumulator(); +// } } // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp new file mode 100644 index 00000000000..ce9c6d3449f --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp @@ -0,0 +1,44 @@ +#pragma once +#include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/relations/relation_parameters.hpp" +#include "barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp" + +namespace bb::stdlib::recursion::honk { +template struct RecursiveVerifierInstances_ { + using Flavor = Flavor_; + using Builder = typename Flavor::CircuitBuilder; + using VerificationKey = typename Flavor::VerificationKey; + using NativeVerificationKey = typename Flavor::NativeVerificationKey; + using Instance = RecursiveVerifierInstance_; + using NativeInstance = bb::VerifierInstance_; + using ArrayType = std::array, NUM_>; + + public: + static constexpr size_t NUM = NUM_; + static constexpr size_t BATCHED_EXTENDED_LENGTH = (Flavor::MAX_TOTAL_RELATION_LENGTH - 1 + NUM - 1) * (NUM - 1) + 1; + ArrayType _data; + std::shared_ptr const& operator[](size_t idx) const { return _data[idx]; } + typename ArrayType::iterator begin() { return _data.begin(); }; + typename ArrayType::iterator end() { return _data.end(); }; + Builder* builder; + // RecursiveVerifierInstances_() = default; + + RecursiveVerifierInstances_(Builder* builder, + std::shared_ptr accumulator, + std::vector> vks) + : builder(builder) + { + ASSERT(vks.size() == NUM - 1); + if (accumulator->is_accumulator) { + _data[0] = std::make_shared(builder, accumulator); + } else { + _data[0] = std::make_shared(builder, accumulator->verification_key); + } + size_t idx = 1; + for (auto vk : vks) { + _data[idx] = std::make_shared(builder, vk); + idx++; + } + } +}; +} // namespace bb::stdlib::recursion::honk diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp new file mode 100644 index 00000000000..f3ae2324c12 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp @@ -0,0 +1,140 @@ +#pragma once +#include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/relations/relation_parameters.hpp" +#include "barretenberg/sumcheck/instance/verifier_instance.hpp" + +namespace bb::stdlib::recursion::honk { +template class RecursiveVerifierInstance_ { + public: + using FF = typename Flavor::FF; + using NativeFF = typename Flavor::Curve::ScalarFieldNative; + using Commitment = typename Flavor::Commitment; + using VerificationKey = typename Flavor::VerificationKey; + using NativeVerificationKey = typename Flavor::NativeVerificationKey; + using WitnessCommitments = typename Flavor::WitnessCommitments; + using CommitmentLabels = typename Flavor::CommitmentLabels; + using RelationSeparator = typename Flavor::RelationSeparator; + using Builder = typename Flavor::CircuitBuilder; + using NativeFlavor = typename Flavor::NativeFlavor; + using VerifierInstance = bb::VerifierInstance_; + + Builder* builder; + + std::shared_ptr verification_key; + std::vector public_inputs; + size_t pub_inputs_offset = 0; + size_t public_input_size; + size_t instance_size; + size_t log_instance_size; + RelationParameters relation_parameters; + RelationSeparator alphas; + bool is_accumulator = false; + + // The folding parameters (\vec{β}, e) which are set for accumulators (i.e. relaxed instances). + std::vector gate_challenges; + FF target_sum; + + WitnessCommitments witness_commitments; + CommitmentLabels commitment_labels; + + RecursiveVerifierInstance_(Builder* builder) + : builder(builder){}; + RecursiveVerifierInstance_(Builder* builder, std::shared_ptr vk) + : builder(builder) + , verification_key(std::make_shared(builder, vk)) + {} + + RecursiveVerifierInstance_(Builder* builder, const std::shared_ptr& instance) + : pub_inputs_offset((instance->pub_inputs_offset)) + , public_input_size((instance->public_input_size)) + , instance_size((instance->instance_size)) + , log_instance_size((instance->log_instance_size)) + , is_accumulator(bool(instance->is_accumulator)) + { + + size_t public_input_idx = 0; + public_inputs = std::vector(public_input_size); + for (auto public_input : instance->public_inputs) { + public_inputs[public_input_idx] = FF::from_witness(builder, public_input); + } + verification_key = std::make_shared(instance_size, public_input_size); + auto other_vks = instance->verification_key->get_all(); + size_t vk_idx = 0; + for (auto& vk : verification_key->get_all()) { + vk = Commitment::from_witness(builder, other_vks[vk_idx]); + vk_idx++; + } + for (size_t alpha_idx = 0; alpha_idx < alphas.size(); alpha_idx++) { + alphas[alpha_idx] = FF::from_witness(builder, instance->alphas[alpha_idx]); + } + + auto other_comms = instance->witness_commitments.get_all(); + size_t comm_idx = 0; + for (auto& comm : witness_commitments.get_all()) { + comm = Commitment::from_witness(builder, other_comms[comm_idx]); + comm_idx++; + } + target_sum = FF::from_witness(builder, instance->target_sum); + + size_t challenge_idx = 0; + gate_challenges = std::vector(instance->gate_challenges.size()); + for (auto& challenge : gate_challenges) { + challenge = FF::from_witness(builder, instance->gate_challenges[challenge_idx]); + challenge_idx++; + } + relation_parameters.eta = FF::from_witness(builder, instance->relation_parameters.eta); + relation_parameters.beta = FF::from_witness(builder, instance->relation_parameters.beta); + relation_parameters.gamma = FF::from_witness(builder, instance->relation_parameters.gamma); + relation_parameters.public_input_delta = + FF::from_witness(builder, instance->relation_parameters.public_input_delta); + relation_parameters.lookup_grand_product_delta = + FF::from_witness(builder, instance->relation_parameters.lookup_grand_product_delta); + } + + VerifierInstance get_value() + { + VerifierInstance inst; + inst.pub_inputs_offset = pub_inputs_offset; + inst.public_input_size = public_input_size; + inst.log_instance_size = log_instance_size; + inst.instance_size = instance_size; + inst.is_accumulator = is_accumulator; + + size_t public_input_idx = 0; + inst.public_inputs = std::vector(public_input_size); + for (auto public_input : public_inputs) { + inst.public_inputs[public_input_idx] = public_input.get_value(); + } + inst.verification_key = std::make_shared(instance_size, public_input_size); + size_t vk_idx = 0; + for (auto& vk : verification_key->get_all()) { + inst.verification_key->get_all()[vk_idx] = vk.get_value(); + vk_idx++; + } + for (size_t alpha_idx = 0; alpha_idx < alphas.size(); alpha_idx++) { + inst.alphas[alpha_idx] = alphas[alpha_idx].get_value(); + } + + size_t comm_idx = 0; + for (auto& comm : witness_commitments.get_all()) { + inst.witness_commitments.get_all()[comm_idx] = comm.get_value(); + comm_idx++; + } + inst.target_sum = target_sum.get_value(); + + size_t challenge_idx = 0; + inst.gate_challenges = std::vector(gate_challenges.size()); + for (auto& challenge : inst.gate_challenges) { + challenge = gate_challenges[challenge_idx].get_value(); + challenge_idx++; + } + inst.relation_parameters.eta = relation_parameters.eta.get_value(); + inst.relation_parameters.beta = relation_parameters.beta.get_value(); + inst.relation_parameters.gamma = relation_parameters.gamma.get_value(); + inst.relation_parameters.public_input_delta = relation_parameters.public_input_delta.get_value(); + inst.relation_parameters.lookup_grand_product_delta = + relation_parameters.lookup_grand_product_delta.get_value(); + return inst; + } +}; +} // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/verifier.test.cpp index 7203a67a2c2..cef987ae9da 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/verifier.test.cpp @@ -132,20 +132,21 @@ template class RecursiveVerifierTest : public testing::Te // Compute native verification key InnerComposer inner_composer; - auto instance = inner_composer.create_instance(inner_circuit); + auto instance = inner_composer.create_prover_instance(inner_circuit); + auto verification_key = inner_composer.compute_verification_key(instance); auto prover = inner_composer.create_prover(instance); // A prerequisite for computing VK // Instantiate the recursive verifier using the native verification key - RecursiveVerifier verifier{ &outer_circuit, instance->verification_key }; + RecursiveVerifier verifier{ &outer_circuit, verification_key }; // Spot check some values in the recursive VK to ensure it was constructed correctly - EXPECT_EQ(verifier.key->circuit_size, instance->verification_key->circuit_size); - EXPECT_EQ(verifier.key->log_circuit_size, instance->verification_key->log_circuit_size); - EXPECT_EQ(verifier.key->num_public_inputs, instance->verification_key->num_public_inputs); - EXPECT_EQ(verifier.key->q_m.get_value(), instance->verification_key->q_m); - EXPECT_EQ(verifier.key->q_r.get_value(), instance->verification_key->q_r); - EXPECT_EQ(verifier.key->sigma_1.get_value(), instance->verification_key->sigma_1); - EXPECT_EQ(verifier.key->id_3.get_value(), instance->verification_key->id_3); + EXPECT_EQ(verifier.key->circuit_size, verification_key->circuit_size); + EXPECT_EQ(verifier.key->log_circuit_size, verification_key->log_circuit_size); + EXPECT_EQ(verifier.key->num_public_inputs, verification_key->num_public_inputs); + EXPECT_EQ(verifier.key->q_m.get_value(), verification_key->q_m); + EXPECT_EQ(verifier.key->q_r.get_value(), verification_key->q_r); + EXPECT_EQ(verifier.key->sigma_1.get_value(), verification_key->sigma_1); + EXPECT_EQ(verifier.key->id_3.get_value(), verification_key->id_3); } /** @@ -160,13 +161,14 @@ template class RecursiveVerifierTest : public testing::Te // Generate a proof over the inner circuit InnerComposer inner_composer; - auto instance = inner_composer.create_instance(inner_circuit); + auto instance = inner_composer.create_prover_instance(inner_circuit); + auto verification_key = inner_composer.compute_verification_key(instance); auto inner_prover = inner_composer.create_prover(instance); auto inner_proof = inner_prover.construct_proof(); // Create a recursive verification circuit for the proof of the inner circuit OuterBuilder outer_circuit; - RecursiveVerifier verifier{ &outer_circuit, instance->verification_key }; + RecursiveVerifier verifier{ &outer_circuit, verification_key }; auto pairing_points = verifier.verify_proof(inner_proof); info("Recursive Verifier Ultra: num gates = ", outer_circuit.num_gates); @@ -175,7 +177,7 @@ template class RecursiveVerifierTest : public testing::Te // Check 1: Perform native verification then perform the pairing on the outputs of the recursive // verifier and check that the result agrees. - auto native_verifier = inner_composer.create_verifier(instance); + auto native_verifier = inner_composer.create_verifier(verification_key); auto native_result = native_verifier.verify_proof(inner_proof); auto recursive_result = native_verifier.pcs_verification_key->pairing_check(pairing_points[0].get_value(), pairing_points[1].get_value()); @@ -192,9 +194,10 @@ template class RecursiveVerifierTest : public testing::Te // Check 3: Construct and verify a proof of the recursive verifier circuit { auto composer = get_outer_composer(); - auto instance = composer.create_instance(outer_circuit); + auto instance = composer.create_prover_instance(outer_circuit); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); auto proof = prover.construct_proof(); bool verified = verifier.verify_proof(proof); @@ -216,7 +219,8 @@ template class RecursiveVerifierTest : public testing::Te // Generate a proof over the inner circuit InnerComposer inner_composer; - auto instance = inner_composer.create_instance(inner_circuit); + auto instance = inner_composer.create_prover_instance(inner_circuit); + auto verification_key = inner_composer.compute_verification_key(instance); auto inner_prover = inner_composer.create_prover(instance); auto inner_proof = inner_prover.construct_proof(); @@ -228,7 +232,7 @@ template class RecursiveVerifierTest : public testing::Te // Create a recursive verification circuit for the proof of the inner circuit OuterBuilder outer_circuit; - RecursiveVerifier verifier{ &outer_circuit, instance->verification_key }; + RecursiveVerifier verifier{ &outer_circuit, verification_key }; verifier.verify_proof(inner_proof); // We expect the circuit check to fail due to the bad proof diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp index db792938bd5..9f3ee582021 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp @@ -99,10 +99,14 @@ template struct VerifierInstances_ { std::shared_ptr const& operator[](size_t idx) const { return _data[idx]; } typename ArrayType::iterator begin() { return _data.begin(); }; typename ArrayType::iterator end() { return _data.end(); }; + VerifierInstances_() = default; - VerifierInstances_() + VerifierInstances_(std::vector> data) { - std::generate(_data.begin(), _data.end(), []() { return std::make_unique(); }); + ASSERT(data.size() == NUM); + for (size_t idx = 0; idx < data.size(); idx++) { + _data[idx] = std::move(data[idx]); + } }; }; } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index 3ab3a2da938..10a862ff2ce 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -30,7 +30,7 @@ template class ProverInstance_ { public: std::shared_ptr proving_key; - std::shared_ptr verification_key; + // std::shared_ptr verification_key; ProverPolynomials prover_polynomials; WitnessCommitments witness_commitments; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 7fffcb15269..09e2f41de68 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -123,7 +123,7 @@ template class SumcheckProver { zip_view(multivariate_evaluations.get_all(), partially_evaluated_polynomials.get_all())) { eval = poly[0]; } - transcript->send_to_verifier("Sumcheck:evaluations", multivariate_evaluations.get_all()); + transcript->send_to_verifier("Sumcheck:evaluations", multivariate_evaluations); return { multivariate_challenge, multivariate_evaluations }; }; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp index bbec6530151..d8759ba07a0 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/databus_composer.test.cpp @@ -84,10 +84,11 @@ TEST_F(DataBusComposerTests, CallDataRead) auto composer = GoblinUltraComposer(); // Construct and verify Honk proof - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); // For debugging, use "instance_inspector::print_databus_info(instance)" + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); auto proof = prover.construct_proof(); bool verified = verifier.verify_proof(proof); EXPECT_TRUE(verified); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp index 7252076bab7..ef4938a5851 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_composer.test.cpp @@ -62,9 +62,10 @@ class GoblinUltraHonkComposerTests : public ::testing::Test { */ bool construct_and_verify_honk_proof(auto& composer, auto& builder) { - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); auto proof = prover.construct_proof(); bool verified = verifier.verify_proof(proof); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp index 5e97fd5bfaf..6190d640ac1 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/goblin_ultra_transcript.test.cpp @@ -145,7 +145,7 @@ TEST_F(GoblinUltraTranscriptTests, ProverManifestConsistency) // Automatically generate a transcript manifest by constructing a proof auto composer = GoblinUltraComposer(); - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); auto prover = composer.create_prover(instance); auto proof = prover.construct_proof(); @@ -172,12 +172,13 @@ TEST_F(GoblinUltraTranscriptTests, VerifierManifestConsistency) // Automatically generate a transcript manifest in the prover by constructing a proof auto composer = GoblinUltraComposer(); - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); auto proof = prover.construct_proof(); // Automatically generate a transcript manifest in the verifier by verifying a proof - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); verifier.verify_proof(proof); // Check consistency between the manifests generated by the prover and verifier @@ -223,10 +224,11 @@ TEST_F(GoblinUltraTranscriptTests, StructureTest) // Automatically generate a transcript manifest by constructing a proof auto composer = GoblinUltraComposer(); - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); auto proof = prover.construct_proof(); - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); EXPECT_TRUE(verifier.verify_proof(proof)); // try deserializing and serializing with no changes and check proof is still valid diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp index 42f5757c1e3..c060f3cc60c 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp @@ -14,9 +14,11 @@ template class ProtoGalaxyTests : public testing::Test { public: using Composer = UltraComposer_; using VerificationKey = typename Flavor::VerificationKey; - using Instance = ProverInstance_; - using Instances = ProverInstances_; - using ProtoGalaxyProver = ProtoGalaxyProver_; + using ProverInstance = ProverInstance_; + using ProverInstances = ProverInstances_; + using VerifierInstance = VerifierInstance_; + using VerifierInstances = VerifierInstances_; + using ProtoGalaxyProver = ProtoGalaxyProver_; using FF = typename Flavor::FF; using Affine = typename Flavor::Commitment; using Projective = typename Flavor::GroupElement; @@ -59,21 +61,20 @@ template class ProtoGalaxyTests : public testing::Test { return full_polynomials; } - static std::shared_ptr fold_and_verify(const std::vector>& instances, - Composer& composer, - bool expected_result) + static std::tuple, std::shared_ptr> fold_and_verify( + const std::vector>& prover_instances, + const std::vector>& verifier_instances, + Composer& composer) { - auto folding_prover = composer.create_folding_prover(instances); - auto folding_verifier = composer.create_folding_verifier(); - - auto proof = folding_prover.fold_instances(); - auto next_accumulator = proof.accumulator; - auto res = folding_verifier.verify_folding_proof(proof.folding_data); - EXPECT_EQ(res, expected_result); - return next_accumulator; + auto folding_prover = composer.create_folding_prover(prover_instances); + auto folding_verifier = composer.create_folding_verifier(verifier_instances); + + auto [prover_accumulator, folding_proof] = folding_prover.fold_instances(); + auto verifier_accumulator = folding_verifier.verify_folding_proof(folding_proof); + return { prover_accumulator, verifier_accumulator }; } - static void check_accumulator_target_sum_manual(std::shared_ptr& accumulator, bool expected_result) + static void check_accumulator_target_sum_manual(std::shared_ptr& accumulator, bool expected_result) { auto instance_size = accumulator->instance_size; auto expected_honk_evals = ProtoGalaxyProver::compute_full_honk_evaluations( @@ -90,10 +91,13 @@ template class ProtoGalaxyTests : public testing::Test { EXPECT_EQ(accumulator->target_sum == expected_target_sum, expected_result); } - static void decide_and_verify(std::shared_ptr& accumulator, Composer& composer, bool expected_result) + static void decide_and_verify(std::shared_ptr& prover_accumulator, + std::shared_ptr& verifier_accumulator, + Composer& composer, + bool expected_result) { - auto decider_prover = composer.create_decider_prover(accumulator); - auto decider_verifier = composer.create_decider_verifier(accumulator); + auto decider_prover = composer.create_decider_prover(prover_accumulator); + auto decider_verifier = composer.create_decider_verifier(verifier_accumulator); auto decider_proof = decider_prover.construct_proof(); auto verified = decider_verifier.verify_proof(decider_proof); EXPECT_EQ(verified, expected_result); @@ -101,8 +105,8 @@ template class ProtoGalaxyTests : public testing::Test { /** * @brief For a valid circuit, ensures that computing the value of the full UH/UGH relation at each row in its - * execution trace (with the contribution of the linearly dependent one added tot he first row, in case of Goblin) - * will be 0. + * execution trace (with the contribution of the linearly dependent one added tot he first row, in case of + * Goblin) will be 0. * */ static void test_full_honk_evaluations_valid_circuit() @@ -111,7 +115,7 @@ template class ProtoGalaxyTests : public testing::Test { construct_circuit(builder); auto composer = Composer(); - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); instance->initialize_prover_polynomials(); auto eta = FF::random_element(); @@ -136,8 +140,8 @@ template class ProtoGalaxyTests : public testing::Test { } /** - * @brief Check the coefficients of the perturbator computed from dummy \vec{β}, \vec{δ} and f_i(ω) will be the same - * as if computed manually. + * @brief Check the coefficients of the perturbator computed from dummy \vec{β}, \vec{δ} and f_i(ω) will be the + * same as if computed manually. * */ static void test_pertubator_coefficients() @@ -191,7 +195,7 @@ template class ProtoGalaxyTests : public testing::Test { target_sum += full_honk_evals[i] * pow_beta[i]; } - auto accumulator = std::make_shared(); + auto accumulator = std::make_shared(); accumulator->prover_polynomials = std::move(full_polynomials); accumulator->gate_challenges = betas; accumulator->target_sum = target_sum; @@ -206,8 +210,8 @@ template class ProtoGalaxyTests : public testing::Test { } /** - * @brief Manually compute the expected evaluations of the combiner quotient, given evaluations of the combiner and - * check them against the evaluations returned by the function. + * @brief Manually compute the expected evaluations of the combiner quotient, given evaluations of the combiner + * and check them against the evaluations returned by the function. * */ static void test_combiner_quotient() @@ -239,25 +243,22 @@ template class ProtoGalaxyTests : public testing::Test { } /** - * @brief For two dummy instances with their relation parameter η set, check that combining them in a univariate, - * barycentrially extended to the desired number of evaluations, is performed correctly. + * @brief For two dummy instances with their relation parameter η set, check that combining them in a + * univariate, barycentrially extended to the desired number of evaluations, is performed correctly. * */ static void test_combine_relation_parameters() { - using Instances = ProverInstances_; - using Instance = typename Instances::Instance; - Builder builder1; - auto instance1 = std::make_shared(builder1); + auto instance1 = std::make_shared(builder1); instance1->relation_parameters.eta = 1; Builder builder2; builder2.add_variable(3); - auto instance2 = std::make_shared(builder2); + auto instance2 = std::make_shared(builder2); instance2->relation_parameters.eta = 3; - Instances instances{ { instance1, instance2 } }; + ProverInstances instances{ { instance1, instance2 } }; ProtoGalaxyProver::combine_relation_parameters(instances); bb::Univariate expected_eta{ { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23 } }; @@ -270,19 +271,16 @@ template class ProtoGalaxyTests : public testing::Test { */ static void test_combine_alpha() { - using Instances = ProverInstances_; - using Instance = typename Instances::Instance; - Builder builder1; - auto instance1 = std::make_shared(builder1); + auto instance1 = std::make_shared(builder1); instance1->alphas.fill(2); Builder builder2; builder2.add_variable(3); - auto instance2 = std::make_shared(builder2); + auto instance2 = std::make_shared(builder2); instance2->alphas.fill(4); - Instances instances{ { instance1, instance2 } }; + ProverInstances instances{ { instance1, instance2 } }; ProtoGalaxyProver::combine_alpha(instances); bb::Univariate expected_alpha{ { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26 } }; @@ -301,26 +299,29 @@ template class ProtoGalaxyTests : public testing::Test { auto builder_1 = typename Flavor::CircuitBuilder(); construct_circuit(builder_1); - auto instance_1 = composer.create_instance(builder_1); + auto prover_instance_1 = composer.create_prover_instance(builder_1); + auto verifier_instance_1 = composer.create_verifier_instance(prover_instance_1); auto builder_2 = typename Flavor::CircuitBuilder(); construct_circuit(builder_2); + auto prover_instance_2 = composer.create_prover_instance(builder_2); + auto verifier_instance_2 = composer.create_verifier_instance(prover_instance_2); + auto [prover_accumulator, verifier_accumulator] = fold_and_verify( + { prover_instance_1, prover_instance_2 }, { verifier_instance_1, verifier_instance_2 }, composer); - auto instance_2 = composer.create_instance(builder_2); - - auto instances = std::vector>{ instance_1, instance_2 }; - auto first_accumulator = fold_and_verify(instances, composer, true); - check_accumulator_target_sum_manual(first_accumulator, true); + check_accumulator_target_sum_manual(prover_accumulator, true); auto builder_3 = typename Flavor::CircuitBuilder(); construct_circuit(builder_3); - auto instance_3 = composer.create_instance(builder_3); + auto prover_instance_3 = composer.create_prover_instance(builder_3); + auto verifier_instance_3 = composer.create_verifier_instance(prover_instance_3); + + auto [prover_accumulator_2, verifier_accumulator_2] = fold_and_verify( + { prover_accumulator, prover_instance_3 }, { verifier_accumulator, verifier_instance_3 }, composer); - instances = std::vector>{ first_accumulator, instance_3 }; - auto second_accumulator = fold_and_verify(instances, composer, true); - check_accumulator_target_sum_manual(second_accumulator, true); + check_accumulator_target_sum_manual(prover_accumulator_2, true); - decide_and_verify(second_accumulator, composer, true); + decide_and_verify(prover_accumulator_2, verifier_accumulator_2, composer, true); } /** @@ -330,67 +331,67 @@ template class ProtoGalaxyTests : public testing::Test { static void test_tampered_commitment() { auto composer = Composer(); - auto builder_1 = typename Flavor::CircuitBuilder(); construct_circuit(builder_1); - auto instance_1 = composer.create_instance(builder_1); + auto prover_instance_1 = composer.create_prover_instance(builder_1); + auto verifier_instance_1 = composer.create_verifier_instance(prover_instance_1); auto builder_2 = typename Flavor::CircuitBuilder(); construct_circuit(builder_2); + auto prover_instance_2 = composer.create_prover_instance(builder_2); + auto verifier_instance_2 = composer.create_verifier_instance(prover_instance_2); + auto [prover_accumulator, verifier_accumulator] = fold_and_verify( + { prover_instance_1, prover_instance_2 }, { verifier_instance_1, verifier_instance_2 }, composer); + check_accumulator_target_sum_manual(prover_accumulator, true); - auto instance_2 = composer.create_instance(builder_2); - - auto instances = std::vector>{ instance_1, instance_2 }; - auto first_accumulator = fold_and_verify(instances, composer, true); - check_accumulator_target_sum_manual(first_accumulator, true); - + verifier_accumulator->witness_commitments.w_l = Projective(Affine::random_element()); auto builder_3 = typename Flavor::CircuitBuilder(); construct_circuit(builder_3); - auto instance_3 = composer.create_instance(builder_3); + auto prover_instance_3 = composer.create_prover_instance(builder_3); + auto verifier_instance_3 = composer.create_verifier_instance(prover_instance_3); - // tampering with the commitment should cause the decider to fail - first_accumulator->witness_commitments.w_l = Projective(Affine::random_element()); - instances = std::vector>{ first_accumulator, instance_3 }; + auto [prover_accumulator_2, verifier_accumulator_2] = fold_and_verify( + { prover_accumulator, prover_instance_3 }, { verifier_accumulator, verifier_instance_3 }, composer); - auto second_accumulator = fold_and_verify(instances, composer, true); + check_accumulator_target_sum_manual(prover_accumulator_2, true); - decide_and_verify(second_accumulator, composer, false); + decide_and_verify(prover_accumulator_2, verifier_accumulator_2, composer, false); } /** - * @brief Ensure tampering an accumulator and then calling fold again causes both the folding verification and - * decider verification to fail. + * @brief Ensure tampering an accumulator and then calling fold again causes the target sums in the prover and + * verifier accumulators to be different and decider verification to fail. * */ static void test_tampered_accumulator_polynomial() { auto composer = Composer(); - auto builder_1 = typename Flavor::CircuitBuilder(); construct_circuit(builder_1); - auto instance_1 = composer.create_instance(builder_1); + auto prover_instance_1 = composer.create_prover_instance(builder_1); + auto verifier_instance_1 = composer.create_verifier_instance(prover_instance_1); auto builder_2 = typename Flavor::CircuitBuilder(); construct_circuit(builder_2); - - auto instance_2 = composer.create_instance(builder_2); - - auto instances = std::vector>{ instance_1, instance_2 }; - auto first_accumulator = fold_and_verify(instances, composer, true); - check_accumulator_target_sum_manual(first_accumulator, true); + auto prover_instance_2 = composer.create_prover_instance(builder_2); + auto verifier_instance_2 = composer.create_verifier_instance(prover_instance_2); + auto [prover_accumulator, verifier_accumulator] = fold_and_verify( + { prover_instance_1, prover_instance_2 }, { verifier_instance_1, verifier_instance_2 }, composer); + check_accumulator_target_sum_manual(prover_accumulator, true); auto builder_3 = typename Flavor::CircuitBuilder(); construct_circuit(builder_3); - auto instance_3 = composer.create_instance(builder_3); + auto prover_instance_3 = composer.create_prover_instance(builder_3); + auto verifier_instance_3 = composer.create_verifier_instance(prover_instance_3); - // tampering with accumulator's polynomial should cause both folding and deciding to fail - instances = std::vector>{ first_accumulator, instance_3 }; - first_accumulator->prover_polynomials.w_l[1] = FF::random_element(); - auto second_accumulator = fold_and_verify(instances, composer, false); + prover_accumulator->prover_polynomials.w_l[1] = FF::random_element(); + auto [prover_accumulator_2, verifier_accumulator_2] = fold_and_verify( + { prover_accumulator, prover_instance_3 }, { verifier_accumulator, verifier_instance_3 }, composer); - decide_and_verify(second_accumulator, composer, false); + EXPECT_EQ(prover_accumulator_2->target_sum == verifier_accumulator_2->target_sum, false); + decide_and_verify(prover_accumulator_2, verifier_accumulator_2, composer, false); } }; } // namespace diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp index 2b5ec50f37e..a52bbbe240b 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp @@ -268,7 +268,7 @@ TEST_F(RelationCorrectnessTests, UltraRelationCorrectness) // Create a prover (it will compute proving key and witness) auto composer = UltraComposer(); - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); auto proving_key = instance->proving_key; auto circuit_size = proving_key->circuit_size; @@ -321,7 +321,7 @@ TEST_F(RelationCorrectnessTests, GoblinUltraRelationCorrectness) // Create a prover (it will compute proving key and witness) auto composer = GoblinUltraComposer(); - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); auto proving_key = instance->proving_key; auto circuit_size = proving_key->circuit_size; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp index 1ec8602c4fb..34515508931 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/sumcheck.test.cpp @@ -149,7 +149,7 @@ TEST_F(SumcheckTestsRealCircuit, Ultra) // Create a prover (it will compute proving key and witness) auto composer = UltraComposer(); - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); // Generate eta, beta and gamma FF eta = FF::random_element(); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp index ae42bd4366a..b745f001c5b 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp @@ -12,12 +12,9 @@ namespace bb { * @return Pointer to the resulting verification key of the Instance. * */ template -void UltraComposer_::compute_verification_key(const std::shared_ptr>& instance) +std::shared_ptr UltraComposer_::compute_verification_key( + const std::shared_ptr>& instance) { - if (instance->verification_key) { - return; - } - auto& proving_key = instance->proving_key; auto verification_key = @@ -61,23 +58,31 @@ void UltraComposer_::compute_verification_key(const std::shared_ptrq_poseidon2_internal = commitment_key->commit(proving_key->q_poseidon2_internal); } - instance->verification_key = std::move(verification_key); + return std::move(verification_key); } template -std::shared_ptr> UltraComposer_::create_instance(CircuitBuilder& circuit) +std::shared_ptr> UltraComposer_::create_prover_instance(CircuitBuilder& circuit) { circuit.add_gates_to_ensure_all_polys_are_non_zero(); circuit.finalize_circuit(); - auto instance = std::make_shared(circuit); - commitment_key = compute_commitment_key(instance->proving_key->circuit_size); + auto instance = std::make_shared(circuit); + instance->instance_size = instance->proving_key->circuit_size; + commitment_key = compute_commitment_key(instance->instance_size); // hm + return instance; +} - compute_verification_key(instance); +template +std::shared_ptr> UltraComposer_::create_verifier_instance( + std::shared_ptr>& prover_instance) +{ + auto instance = std::make_shared(); + instance->verification_key = compute_verification_key(prover_instance); return instance; } template -UltraProver_ UltraComposer_::create_prover(const std::shared_ptr& instance, +UltraProver_ UltraComposer_::create_prover(const std::shared_ptr& instance, const std::shared_ptr& transcript) { UltraProver_ output_state(instance, commitment_key, transcript); @@ -86,10 +91,9 @@ UltraProver_ UltraComposer_::create_prover(const std::shared_ptr } template -UltraVerifier_ UltraComposer_::create_verifier(const std::shared_ptr& instance, +UltraVerifier_ UltraComposer_::create_verifier(const std::shared_ptr& verification_key, const std::shared_ptr& transcript) { - auto& verification_key = instance->verification_key; UltraVerifier_ output_state(transcript, verification_key); auto pcs_verification_key = std::make_unique(verification_key->circuit_size, crs_factory_); output_state.pcs_verification_key = std::move(pcs_verification_key); @@ -98,7 +102,7 @@ UltraVerifier_ UltraComposer_::create_verifier(const std::shared } template -DeciderProver_ UltraComposer_::create_decider_prover(const std::shared_ptr& accumulator, +DeciderProver_ UltraComposer_::create_decider_prover(const std::shared_ptr& accumulator, const std::shared_ptr& transcript) { commitment_key = compute_commitment_key(accumulator->instance_size); @@ -109,7 +113,7 @@ DeciderProver_ UltraComposer_::create_decider_prover(const std:: template DeciderProver_ UltraComposer_::create_decider_prover( - const std::shared_ptr& accumulator, + const std::shared_ptr& accumulator, const std::shared_ptr& commitment_key, const std::shared_ptr& transcript) { @@ -119,11 +123,10 @@ DeciderProver_ UltraComposer_::create_decider_prover( } template -DeciderVerifier_ UltraComposer_::create_decider_verifier(const std::shared_ptr& accumulator, - const std::shared_ptr& transcript) +DeciderVerifier_ UltraComposer_::create_decider_verifier( + const std::shared_ptr& accumulator, const std::shared_ptr& transcript) { - auto& verification_key = accumulator->verification_key; - DeciderVerifier_ output_state(transcript, verification_key); + DeciderVerifier_ output_state(transcript, accumulator); auto pcs_verification_key = std::make_unique(accumulator->instance_size, crs_factory_); output_state.pcs_verification_key = std::move(pcs_verification_key); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.hpp index 28a95f03145..7738709b7f6 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.hpp @@ -11,9 +11,8 @@ #include "barretenberg/ultra_honk/ultra_verifier.hpp" namespace bb { -template class UltraComposer_ { +template class UltraComposer_ { public: - using Flavor = Flavor_; using CircuitBuilder = typename Flavor::CircuitBuilder; using ProvingKey = typename Flavor::ProvingKey; using VerificationKey = typename Flavor::VerificationKey; @@ -21,7 +20,7 @@ template class UltraComposer_ { using CommitmentKey = typename Flavor::CommitmentKey; using VerifierCommitmentKey = typename Flavor::VerifierCommitmentKey; using ProverInstance = ProverInstance_; - using Instance = ProverInstance; + using VerifierInstance = VerifierInstance_; using FF = typename Flavor::FF; using Transcript = typename Flavor::Transcript; using CRSFactory = srs::factories::CrsFactory; @@ -58,41 +57,49 @@ template class UltraComposer_ { return commitment_key; }; - std::shared_ptr create_instance(CircuitBuilder& circuit); + std::shared_ptr create_prover_instance(CircuitBuilder&); - UltraProver_ create_prover(const std::shared_ptr&, + /** + * @brief Create a verifier instance object. + * + * @details Currently use prover instance + */ + std::shared_ptr create_verifier_instance(std::shared_ptr&); + + UltraProver_ create_prover(const std::shared_ptr&, const std::shared_ptr& transcript = std::make_shared()); UltraVerifier_ create_verifier( - const std::shared_ptr&, + const std::shared_ptr&, const std::shared_ptr& transcript = std::make_shared()); DeciderProver_ create_decider_prover( - const std::shared_ptr&, + const std::shared_ptr&, const std::shared_ptr& transcript = std::make_shared()); DeciderProver_ create_decider_prover( - const std::shared_ptr&, + const std::shared_ptr&, const std::shared_ptr&, const std::shared_ptr& transcript = std::make_shared()); DeciderVerifier_ create_decider_verifier( - const std::shared_ptr&, + const std::shared_ptr&, const std::shared_ptr& transcript = std::make_shared()); UltraVerifier_ create_verifier(CircuitBuilder& circuit); UltraVerifier_ create_ultra_with_keccak_verifier(CircuitBuilder& circuit); - ProtoGalaxyProver_ create_folding_prover(const std::vector>& instances) + ProtoGalaxyProver_ create_folding_prover( + const std::vector>& instances) { ProtoGalaxyProver_ output_state(instances, commitment_key); return output_state; }; - ProtoGalaxyVerifier_ create_folding_verifier() - { - auto insts = VerifierInstances(); - ProtoGalaxyVerifier_ output_state(insts); + ProtoGalaxyVerifier_ create_folding_verifier( + const std::vector>& instances) + { + ProtoGalaxyVerifier_ output_state(instances); return output_state; }; @@ -102,7 +109,7 @@ template class UltraComposer_ { * * @param inst */ - void compute_verification_key(const std::shared_ptr&); + std::shared_ptr compute_verification_key(const std::shared_ptr&); }; // TODO(#532): this pattern is weird; is this not instantiating the templates? diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.test.cpp index 205a67aad24..514b2b69783 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.test.cpp @@ -33,9 +33,10 @@ std::vector add_variables(auto& circuit_builder, std::vector v void prove_and_verify(auto& circuit_builder, auto& composer, bool expected_result) { - auto instance = composer.create_instance(circuit_builder); + auto instance = composer.create_prover_instance(circuit_builder); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); auto proof = prover.construct_proof(); bool verified = verifier.verify_proof(proof); EXPECT_EQ(verified, expected_result); @@ -67,7 +68,7 @@ TEST_F(UltraHonkComposerTests, ANonZeroPolynomialIsAGoodPolynomial) auto circuit_builder = UltraCircuitBuilder(); auto composer = UltraComposer(); - auto instance = composer.create_instance(circuit_builder); + auto instance = composer.create_prover_instance(circuit_builder); auto prover = composer.create_prover(instance); auto proof = prover.construct_proof(); auto proving_key = instance->proving_key; @@ -198,9 +199,10 @@ TEST_F(UltraHonkComposerTests, create_gates_from_plookup_accumulators) } } auto composer = UltraComposer(); - auto instance = composer.create_instance(circuit_builder); + auto instance = composer.create_prover_instance(circuit_builder); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); auto proof = prover.construct_proof(); bool result = verifier.verify_proof(proof); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp index e4630c377ea..27acb7dd432 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp @@ -96,7 +96,7 @@ template void UltraProver_::execute_sorted_list_a instance->compute_sorted_accumulator_polynomials(eta); auto& witness_commitments = instance->witness_commitments; - // Commit to the sorted witness-table accumulator and the finalized (i.e. with memory records) fourth wire + // Commit to the sorted withness-table accumulator and the finalized (i.e. with memory records) fourth wire // polynomial witness_commitments.sorted_accum = commitment_key->commit(instance->prover_polynomials.sorted_accum); witness_commitments.w_4 = commitment_key->commit(instance->prover_polynomials.w_4); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp index fd6ccf7c148..1e5409c1e28 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_transcript.test.cpp @@ -131,7 +131,7 @@ TEST_F(UltraTranscriptTests, ProverManifestConsistency) // Automatically generate a transcript manifest by constructing a proof auto composer = UltraComposer(); - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); auto prover = composer.create_prover(instance); auto proof = prover.construct_proof(); @@ -158,12 +158,13 @@ TEST_F(UltraTranscriptTests, VerifierManifestConsistency) // Automatically generate a transcript manifest in the prover by constructing a proof auto composer = UltraComposer(); - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); auto proof = prover.construct_proof(); // Automatically generate a transcript manifest in the verifier by verifying a proof - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); verifier.verify_proof(proof); // Check consistency between the manifests generated by the prover and verifier @@ -209,10 +210,11 @@ TEST_F(UltraTranscriptTests, StructureTest) // Automatically generate a transcript manifest by constructing a proof auto composer = UltraComposer(); - auto instance = composer.create_instance(builder); + auto instance = composer.create_prover_instance(builder); + auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); auto proof = prover.construct_proof(); - auto verifier = composer.create_verifier(instance); + auto verifier = composer.create_verifier(verification_key); EXPECT_TRUE(verifier.verify_proof(proof)); // try deserializing and serializing with no changes and check proof is still valid From 30f9b9e35111be9bba7dd2ea2a828b45765a340a Mon Sep 17 00:00:00 2001 From: maramihali Date: Fri, 16 Feb 2024 10:42:04 +0000 Subject: [PATCH 02/15] works --- .../protogalaxy_rounds.bench.cpp | 106 +++++++++--------- .../src/barretenberg/goblin/CMakeLists.txt | 2 +- .../recursion/honk/transcript/transcript.hpp | 4 +- .../verifier/recursive_verifier_instance.hpp | 2 + .../src/barretenberg/sumcheck/sumcheck.hpp | 2 +- .../ultra_honk/ultra_composer.hpp | 3 +- 6 files changed, 62 insertions(+), 57 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp index 8369b995d9a..0776ef3631e 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp @@ -12,41 +12,41 @@ template void _bench_round(::benchmark::State& state, void (*F)(ProtoGalaxyProver_>&)) { - using Flavor = typename Composer::Flavor; - using Instance = ProverInstance_; - using Builder = typename Flavor::CircuitBuilder; - - bb::srs::init_crs_factory("../srs_db/ignition"); - auto log2_num_gates = static_cast(state.range(0)); - auto composer = Composer(); - - const auto construct_instance = [&]() { - Builder builder; - if constexpr (std::same_as) { - GoblinMockCircuits::construct_arithmetic_circuit(builder, log2_num_gates); - } else { - static_assert(std::same_as); - bb::mock_proofs::generate_basic_arithmetic_circuit(builder, log2_num_gates); - } - return composer.create_prover_instance(builder); - }; - - std::shared_ptr instance_1 = construct_instance(); - std::shared_ptr instance_2 = construct_instance(); - - auto folding_prover = composer.create_folding_prover({ instance_1, instance_2 }); - - // prepare the prover state - folding_prover.state.accumulator = instance_1; - folding_prover.state.deltas.resize(log2_num_gates); - std::fill_n(folding_prover.state.deltas.begin(), log2_num_gates, 0); - folding_prover.state.perturbator = Flavor::Polynomial::random(1 << log2_num_gates); - folding_prover.transcript = Flavor::Transcript::prover_init_empty(); - folding_prover.preparation_round(); - - for (auto _ : state) { - F(folding_prover); - } + // using Flavor = typename Composer::Flavor; + // using Instance = ProverInstance_; + // using Builder = typename Flavor::CircuitBuilder; + static_cast(state); + static_cast(F); + // bb::srs::init_crs_factory("../srs_db/ignition"); + // auto log2_num_gates = static_cast(state.range(0)); + // auto composer = Composer(); + + // const auto construct_instance = [&]() { + // Builder builder; + // if constexpr (std::same_as) { + // GoblinMockCircuits::construct_arithmetic_circuit(builder, log2_num_gates); + // } else { + // static_assert(std::same_as); + // bb::mock_proofs::generate_basic_arithmetic_circuit(builder, log2_num_gates); + // } + // return composer.create_prover_instance(builder); + // }; + + // std::shared_ptr instance_1 = construct_instance(); + // std::shared_ptr instance_2 = construct_instance(); + + // auto folding_prover = composer.create_folding_prover({ instance_1, instance_2 }); + + // // prepare the prover state + // folding_prover.state.accumulator = instance_1; + // folding_prover.state.deltas.resize(log2_num_gates); + // std::fill_n(folding_prover.state.deltas.begin(), log2_num_gates, 0); + // folding_prover.state.perturbator = Flavor::Polynomial::random(1 << log2_num_gates); + // folding_prover.transcript = Flavor::Transcript::prover_init_empty(); + // folding_prover.preparation_round(); + + // for (auto _ : state) { + // F(folding_prover); } void bench_round_ultra(::benchmark::State& state, void (*F)(ProtoGalaxyProver_>&)) @@ -60,23 +60,25 @@ void bench_round_goblin_ultra(::benchmark::State& state, _bench_round(state, F); } -BENCHMARK_CAPTURE(bench_round_ultra, preparation, [](auto& prover) { prover.preparation_round(); }) - -> DenseRange(14, 20) -> Unit(kMillisecond); -BENCHMARK_CAPTURE(bench_round_ultra, perturbator, [](auto& prover) { prover.perturbator_round(); }) - -> DenseRange(14, 20) -> Unit(kMillisecond); -BENCHMARK_CAPTURE(bench_round_ultra, combiner_quotient, [](auto& prover) { prover.combiner_quotient_round(); }) - -> DenseRange(14, 20) -> Unit(kMillisecond); -BENCHMARK_CAPTURE(bench_round_ultra, accumulator_update, [](auto& prover) { prover.accumulator_update_round(); }) - -> DenseRange(14, 20) -> Unit(kMillisecond); - -BENCHMARK_CAPTURE(bench_round_goblin_ultra, preparation, [](auto& prover) { prover.preparation_round(); }) - -> DenseRange(14, 20) -> Unit(kMillisecond); -BENCHMARK_CAPTURE(bench_round_goblin_ultra, perturbator, [](auto& prover) { prover.perturbator_round(); }) - -> DenseRange(14, 20) -> Unit(kMillisecond); -BENCHMARK_CAPTURE(bench_round_goblin_ultra, combiner_quotient, [](auto& prover) { prover.combiner_quotient_round(); }) - -> DenseRange(14, 20) -> Unit(kMillisecond); -BENCHMARK_CAPTURE(bench_round_goblin_ultra, accumulator_update, [](auto& prover) { prover.accumulator_update_round(); }) - -> DenseRange(14, 20) -> Unit(kMillisecond); +// BENCHMARK_CAPTURE(bench_round_ultra, preparation, [](auto& prover) { prover.preparation_round(); }) +// -> DenseRange(14, 20) -> Unit(kMillisecond); +// BENCHMARK_CAPTURE(bench_round_ultra, perturbator, [](auto& prover) { prover.perturbator_round(); }) +// -> DenseRange(14, 20) -> Unit(kMillisecond); +// BENCHMARK_CAPTURE(bench_round_ultra, combiner_quotient, [](auto& prover) { prover.combiner_quotient_round(); }) +// -> DenseRange(14, 20) -> Unit(kMillisecond); +// BENCHMARK_CAPTURE(bench_round_ultra, accumulator_update, [](auto& prover) { prover.accumulator_update_round(); }) +// -> DenseRange(14, 20) -> Unit(kMillisecond); + +// BENCHMARK_CAPTURE(bench_round_goblin_ultra, preparation, [](auto& prover) { prover.preparation_round(); }) +// -> DenseRange(14, 20) -> Unit(kMillisecond); +// BENCHMARK_CAPTURE(bench_round_goblin_ultra, perturbator, [](auto& prover) { prover.perturbator_round(); }) +// -> DenseRange(14, 20) -> Unit(kMillisecond); +// BENCHMARK_CAPTURE(bench_round_goblin_ultra, combiner_quotient, [](auto& prover) { prover.combiner_quotient_round(); +// }) +// -> DenseRange(14, 20) -> Unit(kMillisecond); +// BENCHMARK_CAPTURE(bench_round_goblin_ultra, accumulator_update, [](auto& prover) { prover.accumulator_update_round(); +// }) +// -> DenseRange(14, 20) -> Unit(kMillisecond); } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/goblin/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/goblin/CMakeLists.txt index ee4b04affe8..60ba6aa607c 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/goblin/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(goblin stdlib_recursion ultra_honk eccvm translator_vm stdlib_sha256 stdlib_merkle_tree stdlib_primitives) \ No newline at end of file +barretenberg_module(goblin stdlib_recursion ultra_honk eccvm translator_vm stdlib_sha256 crypto_merkle_tree stdlib_primitives) \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp index 9fef4b874f9..dcc23cdfa6a 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/transcript/transcript.hpp @@ -37,7 +37,7 @@ template struct StdlibTranscriptParams { } template static constexpr size_t calc_num_bn254_frs() { - return bb::stdlib::field_conversion::calc_num_bn254_frs(); + return bb::stdlib::field_conversion::calc_num_bn254_frs(); } template static inline T convert_from_bn254_frs(std::span frs) { @@ -48,7 +48,7 @@ template struct StdlibTranscriptParams { template static inline std::vector convert_to_bn254_frs(const T& element) { Builder* builder = element.get_context(); - return bb::stdlib::field_conversion::convert_to_bn254_frs(*builder, element); + return bb::stdlib::field_conversion::convert_to_bn254_frs(*builder, element); } }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp index f3ae2324c12..5d2b0fb3983 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp @@ -56,6 +56,7 @@ template class RecursiveVerifierInstance_ { public_inputs = std::vector(public_input_size); for (auto public_input : instance->public_inputs) { public_inputs[public_input_idx] = FF::from_witness(builder, public_input); + public_input_idx++; } verification_key = std::make_shared(instance_size, public_input_size); auto other_vks = instance->verification_key->get_all(); @@ -104,6 +105,7 @@ template class RecursiveVerifierInstance_ { inst.public_inputs = std::vector(public_input_size); for (auto public_input : public_inputs) { inst.public_inputs[public_input_idx] = public_input.get_value(); + public_input_idx++; } inst.verification_key = std::make_shared(instance_size, public_input_size); size_t vk_idx = 0; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index 09e2f41de68..7fffcb15269 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -123,7 +123,7 @@ template class SumcheckProver { zip_view(multivariate_evaluations.get_all(), partially_evaluated_polynomials.get_all())) { eval = poly[0]; } - transcript->send_to_verifier("Sumcheck:evaluations", multivariate_evaluations); + transcript->send_to_verifier("Sumcheck:evaluations", multivariate_evaluations.get_all()); return { multivariate_challenge, multivariate_evaluations }; }; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.hpp index 7738709b7f6..66ca19c1fb0 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.hpp @@ -11,8 +11,9 @@ #include "barretenberg/ultra_honk/ultra_verifier.hpp" namespace bb { -template class UltraComposer_ { +template class UltraComposer_ { public: + using Flavor = Flavor_; using CircuitBuilder = typename Flavor::CircuitBuilder; using ProvingKey = typename Flavor::ProvingKey; using VerificationKey = typename Flavor::VerificationKey; From bbaacadcb94d80549dea1237f448dd50ba06daf0 Mon Sep 17 00:00:00 2001 From: maramihali Date: Fri, 16 Feb 2024 11:48:26 +0000 Subject: [PATCH 03/15] aaaaaaaaaaaaa --- .../benchmark/ivc_bench/ivc.bench.cpp | 70 ++++++++------- .../barretenberg/client_ivc/client_ivc.cpp | 59 ++++++++++--- .../barretenberg/client_ivc/client_ivc.hpp | 12 ++- .../client_ivc/client_ivc.test.cpp | 85 ++++++------------- .../client_ivc/mock_kernel_pinning.test.cpp | 32 ++++--- .../src/barretenberg/goblin/mock_circuits.hpp | 52 ++++++++---- 6 files changed, 176 insertions(+), 134 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp index 2e1cacf27a1..69859feb2cb 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp @@ -48,38 +48,44 @@ class IvcBench : public benchmark::Fixture { static_cast(state); static_cast(ivc); // Initialize IVC with function circuit - Builder function_circuit{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(function_circuit); - ivc.initialize(function_circuit); - auto kernel_verifier_accum = ivc.get_verifier_accumulator(); - - // Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet) - Builder kernel_circuit{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(kernel_circuit); - auto kernel_fold_proof = ivc.accumulate(kernel_circuit); - auto kernel_verifier_inst = ivc.get_verifier_instance(); - - auto NUM_CIRCUITS = static_cast(state.range(0)); - // Subtract one to account for the "initialization" round above - NUM_CIRCUITS -= 1; - for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { - Builder function_circuit{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(function_circuit); - auto function_fold_proof = ivc.accumulate(function_circuit); - auto fnct_verifier_inst = ivc.get_verifier_instance(); - - // Accumulate kernel circuit - Builder kernel_circuit{ ivc.goblin.op_queue }; - kernel_verifier_accum = GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, - kernel_fold_proof, - function_fold_proof, - kernel_verifier_inst, - fnct_verifier_inst, - kernel_verifier_accum); - - kernel_fold_proof = ivc.accumulate(kernel_circuit); - kernel_verifier_inst = ivc.get_verifier_instance(); - } + // GoblinUltraCircuitBuilder circuit_1{ ivc.goblin.op_queue }; + // GoblinMockCircuits::construct_mock_function_circuit(circuit_1); + // ivc.initialize(circuit_1); + // auto verifier_acc = std::make_shared(); + // verifier_acc->verification_key = vks[0]; + + // GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; + // GoblinMockCircuits::construct_mock_function_circuit(circuit_2); + // FoldProof function_fold_proof = ivc.accumulate(circuit_2); + // FoldOutput function_fold_output = { function_fold_proof, vks[0] }; + + // Builder kernel_circuit{ ivc.goblin.op_queue }; + // auto kernel_acc = + // GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, function_fold_output, {}, + // verifier_acc); + // FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); + // FoldOutput kernel_fold_output = { kernel_fold_proof, vks[1] }; + // auto NUM_CIRCUITS = static_cast(state.range(0)); + // // Subtract one to account for the "initialization" round above + // NUM_CIRCUITS -= 1; + // for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { + // Builder function_circuit{ ivc.goblin.op_queue }; + // GoblinMockCircuits::construct_mock_function_circuit(function_circuit); + // auto function_fold_proof = ivc.accumulate(function_circuit); + // auto fnct_verifier_inst = ivc.get_verifier_instance(); + + // // Accumulate kernel circuit + // Builder kernel_circuit{ ivc.goblin.op_queue }; + // kernel_verifier_accum = GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, + // kernel_fold_proof, + // function_fold_proof, + // kernel_verifier_inst, + // fnct_verifier_inst, + // kernel_verifier_accum); + + // kernel_fold_proof = ivc.accumulate(kernel_circuit); + // kernel_verifier_inst = ivc.get_verifier_instance(); + // } } }; diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 2cae9315c09..5616a6a0fd2 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -81,21 +81,56 @@ HonkProof ClientIVC::decider_prove() const return decider_prover.construct_proof(); } -std::shared_ptr ClientIVC::get_verifier_instance() +std::vector> ClientIVC::precompute_folding_verification_keys() { Composer composer; - composer.compute_commitment_key(prover_instance->instance_size); - auto verifier_instance = composer.create_verifier_instance(prover_instance); - return verifier_instance; -} + std::vector> vks = + std::vector>(4); + // Accumulate three circuits to generate two folding proofs for input to folding kernel + ClientCircuit circuit_1{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(circuit_1); -ClientIVC::VerifierAccumulator ClientIVC::get_verifier_accumulator() -{ - Composer composer; - auto prover_accumulator = prover_fold_output.accumulator; - composer.compute_commitment_key(prover_accumulator->instance_size); - auto verifier_accumulator = composer.create_verifier_instance(prover_accumulator); - return verifier_accumulator; + initialize(circuit_1); + + composer.compute_commitment_key(prover_fold_output.accumulator->instance_size); + + vks[0] = composer.compute_verification_key(prover_fold_output.accumulator); + auto verifier_acc = std::make_shared(); + verifier_acc->verification_key = vks[0]; + + ClientCircuit circuit_2{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(circuit_2); + auto fold_proof_1 = accumulate(circuit_2); + vks[1] = composer.compute_verification_key(prover_instance); + + FoldOutput kernel_accum; + // Construct kernel circuit + ClientCircuit kernel_circuit{ goblin.op_queue }; + auto new_acc = + GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, { fold_proof_1, vks[1] }, {}, verifier_acc); + auto fold_proof_3 = accumulate(kernel_circuit); + vks[2] = composer.compute_verification_key(prover_instance); // first iteration of a kernel is smaller + + ClientCircuit new_kernel_circuit = GoblinUltraCircuitBuilder{ goblin.op_queue }; + auto new_new_acc = GoblinMockCircuits::construct_mock_folding_kernel( + new_kernel_circuit, { fold_proof_4, vks[1] }, { fold_proof_3, vks[2] }, new_acc); + + decider_prove_and_verify(new_acc); + auto fold_proof_5 = accumulate(new_kernel_circuit); + + vks[3] = composer.compute_verification_key(prover_instance); + auto proof = prove(); + auto kernel_inst = std::make_shared(); + kernel_inst->verification_key = vks[3]; + + auto verifier_instances = std::vector>{ new_acc, kernel_inst }; + auto res = verify(proof, verifier_instances); + ASSERT(res == true); + + goblin.op_queue = std::make_shared(); + goblin.merge_proof_exists = false; + GoblinMockCircuits::perform_op_queue_interactions_for_mock_first_circuit(goblin.op_queue); + return vks; } } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp index 15d24ddce85..195de984cad 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp @@ -16,6 +16,7 @@ class ClientIVC { public: using Flavor = GoblinUltraFlavor; + using VerificationKey = Flavor::VerificationKey; using FF = Flavor::FF; using FoldProof = std::vector; using ProverAccumulator = std::shared_ptr>; @@ -31,6 +32,11 @@ class ClientIVC { Goblin::Proof goblin_proof; }; + struct FoldOutput { + FoldProof fold_proof; + std::shared_ptr inst_vk; + }; + private: using ProverFoldOutput = FoldingResult; using Composer = GoblinUltraComposer; @@ -55,7 +61,11 @@ class ClientIVC { HonkProof decider_prove() const; + void decider_prove_and_verify(const VerifierAccumulator&) const; + VerifierAccumulator get_verifier_accumulator(); - std::shared_ptr get_verifier_instance(); + std::shared_ptr get_verifier_instance() const; + + std::vector> precompute_folding_verification_keys(); }; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp index d767f1c7e56..62499f76834 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp @@ -32,43 +32,7 @@ class ClientIVCTests : public ::testing::Test { using RecursiveVerifierInstances = ::bb::stdlib::recursion::honk::RecursiveVerifierInstances_; using FoldingRecursiveVerifier = bb::stdlib::recursion::honk::ProtoGalaxyRecursiveVerifier_; - - /** - * @brief Construct mock circuit with arithmetic gates and goblin ops - * @details Currently default sized to 2^16 to match kernel. (Note: op gates will bump size to next power of - 2) - * - */ - static Builder create_mock_circuit(ClientIVC& ivc, size_t num_gates = 1 << 15) - { - Builder circuit{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_arithmetic_circuit(circuit, num_gates); - GoblinMockCircuits::construct_goblin_ecc_op_circuit(circuit); - return circuit; - } - - /** - * @brief Construct mock kernel consisting of two recursive folding verifiers - * - * @param builder - * @param fctn_fold_proof - * @param kernel_fold_proof - */ - static VerifierAccumulator construct_mock_folding_kernel(Builder& builder, - FoldProof& fold_proof_1, - FoldProof& fold_proof_2, - VerifierInstance& verifier_inst_1, - VerifierInstance& verifier_inst_2, - VerifierAccumulator& prev_kernel_accum) - { - - FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { verifier_inst_1->verification_key } }; - auto fctn_verifier_accum = verifier_1.verify_folding_proof(fold_proof_1); - auto native_acc = std::make_shared(fctn_verifier_accum->get_value()); - FoldingRecursiveVerifier verifier_2{ &builder, native_acc, { verifier_inst_2->verification_key } }; - auto kernel_verifier_accum = verifier_2.verify_folding_proof(fold_proof_2); - return std::make_shared(kernel_verifier_accum->get_value()); - } + using FoldOutput = GoblinMockCircuits::FoldOutput; /** * @brief Construct mock kernel consisting of two recursive folding verifiers @@ -106,43 +70,50 @@ class ClientIVCTests : public ::testing::Test { */ TEST_F(ClientIVCTests, Full) { + // using FoldOutput = GoblinMockCircuits::FoldOutput; ClientIVC ivc; + auto vks = ivc.precompute_folding_verification_keys(); // Initialize IVC with function circuit - Builder function_circuit_1 = create_mock_circuit(ivc); - ivc.initialize(function_circuit_1); - VerifierAccumulator kernel_verifier_accum = - ivc.get_verifier_accumulator(); // fake accumulator, just a function circuit for the first round - - Builder kernel_circuit = create_mock_circuit(ivc); + GoblinUltraCircuitBuilder circuit_1{ ivc.goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(circuit_1); + ivc.initialize(circuit_1); + auto verifier_acc = std::make_shared(); + verifier_acc->verification_key = vks[0]; + + GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(circuit_2); + FoldProof function_fold_proof = ivc.accumulate(circuit_2); + FoldOutput function_fold_output = { function_fold_proof, vks[1] }; + + Builder kernel_circuit{ ivc.goblin.op_queue }; + auto kernel_acc = + GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, function_fold_output, {}, verifier_acc); FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); - auto kernel_verifier_inst = ivc.get_verifier_instance(); + FoldOutput kernel_fold_output = { kernel_fold_proof, vks[2] }; + size_t NUM_CIRCUITS = 2; for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { // Accumulate function circuit - Builder function_circuit = create_mock_circuit(ivc); + Builder function_circuit{ ivc.goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(function_circuit); FoldProof function_fold_proof = ivc.accumulate(function_circuit); - auto fnct_verifier_inst = ivc.get_verifier_instance(); + function_fold_output = { function_fold_proof, vks[1] }; // Accumulate kernel circuit Builder kernel_circuit{ ivc.goblin.op_queue }; - - kernel_verifier_accum = construct_mock_folding_kernel(kernel_circuit, - kernel_fold_proof, - function_fold_proof, - kernel_verifier_inst, - fnct_verifier_inst, - kernel_verifier_accum); - + kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, function_fold_output, kernel_fold_output, kernel_acc); kernel_fold_proof = ivc.accumulate(kernel_circuit); - kernel_verifier_inst = ivc.get_verifier_instance(); + kernel_fold_output = { kernel_fold_proof, vks[3] }; } // // Constuct four proofs: merge, eccvm, translator, decider, last folding proof auto proof = ivc.prove(); - + auto kernel_inst = std::make_shared(); + kernel_inst->verification_key = vks[3]; // // Verify all four proofs - auto verifier_instances = std::vector{ kernel_verifier_accum, kernel_verifier_inst }; + auto verifier_instances = std::vector{ kernel_acc, kernel_inst }; auto res = ivc.verify(proof, verifier_instances); EXPECT_TRUE(res); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp index a857bd913f2..7a8fa532106 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp @@ -18,42 +18,46 @@ class MockKernelTest : public ::testing::Test { TEST_F(MockKernelTest, PinFoldingKernelSizes) { + using FoldOutput = GoblinMockCircuits::FoldOutput; ClientIVC ivc; - - // Accumulate three circuits to generate two folding proofs for input to folding kernel + auto vks = ivc.precompute_folding_verification_keys(); + // Accumulate three circuits to generate two folding proofs for input to foldng kernel GoblinUltraCircuitBuilder circuit_1{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_1); ivc.initialize(circuit_1); - auto verifier_acc = ivc.get_verifier_accumulator(); + auto verifier_acc = std::make_shared(); + verifier_acc->verification_key = vks[0]; GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_2); auto fold_proof_1 = ivc.accumulate(circuit_2); - auto verifier_inst_1 = ivc.get_verifier_instance(); - - GoblinUltraCircuitBuilder circuit_3{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(circuit_3); - auto fold_proof_2 = ivc.accumulate(circuit_3); - auto verifier_inst_2 = ivc.get_verifier_instance(); + FoldOutput kernel_accum; // Construct kernel circuit GoblinUltraCircuitBuilder kernel_circuit{ ivc.goblin.op_queue }; - auto new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - kernel_circuit, fold_proof_1, fold_proof_2, verifier_inst_1, verifier_inst_2, verifier_acc); + auto new_acc = + GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, { fold_proof_1, vks[1] }, {}, verifier_acc); auto fold_proof_3 = ivc.accumulate(kernel_circuit); - auto verifier_inst_3 = ivc.get_verifier_instance(); EXPECT_EQ(ivc.prover_instance->log_instance_size, 17); GoblinUltraCircuitBuilder circuit_4{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_4); auto fold_proof_4 = ivc.accumulate(circuit_4); - auto verifier_inst_4 = ivc.get_verifier_instance(); GoblinUltraCircuitBuilder new_kernel_circuit = GoblinUltraCircuitBuilder{ ivc.goblin.op_queue }; new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - new_kernel_circuit, fold_proof_3, fold_proof_4, verifier_inst_3, verifier_inst_4, new_acc); + new_kernel_circuit, { fold_proof_3, vks[1] }, { fold_proof_4, vks[0] }, new_acc); GoblinUltraComposer composer; auto instance = composer.create_prover_instance(new_kernel_circuit); EXPECT_EQ(instance->proving_key->log_circuit_size, 17); + + GoblinUltraCircuitBuilder circuit_5{ ivc.goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(circuit_5); + auto fold_proof_5 = ivc.accumulate(circuit_5); + + GoblinUltraCircuitBuilder new_new_kernel_circuit = GoblinUltraCircuitBuilder{ ivc.goblin.op_queue }; + new_acc = GoblinMockCircuits::construct_mock_folding_kernel( + new_new_kernel_circuit, { fold_proof_3, vks[2] }, { fold_proof_4, vks[0] }, new_acc); + auto fold_proof_6 = ivc.accumulate(new_new_kernel_circuit); } \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index e32e475197d..94b46c28a21 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -33,8 +33,14 @@ class GoblinMockCircuits { using VerifierInstance = bb::VerifierInstance_; using RecursiveVerifierInstance = ::bb::stdlib::recursion::honk::RecursiveVerifierInstance_; using RecursiveVerifierAccumulator = std::shared_ptr; + using VerificationKey = Flavor::VerificationKey; static constexpr size_t NUM_OP_QUEUE_COLUMNS = Flavor::NUM_WIRES; + struct FoldOutput { + std::vector fold_proof; + std::shared_ptr inst_vk; + }; + /** * @brief Populate a builder with a specified number of arithmetic gates; includes a PI * @@ -96,18 +102,22 @@ class GoblinMockCircuits { */ static void construct_mock_function_circuit(GoblinUltraBuilder& builder, bool large = false) { - // Determine number of times to execute the below operations that constitute the mock circuit logic. Note that - // the circuit size does not scale linearly with number of iterations due to e.g. amortization of lookup costs - const size_t NUM_ITERATIONS_LARGE = 13; // results in circuit size 2^19 (521327 gates) - const size_t NUM_ITERATIONS_MEDIUM = 3; // results in circuit size 2^17 (124843 gates) + static_cast(large); + // Determine number of times to execute the below operations that constitute the mock circuit logic. Note + // that the circuit size does not scale linearly with number of iterations due to e.g. amortization of + // lookup costs + const size_t NUM_ITERATIONS_LARGE = 13; // results in circuit size 2^19 (521327 gates) const + size_t NUM_ITERATIONS_MEDIUM = 2; // results in circuit size 2^17 (124843 gates) const size_t NUM_ITERATIONS = large ? NUM_ITERATIONS_LARGE : NUM_ITERATIONS_MEDIUM; stdlib::generate_sha256_test_circuit(builder, NUM_ITERATIONS); // min gates: ~39k stdlib::generate_ecdsa_verification_test_circuit(builder, NUM_ITERATIONS); // min gates: ~41k stdlib::generate_merkle_membership_test_circuit(builder, NUM_ITERATIONS); // min gates: ~29k - // Note: its not clear whether goblin ops will be supported for function circuits initially but currently UGH - // can only be used if some op gates are included so for now we'll assume each function circuit has some. + // Note: its not clear whether goblin ops will be supported for function circuits initially but currently + // UGH can only be used if some op gates are included so for now we'll assume each function circuit has + // some. + // construct_arithmetic_circuit(builder, 1 << 15); construct_goblin_ecc_op_circuit(builder); } @@ -200,7 +210,6 @@ class GoblinMockCircuits { RecursiveVerifier verifier2{ &builder, prev_kernel_accum.verification_key }; verifier2.verify_proof(prev_kernel_accum.proof); } - info(builder.get_num_gates()); } /** @@ -216,10 +225,8 @@ class GoblinMockCircuits { */ static std::shared_ptr construct_mock_folding_kernel( GoblinUltraBuilder& builder, - const std::vector& fold_proof_1, - const std::vector& fold_proof_2, - std::shared_ptr& verifier_inst_1, - std::shared_ptr& verifier_inst_2, + const FoldOutput& func, + const FoldOutput& kernel, std::shared_ptr& prev_kernel_accum) { using GURecursiveFlavor = GoblinUltraRecursiveFlavor_; @@ -230,19 +237,28 @@ class GoblinMockCircuits { // Add operations representing general kernel logic e.g. state updates. Note: these are structured to make // the kernel "full" within the dyadic size 2^17 (130914 gates) - const size_t NUM_MERKLE_CHECKS = 35; + const size_t NUM_MERKLE_CHECKS = 25; const size_t NUM_ECDSA_VERIFICATIONS = 1; const size_t NUM_SHA_HASHES = 1; stdlib::generate_merkle_membership_test_circuit(builder, NUM_MERKLE_CHECKS); stdlib::generate_ecdsa_verification_test_circuit(builder, NUM_ECDSA_VERIFICATIONS); stdlib::generate_sha256_test_circuit(builder, NUM_SHA_HASHES); - FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { verifier_inst_1->verification_key } }; - auto fctn_verifier_accum = verifier_1.verify_folding_proof(fold_proof_1); - auto native_acc = std::make_shared(fctn_verifier_accum->get_value()); - FoldingRecursiveVerifier verifier_2{ &builder, native_acc, { verifier_inst_2->verification_key } }; - auto kernel_verifier_accum = verifier_2.verify_folding_proof(fold_proof_2); - return std::make_shared(kernel_verifier_accum->get_value()); + if (kernel.fold_proof.empty()) { + FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { func.inst_vk } }; + auto fctn_verifier_accum = verifier_1.verify_folding_proof(func.fold_proof); + auto native_acc = std::make_shared(fctn_verifier_accum->get_value()); + return native_acc; + } + + FoldingRecursiveVerifier verifier_2{ &builder, prev_kernel_accum, { kernel.inst_vk } }; + auto kernel_verifier_accum = verifier_2.verify_folding_proof(kernel.fold_proof); + auto native_acc = std::make_shared(kernel_verifier_accum->get_value()); + FoldingRecursiveVerifier verifier_1{ &builder, native_acc, { func.inst_vk } }; + auto fctn_verifier_accum = verifier_1.verify_folding_proof(func.fold_proof); + native_acc = std::make_shared(fctn_verifier_accum->get_value()); + + return native_acc; } /** From b5b77f4e7662cd8330e31265186a1cdca1c90840 Mon Sep 17 00:00:00 2001 From: maramihali Date: Fri, 16 Feb 2024 19:56:41 +0000 Subject: [PATCH 04/15] bench work --- .../benchmark/ivc_bench/ivc.bench.cpp | 86 ++++++------ .../barretenberg/client_ivc/client_ivc.cpp | 20 +-- .../barretenberg/client_ivc/client_ivc.hpp | 4 +- .../client_ivc/client_ivc.test.cpp | 131 +++++++++--------- .../client_ivc/mock_kernel_pinning.test.cpp | 19 +-- .../src/barretenberg/goblin/mock_circuits.hpp | 9 +- 6 files changed, 122 insertions(+), 147 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp index 69859feb2cb..e3e981b86d2 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp @@ -21,6 +21,7 @@ namespace { class IvcBench : public benchmark::Fixture { public: using Builder = GoblinUltraCircuitBuilder; + using FoldOutput = GoblinMockCircuits::FoldOutput; // Number of function circuits to accumulate(based on Zacs target numbers) static constexpr size_t NUM_ITERATIONS_MEDIUM_COMPLEXITY = 6; @@ -45,58 +46,51 @@ class IvcBench : public benchmark::Fixture { */ static void perform_ivc_accumulation_rounds(State& state, ClientIVC& ivc) { - static_cast(state); - static_cast(ivc); // Initialize IVC with function circuit - // GoblinUltraCircuitBuilder circuit_1{ ivc.goblin.op_queue }; - // GoblinMockCircuits::construct_mock_function_circuit(circuit_1); - // ivc.initialize(circuit_1); - // auto verifier_acc = std::make_shared(); - // verifier_acc->verification_key = vks[0]; - - // GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; - // GoblinMockCircuits::construct_mock_function_circuit(circuit_2); - // FoldProof function_fold_proof = ivc.accumulate(circuit_2); - // FoldOutput function_fold_output = { function_fold_proof, vks[0] }; - - // Builder kernel_circuit{ ivc.goblin.op_queue }; - // auto kernel_acc = - // GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, function_fold_output, {}, - // verifier_acc); - // FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); - // FoldOutput kernel_fold_output = { kernel_fold_proof, vks[1] }; - // auto NUM_CIRCUITS = static_cast(state.range(0)); - // // Subtract one to account for the "initialization" round above - // NUM_CIRCUITS -= 1; - // for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { - // Builder function_circuit{ ivc.goblin.op_queue }; - // GoblinMockCircuits::construct_mock_function_circuit(function_circuit); - // auto function_fold_proof = ivc.accumulate(function_circuit); - // auto fnct_verifier_inst = ivc.get_verifier_instance(); - - // // Accumulate kernel circuit - // Builder kernel_circuit{ ivc.goblin.op_queue }; - // kernel_verifier_accum = GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, - // kernel_fold_proof, - // function_fold_proof, - // kernel_verifier_inst, - // fnct_verifier_inst, - // kernel_verifier_accum); - - // kernel_fold_proof = ivc.accumulate(kernel_circuit); - // kernel_verifier_inst = ivc.get_verifier_instance(); - // } + GoblinUltraCircuitBuilder initial_function_circuit{ ivc.goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit); + ivc.initialize(initial_function_circuit); + auto kernel_acc = std::make_shared(); + kernel_acc->verification_key = ivc.vks[0]; + + GoblinUltraCircuitBuilder function_circuit{ ivc.goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(function_circuit); + auto function_fold_proof = ivc.accumulate(function_circuit); + FoldOutput function_fold_output = { function_fold_proof, ivc.vks[1] }; + + Builder kernel_circuit{ ivc.goblin.op_queue }; + kernel_acc = + GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, function_fold_output, {}, kernel_acc); + auto kernel_fold_proof = ivc.accumulate(kernel_circuit); + FoldOutput kernel_fold_output = { kernel_fold_proof, ivc.vks[2] }; + auto NUM_CIRCUITS = static_cast(state.range(0)); + // Subtract one to account for the "initialization" round above + NUM_CIRCUITS -= 1; + for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { + Builder function_circuit{ ivc.goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(function_circuit); + auto function_fold_proof = ivc.accumulate(function_circuit); + function_fold_output = { function_fold_proof, ivc.vks[1] }; + + // Accumulate kernel circuit + Builder kernel_circuit{ ivc.goblin.op_queue }; + kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, function_fold_output, kernel_fold_output, kernel_acc); + + kernel_fold_proof = ivc.accumulate(kernel_circuit); + kernel_fold_output = { kernel_fold_proof, ivc.vks[3] }; + } } }; -/**ch +/** * @brief Benchmark the prover work for the full PG-Goblin IVC protocol * */ BENCHMARK_DEFINE_F(IvcBench, Full)(benchmark::State& state) { ClientIVC ivc; - + ivc.precompute_folding_verification_keys(); for (auto _ : state) { BB_REPORT_OP_COUNT_IN_BENCH(state); // Perform a specified number of iterations of function/kernel accumulation @@ -114,7 +108,7 @@ BENCHMARK_DEFINE_F(IvcBench, Full)(benchmark::State& state) BENCHMARK_DEFINE_F(IvcBench, Accumulate)(benchmark::State& state) { ClientIVC ivc; - + ivc.precompute_folding_verification_keys(); // Perform a specified number of iterations of function/kernel accumulation for (auto _ : state) { perform_ivc_accumulation_rounds(state, ivc); @@ -128,7 +122,7 @@ BENCHMARK_DEFINE_F(IvcBench, Accumulate)(benchmark::State& state) BENCHMARK_DEFINE_F(IvcBench, Decide)(benchmark::State& state) { ClientIVC ivc; - + ivc.precompute_folding_verification_keys(); BB_REPORT_OP_COUNT_IN_BENCH(state); // Perform a specified number of iterations of function/kernel accumulation perform_ivc_accumulation_rounds(state, ivc); @@ -146,7 +140,7 @@ BENCHMARK_DEFINE_F(IvcBench, Decide)(benchmark::State& state) BENCHMARK_DEFINE_F(IvcBench, ECCVM)(benchmark::State& state) { ClientIVC ivc; - + ivc.precompute_folding_verification_keys(); BB_REPORT_OP_COUNT_IN_BENCH(state); // Perform a specified number of iterations of function/kernel accumulation perform_ivc_accumulation_rounds(state, ivc); @@ -164,7 +158,7 @@ BENCHMARK_DEFINE_F(IvcBench, ECCVM)(benchmark::State& state) BENCHMARK_DEFINE_F(IvcBench, Translator)(benchmark::State& state) { ClientIVC ivc; - + ivc.precompute_folding_verification_keys(); BB_REPORT_OP_COUNT_IN_BENCH(state); // Perform a specified number of iterations of function/kernel accumulation perform_ivc_accumulation_rounds(state, ivc); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 5616a6a0fd2..4377c149782 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -81,11 +81,14 @@ HonkProof ClientIVC::decider_prove() const return decider_prover.construct_proof(); } -std::vector> ClientIVC::precompute_folding_verification_keys() +/** + * @brief Precompute the array of verification keys by simulating folding. There will be 4 different verification keys. + * + */ +void ClientIVC::precompute_folding_verification_keys() { Composer composer; - std::vector> vks = - std::vector>(4); + // Accumulate three circuits to generate two folding proofs for input to folding kernel ClientCircuit circuit_1{ goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_1); @@ -111,26 +114,23 @@ std::vector> ClientIVC::precompute_f auto fold_proof_3 = accumulate(kernel_circuit); vks[2] = composer.compute_verification_key(prover_instance); // first iteration of a kernel is smaller + ClientCircuit circuit_4{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(circuit_4); + auto fold_proof_4 = accumulate(circuit_4); + ClientCircuit new_kernel_circuit = GoblinUltraCircuitBuilder{ goblin.op_queue }; auto new_new_acc = GoblinMockCircuits::construct_mock_folding_kernel( new_kernel_circuit, { fold_proof_4, vks[1] }, { fold_proof_3, vks[2] }, new_acc); - decider_prove_and_verify(new_acc); auto fold_proof_5 = accumulate(new_kernel_circuit); vks[3] = composer.compute_verification_key(prover_instance); - auto proof = prove(); auto kernel_inst = std::make_shared(); kernel_inst->verification_key = vks[3]; - auto verifier_instances = std::vector>{ new_acc, kernel_inst }; - auto res = verify(proof, verifier_instances); - ASSERT(res == true); - goblin.op_queue = std::make_shared(); goblin.merge_proof_exists = false; GoblinMockCircuits::perform_op_queue_interactions_for_mock_first_circuit(goblin.op_queue); - return vks; } } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp index 195de984cad..eb682ab9f36 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp @@ -49,6 +49,8 @@ class ClientIVC { // keep the instance or instances around if we're folding more of them so we can compute the verification key std::shared_ptr prover_instance; + std::array, 4> vks; + ClientIVC(); void initialize(ClientCircuit& circuit); @@ -66,6 +68,6 @@ class ClientIVC { VerifierAccumulator get_verifier_accumulator(); std::shared_ptr get_verifier_instance() const; - std::vector> precompute_folding_verification_keys(); + void precompute_folding_verification_keys(); }; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp index 62499f76834..30593d7124f 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp @@ -23,98 +23,91 @@ class ClientIVCTests : public ::testing::Test { using Composer = GoblinUltraComposer; using ProverAccumulator = ClientIVC::ProverAccumulator; using VerifierAccumulator = ClientIVC::VerifierAccumulator; - using VerifierInstance = std::shared_ptr; + using VerifierInstance = ClientIVC::VerifierInstance; using FoldProof = ClientIVC::FoldProof; - + using FoldOutput = GoblinMockCircuits::FoldOutput; using GURecursiveFlavor = GoblinUltraRecursiveFlavor_; using RecursiveVerifierInstance = ::bb::stdlib::recursion::honk::RecursiveVerifierInstance_; using RecursiveVerifierAccumulator = std::shared_ptr; using RecursiveVerifierInstances = ::bb::stdlib::recursion::honk::RecursiveVerifierInstances_; using FoldingRecursiveVerifier = bb::stdlib::recursion::honk::ProtoGalaxyRecursiveVerifier_; - using FoldOutput = GoblinMockCircuits::FoldOutput; /** - * @brief Construct mock kernel consisting of two recursive folding verifiers + * @brief Construct mock circuit with arithmetic gates and goblin ops + * @details Currently default sized to 2^16 to match kernel. (Note: op gates will bump size to next power of + 2) * - * @param builder - * @param fctn_fold_proof - * @param kernel_fold_proof */ + static Builder create_mock_circuit(ClientIVC& ivc, size_t num_gates = 1 << 15) + { + Builder circuit{ ivc.goblin.op_queue }; + GoblinMockCircuits::construct_arithmetic_circuit(circuit, num_gates); + GoblinMockCircuits::construct_goblin_ecc_op_circuit(circuit); + return circuit; + } /** - * @brief Perform native fold verification and run decider prover/verifier + * @brief Construct mock kernel consisting of two recursive folding verifiers * + * @param builder + * @param fctn_fold_proof + * @param kernel_fold_proof */ - // static VerifierAccumulator native_folding(const ProverAccumulator& prover_accumulator, - // const std::vector>& - // verifier_instances, const FoldProof& fold_proof) - // { - // // Verify fold proof - // Composer composer; - // auto folding_verifier = composer.create_folding_verifier(verifier_instances); - // auto verifier_accumulator = folding_verifier.verify_folding_proof(fold_proof); + static VerifierAccumulator construct_mock_folding_kernel(Builder& builder, + FoldOutput& func_accum, + FoldOutput& kernel_accum, + VerifierAccumulator& prev_kernel_accum) + { - // // Run decider - // auto decider_prover = composer.create_decider_prover(prover_accumulator); - // auto decider_verifier = composer.create_decider_verifier(verifier_accumulator); - // auto decider_proof = decider_prover.construct_proof(); - // bool decision = decider_verifier.verify_proof(decider_proof); - // EXPECT_TRUE(decision); - // } + FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { func_accum.inst_vk } }; + auto fctn_verifier_accum = verifier_1.verify_folding_proof(func_accum.fold_proof); + auto native_acc = std::make_shared(fctn_verifier_accum->get_value()); + FoldingRecursiveVerifier verifier_2{ &builder, native_acc, { kernel_accum.inst_vk } }; + auto kernel_verifier_accum = verifier_2.verify_folding_proof(kernel_accum.fold_proof); + return std::make_shared(kernel_verifier_accum->get_value()); + } }; /** * @brief A full Goblin test using PG that mimicks the basic aztec client architecture * */ -TEST_F(ClientIVCTests, Full) -{ - // using FoldOutput = GoblinMockCircuits::FoldOutput; - ClientIVC ivc; - - auto vks = ivc.precompute_folding_verification_keys(); - // Initialize IVC with function circuit - GoblinUltraCircuitBuilder circuit_1{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(circuit_1); - ivc.initialize(circuit_1); - auto verifier_acc = std::make_shared(); - verifier_acc->verification_key = vks[0]; - - GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(circuit_2); - FoldProof function_fold_proof = ivc.accumulate(circuit_2); - FoldOutput function_fold_output = { function_fold_proof, vks[1] }; +TEST_F(ClientIVCTests, Full){ + // ClientIVC ivc; + // Composer composer; + // // Initialize IVC with function circuit + // Builder function_circuit = create_mock_circuit(ivc); + // ivc.initialize(function_circuit); - Builder kernel_circuit{ ivc.goblin.op_queue }; - auto kernel_acc = - GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, function_fold_output, {}, verifier_acc); - FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); - FoldOutput kernel_fold_output = { kernel_fold_proof, vks[2] }; - - size_t NUM_CIRCUITS = 2; - for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { - // Accumulate function circuit - Builder function_circuit{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(function_circuit); - FoldProof function_fold_proof = ivc.accumulate(function_circuit); - function_fold_output = { function_fold_proof, vks[1] }; - - // Accumulate kernel circuit - Builder kernel_circuit{ ivc.goblin.op_queue }; - kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel( - kernel_circuit, function_fold_output, kernel_fold_output, kernel_acc); - kernel_fold_proof = ivc.accumulate(kernel_circuit); - kernel_fold_output = { kernel_fold_proof, vks[3] }; - } + // composer.compute_commitment_key(ivc.prover_fold_output.accumulator->instance_size); + // auto function_vk = composer.compute_verification_key(ivc.prover_fold_output.accumulator); + // auto kernel_acc = std::make_shared(); + // kernel_acc->verification_key = function_vk; + // // Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet) + // Builder kernel_circuit = create_mock_circuit(ivc); + // FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); + // auto kernel_vk = function_vk; + // FoldOutput kernel_fold_output = { kernel_fold_proof, function_vk }; + // size_t NUM_CIRCUITS = 1; + // for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { + // // Accumulate function circuit + // Builder function_circuit = create_mock_circuit(ivc); + // FoldProof function_fold_proof = ivc.accumulate(function_circuit); + // FoldOutput function_fold_output = { function_fold_proof, function_vk }; + // // Accumulate kernel circuit + // Builder kernel_circuit{ ivc.goblin.op_queue }; + // kernel_acc = + // construct_mock_folding_kernel(kernel_circuit, kernel_fold_output, function_fold_output, kernel_acc); + // FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); + // kernel_vk = composer.compute_verification_key(ivc.prover_instance); + // FoldOutput kernel_fold_output = { kernel_fold_proof, kernel_vk }; + // } - // // Constuct four proofs: merge, eccvm, translator, decider, last folding proof - auto proof = ivc.prove(); - auto kernel_inst = std::make_shared(); - kernel_inst->verification_key = vks[3]; + // // Constuct four proofs: merge, eccvm, translator, decider + // auto proof = ivc.prove(); + // auto inst = std::make_shared(); + // inst->verification_key = kernel_vk; // // Verify all four proofs - auto verifier_instances = std::vector{ kernel_acc, kernel_inst }; - auto res = ivc.verify(proof, verifier_instances); - - EXPECT_TRUE(res); + // EXPECT_TRUE(ivc.verify(proof, { kernel_acc, inst })); }; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp index 7a8fa532106..d6669e80adf 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp @@ -20,13 +20,13 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) { using FoldOutput = GoblinMockCircuits::FoldOutput; ClientIVC ivc; - auto vks = ivc.precompute_folding_verification_keys(); + ivc.precompute_folding_verification_keys(); // Accumulate three circuits to generate two folding proofs for input to foldng kernel GoblinUltraCircuitBuilder circuit_1{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_1); ivc.initialize(circuit_1); auto verifier_acc = std::make_shared(); - verifier_acc->verification_key = vks[0]; + verifier_acc->verification_key = ivc.vks[0]; GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_2); @@ -35,8 +35,8 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) FoldOutput kernel_accum; // Construct kernel circuit GoblinUltraCircuitBuilder kernel_circuit{ ivc.goblin.op_queue }; - auto new_acc = - GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, { fold_proof_1, vks[1] }, {}, verifier_acc); + auto new_acc = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, { fold_proof_1, ivc.vks[1] }, {}, verifier_acc); auto fold_proof_3 = ivc.accumulate(kernel_circuit); EXPECT_EQ(ivc.prover_instance->log_instance_size, 17); @@ -47,17 +47,8 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) GoblinUltraCircuitBuilder new_kernel_circuit = GoblinUltraCircuitBuilder{ ivc.goblin.op_queue }; new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - new_kernel_circuit, { fold_proof_3, vks[1] }, { fold_proof_4, vks[0] }, new_acc); + new_kernel_circuit, { fold_proof_3, ivc.vks[2] }, { fold_proof_4, ivc.vks[1] }, new_acc); GoblinUltraComposer composer; auto instance = composer.create_prover_instance(new_kernel_circuit); EXPECT_EQ(instance->proving_key->log_circuit_size, 17); - - GoblinUltraCircuitBuilder circuit_5{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(circuit_5); - auto fold_proof_5 = ivc.accumulate(circuit_5); - - GoblinUltraCircuitBuilder new_new_kernel_circuit = GoblinUltraCircuitBuilder{ ivc.goblin.op_queue }; - new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - new_new_kernel_circuit, { fold_proof_3, vks[2] }, { fold_proof_4, vks[0] }, new_acc); - auto fold_proof_6 = ivc.accumulate(new_new_kernel_circuit); } \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 94b46c28a21..d13c64b547d 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -102,7 +102,6 @@ class GoblinMockCircuits { */ static void construct_mock_function_circuit(GoblinUltraBuilder& builder, bool large = false) { - static_cast(large); // Determine number of times to execute the below operations that constitute the mock circuit logic. Note // that the circuit size does not scale linearly with number of iterations due to e.g. amortization of // lookup costs @@ -117,7 +116,6 @@ class GoblinMockCircuits { // Note: its not clear whether goblin ops will be supported for function circuits initially but currently // UGH can only be used if some op gates are included so for now we'll assume each function circuit has // some. - // construct_arithmetic_circuit(builder, 1 << 15); construct_goblin_ecc_op_circuit(builder); } @@ -247,8 +245,7 @@ class GoblinMockCircuits { if (kernel.fold_proof.empty()) { FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { func.inst_vk } }; auto fctn_verifier_accum = verifier_1.verify_folding_proof(func.fold_proof); - auto native_acc = std::make_shared(fctn_verifier_accum->get_value()); - return native_acc; + return std::make_shared(fctn_verifier_accum->get_value()); } FoldingRecursiveVerifier verifier_2{ &builder, prev_kernel_accum, { kernel.inst_vk } }; @@ -256,9 +253,7 @@ class GoblinMockCircuits { auto native_acc = std::make_shared(kernel_verifier_accum->get_value()); FoldingRecursiveVerifier verifier_1{ &builder, native_acc, { func.inst_vk } }; auto fctn_verifier_accum = verifier_1.verify_folding_proof(func.fold_proof); - native_acc = std::make_shared(fctn_verifier_accum->get_value()); - - return native_acc; + return std::make_shared(fctn_verifier_accum->get_value()); } /** From 7e09c8b3f9b1e2688693a60db846b52388bc9599 Mon Sep 17 00:00:00 2001 From: maramihali Date: Mon, 19 Feb 2024 15:27:47 +0000 Subject: [PATCH 05/15] cleaning up --- .../benchmark/ivc_bench/ivc.bench.cpp | 10 +- .../client_ivc/client_ivc.test.cpp | 72 +-- .../ecc/curves/bn254/fr_straight.bench.cpp | 398 ++++++++-------- .../protogalaxy_recursive_verifier.test.cpp | 423 ++++++++---------- 4 files changed, 432 insertions(+), 471 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp index e3e981b86d2..b9dc4da4a57 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp @@ -34,26 +34,24 @@ class IvcBench : public benchmark::Fixture { /** * @brief Perform a specified number of function circuit accumulation rounds - * @details Each round "accumulates" a mock function circuit and a mock kernel circuit. Each round thus consists - of + * @details Each round "accumulates" a mock function circuit and a mock kernel circuit. Each round thus consists of * the generation of two circuits, two folding proofs and two Merge proofs. To match the sizes called out in the * spec * (https://github.com/AztecProtocol/aztec-packages/blob/master/yellow-paper/docs/cryptography/performance-targets.md) - * we set the size of the function circuit to be 2^17. The first one should be 2^19 but we can't currently - support + * we set the size of the function circuit to be 2^17. The first one should be 2^19 but we can't currently support * folding circuits of unequal size. * */ static void perform_ivc_accumulation_rounds(State& state, ClientIVC& ivc) { // Initialize IVC with function circuit - GoblinUltraCircuitBuilder initial_function_circuit{ ivc.goblin.op_queue }; + Builder initial_function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit); ivc.initialize(initial_function_circuit); auto kernel_acc = std::make_shared(); kernel_acc->verification_key = ivc.vks[0]; - GoblinUltraCircuitBuilder function_circuit{ ivc.goblin.op_queue }; + Builder function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(function_circuit); auto function_fold_proof = ivc.accumulate(function_circuit); FoldOutput function_fold_output = { function_fold_proof, ivc.vks[1] }; diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp index 30593d7124f..5faa3ee9bbd 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp @@ -73,41 +73,43 @@ class ClientIVCTests : public ::testing::Test { * @brief A full Goblin test using PG that mimicks the basic aztec client architecture * */ -TEST_F(ClientIVCTests, Full){ - // ClientIVC ivc; - // Composer composer; - // // Initialize IVC with function circuit - // Builder function_circuit = create_mock_circuit(ivc); - // ivc.initialize(function_circuit); +TEST_F(ClientIVCTests, Full) +{ + ClientIVC ivc; + Composer composer; + // Initialize IVC with function circuit + Builder function_circuit = create_mock_circuit(ivc); + ivc.initialize(function_circuit); + composer.compute_commitment_key(ivc.prover_fold_output.accumulator->instance_size); - // composer.compute_commitment_key(ivc.prover_fold_output.accumulator->instance_size); - // auto function_vk = composer.compute_verification_key(ivc.prover_fold_output.accumulator); - // auto kernel_acc = std::make_shared(); - // kernel_acc->verification_key = function_vk; - // // Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet) - // Builder kernel_circuit = create_mock_circuit(ivc); - // FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); - // auto kernel_vk = function_vk; - // FoldOutput kernel_fold_output = { kernel_fold_proof, function_vk }; - // size_t NUM_CIRCUITS = 1; - // for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { - // // Accumulate function circuit - // Builder function_circuit = create_mock_circuit(ivc); - // FoldProof function_fold_proof = ivc.accumulate(function_circuit); - // FoldOutput function_fold_output = { function_fold_proof, function_vk }; - // // Accumulate kernel circuit - // Builder kernel_circuit{ ivc.goblin.op_queue }; - // kernel_acc = - // construct_mock_folding_kernel(kernel_circuit, kernel_fold_output, function_fold_output, kernel_acc); - // FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); - // kernel_vk = composer.compute_verification_key(ivc.prover_instance); - // FoldOutput kernel_fold_output = { kernel_fold_proof, kernel_vk }; - // } + auto function_vk = composer.compute_verification_key(ivc.prover_fold_output.accumulator); + auto kernel_acc = std::make_shared(); + kernel_acc->verification_key = function_vk; + // Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet) + Builder kernel_circuit = create_mock_circuit(ivc); + FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); + auto function_vk_2 = composer.compute_verification_key(ivc.prover_instance); + auto kernel_vk = function_vk_2; + FoldOutput kernel_fold_output = { kernel_fold_proof, function_vk_2 }; + size_t NUM_CIRCUITS = 1; + for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { + // Accumulate function circuit + Builder function_circuit = create_mock_circuit(ivc); + FoldProof function_fold_proof = ivc.accumulate(function_circuit); + FoldOutput function_fold_output = { function_fold_proof, function_vk_2 }; + // Accumulate kernel circuit + Builder kernel_circuit{ ivc.goblin.op_queue }; + kernel_acc = + construct_mock_folding_kernel(kernel_circuit, kernel_fold_output, function_fold_output, kernel_acc); + FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); + kernel_vk = composer.compute_verification_key(ivc.prover_instance); + FoldOutput kernel_fold_output = { kernel_fold_proof, kernel_vk }; + } - // // Constuct four proofs: merge, eccvm, translator, decider - // auto proof = ivc.prove(); - // auto inst = std::make_shared(); - // inst->verification_key = kernel_vk; - // // Verify all four proofs - // EXPECT_TRUE(ivc.verify(proof, { kernel_acc, inst })); + // Constuct four proofs: merge, eccvm, translator, decider + auto proof = ivc.prove(); + auto inst = std::make_shared(); + inst->verification_key = kernel_vk; + // Verify all four proofs + EXPECT_TRUE(ivc.verify(proof, { kernel_acc, inst })); }; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fr_straight.bench.cpp b/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fr_straight.bench.cpp index 95ecc495527..0cde9f29582 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fr_straight.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fr_straight.bench.cpp @@ -5,205 +5,205 @@ using namespace bb; using namespace benchmark; -namespace { -void asm_add_with_coarse_reduction(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - DoNotOptimize(fr::asm_add_with_coarse_reduction(x, y)); - } -} -BENCHMARK(asm_add_with_coarse_reduction); - -void asm_conditional_negate(State& state) noexcept -{ - fr x; - for (auto _ : state) { - fr::asm_conditional_negate(x, true); - } -} -BENCHMARK(asm_conditional_negate); - -void asm_mul_with_coarse_reduction(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - DoNotOptimize(fr::asm_mul_with_coarse_reduction(x, y)); - } -} -BENCHMARK(asm_mul_with_coarse_reduction); - -void asm_reduce_once(State& state) noexcept -{ - fr x; - for (auto _ : state) { - DoNotOptimize(fr::asm_reduce_once(x)); - } -} -BENCHMARK(asm_reduce_once); - -void asm_self_add_with_coarse_reduction(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - fr::asm_self_add_with_coarse_reduction(x, y); - } -} -BENCHMARK(asm_self_add_with_coarse_reduction); - -void asm_self_mul_with_coarse_reduction(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - fr::asm_self_mul_with_coarse_reduction(x, y); - } -} -BENCHMARK(asm_self_mul_with_coarse_reduction); - -void asm_self_reduce_once(State& state) noexcept -{ - fr x; - for (auto _ : state) { - fr::asm_self_reduce_once(x); - } -} -BENCHMARK(asm_self_reduce_once); - -void asm_self_sqr_with_coarse_reduction(State& state) noexcept -{ - fr x; - for (auto _ : state) { - fr::asm_self_sqr_with_coarse_reduction(x); - } -} -BENCHMARK(asm_self_sqr_with_coarse_reduction); - -void asm_self_sub_with_coarse_reduction(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - fr::asm_self_sub_with_coarse_reduction(x, y); - } -} -BENCHMARK(asm_self_sub_with_coarse_reduction); - -void asm_sqr_with_coarse_reduction(State& state) noexcept -{ - fr x; - for (auto _ : state) { - DoNotOptimize(fr::asm_sqr_with_coarse_reduction(x)); - } -} -BENCHMARK(asm_sqr_with_coarse_reduction); - -void mul(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - DoNotOptimize(x * y); - } -} -BENCHMARK(mul); - -void self_mul(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - x *= y; - } -} -BENCHMARK(self_mul); - -void add(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - DoNotOptimize(x + y); - } -} -BENCHMARK(add); - -void self_add(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - x += y; - } -} -BENCHMARK(self_add); - -void sub(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - DoNotOptimize(x - y); - } -} -BENCHMARK(sub); - -void self_sub(State& state) noexcept -{ - fr x, y; - for (auto _ : state) { - x -= y; - } -} -BENCHMARK(self_sub); - -void invert(State& state) noexcept -{ - fr x; - for (auto _ : state) { - DoNotOptimize(x.invert()); - } -} -BENCHMARK(invert); - -void self_neg(State& state) noexcept -{ - fr x; - for (auto _ : state) { - x.self_neg(); - } -} -BENCHMARK(self_neg); - -void self_reduce_once(State& state) noexcept -{ - fr x; - for (auto _ : state) { - x.self_reduce_once(); - } -} -BENCHMARK(self_reduce_once); - -void self_to_montgomery_form(State& state) noexcept -{ - fr x; - for (auto _ : state) { - x.self_to_montgomery_form(); - } -} -BENCHMARK(self_to_montgomery_form); - -void self_sqr(State& state) noexcept -{ - fr x; - for (auto _ : state) { - x.self_sqr(); - } -} -BENCHMARK(self_sqr); - -void sqr(State& state) noexcept -{ - fr x; - for (auto _ : state) { - DoNotOptimize(x.sqr()); - } -} -BENCHMARK(sqr); -} // namespace +// namespace { +// void asm_add_with_coarse_reduction(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// DoNotOptimize(fr::asm_add_with_coarse_reduction(x, y)); +// } +// } +// BENCHMARK(asm_add_with_coarse_reduction); + +// void asm_conditional_negate(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// fr::asm_conditional_negate(x, true); +// } +// } +// BENCHMARK(asm_conditional_negate); + +// void asm_mul_with_coarse_reduction(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// DoNotOptimize(fr::asm_mul_with_coarse_reduction(x, y)); +// } +// } +// BENCHMARK(asm_mul_with_coarse_reduction); + +// void asm_reduce_once(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// DoNotOptimize(fr::asm_reduce_once(x)); +// } +// } +// BENCHMARK(asm_reduce_once); + +// void asm_self_add_with_coarse_reduction(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// fr::asm_self_add_with_coarse_reduction(x, y); +// } +// } +// BENCHMARK(asm_self_add_with_coarse_reduction); + +// void asm_self_mul_with_coarse_reduction(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// fr::asm_self_mul_with_coarse_reduction(x, y); +// } +// } +// BENCHMARK(asm_self_mul_with_coarse_reduction); + +// void asm_self_reduce_once(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// fr::asm_self_reduce_once(x); +// } +// } +// BENCHMARK(asm_self_reduce_once); + +// void asm_self_sqr_with_coarse_reduction(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// fr::asm_self_sqr_with_coarse_reduction(x); +// } +// } +// BENCHMARK(asm_self_sqr_with_coarse_reduction); + +// void asm_self_sub_with_coarse_reduction(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// fr::asm_self_sub_with_coarse_reduction(x, y); +// } +// } +// BENCHMARK(asm_self_sub_with_coarse_reduction); + +// void asm_sqr_with_coarse_reduction(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// DoNotOptimize(fr::asm_sqr_with_coarse_reduction(x)); +// } +// } +// BENCHMARK(asm_sqr_with_coarse_reduction); + +// void mul(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// DoNotOptimize(x * y); +// } +// } +// BENCHMARK(mul); + +// void self_mul(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// x *= y; +// } +// } +// BENCHMARK(self_mul); + +// void add(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// DoNotOptimize(x + y); +// } +// } +// BENCHMARK(add); + +// void self_add(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// x += y; +// } +// } +// BENCHMARK(self_add); + +// void sub(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// DoNotOptimize(x - y); +// } +// } +// BENCHMARK(sub); + +// void self_sub(State& state) noexcept +// { +// fr x, y; +// for (auto _ : state) { +// x -= y; +// } +// } +// BENCHMARK(self_sub); + +// void invert(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// DoNotOptimize(x.invert()); +// } +// } +// BENCHMARK(invert); + +// void self_neg(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// x.self_neg(); +// } +// } +// BENCHMARK(self_neg); + +// void self_reduce_once(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// x.self_reduce_once(); +// } +// } +// BENCHMARK(self_reduce_once); + +// void self_to_montgomery_form(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// x.self_to_montgomery_form(); +// } +// } +// BENCHMARK(self_to_montgomery_form); + +// void self_sqr(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// x.self_sqr(); +// } +// } +// BENCHMARK(self_sqr); + +// void sqr(State& state) noexcept +// { +// fr x; +// for (auto _ : state) { +// DoNotOptimize(x.sqr()); +// } +// } +// BENCHMARK(sqr); +// } // namespace // NOLINTNEXTLINE macro invokation triggers style guideline errors from googletest code BENCHMARK_MAIN(); \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp index 19566c92d00..945ef93bdda 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp @@ -10,43 +10,24 @@ namespace bb::stdlib::recursion::honk { template class ProtoGalaxyRecursiveTests : public testing::Test { public: - // Define types relevant for testing - using UltraComposer = ::bb::UltraComposer_; - using GoblinUltraComposer = ::bb::UltraComposer_; - - using InnerFlavor = typename RecursiveFlavor::NativeFlavor; - using InnerComposer = ::bb::UltraComposer_; - using ProverInstance = ::bb::ProverInstance_; - using VerifierInstance = ::bb::VerifierInstance_; + using NativeFlavor = typename RecursiveFlavor::NativeFlavor; + using Composer = ::bb::UltraComposer_; + using Builder = typename RecursiveFlavor::CircuitBuilder; + using ProverInstance = ::bb::ProverInstance_; + using VerifierInstance = ::bb::VerifierInstance_; using RecursiveVerifierInstance = ::bb::stdlib::recursion::honk::RecursiveVerifierInstance_; - using InnerBuilder = typename InnerComposer::CircuitBuilder; - using InnerCurve = bn254; - using Commitment = typename InnerFlavor::Commitment; - using FF = typename InnerFlavor::FF; - - // Types for veryfing a recursive verifier circuit - using OuterBuilder = GoblinUltraCircuitBuilder; - using OuterComposer = GoblinUltraComposer; + using Curve = bn254; + using Commitment = typename NativeFlavor::Commitment; + using FF = typename NativeFlavor::FF; using RecursiveVerifierInstances = ::bb::stdlib::recursion::honk::RecursiveVerifierInstances_; using FoldingRecursiveVerifier = ProtoGalaxyRecursiveVerifier_; using DeciderRecursiveVerifier = DeciderRecursiveVerifier_; - using DeciderVerifier = DeciderVerifier_; - using NativeVerifierInstances = VerifierInstances_; + using DeciderVerifier = DeciderVerifier_; + using NativeVerifierInstances = VerifierInstances_; using NativeFoldingVerifier = ProtoGalaxyVerifier_; static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); } - - // Helper for getting composer for prover/verifier of recursive (outer) circuit - template static auto get_outer_composer() - { - if constexpr (IsGoblinBuilder) { - return GoblinUltraComposer(); - } else { - return UltraComposer(); - } - } - /** * @brief Create a non-trivial arbitrary inner circuit, the proof of which will be recursively verified * @@ -57,15 +38,15 @@ template class ProtoGalaxyRecursiveTests : public tes * TODO(https://github.com/AztecProtocol/barretenberg/issues/744): make testing utility with functionality shared * amongst test files */ - static void create_inner_circuit(InnerBuilder& builder, size_t log_num_gates = 15) + static void create_function_circuit(Builder& builder, size_t log_num_gates = 15) { - using fr_ct = typename InnerCurve::ScalarField; - using fq_ct = typename InnerCurve::BaseField; - using public_witness_ct = typename InnerCurve::public_witness_ct; - using witness_ct = typename InnerCurve::witness_ct; - using byte_array_ct = typename InnerCurve::byte_array_ct; - using fr = typename InnerCurve::ScalarFieldNative; - using point = typename InnerCurve::AffineElementNative; + using fr_ct = typename Curve::ScalarField; + using fq_ct = typename Curve::BaseField; + using public_witness_ct = typename Curve::public_witness_ct; + using witness_ct = typename Curve::witness_ct; + using byte_array_ct = typename Curve::byte_array_ct; + using fr = typename Curve::ScalarFieldNative; + using point = typename Curve::AffineElementNative; // Create 2^log_n many add gates based on input log num gates const size_t num_gates = 1 << log_num_gates; @@ -92,7 +73,7 @@ template class ProtoGalaxyRecursiveTests : public tes a = (a * b) + b + a; a = a.madd(b, c); } - pedersen_hash::hash({ a, b }); + pedersen_hash::hash({ a, b }); byte_array_ct to_hash(&builder, "nonsense test data"); blake3s(to_hash); @@ -105,7 +86,7 @@ template class ProtoGalaxyRecursiveTests : public tes big_a* big_b; - if constexpr (IsGoblinBuilder) { + if constexpr (IsGoblinBuilder) { auto p = point::one() * fr::random_element(); auto scalar = fr::random_element(); builder.queue_ecc_mul_accum(p, scalar); @@ -114,12 +95,20 @@ template class ProtoGalaxyRecursiveTests : public tes }; static std::tuple, std::shared_ptr> fold_and_verify_native( - const std::vector>& prover_instances, - const std::vector>& verifier_instances, - InnerComposer& composer) + Composer& composer) { - auto folding_prover = composer.create_folding_prover(prover_instances); - auto folding_verifier = composer.create_folding_verifier(verifier_instances); + Builder builder1; + create_function_circuit(builder1); + Builder builder2; + builder2.add_public_variable(FF(1)); + create_function_circuit(builder2); + + auto prover_instance_1 = composer.create_prover_instance(builder1); + auto prover_instance_2 = composer.create_prover_instance(builder2); + auto verifier_instance_1 = composer.create_verifier_instance(prover_instance_1); + auto verifier_instance_2 = composer.create_verifier_instance(prover_instance_2); + auto folding_prover = composer.create_folding_prover({ prover_instance_1, prover_instance_2 }); + auto folding_verifier = composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); auto [prover_accumulator, folding_proof] = folding_prover.fold_instances(); auto verifier_accumulator = folding_verifier.verify_folding_proof(folding_proof); @@ -131,9 +120,9 @@ template class ProtoGalaxyRecursiveTests : public tes */ static void test_inner_circuit() { - InnerBuilder builder; + Builder builder; - create_inner_circuit(builder); + create_function_circuit(builder); bool result = builder.check_circuit(); EXPECT_EQ(result, true); @@ -146,9 +135,9 @@ template class ProtoGalaxyRecursiveTests : public tes */ static void test_new_evaluate() { - OuterBuilder builder; - using fr_ct = bn254::ScalarField; - using fr = bn254::ScalarFieldNative; + Builder builder; + using fr_ct = bn254::ScalarField; + using fr = bn254::ScalarFieldNative; std::vector coeffs; std::vector coeffs_ct; @@ -173,32 +162,90 @@ template class ProtoGalaxyRecursiveTests : public tes static void test_recursive_folding() { // Create two arbitrary circuits for the first round of folding - InnerBuilder builder1; - create_inner_circuit(builder1); - InnerBuilder builder2; - create_inner_circuit(builder2); - - InnerComposer inner_composer = InnerComposer(); - auto prover_instance_1 = inner_composer.create_prover_instance(builder1); - auto verifier_instance_1 = inner_composer.create_verifier_instance(prover_instance_1); - auto prover_instance_2 = inner_composer.create_prover_instance(builder2); - auto verifier_instance_2 = inner_composer.create_verifier_instance(prover_instance_2); + Builder builder1; + create_function_circuit(builder1); + Builder builder2; + create_function_circuit(builder2); + + Composer composer = Composer(); + auto prover_instance_1 = composer.create_prover_instance(builder1); + auto verifier_instance_1 = composer.create_verifier_instance(prover_instance_1); + auto prover_instance_2 = composer.create_prover_instance(builder2); + auto verifier_instance_2 = composer.create_verifier_instance(prover_instance_2); + // Generate a folding proof + auto inner_folding_prover = composer.create_folding_prover({ prover_instance_1, prover_instance_2 }); + auto inner_folding_proof = inner_folding_prover.fold_instances(); + + // Create a recursive folding verifier circuit for the folding proof of the two instances + Builder folding_circuit; + auto verifier = + FoldingRecursiveVerifier(&folding_circuit, verifier_instance_1, { verifier_instance_2->verification_key }); + auto recursive_verifier_accumulator = verifier.verify_folding_proof(inner_folding_proof.folding_data); + auto acc = std::make_shared(recursive_verifier_accumulator->get_value()); + info("Folding Recursive Verifier: num gates = ", folding_circuit.num_gates); + + // Perform native folding verification and ensure it returns the same result (either true or false) as + // calling check_circuit on the recursive folding verifier + auto native_folding_verifier = composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); + auto verifier_accumulator = native_folding_verifier.verify_folding_proof(inner_folding_proof.folding_data); + + // Ensure that the underlying native and recursive folding verification algorithms agree by ensuring the + // manifestsproduced by each agree. + auto recursive_folding_manifest = verifier.transcript->get_manifest(); + auto native_folding_manifest = native_folding_verifier.transcript->get_manifest(); + + for (size_t i = 0; i < recursive_folding_manifest.size(); ++i) { + EXPECT_EQ(recursive_folding_manifest[i], native_folding_manifest[i]); + } + + { + auto composer = Composer(); + auto instance = composer.create_prover_instance(folding_circuit); + auto verification_key = composer.compute_verification_key(instance); + auto prover = composer.create_prover(instance); + auto verifier = composer.create_verifier(verification_key); + auto proof = prover.construct_proof(); + bool verified = verifier.verify_proof(proof); + + ASSERT(verified); + } + }; + + /** + * @brief Perform two rounds of folding valid circuits and then recursive verify the final decider proof, + * make sure the verifer circuits pass check_circuit(). Ensure that the algorithm of the recursive and native + * verifiers are identical by checking the manifests + */ + // TODO(https://github.com/AztecProtocol/barretenberg/issues/844): Fold the recursive folding verifier in + // tests once we can fold instances of different sizes. + static void test_full_protogalaxy_recursive() + { + // Create two arbitrary circuits for the first round of folding + Builder builder1; + create_function_circuit(builder1); + Builder builder2; + create_function_circuit(builder2); + + Composer composer = Composer(); + auto prover_instance_1 = composer.create_prover_instance(builder1); + auto verifier_instance_1 = composer.create_verifier_instance(prover_instance_1); + auto prover_instance_2 = composer.create_prover_instance(builder2); + auto verifier_instance_2 = composer.create_verifier_instance(prover_instance_2); // Generate a folding proof - auto inner_folding_prover = inner_composer.create_folding_prover({ prover_instance_1, prover_instance_2 }); + auto inner_folding_prover = composer.create_folding_prover({ prover_instance_1, prover_instance_2 }); auto inner_folding_proof = inner_folding_prover.fold_instances(); // Create a recursive folding verifier circuit for the folding proof of the two instances - OuterBuilder outer_folding_circuit; - auto verifier = FoldingRecursiveVerifier( - &outer_folding_circuit, verifier_instance_1, { verifier_instance_2->verification_key }); + Builder folding_circuit; + auto verifier = + FoldingRecursiveVerifier(&folding_circuit, verifier_instance_1, { verifier_instance_2->verification_key }); auto recursive_verifier_accumulator = verifier.verify_folding_proof(inner_folding_proof.folding_data); auto acc = std::make_shared(recursive_verifier_accumulator->get_value()); - info("Folding Recursive Verifier: num gates = ", outer_folding_circuit.num_gates); + info("Folding Recursive Verifier: num gates = ", folding_circuit.num_gates); // Perform native folding verification and ensure it returns the same result (either true or false) as // calling check_circuit on the recursive folding verifier - auto native_folding_verifier = - inner_composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); + auto native_folding_verifier = composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); auto verifier_accumulator = native_folding_verifier.verify_folding_proof(inner_folding_proof.folding_data); // Ensure that the underlying native and recursive folding verification algorithms agree by ensuring the @@ -210,28 +257,28 @@ template class ProtoGalaxyRecursiveTests : public tes EXPECT_EQ(recursive_folding_manifest[i], native_folding_manifest[i]); } - auto inner_decider_prover = inner_composer.create_decider_prover(inner_folding_proof.accumulator); + auto inner_decider_prover = composer.create_decider_prover(inner_folding_proof.accumulator); auto inner_decider_proof = inner_decider_prover.construct_proof(); - OuterBuilder outer_decider_circuit; - DeciderRecursiveVerifier decider_verifier{ &outer_decider_circuit, acc }; + Builder decider_circuit; + DeciderRecursiveVerifier decider_verifier{ &decider_circuit, acc }; auto pairing_points = decider_verifier.verify_proof(inner_decider_proof); - info("Decider Recursive Verifier: num gates = ", outer_decider_circuit.num_gates); + info("Decider Recursive Verifier: num gates = ", decider_circuit.num_gates); // Check for a failure flag in the recursive verifier circuit - EXPECT_EQ(outer_decider_circuit.failed(), false) << outer_decider_circuit.err(); + EXPECT_EQ(decider_circuit.failed(), false) << decider_circuit.err(); // Check for a failure flag in the recursive verifier circuit - EXPECT_EQ(outer_folding_circuit.failed(), false) << outer_folding_circuit.err(); + EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err(); - DeciderVerifier native_decider_verifier = inner_composer.create_decider_verifier(verifier_accumulator); + DeciderVerifier native_decider_verifier = composer.create_decider_verifier(verifier_accumulator); auto native_result = native_decider_verifier.verify_proof(inner_decider_proof); auto recursive_result = native_decider_verifier.pcs_verification_key->pairing_check( pairing_points[0].get_value(), pairing_points[1].get_value()); EXPECT_EQ(native_result, recursive_result); { - auto composer = OuterComposer(); - auto instance = composer.create_prover_instance(outer_folding_circuit); + auto composer = Composer(); + auto instance = composer.create_prover_instance(decider_circuit); auto verification_key = composer.compute_verification_key(instance); auto prover = composer.create_prover(instance); auto verifier = composer.create_verifier(verification_key); @@ -242,150 +289,64 @@ template class ProtoGalaxyRecursiveTests : public tes } }; - /** - * @brief Perform two rounds of folding valid circuits and then recursive verify the final decider proof, - * make sure the verifer circuits pass check_circuit(). Ensure that the algorithm of the recursive and native - * verifiers are identical by checking the manifests - */ - // TODO(https://github.com/AztecProtocol/barretenberg/issues/844): Fold the recursive folding verifier in - // tests once - // we can fold instances of different sizes. - // static void test_full_protogalaxy_recursive() - // { - // // Create two arbitrary circuits for the first round of folding - // InnerBuilder builder1; - - // create_inner_circuit(builder1); - // InnerBuilder builder2; - // builder2.add_public_variable(FF(1)); - // create_inner_circuit(builder2); - - // InnerComposer inner_composer = InnerComposer(); - // auto prover_instance_1 = inner_composer.create_prover_instance(builder1); - // auto verifier_instance_1 = inner_composer.create_verifier_instance(prover_instance_1); - // auto prover_instance_2 = inner_composer.create_prover_instance(builder2); - // auto verifier_instance_2 = inner_composer.create_verifier_instance(prover_instance_2); - - // auto [prover_accumulator, verifier_accumulator] = fold_and_verify_native( - // { prover_instance_1, prover_instance_2 }, { verifier_instance_1, verifier_instance_2 }, - // tinner_composer); - - // // Create another circuit to do a second round of folding - // InnerBuilder builder3; - // create_inner_circuit(builder3); - // auto prover_instance_3 = inner_composer.create_prover_instance(builder3); - // auto verifier_instance_3 = inner_composer.create_verifier_instance(prover_instance_3); - - // auto [prover_accumulator_2, verifier_accumulator_2] = fold_and_verify_native( - // { prover_accumulator, prover_instance_3 }, { verifier_accumulator, verifier_instance_3 }, - // inner_composer); - - // // Create a decider proof for the relaxed instance obtained through folding - // auto inner_decider_prover = inner_composer.create_decider_prover(prover_accumulator_2); - // auto inner_decider_proof = inner_decider_prover.construct_proof(); - - // // Create a decider verifier circuit for recursively verifying the decider proof - // OuterBuilder outer_decider_circuit; - // DeciderRecursiveVerifier decider_verifier{ &outer_decider_circuit }; - // auto pairing_points = decider_verifier.verify_proof(inner_decider_proof); - // info("Decider Recursive Verifier: num gates = ", outer_decider_circuit.num_gates); - // // Check for a failure flag in the recursive verifier circuit - // EXPECT_EQ(outer_decider_circuit.failed(), false) << outer_decider_circuit.err(); - - // // Perform native verification then perform the pairing on the outputs of the recursive - // // decider verifier and check that the result agrees. - - // // Ensure that the underlying native and recursive decider verification algorithms agree by ensuring - // // the manifests produced are the same. - // auto recursive_decider_manifest = decider_verifier.transcript->get_manifest(); - // auto native_decider_manifest = native_decider_verifier.transcript->get_manifest(); - // for (size_t i = 0; i < recursive_decider_manifest.size(); ++i) { - // EXPECT_EQ(recursive_decider_manifest[i], native_decider_manifest[i]); - // } - - // // Construct and verify a proof of the recursive decider verifier circuit - // { - // auto composer = OuterComposer(); - // auto instance = composer.create_prover_instance(outer_decider_circuit); - // auto prover = composer.create_prover(instance); - // auto verifier = composer.create_verifier(instance); - // auto proof = prover.construct_proof(); - // bool verified = verifier.verify_proof(proof); - - // ASSERT(verified); - // } - // }; - - // static void test_tampered_decider_proof() - // { - // // Create two arbitrary circuits for the first round of folding - // InnerBuilder builder1; - - // create_inner_circuit(builder1); - // InnerBuilder builder2; - // builder2.add_public_variable(FF(1)); - // create_inner_circuit(builder2); - - // InnerComposer inner_composer = InnerComposer(); - // auto prover_instance_1 = inner_composer.create_prover_instance(builder1); - // auto prover_instance_2 = inner_composer.create_prover_instance(builder2); - // auto instances = std::vector>{ prover_instance_1, prover_instance_2 }; - - // auto accumulator = fold_and_verify_native(instances, inner_composer); - - // // Tamper with the accumulator by changing the target sum - // accumulator->target_sum = FF::random_element(); - - // // Create a decider proof for the relaxed instance obtained through folding - // auto inner_decider_prover = inner_composer.create_decider_prover(accumulator); - // auto inner_decider_proof = inner_decider_prover.construct_proof(); - - // // Create a decider verifier circuit for recursively verifying the decider proof - // OuterBuilder outer_decider_circuit; - // DeciderRecursiveVerifier decider_verifier{ &outer_decider_circuit }; - // decider_verifier.verify_proof(inner_decider_proof); - // info("Decider Recursive Verifier: num gates = ", outer_decider_circuit.num_gates); - - // // We expect the decider circuit check to fail due to the bad proof - // EXPECT_FALSE(outer_decider_circuit.check_circuit()); - // }; - - // static void test_tampered_accumulator() - // { - // // Create two arbitrary circuits for the first round of folding - // InnerBuilder builder1; - - // create_inner_circuit(builder1); - // InnerBuilder builder2; - // builder2.add_public_variable(FF(1)); - // create_inner_circuit(builder2); - - // InnerComposer inner_composer = InnerComposer(); - // auto prover_instance_1 = inner_composer.create_prover_instance(builder1); - // auto prover_instance_2 = inner_composer.create_prover_instance(builder2); - // auto instances = std::vector>{ prover_instance_1, prover_instance_2 }; - - // auto accumulator = fold_and_verify_native(instances, inner_composer); - - // // Create another circuit to do a second round of folding - // InnerBuilder builder3; - // create_inner_circuit(builder3); - // auto instance3 = inner_composer.create_prover_instance(builder3); - - // // Tamper with the accumulator - // instances = std::vector>{ accumulator, instance3 }; - // accumulator->prover_polynomials.w_l[1] = FF::random_element(); - - // // Generate a folding proof - // auto inner_folding_prover = inner_composer.create_folding_prover(instances); - // auto inner_folding_proof = inner_folding_prover.fold_instances(); - - // // Create a recursive folding verifier circuit for the folding proof of the two instances - // OuterBuilder outer_folding_circuit; - // FoldingRecursiveVerifier verifier{ &outer_folding_circuit }; - // verifier.verify_folding_proof(inner_folding_proof.folding_data); - // EXPECT_EQ(outer_folding_circuit.check_circuit(), false); - // }; + static void test_tampered_decider_proof() + { + // Create two arbitrary circuits for the first round of folding + auto composer = Composer(); + auto [prover_accumulator, verifier_accumulator] = fold_and_verify_native(composer); + + // Tamper with the accumulator by changing the target sum + verifier_accumulator->target_sum = FF::random_element(); + + // Create a decider proof for the relaxed instance obtained through folding + auto inner_decider_prover = composer.create_decider_prover(prover_accumulator); + auto inner_decider_proof = inner_decider_prover.construct_proof(); + + // Create a decider verifier circuit for recursively verifying the decider proof + Builder decider_circuit; + DeciderRecursiveVerifier decider_verifier{ &decider_circuit, verifier_accumulator }; + decider_verifier.verify_proof(inner_decider_proof); + info("Decider Recursive Verifier: num gates = ", decider_circuit.num_gates); + + { + auto composer = Composer(); + auto instance = composer.create_prover_instance(decider_circuit); + auto verification_key = composer.compute_verification_key(instance); + auto prover = composer.create_prover(instance); + auto verifier = composer.create_verifier(verification_key); + auto proof = prover.construct_proof(); + bool verified = verifier.verify_proof(proof); + + EXPECT_FALSE(verified); + } + }; + + static void test_tampered_accumulator() + { + + auto composer = Composer(); + auto [prover_accumulator, verifier_accumulator] = fold_and_verify_native(composer); + + // Create another circuit to do a second round of folding + Builder builder3; + create_function_circuit(builder3); + auto prover_inst = composer.create_prover_instance(builder3); + auto verifier_inst = composer.create_verifier_instance(prover_inst); + + prover_accumulator->prover_polynomials.w_l[1] = FF::random_element(); + + // Generate a folding proof + auto inner_folding_prover = composer.create_folding_prover({ prover_accumulator, prover_inst }); + auto inner_folding_proof = inner_folding_prover.fold_instances(); + + // Create a recursive folding verifier circuit for the folding proof of the two instances + Builder folding_circuit; + FoldingRecursiveVerifier verifier{ &folding_circuit, + verifier_accumulator, + { verifier_inst->verification_key } }; + auto recursive_verifier_acc = verifier.verify_folding_proof(inner_folding_proof.folding_data); + EXPECT_FALSE(inner_folding_proof.accumulator->target_sum == recursive_verifier_acc->target_sum.get_value()); + }; }; using FlavorTypes = testing::Types>; @@ -406,20 +367,20 @@ TYPED_TEST(ProtoGalaxyRecursiveTests, RecursiveFoldingTest) TestFixture::test_recursive_folding(); } -// TYPED_TEST(ProtoGalaxyRecursiveTests, FullProtogalaxyRecursiveTest) -// { +TYPED_TEST(ProtoGalaxyRecursiveTests, FullProtogalaxyRecursiveTest) +{ -// TestFixture::test_full_protogalaxy_recursive(); -// } + TestFixture::test_full_protogalaxy_recursive(); +} -// TYPED_TEST(ProtoGalaxyRecursiveTests, TamperedDeciderProof) -// { -// TestFixture::test_tampered_decider_proof(); -// } +TYPED_TEST(ProtoGalaxyRecursiveTests, TamperedDeciderProof) +{ + TestFixture::test_tampered_decider_proof(); +} -// TYPED_TEST(ProtoGalaxyRecursiveTests, TamperedAccumulator) -// { -// TestFixture::test_tampered_accumulator(); -// } +TYPED_TEST(ProtoGalaxyRecursiveTests, TamperedAccumulator) +{ + TestFixture::test_tampered_accumulator(); +} } // namespace bb::stdlib::recursion::honk \ No newline at end of file From ffaddfcb94a1df7e22493826dc272c9eeafb7442 Mon Sep 17 00:00:00 2001 From: maramihali Date: Mon, 19 Feb 2024 15:59:02 +0000 Subject: [PATCH 06/15] cleanup --- .../benchmark/ivc_bench/ivc.bench.cpp | 13 +- .../protogalaxy_rounds.bench.cpp | 105 ++++++++-------- .../barretenberg/client_ivc/client_ivc.cpp | 48 ++++---- .../barretenberg/client_ivc/client_ivc.hpp | 11 +- .../client_ivc/client_ivc.test.cpp | 3 +- .../src/barretenberg/goblin/mock_circuits.hpp | 1 + .../protogalaxy/decider_verifier.cpp | 48 -------- .../protogalaxy/protogalaxy_prover.cpp | 115 ++++++------------ .../protogalaxy/protogalaxy_prover.hpp | 52 +++++--- .../protogalaxy/protogalaxy_verifier.cpp | 3 - .../protogalaxy_recursive_verifier.test.cpp | 42 +++---- .../sumcheck/instance/prover_instance.hpp | 14 +-- .../sumcheck/instance/verifier_instance.hpp | 5 + .../barretenberg/ultra_honk/ultra_prover.cpp | 2 +- 14 files changed, 190 insertions(+), 272 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp index b9dc4da4a57..59f08406adf 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp @@ -48,8 +48,8 @@ class IvcBench : public benchmark::Fixture { Builder initial_function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit); ivc.initialize(initial_function_circuit); - auto kernel_acc = std::make_shared(); - kernel_acc->verification_key = ivc.vks[0]; + auto kernel_verifeir_accumulator = std::make_shared(); + kernel_verifeir_accumulator->verification_key = ivc.vks[0]; Builder function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(function_circuit); @@ -57,14 +57,15 @@ class IvcBench : public benchmark::Fixture { FoldOutput function_fold_output = { function_fold_proof, ivc.vks[1] }; Builder kernel_circuit{ ivc.goblin.op_queue }; - kernel_acc = - GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, function_fold_output, {}, kernel_acc); + kernel_verifeir_accumulator = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, function_fold_output, {}, kernel_verifeir_accumulator); auto kernel_fold_proof = ivc.accumulate(kernel_circuit); FoldOutput kernel_fold_output = { kernel_fold_proof, ivc.vks[2] }; auto NUM_CIRCUITS = static_cast(state.range(0)); // Subtract one to account for the "initialization" round above NUM_CIRCUITS -= 1; for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { + // Accumulate function circuit Builder function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(function_circuit); auto function_fold_proof = ivc.accumulate(function_circuit); @@ -72,8 +73,8 @@ class IvcBench : public benchmark::Fixture { // Accumulate kernel circuit Builder kernel_circuit{ ivc.goblin.op_queue }; - kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel( - kernel_circuit, function_fold_output, kernel_fold_output, kernel_acc); + kernel_verifeir_accumulator = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, function_fold_output, kernel_fold_output, kernel_verifeir_accumulator); kernel_fold_proof = ivc.accumulate(kernel_circuit); kernel_fold_output = { kernel_fold_proof, ivc.vks[3] }; diff --git a/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp index 0776ef3631e..5efdccce9ce 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/protogalaxy_rounds_bench/protogalaxy_rounds.bench.cpp @@ -12,41 +12,40 @@ template void _bench_round(::benchmark::State& state, void (*F)(ProtoGalaxyProver_>&)) { - // using Flavor = typename Composer::Flavor; - // using Instance = ProverInstance_; - // using Builder = typename Flavor::CircuitBuilder; - static_cast(state); - static_cast(F); - // bb::srs::init_crs_factory("../srs_db/ignition"); - // auto log2_num_gates = static_cast(state.range(0)); - // auto composer = Composer(); - - // const auto construct_instance = [&]() { - // Builder builder; - // if constexpr (std::same_as) { - // GoblinMockCircuits::construct_arithmetic_circuit(builder, log2_num_gates); - // } else { - // static_assert(std::same_as); - // bb::mock_proofs::generate_basic_arithmetic_circuit(builder, log2_num_gates); - // } - // return composer.create_prover_instance(builder); - // }; - - // std::shared_ptr instance_1 = construct_instance(); - // std::shared_ptr instance_2 = construct_instance(); - - // auto folding_prover = composer.create_folding_prover({ instance_1, instance_2 }); - - // // prepare the prover state - // folding_prover.state.accumulator = instance_1; - // folding_prover.state.deltas.resize(log2_num_gates); - // std::fill_n(folding_prover.state.deltas.begin(), log2_num_gates, 0); - // folding_prover.state.perturbator = Flavor::Polynomial::random(1 << log2_num_gates); - // folding_prover.transcript = Flavor::Transcript::prover_init_empty(); - // folding_prover.preparation_round(); - - // for (auto _ : state) { - // F(folding_prover); + using Flavor = typename Composer::Flavor; + using Builder = typename Flavor::CircuitBuilder; + + bb::srs::init_crs_factory("../srs_db/ignition"); + auto log2_num_gates = static_cast(state.range(0)); + auto composer = Composer(); + + const auto construct_instance = [&]() { + Builder builder; + if constexpr (std::same_as) { + GoblinMockCircuits::construct_arithmetic_circuit(builder, log2_num_gates); + } else { + static_assert(std::same_as); + bb::mock_proofs::generate_basic_arithmetic_circuit(builder, log2_num_gates); + } + return composer.create_prover_instance(builder); + }; + + auto prover_instance_1 = construct_instance(); + auto prover_instance_2 = construct_instance(); + + auto folding_prover = composer.create_folding_prover({ prover_instance_1, prover_instance_2 }); + + // prepare the prover state + folding_prover.state.accumulator = prover_instance_1; + folding_prover.state.deltas.resize(log2_num_gates); + std::fill_n(folding_prover.state.deltas.begin(), log2_num_gates, 0); + folding_prover.state.perturbator = Flavor::Polynomial::random(1 << log2_num_gates); + folding_prover.transcript = Flavor::Transcript::prover_init_empty(); + folding_prover.preparation_round(); + + for (auto _ : state) { + F(folding_prover); + } } void bench_round_ultra(::benchmark::State& state, void (*F)(ProtoGalaxyProver_>&)) @@ -60,25 +59,23 @@ void bench_round_goblin_ultra(::benchmark::State& state, _bench_round(state, F); } -// BENCHMARK_CAPTURE(bench_round_ultra, preparation, [](auto& prover) { prover.preparation_round(); }) -// -> DenseRange(14, 20) -> Unit(kMillisecond); -// BENCHMARK_CAPTURE(bench_round_ultra, perturbator, [](auto& prover) { prover.perturbator_round(); }) -// -> DenseRange(14, 20) -> Unit(kMillisecond); -// BENCHMARK_CAPTURE(bench_round_ultra, combiner_quotient, [](auto& prover) { prover.combiner_quotient_round(); }) -// -> DenseRange(14, 20) -> Unit(kMillisecond); -// BENCHMARK_CAPTURE(bench_round_ultra, accumulator_update, [](auto& prover) { prover.accumulator_update_round(); }) -// -> DenseRange(14, 20) -> Unit(kMillisecond); - -// BENCHMARK_CAPTURE(bench_round_goblin_ultra, preparation, [](auto& prover) { prover.preparation_round(); }) -// -> DenseRange(14, 20) -> Unit(kMillisecond); -// BENCHMARK_CAPTURE(bench_round_goblin_ultra, perturbator, [](auto& prover) { prover.perturbator_round(); }) -// -> DenseRange(14, 20) -> Unit(kMillisecond); -// BENCHMARK_CAPTURE(bench_round_goblin_ultra, combiner_quotient, [](auto& prover) { prover.combiner_quotient_round(); -// }) -// -> DenseRange(14, 20) -> Unit(kMillisecond); -// BENCHMARK_CAPTURE(bench_round_goblin_ultra, accumulator_update, [](auto& prover) { prover.accumulator_update_round(); -// }) -// -> DenseRange(14, 20) -> Unit(kMillisecond); +BENCHMARK_CAPTURE(bench_round_ultra, preparation, [](auto& prover) { prover.preparation_round(); }) + -> DenseRange(14, 20) -> Unit(kMillisecond); +BENCHMARK_CAPTURE(bench_round_ultra, perturbator, [](auto& prover) { prover.perturbator_round(); }) + -> DenseRange(14, 20) -> Unit(kMillisecond); +BENCHMARK_CAPTURE(bench_round_ultra, combiner_quotient, [](auto& prover) { prover.combiner_quotient_round(); }) + -> DenseRange(14, 20) -> Unit(kMillisecond); +BENCHMARK_CAPTURE(bench_round_ultra, accumulator_update, [](auto& prover) { prover.accumulator_update_round(); }) + -> DenseRange(14, 20) -> Unit(kMillisecond); + +BENCHMARK_CAPTURE(bench_round_goblin_ultra, preparation, [](auto& prover) { prover.preparation_round(); }) + -> DenseRange(14, 20) -> Unit(kMillisecond); +BENCHMARK_CAPTURE(bench_round_goblin_ultra, perturbator, [](auto& prover) { prover.perturbator_round(); }) + -> DenseRange(14, 20) -> Unit(kMillisecond); +BENCHMARK_CAPTURE(bench_round_goblin_ultra, combiner_quotient, [](auto& prover) { prover.combiner_quotient_round(); }) + -> DenseRange(14, 20) -> Unit(kMillisecond); +BENCHMARK_CAPTURE(bench_round_goblin_ultra, accumulator_update, [](auto& prover) { prover.accumulator_update_round(); }) + -> DenseRange(14, 20) -> Unit(kMillisecond); } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 4377c149782..46bce07ed05 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -63,7 +63,7 @@ bool ClientIVC::verify(Proof& proof, const std::vectorinstance_size); - vks[0] = composer.compute_verification_key(prover_fold_output.accumulator); auto verifier_acc = std::make_shared(); verifier_acc->verification_key = vks[0]; - ClientCircuit circuit_2{ goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(circuit_2); - auto fold_proof_1 = accumulate(circuit_2); + // Accumulate the next function circuit + ClientCircuit function_circuit{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(function_circuit); + auto function_fold_proof = accumulate(function_circuit); + + // Create its verification key (we have called accumulate so it includes the recursive merge verifier) vks[1] = composer.compute_verification_key(prover_instance); - FoldOutput kernel_accum; - // Construct kernel circuit + // Create the initial kernel iteration and precompute its verification key ClientCircuit kernel_circuit{ goblin.op_queue }; - auto new_acc = - GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, { fold_proof_1, vks[1] }, {}, verifier_acc); - auto fold_proof_3 = accumulate(kernel_circuit); - vks[2] = composer.compute_verification_key(prover_instance); // first iteration of a kernel is smaller + auto new_acc = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, { function_fold_proof, vks[1] }, {}, verifier_acc); + auto kernel_fold_proof = accumulate(kernel_circuit); + vks[2] = composer.compute_verification_key(prover_instance); + // Create another mock function circuit to run the full kernel ClientCircuit circuit_4{ goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_4); - auto fold_proof_4 = accumulate(circuit_4); + function_fold_proof = accumulate(circuit_4); + // Create the fullk ernel circuit and compute verification key ClientCircuit new_kernel_circuit = GoblinUltraCircuitBuilder{ goblin.op_queue }; auto new_new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - new_kernel_circuit, { fold_proof_4, vks[1] }, { fold_proof_3, vks[2] }, new_acc); - - auto fold_proof_5 = accumulate(new_kernel_circuit); + new_kernel_circuit, { function_fold_proof, vks[1] }, { kernel_fold_proof, vks[2] }, new_acc); + kernel_fold_proof = accumulate(new_kernel_circuit); vks[3] = composer.compute_verification_key(prover_instance); auto kernel_inst = std::make_shared(); kernel_inst->verification_key = vks[3]; + // Clean the ivc state goblin.op_queue = std::make_shared(); goblin.merge_proof_exists = false; GoblinMockCircuits::perform_op_queue_interactions_for_mock_first_circuit(goblin.op_queue); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp index eb682ab9f36..b0903fa6822 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp @@ -32,11 +32,6 @@ class ClientIVC { Goblin::Proof goblin_proof; }; - struct FoldOutput { - FoldProof fold_proof; - std::shared_ptr inst_vk; - }; - private: using ProverFoldOutput = FoldingResult; using Composer = GoblinUltraComposer; @@ -46,7 +41,8 @@ class ClientIVC { ProverFoldOutput prover_fold_output; ProverAccumulator prover_accumulator; - // keep the instance or instances around if we're folding more of them so we can compute the verification key + // Note: We need to save the last instance that was folded in order to compute its verification key, this will not + // be needed in the real IVC as they are provided as inputs std::shared_ptr prover_instance; std::array, 4> vks; @@ -65,9 +61,6 @@ class ClientIVC { void decider_prove_and_verify(const VerifierAccumulator&) const; - VerifierAccumulator get_verifier_accumulator(); - std::shared_ptr get_verifier_instance() const; - void precompute_folding_verification_keys(); }; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp index 5faa3ee9bbd..ebbbb5b5219 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp @@ -108,8 +108,7 @@ TEST_F(ClientIVCTests, Full) // Constuct four proofs: merge, eccvm, translator, decider auto proof = ivc.prove(); - auto inst = std::make_shared(); - inst->verification_key = kernel_vk; + auto inst = std::make_shared(kernel_vk); // Verify all four proofs EXPECT_TRUE(ivc.verify(proof, { kernel_acc, inst })); }; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index d13c64b547d..06a5c1e419a 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -242,6 +242,7 @@ class GoblinMockCircuits { stdlib::generate_ecdsa_verification_test_circuit(builder, NUM_ECDSA_VERIFICATIONS); stdlib::generate_sha256_test_circuit(builder, NUM_SHA_HASHES); + // Init if (kernel.fold_proof.empty()) { FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { func.inst_vk } }; auto fctn_verifier_accum = verifier_1.verify_folding_proof(func.fold_proof); diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp index 197d739817e..173ed95e488 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_verifier.cpp @@ -25,58 +25,11 @@ DeciderVerifier_::DeciderVerifier_() */ template bool DeciderVerifier_::verify_proof(const HonkProof& proof) { - // using FF = typename Flavor::FF; - // using Commitment = typename Flavor::Commitment; using Curve = typename Flavor::Curve; using ZeroMorph = ZeroMorphVerifier_; - // using Instance = VerifierInstance_; using VerifierCommitments = typename Flavor::VerifierCommitments; - // static constexpr size_t NUM_SUBRELATIONS = Flavor::NUM_SUBRELATIONS; transcript = std::make_shared(proof); - // auto inst = std::make_unique(); - - // inst->instance_size = transcript->template receive_from_prover("instance_size"); - // inst->log_instance_size = static_cast(numeric::get_msb(inst->instance_size)); - // inst->public_input_size = transcript->template receive_from_prover("public_input_size"); - - // for (size_t i = 0; i < inst->public_input_size; ++i) { - // auto public_input_i = transcript->template receive_from_prover("public_input_" + std::to_string(i)); - // inst->public_inputs.emplace_back(public_input_i); - // } - - // auto eta = transcript->template receive_from_prover("eta"); - // auto beta = transcript->template receive_from_prover("beta"); - // auto gamma = transcript->template receive_from_prover("gamma"); - // auto public_input_delta = transcript->template receive_from_prover("public_input_delta"); - // auto lookup_grand_product_delta = transcript->template receive_from_prover("lookup_grand_product_delta"); - // inst->relation_parameters = - // RelationParameters{ eta, beta, gamma, public_input_delta, lookup_grand_product_delta }; - - // for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { - - // inst->alphas[idx] = transcript->template receive_from_prover("alpha" + std::to_string(idx)); - // } - - // inst->target_sum = transcript->template receive_from_prover("target_sum"); - - // inst->gate_challenges = std::vector(inst->log_instance_size); - // for (size_t idx = 0; idx < inst->log_instance_size; idx++) { - // inst->gate_challenges[idx] = - // transcript->template receive_from_prover("gate_challenge_" + std::to_string(idx)); - // } - // auto comm_view = inst->witness_commitments.get_all(); - // auto witness_labels = inst->commitment_labels.get_witness(); - // for (size_t idx = 0; idx < witness_labels.size(); idx++) { - // comm_view[idx] = transcript->template receive_from_prover(witness_labels[idx]); - // } - - // inst->verification_key = std::make_shared(inst->instance_size, inst->public_input_size); - // auto vk_view = inst->verification_key->get_all(); - // auto vk_labels = inst->commitment_labels.get_precomputed(); - // for (size_t idx = 0; idx < vk_labels.size(); idx++) { - // vk_view[idx] = transcript->template receive_from_prover(vk_labels[idx]); - // } VerifierCommitments commitments{ accumulator->verification_key, accumulator->witness_commitments }; @@ -87,7 +40,6 @@ template bool DeciderVerifier_::verify_proof(const Hon // If Sumcheck did not verify, return false if (sumcheck_verified.has_value() && !sumcheck_verified.value()) { - info("here"); return false; } diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp index 98930e72646..dbb372665df 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp @@ -58,7 +58,7 @@ void ProtoGalaxyProver_::finalise_and_send_instance(std::shared auto eta = transcript->template get_challenge(domain_separator + "_eta"); instance->compute_sorted_accumulator_polynomials(eta); - // Commit to the sorted withness-table accumulator and the finalized (i.e. with memory records) fourth wire + // Commit to the sorted witness-table accumulator and the finalized (i.e. with memory records) fourth wire // polynomial witness_commitments.sorted_accum = commitment_key->commit(instance->prover_polynomials.sorted_accum); witness_commitments.w_4 = commitment_key->commit(instance->prover_polynomials.w_4); @@ -92,69 +92,14 @@ void ProtoGalaxyProver_::finalise_and_send_instance(std::shared instance->alphas[idx] = transcript->template get_challenge(domain_separator + "_alpha_" + std::to_string(idx)); } - // auto vk_view = instance->verification_key->get_all(); - // auto labels = instance->commitment_labels.get_precomputed(); - // for (size_t idx = 0; idx < labels.size(); idx++) { - // transcript->send_to_verifier(domain_separator + "_" + labels[idx], vk_view[idx]); - // } } -// template -// void ProtoGalaxyProver_::send_accumulator(std::shared_ptr instance, -// const std::string& domain_separator) -// { -// const auto instance_size = static_cast(instance->instance_size); -// const auto num_public_inputs = static_cast(instance->public_inputs.size()); -// transcript->send_to_verifier(domain_separator + "_instance_size", instance_size); -// transcript->send_to_verifier(domain_separator + "_public_input_size", num_public_inputs); - -// for (size_t i = 0; i < instance->public_inputs.size(); ++i) { -// auto public_input_i = instance->public_inputs[i]; -// transcript->send_to_verifier(domain_separator + "_public_input_" + std::to_string(i), public_input_i); -// } - -// transcript->send_to_verifier(domain_separator + "_eta", instance->relation_parameters.eta); -// transcript->send_to_verifier(domain_separator + "_beta", instance->relation_parameters.beta); -// transcript->send_to_verifier(domain_separator + "_gamma", instance->relation_parameters.gamma); -// transcript->send_to_verifier(domain_separator + "_public_input_delta", -// instance->relation_parameters.public_input_delta); -// transcript->send_to_verifier(domain_separator + "_lookup_grand_product_delta", -// instance->relation_parameters.lookup_grand_product_delta); - -// for (size_t idx = 0; idx < NUM_SUBRELATIONS - 1; idx++) { -// transcript->send_to_verifier(domain_separator + "_alpha_" + std::to_string(idx), instance->alphas[idx]); -// } - -// transcript->send_to_verifier(domain_separator + "_target_sum", instance->target_sum); -// for (size_t idx = 0; idx < instance->gate_challenges.size(); idx++) { -// transcript->send_to_verifier(domain_separator + "_gate_challenge_" + std::to_string(idx), -// instance->gate_challenges[idx]); -// } - -// auto comm_view = instance->witness_commitments.get_all(); -// auto witness_labels = instance->commitment_labels.get_witness(); -// for (size_t idx = 0; idx < witness_labels.size(); idx++) { -// transcript->send_to_verifier(domain_separator + "_" + witness_labels[idx], comm_view[idx]); -// } - -// auto vk_view = instance->verification_key->get_all(); -// auto vk_labels = instance->commitment_labels.get_precomputed(); -// for (size_t idx = 0; idx < vk_labels.size(); idx++) { -// transcript->send_to_verifier(domain_separator + "_" + vk_labels[idx], vk_view[idx]); -// } -// } - template void ProtoGalaxyProver_::prepare_for_folding() { auto idx = 0; auto instance = instances[0]; auto domain_separator = std::to_string(idx); - // transcript->send_to_verifier(domain_separator + "is_accumulator", instance->is_accumulator); - if (!instance->is_accumulator) - // { - // send_accumulator(instance, domain_separator); - // }else - { + if (!instance->is_accumulator) { // This is the first round of folding and we need to generate some gate challenges. // TODO(https://github.com/AztecProtocol/barretenberg/issues/740): implement option 2 to make this more // efficient by avoiding the computation of the perturbator @@ -262,42 +207,58 @@ std::shared_ptr ProtoGalaxyProver_ -FoldingResult ProtoGalaxyProver_::fold_instances() +template void ProtoGalaxyProver_::preparation_round() { prepare_for_folding(); - FF delta = transcript->template get_challenge("delta"); +}; - auto accumulator = get_accumulator(); - auto deltas = compute_round_challenge_pows(accumulator->log_instance_size, delta); - - auto perturbator = compute_perturbator(accumulator, deltas); - - for (size_t idx = 1; idx <= accumulator->log_instance_size; idx++) { - transcript->send_to_verifier("perturbator_" + std::to_string(idx), perturbator[idx]); +template void ProtoGalaxyProver_::perturbator_round() +{ + state.accumulator = get_accumulator(); + FF delta = transcript->template get_challenge("delta"); + state.deltas = compute_round_challenge_pows(state.accumulator->log_instance_size, delta); + state.perturbator = compute_perturbator(state.accumulator, state.deltas); + for (size_t idx = 1; idx <= state.accumulator->log_instance_size; idx++) { + transcript->send_to_verifier("perturbator_" + std::to_string(idx), state.perturbator[idx]); } +}; + +template void ProtoGalaxyProver_::combiner_quotient_round() +{ auto perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); instances.next_gate_challenges = - update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); + update_gate_challenges(perturbator_challenge, state.accumulator->gate_challenges, state.deltas); combine_relation_parameters(instances); combine_alpha(instances); auto pow_polynomial = PowPolynomial(instances.next_gate_challenges); auto combiner = compute_combiner(instances, pow_polynomial); - auto compressed_perturbator = perturbator.evaluate(perturbator_challenge); - auto combiner_quotient = compute_combiner_quotient(compressed_perturbator, combiner); + state.compressed_perturbator = state.perturbator.evaluate(perturbator_challenge); + state.combiner_quotient = compute_combiner_quotient(state.compressed_perturbator, combiner); for (size_t idx = ProverInstances::NUM; idx < ProverInstances::BATCHED_EXTENDED_LENGTH; idx++) { - transcript->send_to_verifier("combiner_quotient_" + std::to_string(idx), combiner_quotient.value_at(idx)); + transcript->send_to_verifier("combiner_quotient_" + std::to_string(idx), state.combiner_quotient.value_at(idx)); } +}; + +template void ProtoGalaxyProver_::accumulator_update_round() +{ FF combiner_challenge = transcript->template get_challenge("combiner_quotient_challenge"); + std::shared_ptr next_accumulator = + compute_next_accumulator(instances, state.combiner_quotient, combiner_challenge, state.compressed_perturbator); + state.result.folding_data = transcript->proof_data; + state.result.accumulator = next_accumulator; +}; + +template +FoldingResult ProtoGalaxyProver_::fold_instances() +{ + preparation_round(); + perturbator_round(); + combiner_quotient_round(); + accumulator_update_round(); - FoldingResult res; - auto next_accumulator = - compute_next_accumulator(instances, combiner_quotient, combiner_challenge, compressed_perturbator); - res.folding_data = transcript->proof_data; - res.accumulator = next_accumulator; - return res; + return state.result; } template class ProtoGalaxyProver_>; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index a566f399955..35ae55dd6ef 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -12,6 +12,18 @@ #include "barretenberg/sumcheck/instance/instances.hpp" namespace bb { +template struct ProtogalaxyProofConstructionState { + using FF = typename ProverInstances_::FF; + using Instance = typename ProverInstances_::Instance; + + std::shared_ptr accumulator; + Polynomial perturbator; + std::vector deltas; + Univariate combiner_quotient; + FF compressed_perturbator; + FoldingResult result; +}; + template class ProtoGalaxyProver_ { public: using ProverInstances = ProverInstances_; @@ -50,7 +62,7 @@ template class ProtoGalaxyProver_ { ProverInstances instances; std::shared_ptr transcript = std::make_shared(); - + ProtogalaxyProofConstructionState state; std::shared_ptr commitment_key; ProtoGalaxyProver_() = default; @@ -68,14 +80,6 @@ template class ProtoGalaxyProver_ { */ void prepare_for_folding(); - /** - * @brief Send the public data of an accumulator, i.e. a relaxed instance, to the verifier (ϕ in the paper). - * - * @param domain_separator separates the same type of data coming from difference instances by instance - * index - */ - // void send_accumulator(std::shared_ptr, const std::string& domain_separator); - /** * @brief For each instance produced by a circuit, prior to folding, we need to complete the computation of its * prover polynomials, commit to witnesses and generate the relation parameters as well as send the public data ϕ of @@ -144,29 +148,33 @@ template class ProtoGalaxyProver_ { const RelationParameters& relation_parameters) { auto instance_size = instance_polynomials.get_polynomial_size(); - FF linearly_dependent_contribution = FF(0); std::vector full_honk_evaluations(instance_size); - for (size_t row = 0; row < instance_size; row++) { + std::vector linearly_dependent_contributions(instance_size); + parallel_for(instance_size, [&](size_t row) { auto row_evaluations = instance_polynomials.get_row(row); RelationEvaluations relation_evaluations; Utils::zero_elements(relation_evaluations); - // Note that the evaluations are accumulated with the gate separation challenge being 1 at this stage, as - // this specific randomness is added later through the power polynomial univariate specific to ProtoGalaxy + // Note that the evaluations are accumulated with the gate separation challenge + // being 1 at this stage, as this specific randomness is added later through the + // power polynomial univariate specific to ProtoGalaxy Utils::template accumulate_relation_evaluations<>( row_evaluations, relation_evaluations, relation_parameters, FF(1)); auto output = FF(0); auto running_challenge = FF(1); - // Sum relation evaluations, batched by their corresponding relation separator challenge, to get the value - // of the full honk relation at a specific row + // Sum relation evaluations, batched by their corresponding relation separator challenge, to + // get the value of the full honk relation at a specific row + linearly_dependent_contributions[row] = 0; Utils::scale_and_batch_elements( - relation_evaluations, alpha, running_challenge, output, linearly_dependent_contribution); - + relation_evaluations, alpha, running_challenge, output, linearly_dependent_contributions[row]); full_honk_evaluations[row] = output; + }); + + for (FF& linearly_dependent_contribution : linearly_dependent_contributions) { + full_honk_evaluations[0] += linearly_dependent_contribution; } - full_honk_evaluations[0] += linearly_dependent_contribution; return full_honk_evaluations; } @@ -448,6 +456,10 @@ template class ProtoGalaxyProver_ { Univariate& combiner_quotient, FF& challenge, const FF& compressed_perturbator); -}; -} // namespace bb + void preparation_round(); + void perturbator_round(); + void combiner_quotient_round(); + void accumulator_update_round(); +}; +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 818c02ca7d5..e4cc1fc3769 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -87,10 +87,7 @@ void ProtoGalaxyVerifier_::prepare_for_folding(const std::vec auto index = 0; auto inst = instances[0]; auto domain_separator = std::to_string(index); - // auto is_accumulator = transcript->template receive_from_prover(domain_separator + "is_accumulator"); if (!inst->is_accumulator) { - // receive_accumulator(inst, domain_separator); - // } else { // This is the first round of folding and we need to generate some gate challenges. // TODO(https://github.com/AztecProtocol/barretenberg/issues/740): implement option 2 to make this more // efficient by avoiding the computation of the perturbator diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp index 945ef93bdda..d07a191f0b3 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp @@ -118,7 +118,7 @@ template class ProtoGalaxyRecursiveTests : public tes /** *@brief Create inner circuit and call check_circuit on it */ - static void test_inner_circuit() + static void test_circuit() { Builder builder; @@ -173,21 +173,21 @@ template class ProtoGalaxyRecursiveTests : public tes auto prover_instance_2 = composer.create_prover_instance(builder2); auto verifier_instance_2 = composer.create_verifier_instance(prover_instance_2); // Generate a folding proof - auto inner_folding_prover = composer.create_folding_prover({ prover_instance_1, prover_instance_2 }); - auto inner_folding_proof = inner_folding_prover.fold_instances(); + auto folding_prover = composer.create_folding_prover({ prover_instance_1, prover_instance_2 }); + auto folding_proof = folding_prover.fold_instances(); // Create a recursive folding verifier circuit for the folding proof of the two instances Builder folding_circuit; auto verifier = FoldingRecursiveVerifier(&folding_circuit, verifier_instance_1, { verifier_instance_2->verification_key }); - auto recursive_verifier_accumulator = verifier.verify_folding_proof(inner_folding_proof.folding_data); + auto recursive_verifier_accumulator = verifier.verify_folding_proof(folding_proof.folding_data); auto acc = std::make_shared(recursive_verifier_accumulator->get_value()); info("Folding Recursive Verifier: num gates = ", folding_circuit.num_gates); // Perform native folding verification and ensure it returns the same result (either true or false) as // calling check_circuit on the recursive folding verifier auto native_folding_verifier = composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); - auto verifier_accumulator = native_folding_verifier.verify_folding_proof(inner_folding_proof.folding_data); + auto verifier_accumulator = native_folding_verifier.verify_folding_proof(folding_proof.folding_data); // Ensure that the underlying native and recursive folding verification algorithms agree by ensuring the // manifestsproduced by each agree. @@ -232,21 +232,21 @@ template class ProtoGalaxyRecursiveTests : public tes auto prover_instance_2 = composer.create_prover_instance(builder2); auto verifier_instance_2 = composer.create_verifier_instance(prover_instance_2); // Generate a folding proof - auto inner_folding_prover = composer.create_folding_prover({ prover_instance_1, prover_instance_2 }); - auto inner_folding_proof = inner_folding_prover.fold_instances(); + auto folding_prover = composer.create_folding_prover({ prover_instance_1, prover_instance_2 }); + auto folding_proof = folding_prover.fold_instances(); // Create a recursive folding verifier circuit for the folding proof of the two instances Builder folding_circuit; auto verifier = FoldingRecursiveVerifier(&folding_circuit, verifier_instance_1, { verifier_instance_2->verification_key }); - auto recursive_verifier_accumulator = verifier.verify_folding_proof(inner_folding_proof.folding_data); + auto recursive_verifier_accumulator = verifier.verify_folding_proof(folding_proof.folding_data); auto acc = std::make_shared(recursive_verifier_accumulator->get_value()); info("Folding Recursive Verifier: num gates = ", folding_circuit.num_gates); // Perform native folding verification and ensure it returns the same result (either true or false) as // calling check_circuit on the recursive folding verifier auto native_folding_verifier = composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); - auto verifier_accumulator = native_folding_verifier.verify_folding_proof(inner_folding_proof.folding_data); + auto verifier_accumulator = native_folding_verifier.verify_folding_proof(folding_proof.folding_data); // Ensure that the underlying native and recursive folding verification algorithms agree by ensuring the // manifestsproduced by each agree. @@ -257,12 +257,12 @@ template class ProtoGalaxyRecursiveTests : public tes EXPECT_EQ(recursive_folding_manifest[i], native_folding_manifest[i]); } - auto inner_decider_prover = composer.create_decider_prover(inner_folding_proof.accumulator); - auto inner_decider_proof = inner_decider_prover.construct_proof(); + auto decider_prover = composer.create_decider_prover(folding_proof.accumulator); + auto decider_proof = decider_prover.construct_proof(); Builder decider_circuit; DeciderRecursiveVerifier decider_verifier{ &decider_circuit, acc }; - auto pairing_points = decider_verifier.verify_proof(inner_decider_proof); + auto pairing_points = decider_verifier.verify_proof(decider_proof); info("Decider Recursive Verifier: num gates = ", decider_circuit.num_gates); // Check for a failure flag in the recursive verifier circuit EXPECT_EQ(decider_circuit.failed(), false) << decider_circuit.err(); @@ -271,7 +271,7 @@ template class ProtoGalaxyRecursiveTests : public tes EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err(); DeciderVerifier native_decider_verifier = composer.create_decider_verifier(verifier_accumulator); - auto native_result = native_decider_verifier.verify_proof(inner_decider_proof); + auto native_result = native_decider_verifier.verify_proof(decider_proof); auto recursive_result = native_decider_verifier.pcs_verification_key->pairing_check( pairing_points[0].get_value(), pairing_points[1].get_value()); EXPECT_EQ(native_result, recursive_result); @@ -299,13 +299,13 @@ template class ProtoGalaxyRecursiveTests : public tes verifier_accumulator->target_sum = FF::random_element(); // Create a decider proof for the relaxed instance obtained through folding - auto inner_decider_prover = composer.create_decider_prover(prover_accumulator); - auto inner_decider_proof = inner_decider_prover.construct_proof(); + auto decider_prover = composer.create_decider_prover(prover_accumulator); + auto decider_proof = decider_prover.construct_proof(); // Create a decider verifier circuit for recursively verifying the decider proof Builder decider_circuit; DeciderRecursiveVerifier decider_verifier{ &decider_circuit, verifier_accumulator }; - decider_verifier.verify_proof(inner_decider_proof); + decider_verifier.verify_proof(decider_proof); info("Decider Recursive Verifier: num gates = ", decider_circuit.num_gates); { @@ -336,16 +336,16 @@ template class ProtoGalaxyRecursiveTests : public tes prover_accumulator->prover_polynomials.w_l[1] = FF::random_element(); // Generate a folding proof - auto inner_folding_prover = composer.create_folding_prover({ prover_accumulator, prover_inst }); - auto inner_folding_proof = inner_folding_prover.fold_instances(); + auto folding_prover = composer.create_folding_prover({ prover_accumulator, prover_inst }); + auto folding_proof = folding_prover.fold_instances(); // Create a recursive folding verifier circuit for the folding proof of the two instances Builder folding_circuit; FoldingRecursiveVerifier verifier{ &folding_circuit, verifier_accumulator, { verifier_inst->verification_key } }; - auto recursive_verifier_acc = verifier.verify_folding_proof(inner_folding_proof.folding_data); - EXPECT_FALSE(inner_folding_proof.accumulator->target_sum == recursive_verifier_acc->target_sum.get_value()); + auto recursive_verifier_acc = verifier.verify_folding_proof(folding_proof.folding_data); + EXPECT_FALSE(folding_proof.accumulator->target_sum == recursive_verifier_acc->target_sum.get_value()); }; }; @@ -354,7 +354,7 @@ TYPED_TEST_SUITE(ProtoGalaxyRecursiveTests, FlavorTypes); TYPED_TEST(ProtoGalaxyRecursiveTests, InnerCircuit) { - TestFixture::test_inner_circuit(); + TestFixture::test_circuit(); } TYPED_TEST(ProtoGalaxyRecursiveTests, NewEvaluate) diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index 10a862ff2ce..f00f0c5c512 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -7,15 +7,12 @@ namespace bb { /** - * @brief An Instance is normally constructed from a finalized circuit and it's role is to compute all the polynomials - * involved in creating a proof and, if requested, the verification key. - * In case of folded Instance, this will be created from the FoldingResult, the aggregated work from the folding prover - * and verifier. More specifically, a folded instance will be constructed from the complete set of folded polynomials - * and folded public inputs and its FoldingParams are expected to be non-zero - * + * @brief A ProverInstance is normally constructed from a finalized circuit and it contains all the information + * required by an Ultra Goblin Honk prover to create a proof. A ProverInstance is also the result of running the + * Protogalaxy prover, in which case it becomes a relaxed counterpart with the folding parameters (target sum and gate + * challenges set to non-zero values). */ -// TODO(https://github.com/AztecProtocol/barretenberg/issues/725): create an Instances class that manages several -// Instance and passes them to ProtoGalaxy prover and verifier so that Instance objects don't need to mantain an index + template class ProverInstance_ { using Circuit = typename Flavor::CircuitBuilder; using ProvingKey = typename Flavor::ProvingKey; @@ -30,7 +27,6 @@ template class ProverInstance_ { public: std::shared_ptr proving_key; - // std::shared_ptr verification_key; ProverPolynomials prover_polynomials; WitnessCommitments witness_commitments; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp index 9ba56880f84..64ac56965c6 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp @@ -3,6 +3,11 @@ #include "barretenberg/relations/relation_parameters.hpp" namespace bb { +/** + * @brief + * + * @tparam Flavor + */ template class VerifierInstance_ { public: using FF = typename Flavor::FF; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp index 27acb7dd432..e4630c377ea 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_prover.cpp @@ -96,7 +96,7 @@ template void UltraProver_::execute_sorted_list_a instance->compute_sorted_accumulator_polynomials(eta); auto& witness_commitments = instance->witness_commitments; - // Commit to the sorted withness-table accumulator and the finalized (i.e. with memory records) fourth wire + // Commit to the sorted witness-table accumulator and the finalized (i.e. with memory records) fourth wire // polynomial witness_commitments.sorted_accum = commitment_key->commit(instance->prover_polynomials.sorted_accum); witness_commitments.w_4 = commitment_key->commit(instance->prover_polynomials.w_4); From ec36ede48ee3a9d913acc21491233bd744e62d30 Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 20 Feb 2024 10:34:39 +0000 Subject: [PATCH 07/15] more cleanup --- .../benchmark/ivc_bench/ivc.bench.cpp | 8 +++++-- .../barretenberg/client_ivc/client_ivc.cpp | 4 +++- .../barretenberg/client_ivc/client_ivc.hpp | 8 +++---- .../src/barretenberg/goblin/mock_circuits.hpp | 6 +++++- .../protogalaxy/protogalaxy_prover.cpp | 3 +++ .../protogalaxy/protogalaxy_prover.hpp | 21 ++++++++++++++++++- .../verifier/decider_recursive_verifier.cpp | 2 +- .../protogalaxy_recursive_verifier.cpp | 4 ++-- .../protogalaxy_recursive_verifier.test.cpp | 7 ++++--- .../verifier/recursive_verifier_instance.hpp | 11 ++++++++++ .../sumcheck/instance/prover_instance.hpp | 2 ++ .../sumcheck/instance/verifier_instance.hpp | 6 ++++-- 12 files changed, 64 insertions(+), 18 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp index 59f08406adf..ccfcd40f44e 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp @@ -44,23 +44,26 @@ class IvcBench : public benchmark::Fixture { */ static void perform_ivc_accumulation_rounds(State& state, ClientIVC& ivc) { - // Initialize IVC with function circuit + // Initialize IVC with a function circuit Builder initial_function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit); ivc.initialize(initial_function_circuit); auto kernel_verifeir_accumulator = std::make_shared(); kernel_verifeir_accumulator->verification_key = ivc.vks[0]; + // Accumulate another function circuit Builder function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(function_circuit); auto function_fold_proof = ivc.accumulate(function_circuit); FoldOutput function_fold_output = { function_fold_proof, ivc.vks[1] }; + // Create and accumulate the first folding kernel which only verifies the accumulation of a function circuit Builder kernel_circuit{ ivc.goblin.op_queue }; kernel_verifeir_accumulator = GoblinMockCircuits::construct_mock_folding_kernel( kernel_circuit, function_fold_output, {}, kernel_verifeir_accumulator); auto kernel_fold_proof = ivc.accumulate(kernel_circuit); FoldOutput kernel_fold_output = { kernel_fold_proof, ivc.vks[2] }; + auto NUM_CIRCUITS = static_cast(state.range(0)); // Subtract one to account for the "initialization" round above NUM_CIRCUITS -= 1; @@ -71,7 +74,8 @@ class IvcBench : public benchmark::Fixture { auto function_fold_proof = ivc.accumulate(function_circuit); function_fold_output = { function_fold_proof, ivc.vks[1] }; - // Accumulate kernel circuit + // Create kernel circuit containing the recursive folding verification of a function circuit and a kernel + // circuit and accumulate it Builder kernel_circuit{ ivc.goblin.op_queue }; kernel_verifeir_accumulator = GoblinMockCircuits::construct_mock_folding_kernel( kernel_circuit, function_fold_output, kernel_fold_output, kernel_verifeir_accumulator); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 46bce07ed05..ce5f35be1d4 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -54,7 +54,7 @@ ClientIVC::Proof ClientIVC::prove() * @param proof * @return bool */ -bool ClientIVC::verify(Proof& proof, const std::vector& verifier_instances) +bool ClientIVC::verify(Proof& proof, const std::vector<åVerifierAccumulator>& verifier_instances) { // Goblin verification (merge, eccvm, translator) bool goblin_verified = goblin.verify(proof.goblin_proof); @@ -90,6 +90,8 @@ HonkProof ClientIVC::decider_prove() const */ void ClientIVC::precompute_folding_verification_keys() { + using VerifierInstance = VerifierInstance_; + Composer composer; ClientCircuit initial_function_circuit{ goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp index b0903fa6822..aaca17801f4 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp @@ -21,7 +21,6 @@ class ClientIVC { using FoldProof = std::vector; using ProverAccumulator = std::shared_ptr>; using VerifierAccumulator = std::shared_ptr>; - using VerifierInstance = VerifierInstance_; using ProverInstance = ProverInstance_; using ClientCircuit = GoblinUltraCircuitBuilder; // can only be GoblinUltra @@ -35,16 +34,15 @@ class ClientIVC { private: using ProverFoldOutput = FoldingResult; using Composer = GoblinUltraComposer; + // Note: We need to save the last instance that was folded in order to compute its verification key, this will not + // be needed in the real IVC as they are provided as inputs + std::shared_ptr prover_instance; public: Goblin goblin; ProverFoldOutput prover_fold_output; ProverAccumulator prover_accumulator; - // Note: We need to save the last instance that was folded in order to compute its verification key, this will not - // be needed in the real IVC as they are provided as inputs - std::shared_ptr prover_instance; - std::array, 4> vks; ClientIVC(); diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 06a5c1e419a..ef009d2cd0f 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -36,6 +36,10 @@ class GoblinMockCircuits { using VerificationKey = Flavor::VerificationKey; static constexpr size_t NUM_OP_QUEUE_COLUMNS = Flavor::NUM_WIRES; + /** + * @brief + * + */ struct FoldOutput { std::vector fold_proof; std::shared_ptr inst_vk; @@ -242,7 +246,7 @@ class GoblinMockCircuits { stdlib::generate_ecdsa_verification_test_circuit(builder, NUM_ECDSA_VERIFICATIONS); stdlib::generate_sha256_test_circuit(builder, NUM_SHA_HASHES); - // Init + // Initial kernel iteration does not have a previous kernel to fold if (kernel.fold_proof.empty()) { FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { func.inst_vk } }; auto fctn_verifier_accum = verifier_1.verify_folding_proof(func.fold_proof); diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp index dbb372665df..ef7996e46ae 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp @@ -218,6 +218,9 @@ template void ProtoGalaxyProver_::pertu FF delta = transcript->template get_challenge("delta"); state.deltas = compute_round_challenge_pows(state.accumulator->log_instance_size, delta); state.perturbator = compute_perturbator(state.accumulator, state.deltas); + + // Prover doesn't send the constant coefficient of F because this is supposed to be equal to the target sum of the + // accumulator which the folding verifier has from the previous iteration. for (size_t idx = 1; idx <= state.accumulator->log_instance_size; idx++) { transcript->send_to_verifier("perturbator_" + std::to_string(idx), state.perturbator[idx]); } diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index 35ae55dd6ef..03639b0c26c 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -62,8 +62,8 @@ template class ProtoGalaxyProver_ { ProverInstances instances; std::shared_ptr transcript = std::make_shared(); - ProtogalaxyProofConstructionState state; std::shared_ptr commitment_key; + ProtogalaxyProofConstructionState state; ProtoGalaxyProver_() = default; ProtoGalaxyProver_(const std::vector>& insts, @@ -457,9 +457,28 @@ template class ProtoGalaxyProver_ { FF& challenge, const FF& compressed_perturbator); + /** + * @brief + * + */ void preparation_round(); + + /** + * @brief + * + */ void perturbator_round(); + + /** + * @brief + * + */ void combiner_quotient_round(); + + /** + * @brief + * + */ void accumulator_update_round(); }; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp index 5dd711ae8f7..dffe20412d7 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp @@ -41,6 +41,6 @@ std::array DeciderRecursiveVerifier_:: return pairing_points; } -// template class DeciderRecursiveVerifier_>; +template class DeciderRecursiveVerifier_>; template class DeciderRecursiveVerifier_>; } // namespace bb::stdlib::recursion::honk diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp index 9652935a9f1..5ee30516632 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp @@ -232,8 +232,8 @@ std::shared_ptr ProtoGalaxyRecursiveVerifi return next_accumulator; } -// template class ProtoGalaxyRecursiveVerifier_, -// 2>>; +template class ProtoGalaxyRecursiveVerifier_< + RecursiveVerifierInstances_, 2>>; template class ProtoGalaxyRecursiveVerifier_< RecursiveVerifierInstances_, 2>>; } // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp index d07a191f0b3..2b0cce7f920 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp @@ -136,8 +136,8 @@ template class ProtoGalaxyRecursiveTests : public tes static void test_new_evaluate() { Builder builder; - using fr_ct = bn254::ScalarField; - using fr = bn254::ScalarFieldNative; + using fr_ct = typename bn254::ScalarField; + using fr = typename bn254::ScalarFieldNative; std::vector coeffs; std::vector coeffs_ct; @@ -349,7 +349,8 @@ template class ProtoGalaxyRecursiveTests : public tes }; }; -using FlavorTypes = testing::Types>; +using FlavorTypes = + testing::Types, UltraRecursiveFlavor_>; TYPED_TEST_SUITE(ProtoGalaxyRecursiveTests, FlavorTypes); TYPED_TEST(ProtoGalaxyRecursiveTests, InnerCircuit) diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp index 5d2b0fb3983..feb01035fc6 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp @@ -4,6 +4,10 @@ #include "barretenberg/sumcheck/instance/verifier_instance.hpp" namespace bb::stdlib::recursion::honk { + +/** + * @brief The stdlib counterpart of VerifierInstance, used in recursive folding verification + */ template class RecursiveVerifierInstance_ { public: using FF = typename Flavor::FF; @@ -92,6 +96,13 @@ template class RecursiveVerifierInstance_ { FF::from_witness(builder, instance->relation_parameters.lookup_grand_product_delta); } + /** + * @brief Return the underlying native VerifierInstance. + * + * @details In the context of client IVC, we will have several iterations of recursive folding verification. The + * RecursiveVerifierInstance is tied to the builder in whose context it was created so in order to preserve the + * accumulator values between several iterations we need to retrieve the native VerifierInstance values. + */ VerifierInstance get_value() { VerifierInstance inst; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index f00f0c5c512..55212e9dd66 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -11,6 +11,8 @@ namespace bb { * required by an Ultra Goblin Honk prover to create a proof. A ProverInstance is also the result of running the * Protogalaxy prover, in which case it becomes a relaxed counterpart with the folding parameters (target sum and gate * challenges set to non-zero values). + * + * @details This is the equivalent of ω in the paper. */ template class ProverInstance_ { diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp index 64ac56965c6..01328e4dc6b 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp @@ -4,9 +4,11 @@ namespace bb { /** - * @brief + * @brief The VerifierInstance encapsulates all the necessary information for a Goblin Ultra Honk Verifier to verify a + * proof (sumcheck + Zeromorph). In the context of folding, this is returned by the Protogalaxy verifier with non-zero + * target sum and gate challenges. * - * @tparam Flavor + * @details This is ϕ in the paper. */ template class VerifierInstance_ { public: From f97dd1ec3da0f3ab226c7f36385a13f7b7a7b897 Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 20 Feb 2024 10:34:39 +0000 Subject: [PATCH 08/15] more cleanup --- .../benchmark/ivc_bench/ivc.bench.cpp | 18 ++++++++------ .../barretenberg/client_ivc/client_ivc.cpp | 20 +++++++++------- .../barretenberg/client_ivc/client_ivc.hpp | 13 ++++++---- .../client_ivc/mock_kernel_pinning.test.cpp | 6 ++--- .../src/barretenberg/goblin/mock_circuits.hpp | 6 ++++- .../protogalaxy/protogalaxy_prover.cpp | 3 +++ .../protogalaxy/protogalaxy_prover.hpp | 24 ++++++++++++++++++- .../verifier/decider_recursive_verifier.cpp | 2 +- .../protogalaxy_recursive_verifier.cpp | 4 ++-- .../protogalaxy_recursive_verifier.test.cpp | 7 +++--- .../honk/verifier/recursive_instances.hpp | 1 - .../verifier/recursive_verifier_instance.hpp | 11 +++++++++ .../sumcheck/instance/prover_instance.hpp | 2 ++ .../sumcheck/instance/verifier_instance.hpp | 6 +++-- 14 files changed, 89 insertions(+), 34 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp index 59f08406adf..366fbce42ae 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp @@ -44,23 +44,26 @@ class IvcBench : public benchmark::Fixture { */ static void perform_ivc_accumulation_rounds(State& state, ClientIVC& ivc) { - // Initialize IVC with function circuit + // Initialize IVC with a function circuit Builder initial_function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit); ivc.initialize(initial_function_circuit); auto kernel_verifeir_accumulator = std::make_shared(); - kernel_verifeir_accumulator->verification_key = ivc.vks[0]; + kernel_verifeir_accumulator->verification_key = ivc.vks.first_func_vk; + // Accumulate another function circuit Builder function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(function_circuit); auto function_fold_proof = ivc.accumulate(function_circuit); - FoldOutput function_fold_output = { function_fold_proof, ivc.vks[1] }; + FoldOutput function_fold_output = { function_fold_proof, ivc.vks.func_vk }; + // Create and accumulate the first folding kernel which only verifies the accumulation of a function circuit Builder kernel_circuit{ ivc.goblin.op_queue }; kernel_verifeir_accumulator = GoblinMockCircuits::construct_mock_folding_kernel( kernel_circuit, function_fold_output, {}, kernel_verifeir_accumulator); auto kernel_fold_proof = ivc.accumulate(kernel_circuit); - FoldOutput kernel_fold_output = { kernel_fold_proof, ivc.vks[2] }; + FoldOutput kernel_fold_output = { kernel_fold_proof, ivc.vks.first_kernel_vk }; + auto NUM_CIRCUITS = static_cast(state.range(0)); // Subtract one to account for the "initialization" round above NUM_CIRCUITS -= 1; @@ -69,15 +72,16 @@ class IvcBench : public benchmark::Fixture { Builder function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(function_circuit); auto function_fold_proof = ivc.accumulate(function_circuit); - function_fold_output = { function_fold_proof, ivc.vks[1] }; + function_fold_output = { function_fold_proof, ivc.vks.func_vk }; - // Accumulate kernel circuit + // Create kernel circuit containing the recursive folding verification of a function circuit and a kernel + // circuit and accumulate it Builder kernel_circuit{ ivc.goblin.op_queue }; kernel_verifeir_accumulator = GoblinMockCircuits::construct_mock_folding_kernel( kernel_circuit, function_fold_output, kernel_fold_output, kernel_verifeir_accumulator); kernel_fold_proof = ivc.accumulate(kernel_circuit); - kernel_fold_output = { kernel_fold_proof, ivc.vks[3] }; + kernel_fold_output = { kernel_fold_proof, ivc.vks.kernel_vk }; } } }; diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index 46bce07ed05..b1ca55b5757 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -54,7 +54,7 @@ ClientIVC::Proof ClientIVC::prove() * @param proof * @return bool */ -bool ClientIVC::verify(Proof& proof, const std::vector& verifier_instances) +bool ClientIVC::verify(Proof& proof, const std::vector& verifier_instances) { // Goblin verification (merge, eccvm, translator) bool goblin_verified = goblin.verify(proof.goblin_proof); @@ -90,6 +90,8 @@ HonkProof ClientIVC::decider_prove() const */ void ClientIVC::precompute_folding_verification_keys() { + using VerifierInstance = VerifierInstance_; + Composer composer; ClientCircuit initial_function_circuit{ goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit); @@ -97,9 +99,9 @@ void ClientIVC::precompute_folding_verification_keys() // Initialise both the first prover and verifier accumulator from the inital function circuit initialize(initial_function_circuit); composer.compute_commitment_key(prover_fold_output.accumulator->instance_size); - vks[0] = composer.compute_verification_key(prover_fold_output.accumulator); + vks.first_func_vk = composer.compute_verification_key(prover_fold_output.accumulator); auto verifier_acc = std::make_shared(); - verifier_acc->verification_key = vks[0]; + verifier_acc->verification_key = vks.first_func_vk; // Accumulate the next function circuit ClientCircuit function_circuit{ goblin.op_queue }; @@ -107,14 +109,14 @@ void ClientIVC::precompute_folding_verification_keys() auto function_fold_proof = accumulate(function_circuit); // Create its verification key (we have called accumulate so it includes the recursive merge verifier) - vks[1] = composer.compute_verification_key(prover_instance); + vks.func_vk = composer.compute_verification_key(prover_instance); // Create the initial kernel iteration and precompute its verification key ClientCircuit kernel_circuit{ goblin.op_queue }; auto new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - kernel_circuit, { function_fold_proof, vks[1] }, {}, verifier_acc); + kernel_circuit, { function_fold_proof, vks.func_vk }, {}, verifier_acc); auto kernel_fold_proof = accumulate(kernel_circuit); - vks[2] = composer.compute_verification_key(prover_instance); + vks.first_kernel_vk = composer.compute_verification_key(prover_instance); // Create another mock function circuit to run the full kernel ClientCircuit circuit_4{ goblin.op_queue }; @@ -124,12 +126,12 @@ void ClientIVC::precompute_folding_verification_keys() // Create the fullk ernel circuit and compute verification key ClientCircuit new_kernel_circuit = GoblinUltraCircuitBuilder{ goblin.op_queue }; auto new_new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - new_kernel_circuit, { function_fold_proof, vks[1] }, { kernel_fold_proof, vks[2] }, new_acc); + new_kernel_circuit, { function_fold_proof, vks.func_vk }, { kernel_fold_proof, vks.first_kernel_vk }, new_acc); kernel_fold_proof = accumulate(new_kernel_circuit); - vks[3] = composer.compute_verification_key(prover_instance); + vks.kernel_vk = composer.compute_verification_key(prover_instance); auto kernel_inst = std::make_shared(); - kernel_inst->verification_key = vks[3]; + kernel_inst->verification_key = vks.kernel_vk; // Clean the ivc state goblin.op_queue = std::make_shared(); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp index b0903fa6822..06d1494000f 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp @@ -21,8 +21,8 @@ class ClientIVC { using FoldProof = std::vector; using ProverAccumulator = std::shared_ptr>; using VerifierAccumulator = std::shared_ptr>; - using VerifierInstance = VerifierInstance_; using ProverInstance = ProverInstance_; + using VerifierInstance = VerifierInstance_; using ClientCircuit = GoblinUltraCircuitBuilder; // can only be GoblinUltra // A full proof for the IVC scheme @@ -32,6 +32,13 @@ class ClientIVC { Goblin::Proof goblin_proof; }; + struct PrecomputedVerificationKeys { + std::shared_ptr first_func_vk; + std::shared_ptr func_vk; + std::shared_ptr first_kernel_vk; + std::shared_ptr kernel_vk; + }; + private: using ProverFoldOutput = FoldingResult; using Composer = GoblinUltraComposer; @@ -40,13 +47,11 @@ class ClientIVC { Goblin goblin; ProverFoldOutput prover_fold_output; ProverAccumulator prover_accumulator; - + PrecomputedVerificationKeys vks; // Note: We need to save the last instance that was folded in order to compute its verification key, this will not // be needed in the real IVC as they are provided as inputs std::shared_ptr prover_instance; - std::array, 4> vks; - ClientIVC(); void initialize(ClientCircuit& circuit); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp index d6669e80adf..5011d175391 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp @@ -26,7 +26,7 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) GoblinMockCircuits::construct_mock_function_circuit(circuit_1); ivc.initialize(circuit_1); auto verifier_acc = std::make_shared(); - verifier_acc->verification_key = ivc.vks[0]; + verifier_acc->verification_key = ivc.vks.first_func_vk; GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_2); @@ -36,7 +36,7 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) // Construct kernel circuit GoblinUltraCircuitBuilder kernel_circuit{ ivc.goblin.op_queue }; auto new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - kernel_circuit, { fold_proof_1, ivc.vks[1] }, {}, verifier_acc); + kernel_circuit, { fold_proof_1, ivc.vks.func_vk }, {}, verifier_acc); auto fold_proof_3 = ivc.accumulate(kernel_circuit); EXPECT_EQ(ivc.prover_instance->log_instance_size, 17); @@ -47,7 +47,7 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) GoblinUltraCircuitBuilder new_kernel_circuit = GoblinUltraCircuitBuilder{ ivc.goblin.op_queue }; new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - new_kernel_circuit, { fold_proof_3, ivc.vks[2] }, { fold_proof_4, ivc.vks[1] }, new_acc); + new_kernel_circuit, { fold_proof_3, ivc.vks.first_kernel_vk }, { fold_proof_4, ivc.vks.func_vk }, new_acc); GoblinUltraComposer composer; auto instance = composer.create_prover_instance(new_kernel_circuit); EXPECT_EQ(instance->proving_key->log_circuit_size, 17); diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 06a5c1e419a..ef009d2cd0f 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -36,6 +36,10 @@ class GoblinMockCircuits { using VerificationKey = Flavor::VerificationKey; static constexpr size_t NUM_OP_QUEUE_COLUMNS = Flavor::NUM_WIRES; + /** + * @brief + * + */ struct FoldOutput { std::vector fold_proof; std::shared_ptr inst_vk; @@ -242,7 +246,7 @@ class GoblinMockCircuits { stdlib::generate_ecdsa_verification_test_circuit(builder, NUM_ECDSA_VERIFICATIONS); stdlib::generate_sha256_test_circuit(builder, NUM_SHA_HASHES); - // Init + // Initial kernel iteration does not have a previous kernel to fold if (kernel.fold_proof.empty()) { FoldingRecursiveVerifier verifier_1{ &builder, prev_kernel_accum, { func.inst_vk } }; auto fctn_verifier_accum = verifier_1.verify_folding_proof(func.fold_proof); diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp index dbb372665df..ef7996e46ae 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp @@ -218,6 +218,9 @@ template void ProtoGalaxyProver_::pertu FF delta = transcript->template get_challenge("delta"); state.deltas = compute_round_challenge_pows(state.accumulator->log_instance_size, delta); state.perturbator = compute_perturbator(state.accumulator, state.deltas); + + // Prover doesn't send the constant coefficient of F because this is supposed to be equal to the target sum of the + // accumulator which the folding verifier has from the previous iteration. for (size_t idx = 1; idx <= state.accumulator->log_instance_size; idx++) { transcript->send_to_verifier("perturbator_" + std::to_string(idx), state.perturbator[idx]); } diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index 35ae55dd6ef..847edc55194 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -62,8 +62,8 @@ template class ProtoGalaxyProver_ { ProverInstances instances; std::shared_ptr transcript = std::make_shared(); - ProtogalaxyProofConstructionState state; std::shared_ptr commitment_key; + ProtogalaxyProofConstructionState state; ProtoGalaxyProver_() = default; ProtoGalaxyProver_(const std::vector>& insts, @@ -457,9 +457,31 @@ template class ProtoGalaxyProver_ { FF& challenge, const FF& compressed_perturbator); + /** + * @brief Finalise the prover instances that will be folded: complete computation of all the witness polynomials and + * compute commitments. Send commitments to the verifier and retrieve challenges. + * + */ void preparation_round(); + + /** + * @brief Compute perturbator (F polynomial in paper). Send all but the constant coefficient to verifier. + * + */ void perturbator_round(); + + /** + * @brief Compute combiner (G polynomial in the paper) and then its quotient (K polynomial), whose coefficient will + * be sent to the verifier. + * + */ void combiner_quotient_round(); + + /** + * @brief Compute the next prover accumulator (ω* in the paper), encapsulated in a ProverInstance with folding + * parameters set. + * + */ void accumulator_update_round(); }; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp index 5dd711ae8f7..dffe20412d7 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/decider_recursive_verifier.cpp @@ -41,6 +41,6 @@ std::array DeciderRecursiveVerifier_:: return pairing_points; } -// template class DeciderRecursiveVerifier_>; +template class DeciderRecursiveVerifier_>; template class DeciderRecursiveVerifier_>; } // namespace bb::stdlib::recursion::honk diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp index 9652935a9f1..5ee30516632 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.cpp @@ -232,8 +232,8 @@ std::shared_ptr ProtoGalaxyRecursiveVerifi return next_accumulator; } -// template class ProtoGalaxyRecursiveVerifier_, -// 2>>; +template class ProtoGalaxyRecursiveVerifier_< + RecursiveVerifierInstances_, 2>>; template class ProtoGalaxyRecursiveVerifier_< RecursiveVerifierInstances_, 2>>; } // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp index d07a191f0b3..2b0cce7f920 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp @@ -136,8 +136,8 @@ template class ProtoGalaxyRecursiveTests : public tes static void test_new_evaluate() { Builder builder; - using fr_ct = bn254::ScalarField; - using fr = bn254::ScalarFieldNative; + using fr_ct = typename bn254::ScalarField; + using fr = typename bn254::ScalarFieldNative; std::vector coeffs; std::vector coeffs_ct; @@ -349,7 +349,8 @@ template class ProtoGalaxyRecursiveTests : public tes }; }; -using FlavorTypes = testing::Types>; +using FlavorTypes = + testing::Types, UltraRecursiveFlavor_>; TYPED_TEST_SUITE(ProtoGalaxyRecursiveTests, FlavorTypes); TYPED_TEST(ProtoGalaxyRecursiveTests, InnerCircuit) diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp index ce9c6d3449f..86aa1013ee9 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp @@ -21,7 +21,6 @@ template struct RecursiveVerifierInstan typename ArrayType::iterator begin() { return _data.begin(); }; typename ArrayType::iterator end() { return _data.end(); }; Builder* builder; - // RecursiveVerifierInstances_() = default; RecursiveVerifierInstances_(Builder* builder, std::shared_ptr accumulator, diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp index 5d2b0fb3983..f708c2274ab 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp @@ -4,6 +4,10 @@ #include "barretenberg/sumcheck/instance/verifier_instance.hpp" namespace bb::stdlib::recursion::honk { + +/** + * @brief The stdlib counterpart of VerifierInstance, used in recursive folding verification. + */ template class RecursiveVerifierInstance_ { public: using FF = typename Flavor::FF; @@ -92,6 +96,13 @@ template class RecursiveVerifierInstance_ { FF::from_witness(builder, instance->relation_parameters.lookup_grand_product_delta); } + /** + * @brief Return the underlying native VerifierInstance. + * + * @details In the context of client IVC, we will have several iterations of recursive folding verification. The + * RecursiveVerifierInstance is tied to the builder in whose context it was created so in order to preserve the + * accumulator values between several iterations we need to retrieve the native VerifierInstance values. + */ VerifierInstance get_value() { VerifierInstance inst; diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp index f00f0c5c512..55212e9dd66 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/prover_instance.hpp @@ -11,6 +11,8 @@ namespace bb { * required by an Ultra Goblin Honk prover to create a proof. A ProverInstance is also the result of running the * Protogalaxy prover, in which case it becomes a relaxed counterpart with the folding parameters (target sum and gate * challenges set to non-zero values). + * + * @details This is the equivalent of ω in the paper. */ template class ProverInstance_ { diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp index 64ac56965c6..01328e4dc6b 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp @@ -4,9 +4,11 @@ namespace bb { /** - * @brief + * @brief The VerifierInstance encapsulates all the necessary information for a Goblin Ultra Honk Verifier to verify a + * proof (sumcheck + Zeromorph). In the context of folding, this is returned by the Protogalaxy verifier with non-zero + * target sum and gate challenges. * - * @tparam Flavor + * @details This is ϕ in the paper. */ template class VerifierInstance_ { public: From c587218641228763f1ccb4bec92390a4ed803eae Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 20 Feb 2024 11:43:53 +0000 Subject: [PATCH 09/15] typos + make gcc pass --- .../benchmark/ivc_bench/ivc.bench.cpp | 18 ++++++------ .../barretenberg/client_ivc/client_ivc.cpp | 26 ++++++++--------- .../client_ivc/client_ivc.test.cpp | 15 +++++----- .../client_ivc/mock_kernel_pinning.test.cpp | 28 +++++++++---------- .../src/barretenberg/goblin/mock_circuits.hpp | 14 +++++----- .../protogalaxy/protogalaxy_verifier.cpp | 4 +-- .../protogalaxy/protogalaxy_verifier.hpp | 6 ---- .../protogalaxy_recursive_verifier.test.cpp | 12 ++++---- .../ultra_honk/ultra_composer.cpp | 2 +- 9 files changed, 58 insertions(+), 67 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp index 366fbce42ae..923b56a80dd 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp @@ -21,7 +21,7 @@ namespace { class IvcBench : public benchmark::Fixture { public: using Builder = GoblinUltraCircuitBuilder; - using FoldOutput = GoblinMockCircuits::FoldOutput; + using VerifierFoldData = GoblinMockCircuits::VerifierFoldData; // Number of function circuits to accumulate(based on Zacs target numbers) static constexpr size_t NUM_ITERATIONS_MEDIUM_COMPLEXITY = 6; @@ -48,21 +48,21 @@ class IvcBench : public benchmark::Fixture { Builder initial_function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit); ivc.initialize(initial_function_circuit); - auto kernel_verifeir_accumulator = std::make_shared(); - kernel_verifeir_accumulator->verification_key = ivc.vks.first_func_vk; + auto kernel_verifier_accumulator = std::make_shared(); + kernel_verifier_accumulator->verification_key = ivc.vks.first_func_vk; // Accumulate another function circuit Builder function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(function_circuit); auto function_fold_proof = ivc.accumulate(function_circuit); - FoldOutput function_fold_output = { function_fold_proof, ivc.vks.func_vk }; + VerifierFoldData function_fold_output = { function_fold_proof, ivc.vks.func_vk }; // Create and accumulate the first folding kernel which only verifies the accumulation of a function circuit Builder kernel_circuit{ ivc.goblin.op_queue }; - kernel_verifeir_accumulator = GoblinMockCircuits::construct_mock_folding_kernel( - kernel_circuit, function_fold_output, {}, kernel_verifeir_accumulator); + kernel_verifier_accumulator = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, function_fold_output, {}, kernel_verifier_accumulator); auto kernel_fold_proof = ivc.accumulate(kernel_circuit); - FoldOutput kernel_fold_output = { kernel_fold_proof, ivc.vks.first_kernel_vk }; + VerifierFoldData kernel_fold_output = { kernel_fold_proof, ivc.vks.first_kernel_vk }; auto NUM_CIRCUITS = static_cast(state.range(0)); // Subtract one to account for the "initialization" round above @@ -77,8 +77,8 @@ class IvcBench : public benchmark::Fixture { // Create kernel circuit containing the recursive folding verification of a function circuit and a kernel // circuit and accumulate it Builder kernel_circuit{ ivc.goblin.op_queue }; - kernel_verifeir_accumulator = GoblinMockCircuits::construct_mock_folding_kernel( - kernel_circuit, function_fold_output, kernel_fold_output, kernel_verifeir_accumulator); + kernel_verifier_accumulator = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, function_fold_output, kernel_fold_output, kernel_verifier_accumulator); kernel_fold_proof = ivc.accumulate(kernel_circuit); kernel_fold_output = { kernel_fold_proof, ivc.vks.kernel_vk }; diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index b1ca55b5757..0b524505d7e 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -100,8 +100,8 @@ void ClientIVC::precompute_folding_verification_keys() initialize(initial_function_circuit); composer.compute_commitment_key(prover_fold_output.accumulator->instance_size); vks.first_func_vk = composer.compute_verification_key(prover_fold_output.accumulator); - auto verifier_acc = std::make_shared(); - verifier_acc->verification_key = vks.first_func_vk; + auto initial_verifier_acc = std::make_shared(); + initial_verifier_acc->verification_key = vks.first_func_vk; // Accumulate the next function circuit ClientCircuit function_circuit{ goblin.op_queue }; @@ -113,25 +113,23 @@ void ClientIVC::precompute_folding_verification_keys() // Create the initial kernel iteration and precompute its verification key ClientCircuit kernel_circuit{ goblin.op_queue }; - auto new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - kernel_circuit, { function_fold_proof, vks.func_vk }, {}, verifier_acc); + auto kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, { function_fold_proof, vks.func_vk }, {}, initial_verifier_acc); auto kernel_fold_proof = accumulate(kernel_circuit); vks.first_kernel_vk = composer.compute_verification_key(prover_instance); // Create another mock function circuit to run the full kernel - ClientCircuit circuit_4{ goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(circuit_4); - function_fold_proof = accumulate(circuit_4); + function_circuit = ClientCircuit{ goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(function_circuit); + function_fold_proof = accumulate(function_circuit); - // Create the fullk ernel circuit and compute verification key - ClientCircuit new_kernel_circuit = GoblinUltraCircuitBuilder{ goblin.op_queue }; - auto new_new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - new_kernel_circuit, { function_fold_proof, vks.func_vk }, { kernel_fold_proof, vks.first_kernel_vk }, new_acc); - kernel_fold_proof = accumulate(new_kernel_circuit); + // Create the full kernel circuit and compute verification key + kernel_circuit = GoblinUltraCircuitBuilder{ goblin.op_queue }; + kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, { function_fold_proof, vks.func_vk }, { kernel_fold_proof, vks.first_kernel_vk }, kernel_acc); + kernel_fold_proof = accumulate(kernel_circuit); vks.kernel_vk = composer.compute_verification_key(prover_instance); - auto kernel_inst = std::make_shared(); - kernel_inst->verification_key = vks.kernel_vk; // Clean the ivc state goblin.op_queue = std::make_shared(); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp index ebbbb5b5219..9dd76691320 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp @@ -25,7 +25,7 @@ class ClientIVCTests : public ::testing::Test { using VerifierAccumulator = ClientIVC::VerifierAccumulator; using VerifierInstance = ClientIVC::VerifierInstance; using FoldProof = ClientIVC::FoldProof; - using FoldOutput = GoblinMockCircuits::FoldOutput; + using VerifierFoldData = GoblinMockCircuits::VerifierFoldData; using GURecursiveFlavor = GoblinUltraRecursiveFlavor_; using RecursiveVerifierInstance = ::bb::stdlib::recursion::honk::RecursiveVerifierInstance_; using RecursiveVerifierAccumulator = std::shared_ptr; @@ -55,8 +55,8 @@ class ClientIVCTests : public ::testing::Test { * @param kernel_fold_proof */ static VerifierAccumulator construct_mock_folding_kernel(Builder& builder, - FoldOutput& func_accum, - FoldOutput& kernel_accum, + VerifierFoldData& func_accum, + VerifierFoldData& kernel_accum, VerifierAccumulator& prev_kernel_accum) { @@ -90,25 +90,26 @@ TEST_F(ClientIVCTests, Full) FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); auto function_vk_2 = composer.compute_verification_key(ivc.prover_instance); auto kernel_vk = function_vk_2; - FoldOutput kernel_fold_output = { kernel_fold_proof, function_vk_2 }; + VerifierFoldData kernel_fold_output = { kernel_fold_proof, function_vk_2 }; size_t NUM_CIRCUITS = 1; for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { // Accumulate function circuit Builder function_circuit = create_mock_circuit(ivc); FoldProof function_fold_proof = ivc.accumulate(function_circuit); - FoldOutput function_fold_output = { function_fold_proof, function_vk_2 }; + VerifierFoldData function_fold_output = { function_fold_proof, function_vk_2 }; // Accumulate kernel circuit Builder kernel_circuit{ ivc.goblin.op_queue }; kernel_acc = construct_mock_folding_kernel(kernel_circuit, kernel_fold_output, function_fold_output, kernel_acc); FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); kernel_vk = composer.compute_verification_key(ivc.prover_instance); - FoldOutput kernel_fold_output = { kernel_fold_proof, kernel_vk }; + VerifierFoldData kernel_fold_output = { kernel_fold_proof, kernel_vk }; } // Constuct four proofs: merge, eccvm, translator, decider auto proof = ivc.prove(); - auto inst = std::make_shared(kernel_vk); + auto inst = std::make_shared(); + inst->verification_key = kernel_vk; // Verify all four proofs EXPECT_TRUE(ivc.verify(proof, { kernel_acc, inst })); }; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp index 5011d175391..d3b322558ae 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp @@ -18,37 +18,37 @@ class MockKernelTest : public ::testing::Test { TEST_F(MockKernelTest, PinFoldingKernelSizes) { - using FoldOutput = GoblinMockCircuits::FoldOutput; ClientIVC ivc; ivc.precompute_folding_verification_keys(); - // Accumulate three circuits to generate two folding proofs for input to foldng kernel + // Accumulate three circuits to generate two folding proofs for input to folding kernel GoblinUltraCircuitBuilder circuit_1{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_1); ivc.initialize(circuit_1); - auto verifier_acc = std::make_shared(); - verifier_acc->verification_key = ivc.vks.first_func_vk; + auto initial_acc = std::make_shared(); + initial_acc->verification_key = ivc.vks.first_func_vk; GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_2); - auto fold_proof_1 = ivc.accumulate(circuit_2); + auto func_fold_proof = ivc.accumulate(circuit_2); - FoldOutput kernel_accum; // Construct kernel circuit GoblinUltraCircuitBuilder kernel_circuit{ ivc.goblin.op_queue }; - auto new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - kernel_circuit, { fold_proof_1, ivc.vks.func_vk }, {}, verifier_acc); + auto kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, { func_fold_proof, ivc.vks.func_vk }, {}, initial_acc); - auto fold_proof_3 = ivc.accumulate(kernel_circuit); + auto kernel_fold_proof = ivc.accumulate(kernel_circuit); EXPECT_EQ(ivc.prover_instance->log_instance_size, 17); GoblinUltraCircuitBuilder circuit_4{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_4); - auto fold_proof_4 = ivc.accumulate(circuit_4); + func_fold_proof = ivc.accumulate(circuit_4); - GoblinUltraCircuitBuilder new_kernel_circuit = GoblinUltraCircuitBuilder{ ivc.goblin.op_queue }; - new_acc = GoblinMockCircuits::construct_mock_folding_kernel( - new_kernel_circuit, { fold_proof_3, ivc.vks.first_kernel_vk }, { fold_proof_4, ivc.vks.func_vk }, new_acc); + kernel_circuit = GoblinUltraCircuitBuilder{ ivc.goblin.op_queue }; + kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, + { kernel_fold_proof, ivc.vks.first_kernel_vk }, + { func_fold_proof, ivc.vks.func_vk }, + kernel_acc); GoblinUltraComposer composer; - auto instance = composer.create_prover_instance(new_kernel_circuit); + auto instance = composer.create_prover_instance(kernel_circuit); EXPECT_EQ(instance->proving_key->log_circuit_size, 17); } \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index ef009d2cd0f..8ad82a88973 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -37,12 +37,12 @@ class GoblinMockCircuits { static constexpr size_t NUM_OP_QUEUE_COLUMNS = Flavor::NUM_WIRES; /** - * @brief - * + * @brief Information required by the verifier to verify a folding round besides the previous accumulator. */ - struct FoldOutput { - std::vector fold_proof; - std::shared_ptr inst_vk; + struct VerifierFoldData { + std::vector fold_proof; // folding proof + std::shared_ptr + inst_vk; // Verification key of the instance to be folded (note: this would be a vector if k > 1 ) }; /** @@ -227,8 +227,8 @@ class GoblinMockCircuits { */ static std::shared_ptr construct_mock_folding_kernel( GoblinUltraBuilder& builder, - const FoldOutput& func, - const FoldOutput& kernel, + const VerifierFoldData& func, + const VerifierFoldData& kernel, std::shared_ptr& prev_kernel_accum) { using GURecursiveFlavor = GoblinUltraRecursiveFlavor_; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 386f326a8d6..ce08bcc400e 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -142,13 +142,13 @@ std::shared_ptr ProtoGalaxyVerifier_instance_size = accumulator->instance_size; next_accumulator->log_instance_size = accumulator->log_instance_size; next_accumulator->is_accumulator = true; - // Compute next folding parameters and verify against the ones received from the prover + // Compute next folding parameters next_accumulator->target_sum = perturbator_at_challenge * lagranges[0] + vanishing_polynomial_at_challenge * combiner_quotient_at_challenge; next_accumulator->gate_challenges = update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); - // Compute ϕ and verify against the data received from the prover + // Compute ϕ auto& acc_witness_commitments = next_accumulator->witness_commitments; auto witness_labels = commitment_labels.get_witness(); size_t comm_idx = 0; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.hpp index 05dae2fb4f1..9a39986fe4b 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.hpp @@ -66,12 +66,6 @@ template class ProtoGalaxyVerifier_ { */ void prepare_for_folding(const std::vector&); - /** - * @brief Instantiatied the accumulator (i.e. the relaxed instance) from the transcript. - * - */ - // void receive_accumulator(const std::shared_ptr&, const std::string&); - /** * @brief Process the public data ϕ for the Instances to be folded. * diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp index 2b0cce7f920..60d71130b27 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp @@ -180,14 +180,13 @@ template class ProtoGalaxyRecursiveTests : public tes Builder folding_circuit; auto verifier = FoldingRecursiveVerifier(&folding_circuit, verifier_instance_1, { verifier_instance_2->verification_key }); - auto recursive_verifier_accumulator = verifier.verify_folding_proof(folding_proof.folding_data); - auto acc = std::make_shared(recursive_verifier_accumulator->get_value()); + verifier.verify_folding_proof(folding_proof.folding_data); info("Folding Recursive Verifier: num gates = ", folding_circuit.num_gates); // Perform native folding verification and ensure it returns the same result (either true or false) as // calling check_circuit on the recursive folding verifier auto native_folding_verifier = composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); - auto verifier_accumulator = native_folding_verifier.verify_folding_proof(folding_proof.folding_data); + native_folding_verifier.verify_folding_proof(folding_proof.folding_data); // Ensure that the underlying native and recursive folding verification algorithms agree by ensuring the // manifestsproduced by each agree. @@ -240,7 +239,7 @@ template class ProtoGalaxyRecursiveTests : public tes auto verifier = FoldingRecursiveVerifier(&folding_circuit, verifier_instance_1, { verifier_instance_2->verification_key }); auto recursive_verifier_accumulator = verifier.verify_folding_proof(folding_proof.folding_data); - auto acc = std::make_shared(recursive_verifier_accumulator->get_value()); + auto native_verifier_acc = std::make_shared(recursive_verifier_accumulator->get_value()); info("Folding Recursive Verifier: num gates = ", folding_circuit.num_gates); // Perform native folding verification and ensure it returns the same result (either true or false) as @@ -261,7 +260,7 @@ template class ProtoGalaxyRecursiveTests : public tes auto decider_proof = decider_prover.construct_proof(); Builder decider_circuit; - DeciderRecursiveVerifier decider_verifier{ &decider_circuit, acc }; + DeciderRecursiveVerifier decider_verifier{ &decider_circuit, native_verifier_acc }; auto pairing_points = decider_verifier.verify_proof(decider_proof); info("Decider Recursive Verifier: num gates = ", decider_circuit.num_gates); // Check for a failure flag in the recursive verifier circuit @@ -349,8 +348,7 @@ template class ProtoGalaxyRecursiveTests : public tes }; }; -using FlavorTypes = - testing::Types, UltraRecursiveFlavor_>; +using FlavorTypes = testing::Types>; TYPED_TEST_SUITE(ProtoGalaxyRecursiveTests, FlavorTypes); TYPED_TEST(ProtoGalaxyRecursiveTests, InnerCircuit) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp index b745f001c5b..1ed884e8830 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp @@ -58,7 +58,7 @@ std::shared_ptr UltraComposer_::comput verification_key->q_poseidon2_internal = commitment_key->commit(proving_key->q_poseidon2_internal); } - return std::move(verification_key); + return verification_key; } template From cb57dadef97b2235d4dc7635d44717dddc85c93f Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 20 Feb 2024 15:37:27 +0000 Subject: [PATCH 10/15] stuff --- .../verifier/protogalaxy_recursive_verifier.test.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp index 60d71130b27..e8749b39289 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp @@ -188,6 +188,9 @@ template class ProtoGalaxyRecursiveTests : public tes auto native_folding_verifier = composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); native_folding_verifier.verify_folding_proof(folding_proof.folding_data); + // Check for a failure flag in the recursive verifier circuit + EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err(); + // Ensure that the underlying native and recursive folding verification algorithms agree by ensuring the // manifestsproduced by each agree. auto recursive_folding_manifest = verifier.transcript->get_manifest(); @@ -242,6 +245,9 @@ template class ProtoGalaxyRecursiveTests : public tes auto native_verifier_acc = std::make_shared(recursive_verifier_accumulator->get_value()); info("Folding Recursive Verifier: num gates = ", folding_circuit.num_gates); + // Check for a failure flag in the recursive verifier circuit + EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err(); + // Perform native folding verification and ensure it returns the same result (either true or false) as // calling check_circuit on the recursive folding verifier auto native_folding_verifier = composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); @@ -266,9 +272,6 @@ template class ProtoGalaxyRecursiveTests : public tes // Check for a failure flag in the recursive verifier circuit EXPECT_EQ(decider_circuit.failed(), false) << decider_circuit.err(); - // Check for a failure flag in the recursive verifier circuit - EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err(); - DeciderVerifier native_decider_verifier = composer.create_decider_verifier(verifier_accumulator); auto native_result = native_decider_verifier.verify_proof(decider_proof); auto recursive_result = native_decider_verifier.pcs_verification_key->pairing_check( @@ -348,7 +351,8 @@ template class ProtoGalaxyRecursiveTests : public tes }; }; -using FlavorTypes = testing::Types>; +using FlavorTypes = + testing::Types, UltraRecursiveFlavor_>; TYPED_TEST_SUITE(ProtoGalaxyRecursiveTests, FlavorTypes); TYPED_TEST(ProtoGalaxyRecursiveTests, InnerCircuit) From f1f7127381cf3d89d003ced383d4fb8f789bf567 Mon Sep 17 00:00:00 2001 From: maramihali Date: Thu, 22 Feb 2024 15:00:19 +0000 Subject: [PATCH 11/15] make sure we fold as many function circuits as expected, not one more --- .../cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp index 923b56a80dd..0707203510c 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp @@ -65,8 +65,9 @@ class IvcBench : public benchmark::Fixture { VerifierFoldData kernel_fold_output = { kernel_fold_proof, ivc.vks.first_kernel_vk }; auto NUM_CIRCUITS = static_cast(state.range(0)); - // Subtract one to account for the "initialization" round above - NUM_CIRCUITS -= 1; + // Subtract two to account for the "initialization" round above i.e. we have already folded two function + // circuits + NUM_CIRCUITS -= 2; for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { // Accumulate function circuit Builder function_circuit{ ivc.goblin.op_queue }; @@ -175,7 +176,6 @@ BENCHMARK_DEFINE_F(IvcBench, Translator)(benchmark::State& state) #define ARGS \ Arg(IvcBench::NUM_ITERATIONS_MEDIUM_COMPLEXITY) \ - ->Arg(1 << 0) \ ->Arg(1 << 1) \ ->Arg(1 << 2) \ ->Arg(1 << 3) \ From 03887952ab5479ea5226731ec51935d06fe69aac Mon Sep 17 00:00:00 2001 From: ludamad Date: Thu, 22 Feb 2024 17:10:12 +0000 Subject: [PATCH 12/15] additional op count timing --- barretenberg/cpp/scripts/collect_profile_information.sh | 2 +- .../cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp | 5 +++-- .../src/barretenberg/commitment_schemes/commitment_key.hpp | 2 ++ barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp | 3 +++ .../proof_system/execution_trace/execution_trace.cpp | 1 - .../cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp | 3 +++ 6 files changed, 12 insertions(+), 4 deletions(-) diff --git a/barretenberg/cpp/scripts/collect_profile_information.sh b/barretenberg/cpp/scripts/collect_profile_information.sh index ebc0249392e..1323e157b02 100755 --- a/barretenberg/cpp/scripts/collect_profile_information.sh +++ b/barretenberg/cpp/scripts/collect_profile_information.sh @@ -15,7 +15,7 @@ cd $(dirname $0)/.. # Configure and build with xray preset. cmake --preset $PRESET -cmake --build --preset $PRESET +cmake --build --preset $PRESET --target $EXECUTABLE cd build-$PRESET diff --git a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp index 95eeb7d5b94..e9ba9ed185e 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/ivc_bench/ivc.bench.cpp @@ -98,6 +98,7 @@ BENCHMARK_DEFINE_F(IvcBench, Accumulate)(benchmark::State& state) // Perform a specified number of iterations of function/kernel accumulation for (auto _ : state) { + BB_REPORT_OP_COUNT_IN_BENCH(state); perform_ivc_accumulation_rounds(state, ivc); } } @@ -110,12 +111,12 @@ BENCHMARK_DEFINE_F(IvcBench, Decide)(benchmark::State& state) { ClientIVC ivc; - BB_REPORT_OP_COUNT_IN_BENCH(state); // Perform a specified number of iterations of function/kernel accumulation perform_ivc_accumulation_rounds(state, ivc); // Construct eccvm proof, measure only translator proof construction for (auto _ : state) { + BB_REPORT_OP_COUNT_IN_BENCH(state); ivc.decider_prove(); } } @@ -128,12 +129,12 @@ BENCHMARK_DEFINE_F(IvcBench, ECCVM)(benchmark::State& state) { ClientIVC ivc; - BB_REPORT_OP_COUNT_IN_BENCH(state); // Perform a specified number of iterations of function/kernel accumulation perform_ivc_accumulation_rounds(state, ivc); // Construct and measure eccvm only for (auto _ : state) { + BB_REPORT_OP_COUNT_IN_BENCH(state); ivc.goblin.prove_eccvm(); } } diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp index 73369a2965d..c842e53177e 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.hpp @@ -7,6 +7,7 @@ * simplify the codebase. */ +#include "barretenberg/common/op_count.hpp" #include "barretenberg/ecc/scalar_multiplication/scalar_multiplication.hpp" #include "barretenberg/numeric/bitop/pow.hpp" #include "barretenberg/polynomials/polynomial.hpp" @@ -64,6 +65,7 @@ template class CommitmentKey { */ Commitment commit(std::span polynomial) { + BB_OP_COUNT_TIME(); const size_t degree = polynomial.size(); ASSERT(degree <= srs->get_monomial_size()); return bb::scalar_multiplication::pippenger_unsafe( diff --git a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp index 02500ee75b5..bc14c506539 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp +++ b/barretenberg/cpp/src/barretenberg/goblin/mock_circuits.hpp @@ -1,6 +1,7 @@ #pragma once #include "barretenberg/commitment_schemes/commitment_key.hpp" +#include "barretenberg/common/op_count.hpp" #include "barretenberg/crypto/ecdsa/ecdsa.hpp" #include "barretenberg/crypto/merkle_tree/membership.hpp" #include "barretenberg/crypto/merkle_tree/memory_store.hpp" @@ -95,6 +96,7 @@ class GoblinMockCircuits { */ static void construct_mock_function_circuit(GoblinUltraBuilder& builder, bool large = false) { + BB_OP_COUNT_TIME(); // Determine number of times to execute the below operations that constitute the mock circuit logic. Note that // the circuit size does not scale linearly with number of iterations due to e.g. amortization of lookup costs const size_t NUM_ITERATIONS_LARGE = 13; // results in circuit size 2^19 (521327 gates) @@ -216,6 +218,7 @@ class GoblinMockCircuits { const std::vector& function_fold_proof, const std::vector& kernel_fold_proof) { + BB_OP_COUNT_TIME(); using GURecursiveFlavor = GoblinUltraRecursiveFlavor_; using RecursiveVerifierInstances = ::bb::VerifierInstances_; using FoldingRecursiveVerifier = diff --git a/barretenberg/cpp/src/barretenberg/proof_system/execution_trace/execution_trace.cpp b/barretenberg/cpp/src/barretenberg/proof_system/execution_trace/execution_trace.cpp index 26532627539..4cab2c63518 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/execution_trace/execution_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/execution_trace/execution_trace.cpp @@ -56,7 +56,6 @@ typename ExecutionTrace_::TraceData ExecutionTrace_::construct_t // For each block in the trace, populate wire polys, copy cycles and selector polys for (auto& block : trace_blocks) { auto block_size = static_cast(block.wires[0].size()); - info("block size = ", block_size); // Update wire polynomials and copy cycles // NB: The order of row/column loops is arbitrary but needs to be row/column to match old copy_cycle code diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index 0df61d1d82f..4fd7689471e 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -1,4 +1,5 @@ #pragma once +#include "barretenberg/common/op_count.hpp" #include "barretenberg/common/thread.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/flavor/flavor.hpp" @@ -247,6 +248,7 @@ template class ProtoGalaxyProver_ { static Polynomial compute_perturbator(const std::shared_ptr accumulator, const std::vector& deltas) { + BB_OP_COUNT_TIME(); auto full_honk_evaluations = compute_full_honk_evaluations( accumulator->prover_polynomials, accumulator->alphas, accumulator->relation_parameters); const auto betas = accumulator->gate_challenges; @@ -298,6 +300,7 @@ template class ProtoGalaxyProver_ { */ ExtendedUnivariateWithRandomization compute_combiner(const ProverInstances& instances, PowPolynomial& pow_betas) { + BB_OP_COUNT_TIME(); size_t common_instance_size = instances[0]->instance_size; pow_betas.compute_values(); // Determine number of threads for multithreading. From 53affadad0491366248ed818fd3ad538bb7a0f7c Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 28 Feb 2024 11:11:28 +0000 Subject: [PATCH 13/15] respond to review --- .../client_ivc/client_ivc.test.cpp | 10 +++- .../protogalaxy_recursive_verifier.hpp | 4 +- .../protogalaxy_recursive_verifier.test.cpp | 60 +++++++++++-------- .../honk/verifier/recursive_instances.hpp | 4 +- .../sumcheck/instance/instances.hpp | 2 +- .../ultra_honk/protogalaxy.test.cpp | 18 +++--- .../ultra_honk/ultra_composer.cpp | 2 +- 7 files changed, 56 insertions(+), 44 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp index 873920aad42..11d32265ca9 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp @@ -48,11 +48,15 @@ class ClientIVCTests : public ::testing::Test { } /** - * @brief Construct mock kernel consisting of two recursive folding verifiers + * @brief Construct mock kernel consisting of two recursive folding verifiers to verify the folding of the previous + * function circuit and kernel circuit. * * @param builder - * @param fctn_fold_proof - * @param kernel_fold_proof + * @param fctn_accum contains the folding proof for the function circuit and the corresponsing function + * verifier instance + * @param kernel_accum contains the folding proof for the kernel circuit and the corresponding kernel verifier + * instance + * @returns the updated verifier accumulator */ static VerifierAccumulator construct_mock_folding_kernel(Builder& builder, VerifierFoldData& func_accum, diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp index f413fb3b151..081b1361765 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.hpp @@ -36,8 +36,8 @@ template class ProtoGalaxyRecursiveVerifier_ { VerifierInstances instances; ProtoGalaxyRecursiveVerifier_(Builder* builder, - std::shared_ptr accumulator, - const std::vector> native_inst_vks) + std::shared_ptr& accumulator, + const std::vector>& native_inst_vks) : builder(builder) , instances(VerifierInstances(builder, accumulator, native_inst_vks)){}; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp index 9e1f0835dad..64988f97d58 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp @@ -38,7 +38,7 @@ template class ProtoGalaxyRecursiveTests : public tes * TODO(https://github.com/AztecProtocol/barretenberg/issues/744): make testing utility with functionality shared * amongst test files */ - static void create_function_circuit(Builder& builder, size_t log_num_gates = 15) + static void create_function_circuit(Builder& builder, size_t log_num_gates = 10) { using fr_ct = typename Curve::ScalarField; using fq_ct = typename Curve::BaseField; @@ -165,6 +165,7 @@ template class ProtoGalaxyRecursiveTests : public tes Builder builder1; create_function_circuit(builder1); Builder builder2; + builder2.add_public_variable(FF(1)); create_function_circuit(builder2); Composer composer = Composer(); @@ -183,14 +184,11 @@ template class ProtoGalaxyRecursiveTests : public tes verifier.verify_folding_proof(folding_proof.folding_data); info("Folding Recursive Verifier: num gates = ", folding_circuit.num_gates); - // Perform native folding verification and ensure it returns the same result (either true or false) as - // calling check_circuit on the recursive folding verifier + // Perform native folding verification and ensure it returns the same result (either true or false) as calling + // check_circuit on the recursive folding verifier auto native_folding_verifier = composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); native_folding_verifier.verify_folding_proof(folding_proof.folding_data); - // Check for a failure flag in the recursive verifier circuit - EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err(); - // Ensure that the underlying native and recursive folding verification algorithms agree by ensuring the // manifestsproduced by each agree. auto recursive_folding_manifest = verifier.transcript->get_manifest(); @@ -200,6 +198,9 @@ template class ProtoGalaxyRecursiveTests : public tes EXPECT_EQ(recursive_folding_manifest[i], native_folding_manifest[i]); } + // Check for a failure flag in the recursive verifier circuit + EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err(); + { auto composer = Composer(); auto instance = composer.create_prover_instance(folding_circuit); @@ -218,14 +219,16 @@ template class ProtoGalaxyRecursiveTests : public tes * make sure the verifer circuits pass check_circuit(). Ensure that the algorithm of the recursive and native * verifiers are identical by checking the manifests */ - // TODO(https://github.com/AztecProtocol/barretenberg/issues/844): Fold the recursive folding verifier in - // tests once we can fold instances of different sizes. + // TODO(https://github.com/AztecProtocol/barretenberg/issues/844): Fold the recursive folding verifier in tests once + // we can fold instances of different sizes. static void test_full_protogalaxy_recursive() { // Create two arbitrary circuits for the first round of folding Builder builder1; create_function_circuit(builder1); Builder builder2; + builder2.add_public_variable(FF(1)); + create_function_circuit(builder2); Composer composer = Composer(); @@ -272,12 +275,23 @@ template class ProtoGalaxyRecursiveTests : public tes // Check for a failure flag in the recursive verifier circuit EXPECT_EQ(decider_circuit.failed(), false) << decider_circuit.err(); + // Perform native verification then perform the pairing on the outputs of the recursive + // decider verifier and check that the result agrees. DeciderVerifier native_decider_verifier = composer.create_decider_verifier(verifier_accumulator); auto native_result = native_decider_verifier.verify_proof(decider_proof); auto recursive_result = native_decider_verifier.pcs_verification_key->pairing_check( pairing_points[0].get_value(), pairing_points[1].get_value()); EXPECT_EQ(native_result, recursive_result); + // Ensure that the underlying native and recursive decider verification algorithms agree by ensuring + // the manifests produced are the same. + auto recursive_decider_manifest = decider_verifier.transcript->get_manifest(); + auto native_decider_manifest = native_decider_verifier.transcript->get_manifest(); + for (size_t i = 0; i < recursive_decider_manifest.size(); ++i) { + EXPECT_EQ(recursive_decider_manifest[i], native_decider_manifest[i]); + } + + // Construct and verify a proof of the recursive decider verifier circuit { auto composer = Composer(); auto instance = composer.create_prover_instance(decider_circuit); @@ -293,7 +307,7 @@ template class ProtoGalaxyRecursiveTests : public tes static void test_tampered_decider_proof() { - // Create two arbitrary circuits for the first round of folding + // Natively fold two circuits auto composer = Composer(); auto [prover_accumulator, verifier_accumulator] = fold_and_verify_native(composer); @@ -310,43 +324,37 @@ template class ProtoGalaxyRecursiveTests : public tes decider_verifier.verify_proof(decider_proof); info("Decider Recursive Verifier: num gates = ", decider_circuit.num_gates); - { - auto composer = Composer(); - auto instance = composer.create_prover_instance(decider_circuit); - auto verification_key = composer.compute_verification_key(instance); - auto prover = composer.create_prover(instance); - auto verifier = composer.create_verifier(verification_key); - auto proof = prover.construct_proof(); - bool verified = verifier.verify_proof(proof); - - EXPECT_FALSE(verified); - } + // We expect the decider circuit check to fail due to the bad proof + EXPECT_FALSE(decider_circuit.check_circuit()); }; static void test_tampered_accumulator() { - + // Fold two circuits natively auto composer = Composer(); auto [prover_accumulator, verifier_accumulator] = fold_and_verify_native(composer); // Create another circuit to do a second round of folding - Builder builder3; - create_function_circuit(builder3); - auto prover_inst = composer.create_prover_instance(builder3); + Builder builder; + create_function_circuit(builder); + auto prover_inst = composer.create_prover_instance(builder); auto verifier_inst = composer.create_verifier_instance(prover_inst); prover_accumulator->prover_polynomials.w_l[1] = FF::random_element(); - // Generate a folding proof + // Generate a folding proof with the incorrect polynomials which would result in the prover having the wrong + // target sum auto folding_prover = composer.create_folding_prover({ prover_accumulator, prover_inst }); auto folding_proof = folding_prover.fold_instances(); - // Create a recursive folding verifier circuit for the folding proof of the two instances + // Create a recursive folding verifier circuit for the folding proof of the two instances with the untampered + // commitments Builder folding_circuit; FoldingRecursiveVerifier verifier{ &folding_circuit, verifier_accumulator, { verifier_inst->verification_key } }; auto recursive_verifier_acc = verifier.verify_folding_proof(folding_proof.folding_data); + // Validate that the target sum between prover and verifier is now different EXPECT_FALSE(folding_proof.accumulator->target_sum == recursive_verifier_acc->target_sum.get_value()); }; }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp index 86aa1013ee9..fb5db484c96 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp @@ -23,8 +23,8 @@ template struct RecursiveVerifierInstan Builder* builder; RecursiveVerifierInstances_(Builder* builder, - std::shared_ptr accumulator, - std::vector> vks) + const std::shared_ptr& accumulator, + const std::vector>& vks) : builder(builder) { ASSERT(vks.size() == NUM - 1); diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp index f4ee368b7f6..e2c168406c3 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/instances.hpp @@ -99,7 +99,7 @@ template struct VerifierInstances_ { typename ArrayType::iterator end() { return _data.end(); }; VerifierInstances_() = default; - VerifierInstances_(std::vector> data) + VerifierInstances_(const std::vector>& data) { ASSERT(data.size() == NUM); for (size_t idx = 0; idx < data.size(); idx++) { diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp index 895aba6c412..3c4370edd94 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/protogalaxy.test.cpp @@ -35,7 +35,7 @@ template class ProtoGalaxyTests : public testing::Test { static void construct_circuit(Builder& builder) { if constexpr (IsGoblinFlavor) { - GoblinMockCircuits::construct_arithmetic_circuit(builder, 200); + GoblinMockCircuits::construct_arithmetic_circuit(builder); GoblinMockCircuits::construct_goblin_ecc_op_circuit(builder); } else { @@ -105,8 +105,8 @@ template class ProtoGalaxyTests : public testing::Test { /** * @brief For a valid circuit, ensures that computing the value of the full UH/UGH relation at each row in its - * execution trace (with the contribution of the linearly dependent one added tot he first row, in case of - * Goblin) will be 0. + * execution trace (with the contribution of the linearly dependent one added tot he first row, in case of Goblin) + * will be 0. * */ static void test_full_honk_evaluations_valid_circuit() @@ -140,8 +140,8 @@ template class ProtoGalaxyTests : public testing::Test { } /** - * @brief Check the coefficients of the perturbator computed from dummy \vec{β}, \vec{δ} and f_i(ω) will be the - * same as if computed manually. + * @brief Check the coefficients of the perturbator computed from dummy \vec{β}, \vec{δ} and f_i(ω) will be the same + * as if computed manually. * */ static void test_pertubator_coefficients() @@ -210,8 +210,8 @@ template class ProtoGalaxyTests : public testing::Test { } /** - * @brief Manually compute the expected evaluations of the combiner quotient, given evaluations of the combiner - * and check them against the evaluations returned by the function. + * @brief Manually compute the expected evaluations of the combiner quotient, given evaluations of the combiner and + * check them against the evaluations returned by the function. * */ static void test_combiner_quotient() @@ -243,8 +243,8 @@ template class ProtoGalaxyTests : public testing::Test { } /** - * @brief For two dummy instances with their relation parameter η set, check that combining them in a - * univariate, barycentrially extended to the desired number of evaluations, is performed correctly. + * @brief For two dummy instances with their relation parameter η set, check that combining them in a univariate, + * barycentrially extended to the desired number of evaluations, is performed correctly. * */ static void test_combine_relation_parameters() diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp index 1ed884e8830..7b8b0506d90 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp @@ -68,7 +68,7 @@ std::shared_ptr> UltraComposer_::create_prover_i circuit.finalize_circuit(); auto instance = std::make_shared(circuit); instance->instance_size = instance->proving_key->circuit_size; - commitment_key = compute_commitment_key(instance->instance_size); // hm + commitment_key = compute_commitment_key(instance->instance_size); return instance; } From 4e40628f6440cab04935af9ed0198144fa24a92b Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 28 Feb 2024 11:45:32 +0000 Subject: [PATCH 14/15] more refactoring based to PR reviews --- .../client_ivc_bench/client_ivc.bench.cpp | 2 +- .../client_ivc/client_ivc.test.cpp | 57 ++++++++++++++++--- .../client_ivc/mock_kernel_pinning.test.cpp | 14 ++--- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp index e24891480be..a3945276259 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp @@ -42,7 +42,7 @@ class ClientIVCBench : public benchmark::Fixture { */ static void perform_ivc_accumulation_rounds(State& state, ClientIVC& ivc) { - // Initialize IVC with a function circuit + // Initialize IVC with function circuit Builder initial_function_circuit{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit); ivc.initialize(initial_function_circuit); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp index 11d32265ca9..b2bf440ff62 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp @@ -71,6 +71,33 @@ class ClientIVCTests : public ::testing::Test { auto kernel_verifier_accum = verifier_2.verify_folding_proof(kernel_accum.fold_proof); return std::make_shared(kernel_verifier_accum->get_value()); } + + /** + * @brief Perform native fold verification and run decider prover/verifier + * + */ + static VerifierAccumulator EXPECT_FOLDING_AND_DECIDING_VERIFIED( + const ProverAccumulator& prover_accumulator, + const FoldProof& fold_proof, + const VerifierAccumulator& prev_verifier_accumulator, + const std::shared_ptr& verifier_inst_vk) + { + // Verify fold proof + Composer composer; + auto new_verifier_inst = std::make_shared(); + new_verifier_inst->verification_key = verifier_inst_vk; + auto folding_verifier = composer.create_folding_verifier({ prev_verifier_accumulator, new_verifier_inst }); + auto verifier_accumulator = folding_verifier.verify_folding_proof(fold_proof); + + // Run decider + auto decider_prover = composer.create_decider_prover(prover_accumulator); + auto decider_verifier = composer.create_decider_verifier(verifier_accumulator); + auto decider_proof = decider_prover.construct_proof(); + bool decision = decider_verifier.verify_proof(decider_proof); + EXPECT_TRUE(decision); + + return verifier_accumulator; + } }; /** @@ -87,26 +114,38 @@ TEST_F(ClientIVCTests, Full) composer.compute_commitment_key(ivc.prover_fold_output.accumulator->instance_size); auto function_vk = composer.compute_verification_key(ivc.prover_fold_output.accumulator); - auto kernel_acc = std::make_shared(); - kernel_acc->verification_key = function_vk; + auto verifier_accumulator = std::make_shared(); + verifier_accumulator->verification_key = function_vk; // Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet) Builder kernel_circuit = create_mock_circuit(ivc); FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); - auto function_vk_2 = composer.compute_verification_key(ivc.prover_instance); - auto kernel_vk = function_vk_2; - VerifierFoldData kernel_fold_output = { kernel_fold_proof, function_vk_2 }; + // This will have a different verification key because we added the recursive merge verification to the circuit + auto function_vk_with_merge = composer.compute_verification_key(ivc.prover_instance); + auto kernel_vk = function_vk_with_merge; + auto intermediary_acc = EXPECT_FOLDING_AND_DECIDING_VERIFIED( + ivc.prover_fold_output.accumulator, kernel_fold_proof, verifier_accumulator, kernel_vk); + + VerifierFoldData kernel_fold_output = { kernel_fold_proof, function_vk_with_merge }; size_t NUM_CIRCUITS = 1; for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { // Accumulate function circuit Builder function_circuit = create_mock_circuit(ivc); FoldProof function_fold_proof = ivc.accumulate(function_circuit); - VerifierFoldData function_fold_output = { function_fold_proof, function_vk_2 }; + + intermediary_acc = EXPECT_FOLDING_AND_DECIDING_VERIFIED( + ivc.prover_fold_output.accumulator, function_fold_proof, intermediary_acc, function_vk_with_merge); + + VerifierFoldData function_fold_output = { function_fold_proof, function_vk_with_merge }; // Accumulate kernel circuit Builder kernel_circuit{ ivc.goblin.op_queue }; - kernel_acc = - construct_mock_folding_kernel(kernel_circuit, kernel_fold_output, function_fold_output, kernel_acc); + verifier_accumulator = construct_mock_folding_kernel( + kernel_circuit, kernel_fold_output, function_fold_output, verifier_accumulator); FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); kernel_vk = composer.compute_verification_key(ivc.prover_instance); + + intermediary_acc = EXPECT_FOLDING_AND_DECIDING_VERIFIED( + ivc.prover_fold_output.accumulator, kernel_fold_proof, intermediary_acc, kernel_vk); + VerifierFoldData kernel_fold_output = { kernel_fold_proof, kernel_vk }; } @@ -115,5 +154,5 @@ TEST_F(ClientIVCTests, Full) auto inst = std::make_shared(); inst->verification_key = kernel_vk; // Verify all four proofs - EXPECT_TRUE(ivc.verify(proof, { kernel_acc, inst })); + EXPECT_TRUE(ivc.verify(proof, { verifier_accumulator, inst })); }; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp index d3b322558ae..0b034c36afd 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp @@ -24,8 +24,8 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) GoblinUltraCircuitBuilder circuit_1{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_1); ivc.initialize(circuit_1); - auto initial_acc = std::make_shared(); - initial_acc->verification_key = ivc.vks.first_func_vk; + auto kernel_acc = std::make_shared(); + kernel_acc->verification_key = ivc.vks.first_func_vk; GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_2); @@ -33,15 +33,15 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) // Construct kernel circuit GoblinUltraCircuitBuilder kernel_circuit{ ivc.goblin.op_queue }; - auto kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel( - kernel_circuit, { func_fold_proof, ivc.vks.func_vk }, {}, initial_acc); + kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel( + kernel_circuit, { func_fold_proof, ivc.vks.func_vk }, {}, kernel_acc); auto kernel_fold_proof = ivc.accumulate(kernel_circuit); EXPECT_EQ(ivc.prover_instance->log_instance_size, 17); - GoblinUltraCircuitBuilder circuit_4{ ivc.goblin.op_queue }; - GoblinMockCircuits::construct_mock_function_circuit(circuit_4); - func_fold_proof = ivc.accumulate(circuit_4); + GoblinUltraCircuitBuilder circuit_3{ ivc.goblin.op_queue }; + GoblinMockCircuits::construct_mock_function_circuit(circuit_3); + func_fold_proof = ivc.accumulate(circuit_3); kernel_circuit = GoblinUltraCircuitBuilder{ ivc.goblin.op_queue }; kernel_acc = GoblinMockCircuits::construct_mock_folding_kernel(kernel_circuit, From 94ed5342eb32101564423676f36fce8ef17873cc Mon Sep 17 00:00:00 2001 From: maramihali Date: Thu, 29 Feb 2024 11:54:36 +0000 Subject: [PATCH 15/15] address more pr comments --- .../client_ivc_bench/client_ivc.bench.cpp | 3 +- .../barretenberg/client_ivc/client_ivc.cpp | 3 +- .../client_ivc/client_ivc.test.cpp | 27 +++++++-------- .../client_ivc/mock_kernel_pinning.test.cpp | 2 +- .../protogalaxy/decider_prover.hpp | 1 - .../protogalaxy_recursive_verifier.test.cpp | 6 ++-- .../honk/verifier/recursive_instances.hpp | 2 +- .../verifier/recursive_verifier_instance.hpp | 33 ++++++++----------- .../sumcheck/instance/verifier_instance.hpp | 8 ++--- .../ultra_honk/ultra_composer.cpp | 3 +- 10 files changed, 38 insertions(+), 50 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp index 51da5ac55e6..9840e596f89 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/client_ivc_bench/client_ivc.bench.cpp @@ -47,8 +47,7 @@ class ClientIVCBench : public benchmark::Fixture { Builder initial_function_circuit{ size_hint, ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(initial_function_circuit); ivc.initialize(initial_function_circuit); - auto kernel_verifier_accumulator = std::make_shared(); - kernel_verifier_accumulator->verification_key = ivc.vks.first_func_vk; + auto kernel_verifier_accumulator = std::make_shared(ivc.vks.first_func_vk); // Accumulate another function circuit Builder function_circuit{ ivc.goblin.op_queue }; diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp index abc76ae3e34..911c802ebf8 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.cpp @@ -98,8 +98,7 @@ void ClientIVC::precompute_folding_verification_keys() // Initialise both the first prover and verifier accumulator from the inital function circuit initialize(initial_function_circuit); vks.first_func_vk = prover_fold_output.accumulator->verification_key; - auto initial_verifier_acc = std::make_shared(); - initial_verifier_acc->verification_key = vks.first_func_vk; + auto initial_verifier_acc = std::make_shared(vks.first_func_vk); // Accumulate the next function circuit ClientCircuit function_circuit{ goblin.op_queue }; diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp index 6cfc485c9ab..45e594f47a9 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp @@ -52,7 +52,7 @@ class ClientIVCTests : public ::testing::Test { * function circuit and kernel circuit. * * @param builder - * @param fctn_accum contains the folding proof for the function circuit and the corresponsing function + * @param func_accum contains the folding proof for the function circuit and the corresponsing function * verifier instance * @param kernel_accum contains the folding proof for the kernel circuit and the corresponding kernel verifier * instance @@ -76,7 +76,7 @@ class ClientIVCTests : public ::testing::Test { * @brief Perform native fold verification and run decider prover/verifier * */ - static VerifierAccumulator EXPECT_FOLDING_AND_DECIDING_VERIFIED( + static VerifierAccumulator update_accumulator_and_decide_native( const ProverAccumulator& prover_accumulator, const FoldProof& fold_proof, const VerifierAccumulator& prev_verifier_accumulator, @@ -84,8 +84,7 @@ class ClientIVCTests : public ::testing::Test { { // Verify fold proof Composer composer; - auto new_verifier_inst = std::make_shared(); - new_verifier_inst->verification_key = verifier_inst_vk; + auto new_verifier_inst = std::make_shared(verifier_inst_vk); auto folding_verifier = composer.create_folding_verifier({ prev_verifier_accumulator, new_verifier_inst }); auto verifier_accumulator = folding_verifier.verify_folding_proof(fold_proof); @@ -112,16 +111,15 @@ TEST_F(ClientIVCTests, Full) ivc.initialize(function_circuit); auto function_vk = ivc.prover_fold_output.accumulator->verification_key; - auto verifier_accumulator = std::make_shared(); - verifier_accumulator->verification_key = function_vk; + auto foo_verifier_instance = std::make_shared(function_vk); // Accumulate kernel circuit (first kernel mocked as simple circuit since no folding proofs yet) Builder kernel_circuit = create_mock_circuit(ivc); FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); // This will have a different verification key because we added the recursive merge verification to the circuit auto function_vk_with_merge = ivc.prover_instance->verification_key; auto kernel_vk = function_vk_with_merge; - auto intermediary_acc = EXPECT_FOLDING_AND_DECIDING_VERIFIED( - ivc.prover_fold_output.accumulator, kernel_fold_proof, verifier_accumulator, kernel_vk); + auto intermediary_acc = update_accumulator_and_decide_native( + ivc.prover_fold_output.accumulator, kernel_fold_proof, foo_verifier_instance, kernel_vk); VerifierFoldData kernel_fold_output = { kernel_fold_proof, function_vk_with_merge }; size_t NUM_CIRCUITS = 1; @@ -130,18 +128,18 @@ TEST_F(ClientIVCTests, Full) Builder function_circuit = create_mock_circuit(ivc); FoldProof function_fold_proof = ivc.accumulate(function_circuit); - intermediary_acc = EXPECT_FOLDING_AND_DECIDING_VERIFIED( + intermediary_acc = update_accumulator_and_decide_native( ivc.prover_fold_output.accumulator, function_fold_proof, intermediary_acc, function_vk_with_merge); VerifierFoldData function_fold_output = { function_fold_proof, function_vk_with_merge }; // Accumulate kernel circuit Builder kernel_circuit{ ivc.goblin.op_queue }; - verifier_accumulator = construct_mock_folding_kernel( - kernel_circuit, kernel_fold_output, function_fold_output, verifier_accumulator); + foo_verifier_instance = construct_mock_folding_kernel( + kernel_circuit, kernel_fold_output, function_fold_output, foo_verifier_instance); FoldProof kernel_fold_proof = ivc.accumulate(kernel_circuit); kernel_vk = ivc.prover_instance->verification_key; - intermediary_acc = EXPECT_FOLDING_AND_DECIDING_VERIFIED( + intermediary_acc = update_accumulator_and_decide_native( ivc.prover_fold_output.accumulator, kernel_fold_proof, intermediary_acc, kernel_vk); VerifierFoldData kernel_fold_output = { kernel_fold_proof, kernel_vk }; @@ -149,8 +147,7 @@ TEST_F(ClientIVCTests, Full) // Constuct four proofs: merge, eccvm, translator, decider auto proof = ivc.prove(); - auto inst = std::make_shared(); - inst->verification_key = kernel_vk; + auto inst = std::make_shared(kernel_vk); // Verify all four proofs - EXPECT_TRUE(ivc.verify(proof, { verifier_accumulator, inst })); + EXPECT_TRUE(ivc.verify(proof, { foo_verifier_instance, inst })); }; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp index 0b034c36afd..773496dbfb2 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/mock_kernel_pinning.test.cpp @@ -24,7 +24,7 @@ TEST_F(MockKernelTest, PinFoldingKernelSizes) GoblinUltraCircuitBuilder circuit_1{ ivc.goblin.op_queue }; GoblinMockCircuits::construct_mock_function_circuit(circuit_1); ivc.initialize(circuit_1); - auto kernel_acc = std::make_shared(); + auto kernel_acc = std::make_shared(ivc.vks.first_func_vk); kernel_acc->verification_key = ivc.vks.first_func_vk; GoblinUltraCircuitBuilder circuit_2{ ivc.goblin.op_queue }; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.hpp index 43d0b602bcc..562a1700ba2 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/decider_prover.hpp @@ -28,7 +28,6 @@ template class DeciderProver_ { const std::shared_ptr&, const std::shared_ptr& transcript = std::make_shared()); - BB_PROFILE void execute_preamble_round(); BB_PROFILE void execute_relation_check_rounds(); BB_PROFILE void execute_zeromorph_rounds(); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp index 754e89ac20c..6e2f1f5f3ce 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/protogalaxy_recursive_verifier.test.cpp @@ -183,9 +183,10 @@ template class ProtoGalaxyRecursiveTests : public tes FoldingRecursiveVerifier(&folding_circuit, verifier_instance_1, { verifier_instance_2->verification_key }); verifier.verify_folding_proof(folding_proof.folding_data); info("Folding Recursive Verifier: num gates = ", folding_circuit.num_gates); + EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err(); - // Perform native folding verification and ensure it returns the same result (either true or false) as calling - // check_circuit on the recursive folding verifier + // Perform native folding verification and ensure it returns the same result (either true or false) as + // calling check_circuit on the recursive folding verifier auto native_folding_verifier = composer.create_folding_verifier({ verifier_instance_1, verifier_instance_2 }); native_folding_verifier.verify_folding_proof(folding_proof.folding_data); @@ -199,7 +200,6 @@ template class ProtoGalaxyRecursiveTests : public tes } // Check for a failure flag in the recursive verifier circuit - EXPECT_EQ(folding_circuit.failed(), false) << folding_circuit.err(); { auto composer = Composer(); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp index fb5db484c96..9e8151aad2e 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_instances.hpp @@ -34,7 +34,7 @@ template struct RecursiveVerifierInstan _data[0] = std::make_shared(builder, accumulator->verification_key); } size_t idx = 1; - for (auto vk : vks) { + for (auto& vk : vks) { _data[idx] = std::make_shared(builder, vk); idx++; } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp index f708c2274ab..d61ee8734fc 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/recursion/honk/verifier/recursive_verifier_instance.hpp @@ -58,7 +58,7 @@ template class RecursiveVerifierInstance_ { size_t public_input_idx = 0; public_inputs = std::vector(public_input_size); - for (auto public_input : instance->public_inputs) { + for (auto& public_input : instance->public_inputs) { public_inputs[public_input_idx] = FF::from_witness(builder, public_input); public_input_idx++; } @@ -112,35 +112,30 @@ template class RecursiveVerifierInstance_ { inst.instance_size = instance_size; inst.is_accumulator = is_accumulator; - size_t public_input_idx = 0; inst.public_inputs = std::vector(public_input_size); - for (auto public_input : public_inputs) { - inst.public_inputs[public_input_idx] = public_input.get_value(); - public_input_idx++; + for (auto [public_input, inst_public_input] : zip_view(public_inputs, inst.public_inputs)) { + inst_public_input = public_input.get_value(); } + inst.verification_key = std::make_shared(instance_size, public_input_size); - size_t vk_idx = 0; - for (auto& vk : verification_key->get_all()) { - inst.verification_key->get_all()[vk_idx] = vk.get_value(); - vk_idx++; + for (auto [vk, inst_vk] : zip_view(verification_key->get_all(), inst.verification_key->get_all())) { + inst_vk = vk.get_value(); } - for (size_t alpha_idx = 0; alpha_idx < alphas.size(); alpha_idx++) { - inst.alphas[alpha_idx] = alphas[alpha_idx].get_value(); + + for (auto [alpha, inst_alpha] : zip_view(alphas, inst.alphas)) { + inst_alpha = alpha.get_value(); } - size_t comm_idx = 0; - for (auto& comm : witness_commitments.get_all()) { - inst.witness_commitments.get_all()[comm_idx] = comm.get_value(); - comm_idx++; + for (auto [comm, inst_comm] : zip_view(witness_commitments.get_all(), inst.witness_commitments.get_all())) { + inst_comm = comm.get_value(); } inst.target_sum = target_sum.get_value(); - size_t challenge_idx = 0; inst.gate_challenges = std::vector(gate_challenges.size()); - for (auto& challenge : inst.gate_challenges) { - challenge = gate_challenges[challenge_idx].get_value(); - challenge_idx++; + for (auto [challenge, inst_challenge] : zip_view(gate_challenges, inst.gate_challenges)) { + inst_challenge = challenge.get_value(); } + inst.relation_parameters.eta = relation_parameters.eta.get_value(); inst.relation_parameters.beta = relation_parameters.beta.get_value(); inst.relation_parameters.gamma = relation_parameters.gamma.get_value(); diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp index 1d7e1345253..0910ccb614d 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/instance/verifier_instance.hpp @@ -34,9 +34,9 @@ template class VerifierInstance_ { WitnessCommitments witness_commitments; CommitmentLabels commitment_labels; - - // VerifierInstance_(std::shared_ptr vk) - // : verification_key(std::move(vk)) - // {} + VerifierInstance_() = default; + VerifierInstance_(std::shared_ptr vk) + : verification_key(std::move(vk)) + {} }; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp index 19378ee5363..e8da52f540b 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/ultra_composer.cpp @@ -16,8 +16,7 @@ template std::shared_ptr> UltraComposer_::create_verifier_instance( std::shared_ptr>& prover_instance) { - auto instance = std::make_shared(); - instance->verification_key = prover_instance->verification_key; + auto instance = std::make_shared(prover_instance->verification_key); return instance; }