From ffaddfcb94a1df7e22493826dc272c9eeafb7442 Mon Sep 17 00:00:00 2001 From: maramihali Date: Mon, 19 Feb 2024 15:59:02 +0000 Subject: [PATCH] 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);