From 4c7f24f8ea8c21bc8114ead67d2082a06c9c5493 Mon Sep 17 00:00:00 2001 From: Lucas Xia Date: Tue, 20 Feb 2024 05:56:32 -0500 Subject: [PATCH] chore: make first iteration of protogalaxy more efficient (#4630) This work makes the first iteration of protogalaxy more efficient by removing the perturbator computation in just the first iteration. We can do this because in the first iteration, there is no accumulator, so we're just folding instances together. Because of this, we can assume that f_i(\omega) is 0 for all i. This seems suspicious, but this assumption is fine because if the instances were not valid (some f_i(\omega) is not 0), folding invalid instances would yield an invalid accumlator so it wouldn't matter in the end. Normally, we can't do this because f_i(\omega) for a correct accumulator is not all 0s, as \omega is some folded thing. Fixes https://github.com/AztecProtocol/barretenberg/issues/740. --- .../protogalaxy/protogalaxy_prover.cpp | 20 ++++++++----------- .../protogalaxy/protogalaxy_prover.hpp | 2 -- .../protogalaxy/protogalaxy_verifier.cpp | 19 +++++++----------- .../protogalaxy_recursive_verifier.cpp | 19 +++++++----------- 4 files changed, 22 insertions(+), 38 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp index 372926ddafb..b32aecff411 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.cpp @@ -154,17 +154,9 @@ template void ProtoGalaxyProver_::prepa 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 finalise_and_send_instance(instance, domain_separator); instance->target_sum = 0; - auto beta = transcript->template get_challenge(domain_separator + "_initial_gate_challenge"); - std::vector gate_challenges(instance->log_instance_size); - gate_challenges[0] = beta; - for (size_t i = 1; i < instance->log_instance_size; i++) { - gate_challenges[i] = gate_challenges[i - 1].sqr(); - } - instance->gate_challenges = gate_challenges; + instance->gate_challenges = std::vector(instance->log_instance_size, 0); } idx++; @@ -315,9 +307,13 @@ template void ProtoGalaxyProver_::pertu 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]); + state.perturbator = Polynomial(state.accumulator->log_instance_size + 1); // initialize to all zeros + // compute perturbator only if this is not the first round and has an accumulator + if (state.accumulator->is_accumulator) { + 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]); + } } }; diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp index cbe139eb37c..0df61d1d82f 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover.hpp @@ -134,8 +134,6 @@ template class ProtoGalaxyProver_ { // Returns the accumulator, which is the first element in ProverInstances. The accumulator is assumed to have the // FoldingParameters set and be the result of a previous round of folding. - // TODO(https://github.com/AztecProtocol/barretenberg/issues/740): handle the case when the accumulator is empty - // (i.e. we are in the first round of folding)/ std::shared_ptr get_accumulator() { return instances[0]; } /** diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 07b32554f34..bdcfa0500e9 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -159,17 +159,9 @@ void ProtoGalaxyVerifier_::prepare_for_folding(const std::vec 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 receive_and_finalise_instance(inst, domain_separator); inst->target_sum = 0; - auto beta = transcript->template get_challenge(domain_separator + "_initial_gate_challenge"); - std::vector gate_challenges(inst->log_instance_size); - gate_challenges[0] = beta; - for (size_t i = 1; i < inst->log_instance_size; i++) { - gate_challenges[i] = gate_challenges[i - 1].sqr(); - } - inst->gate_challenges = gate_challenges; + inst->gate_challenges = std::vector(inst->log_instance_size, 0); } index++; @@ -189,9 +181,12 @@ bool ProtoGalaxyVerifier_::verify_folding_proof(const std::ve auto accumulator = get_accumulator(); 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++) { - perturbator_coeffs[idx] = transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); + std::vector perturbator_coeffs(accumulator->log_instance_size + 1, 0); + if (accumulator->is_accumulator) { + for (size_t idx = 0; 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) { 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..6ac10f7cd30 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 @@ -164,17 +164,9 @@ template void ProtoGalaxyRecursiveVerifier_target_sum = 0; - auto beta = transcript->template get_challenge(domain_separator + "_initial_gate_challenge"); - std::vector gate_challenges(inst->log_instance_size); - gate_challenges[0] = beta; - for (size_t i = 1; i < inst->log_instance_size; i++) { - gate_challenges[i] = gate_challenges[i - 1].sqr(); - } - inst->gate_challenges = gate_challenges; + inst->gate_challenges = std::vector(inst->log_instance_size, 0); } index++; @@ -199,9 +191,12 @@ void ProtoGalaxyRecursiveVerifier_::verify_folding_proof(cons auto accumulator = get_accumulator(); 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++) { - perturbator_coeffs[idx] = transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); + std::vector perturbator_coeffs(accumulator->log_instance_size + 1, 0); + if (accumulator->is_accumulator) { + for (size_t idx = 0; 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