From f97dd1ec3da0f3ab226c7f36385a13f7b7a7b897 Mon Sep 17 00:00:00 2001 From: maramihali Date: Tue, 20 Feb 2024 10:34:39 +0000 Subject: [PATCH] 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: