From a4f61b39c39bf01a1071b52bbf042408f29d5564 Mon Sep 17 00:00:00 2001 From: iakovenkos <105737703+iakovenkos@users.noreply.github.com> Date: Tue, 17 Sep 2024 22:20:19 +0200 Subject: [PATCH] refactor: Protogalaxy recursive verifier matches native verifier (#8568) Continuation of PG refactoring - PG recursive verifier made similar to native PG verifier - In recursive setting: accumulator is mutated in place. - Sharing the code with prover_verifier_shared for functions that compute powers of round challenges and update gate challenges - Renaming + Constifying a lot --- .../protogalaxy/prover_verifier_shared.cpp | 27 --- .../protogalaxy/prover_verifier_shared.hpp | 51 +++++- .../protogalaxy_recursive_verifier.cpp | 162 ++++++++---------- .../protogalaxy_recursive_verifier.hpp | 128 ++------------ .../protogalaxy_recursive_verifier.test.cpp | 3 +- .../recursive_decider_verification_keys.hpp | 77 +++++++++ 6 files changed, 209 insertions(+), 239 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/protogalaxy/prover_verifier_shared.cpp diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/prover_verifier_shared.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/prover_verifier_shared.cpp deleted file mode 100644 index e6399e54465..00000000000 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/prover_verifier_shared.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "barretenberg/protogalaxy/prover_verifier_shared.hpp" - -namespace bb { -std::vector update_gate_challenges(const fr& perturbator_challenge, - const std::vector& gate_challenges, - const std::vector& init_challenges) -{ - const size_t num_challenges = gate_challenges.size(); - std::vector next_gate_challenges(num_challenges); - - for (size_t idx = 0; idx < num_challenges; idx++) { - next_gate_challenges[idx] = gate_challenges[idx] + perturbator_challenge * init_challenges[idx]; - } - return next_gate_challenges; -} - -std::vector compute_round_challenge_pows(const size_t num_powers, const fr& round_challenge) -{ - std::vector pows(num_powers); - pows[0] = round_challenge; - for (size_t i = 1; i < num_powers; i++) { - pows[i] = pows[i - 1].sqr(); - } - return pows; -} - -} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/prover_verifier_shared.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/prover_verifier_shared.hpp index 9739c895d1c..181d7b30f3d 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/prover_verifier_shared.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/prover_verifier_shared.hpp @@ -1,20 +1,57 @@ #pragma once -#include "barretenberg/ecc/curves/bn254/fr.hpp" #include - namespace bb { + /** * @brief Compute the gate challenges used in the combiner calculation. * @details This is Step 8 of the protocol as written in the paper. */ -std::vector update_gate_challenges(const fr& perturbator_challenge, - const std::vector& gate_challenges, - const std::vector& init_challenges); +template +std::vector update_gate_challenges(const FF& perturbator_challenge, + const std::vector& gate_challenges, + const std::vector& init_challenges) +{ + const size_t num_challenges = gate_challenges.size(); + std::vector next_gate_challenges(num_challenges); + for (size_t idx = 0; idx < num_challenges; idx++) { + next_gate_challenges[idx] = gate_challenges[idx] + perturbator_challenge * init_challenges[idx]; + } + return next_gate_challenges; +} /** * @brief Given δ, compute the vector [δ, δ^2,..., δ^num_powers]. * @details This is Step 2 of the protocol as written in the paper. */ -std::vector compute_round_challenge_pows(const size_t num_powers, const fr& round_challenge); +template std::vector compute_round_challenge_pows(const size_t num_powers, const FF& round_challenge) +{ + std::vector pows(num_powers); + pows[0] = round_challenge; + for (size_t i = 1; i < num_powers; i++) { + pows[i] = pows[i - 1].sqr(); + } + return pows; +} + +/** + * @brief Evaluates the perturbator at a given scalar, in a sequential manner for the recursive setting. + * + * @details This method is equivalent to the one in the Polynomial class for evaluating a polynomial, represented by + * coefficients in monomial basis, at a given point. The Polynomial class is used in the native verifier for + * constructing and computing the perturbator. We implement this separate functionality here in the recursive + * folding verifier to avoid instantiating the entire Polynomial class on stdlib::bn254. Furthermore, the evaluation + * needs to be done sequentially as we don't support a parallel_for in circuits. + * + */ +template static FF evaluate_perturbator(std::vector coeffs, FF point) +{ + FF point_acc = FF(1); + FF result = FF(0); + for (size_t i = 0; i < coeffs.size(); i++) { + result += coeffs[i] * point_acc; + point_acc *= point; + } + return result; +}; -} // namespace bb \ No newline at end of file +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.cpp index b64d0b09f38..698591f0ab8 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.cpp @@ -1,38 +1,38 @@ #include "protogalaxy_recursive_verifier.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" -#include "barretenberg/stdlib/protogalaxy_verifier/recursive_decider_verification_keys.hpp" +#include "barretenberg/protogalaxy/prover_verifier_shared.hpp" +#include "barretenberg/stdlib/honk_verifier/oink_recursive_verifier.hpp" +#include "barretenberg/ultra_honk/decider_keys.hpp" namespace bb::stdlib::recursion::honk { template -void ProtogalaxyRecursiveVerifier_::receive_and_finalise_key( - const std::shared_ptr& inst, std::string& domain_separator) +void ProtogalaxyRecursiveVerifier_::run_oink_verifier_on_one_incomplete_key( + const std::shared_ptr& key, std::string& domain_separator) { - domain_separator = domain_separator + "_"; - OinkVerifier oink_verifier{ builder, inst, transcript, domain_separator }; + OinkRecursiveVerifier_ oink_verifier{ builder, key, transcript, domain_separator + '_' }; oink_verifier.verify(); } -// TODO(https://github.com/AztecProtocol/barretenberg/issues/795): The rounds prior to actual verifying are common -// between decider and folding verifier and could be somehow shared so we do not duplicate code so much. template -void ProtogalaxyRecursiveVerifier_::prepare_for_folding() +void ProtogalaxyRecursiveVerifier_::run_oink_verifier_on_each_incomplete_key( + const std::vector& proof) { - auto index = 0; - auto inst = keys_to_fold[0]; + transcript = std::make_shared(proof); + size_t index = 0; + auto key = keys_to_fold[0]; auto domain_separator = std::to_string(index); - - if (!inst->is_accumulator) { - receive_and_finalise_key(inst, domain_separator); - inst->target_sum = 0; - inst->gate_challenges = std::vector(static_cast(inst->verification_key->log_circuit_size), 0); + if (!key->is_accumulator) { + run_oink_verifier_on_one_incomplete_key(key, domain_separator); + key->target_sum = 0; + key->gate_challenges = std::vector(static_cast(key->verification_key->log_circuit_size), 0); } index++; for (auto it = keys_to_fold.begin() + 1; it != keys_to_fold.end(); it++, index++) { - auto inst = *it; + auto key = *it; auto domain_separator = std::to_string(index); - receive_and_finalise_key(inst, domain_separator); + run_oink_verifier_on_one_incomplete_key(key, domain_separator); } } @@ -40,98 +40,79 @@ template std::shared_ptr ProtogalaxyRecursiveVerifier_< DeciderVerificationKeys>::verify_folding_proof(const StdlibProof& proof) { - using Transcript = typename Flavor::Transcript; + static constexpr size_t BATCHED_EXTENDED_LENGTH = DeciderVerificationKeys::BATCHED_EXTENDED_LENGTH; + static constexpr size_t NUM_KEYS = DeciderVerificationKeys::NUM; + static constexpr size_t COMBINER_LENGTH = BATCHED_EXTENDED_LENGTH - NUM_KEYS; - transcript = std::make_shared(proof); - prepare_for_folding(); + run_oink_verifier_on_each_incomplete_key(proof); - auto delta = transcript->template get_challenge("delta"); - auto accumulator = get_accumulator(); - auto deltas = - compute_round_challenge_pows(static_cast(accumulator->verification_key->log_circuit_size), delta); + std::shared_ptr accumulator = keys_to_fold[0]; + const size_t log_circuit_size = static_cast(accumulator->verification_key->log_circuit_size); - std::vector perturbator_coeffs(static_cast(accumulator->verification_key->log_circuit_size) + 1, 0); + // Perturbator round + const FF delta = transcript->template get_challenge("delta"); + const std::vector deltas = compute_round_challenge_pows(log_circuit_size, delta); + std::vector perturbator_coeffs(log_circuit_size + 1, 0); if (accumulator->is_accumulator) { - for (size_t idx = 1; idx <= static_cast(accumulator->verification_key->log_circuit_size); idx++) { + for (size_t idx = 1; idx <= log_circuit_size; idx++) { perturbator_coeffs[idx] = transcript->template receive_from_prover("perturbator_" + std::to_string(idx)); } } + const FF perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); + // Combiner quotient round perturbator_coeffs[0] = accumulator->target_sum; - - FF perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); - - auto perturbator_at_challenge = evaluate_perturbator(perturbator_coeffs, perturbator_challenge); - // The degree of K(X) is dk - k - 1 = k(d - 1) - 1. Hence we need k(d - 1) evaluations to represent it. - std::array - combiner_quotient_evals; - for (size_t idx = 0; idx < DeciderVerificationKeys::BATCHED_EXTENDED_LENGTH - DeciderVerificationKeys::NUM; idx++) { - combiner_quotient_evals[idx] = transcript->template receive_from_prover( - "combiner_quotient_" + std::to_string(idx + DeciderVerificationKeys::NUM)); - } - Univariate combiner_quotient( - combiner_quotient_evals); - FF combiner_challenge = transcript->template get_challenge("combiner_quotient_challenge"); - auto combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); // fine recursive i think - - 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->verification_key = std::make_shared( - accumulator->verification_key->circuit_size, accumulator->verification_key->num_public_inputs); - next_accumulator->verification_key->pcs_verification_key = accumulator->verification_key->pcs_verification_key; - next_accumulator->verification_key->pub_inputs_offset = accumulator->verification_key->pub_inputs_offset; - next_accumulator->verification_key->contains_recursive_proof = - accumulator->verification_key->contains_recursive_proof; - next_accumulator->verification_key->recursive_proof_public_input_indices = - accumulator->verification_key->recursive_proof_public_input_indices; - if constexpr (IsGoblinFlavor) { // Databus commitment propagation data - next_accumulator->verification_key->databus_propagation_data = - accumulator->verification_key->databus_propagation_data; + const FF perturbator_evaluation = evaluate_perturbator(perturbator_coeffs, perturbator_challenge); + + std::array + combiner_quotient_evals; // The degree of the combiner quotient (K in the paper) is dk - k - 1 = k(d - 1) - 1. + // Hence we need k(d - 1) evaluations to represent it. + for (size_t idx = 0; idx < COMBINER_LENGTH; idx++) { + combiner_quotient_evals[idx] = + transcript->template receive_from_prover("combiner_quotient_" + std::to_string(idx + NUM_KEYS)); } - next_accumulator->public_inputs = accumulator->public_inputs; + // Folding + const FF combiner_challenge = transcript->template get_challenge("combiner_quotient_challenge"); + const Univariate combiner_quotient(combiner_quotient_evals); + const FF combiner_quotient_at_challenge = combiner_quotient.evaluate(combiner_challenge); - next_accumulator->is_accumulator = true; + const FF vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); + const std::vector lagranges = { FF(1) - combiner_challenge, combiner_challenge }; // 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 ϕ - fold_commitments(lagranges, keys_to_fold, next_accumulator); - - size_t alpha_idx = 0; - for (auto& alpha : next_accumulator->alphas) { - alpha = FF(0); - size_t vk_idx = 0; - for (auto& key : keys_to_fold) { - alpha += key->alphas[alpha_idx] * lagranges[vk_idx]; - vk_idx++; - } - alpha_idx++; + accumulator->is_accumulator = true; + accumulator->target_sum = + perturbator_evaluation * lagranges[0] + vanishing_polynomial_at_challenge * combiner_quotient_at_challenge; + accumulator->gate_challenges = update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); + + // Fold the commitments + for (auto [combination, to_combine] : + zip_view(accumulator->verification_key->get_all(), keys_to_fold.get_precomputed_commitments())) { + combination = Commitment::batch_mul( + to_combine, lagranges, /*max_num_bits=*/0, /*with_edgecases=*/IsUltraBuilder); + } + + for (auto [combination, to_combine] : + zip_view(accumulator->witness_commitments.get_all(), keys_to_fold.get_witness_commitments())) { + combination = Commitment::batch_mul( + to_combine, lagranges, /*max_num_bits=*/0, /*with_edgecases=*/IsUltraBuilder); } - auto& expected_parameters = next_accumulator->relation_parameters; - for (size_t inst_idx = 0; inst_idx < DeciderVerificationKeys::NUM; inst_idx++) { - auto& key = keys_to_fold[inst_idx]; - expected_parameters.eta += key->relation_parameters.eta * lagranges[inst_idx]; - expected_parameters.eta_two += key->relation_parameters.eta_two * lagranges[inst_idx]; - expected_parameters.eta_three += key->relation_parameters.eta_three * lagranges[inst_idx]; - expected_parameters.beta += key->relation_parameters.beta * lagranges[inst_idx]; - expected_parameters.gamma += key->relation_parameters.gamma * lagranges[inst_idx]; - expected_parameters.public_input_delta += key->relation_parameters.public_input_delta * lagranges[inst_idx]; - expected_parameters.lookup_grand_product_delta += - key->relation_parameters.lookup_grand_product_delta * lagranges[inst_idx]; + // Fold the relation parameters + for (auto [combination, to_combine] : zip_view(accumulator->alphas, keys_to_fold.get_alphas())) { + combination = linear_combination(to_combine, lagranges); } - return next_accumulator; + for (auto [combination, to_combine] : + zip_view(accumulator->relation_parameters.get_to_fold(), keys_to_fold.get_relation_parameters())) { + combination = linear_combination(to_combine, lagranges); + } + + return accumulator; } +// Instantiate the template with specific flavors and builders template class ProtogalaxyRecursiveVerifier_< RecursiveDeciderVerificationKeys_, 2>>; template class ProtogalaxyRecursiveVerifier_< @@ -144,4 +125,5 @@ template class ProtogalaxyRecursiveVerifier_< RecursiveDeciderVerificationKeys_, 2>>; template class ProtogalaxyRecursiveVerifier_< RecursiveDeciderVerificationKeys_, 2>>; -} // namespace bb::stdlib::recursion::honk \ No newline at end of file + +} // namespace bb::stdlib::recursion::honk diff --git a/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.hpp b/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.hpp index fc1202cc071..4cde2740f6d 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.hpp @@ -2,46 +2,40 @@ #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/honk/proof_system/types/proof.hpp" #include "barretenberg/protogalaxy/folding_result.hpp" -#include "barretenberg/stdlib/honk_verifier/oink_recursive_verifier.hpp" #include "barretenberg/stdlib/protogalaxy_verifier/recursive_decider_verification_keys.hpp" #include "barretenberg/stdlib/transcript/transcript.hpp" #include "barretenberg/stdlib_circuit_builders/mega_recursive_flavor.hpp" #include "barretenberg/stdlib_circuit_builders/ultra_recursive_flavor.hpp" +#include "barretenberg/ultra_honk/decider_keys.hpp" namespace bb::stdlib::recursion::honk { template class ProtogalaxyRecursiveVerifier_ { public: using Flavor = typename DeciderVerificationKeys::Flavor; - using NativeFlavor = typename Flavor::NativeFlavor; using FF = typename Flavor::FF; using Commitment = typename Flavor::Commitment; - using GroupElement = typename Flavor::GroupElement; using DeciderVK = typename DeciderVerificationKeys::DeciderVK; - using NativeDeciderVK = bb::DeciderVerificationKey_; 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 = DeciderVerificationKeys::NUM; using Transcript = bb::BaseTranscript>; - using OinkVerifier = OinkRecursiveVerifier_; + + static constexpr size_t NUM_SUBRELATIONS = Flavor::NUM_SUBRELATIONS; + struct VerifierInput { public: - using DeciderVK = NativeDeciderVK; + using NativeFlavor = typename Flavor::NativeFlavor; + using DeciderVK = bb::DeciderVerificationKey_; + using NativeVerificationKey = typename Flavor::NativeVerificationKey; std::shared_ptr accumulator; std::vector> decider_vks; }; - static constexpr size_t NUM_SUBRELATIONS = Flavor::NUM_SUBRELATIONS; + Builder* builder; - CommitmentLabels commitment_labels; + DeciderVerificationKeys keys_to_fold; - Builder* builder; std::shared_ptr transcript; - DeciderVerificationKeys keys_to_fold; ProtogalaxyRecursiveVerifier_(Builder* builder, const std::shared_ptr& accumulator, @@ -50,52 +44,14 @@ template class ProtogalaxyRecursiveVerifier_ { , keys_to_fold(DeciderVerificationKeys(builder, accumulator, decider_vks)){}; /** - * @brief Given δ, compute the vector [δ, δ^2,..., δ^num_powers]. - * @details This is Step 2 of the protocol as written in the paper. - */ - static std::vector compute_round_challenge_pows(const size_t num_powers, const FF& round_challenge) - { - std::vector pows(num_powers); - pows[0] = round_challenge; - for (size_t i = 1; i < num_powers; i++) { - pows[i] = pows[i - 1].sqr(); - } - return pows; - } - - static std::vector update_gate_challenges(const FF perturbator_challenge, - const std::vector& gate_challenges, - const std::vector& round_challenges) - { - const size_t num_challenges = gate_challenges.size(); - std::vector next_gate_challenges(num_challenges); - - for (size_t idx = 0; idx < num_challenges; idx++) { - next_gate_challenges[idx] = gate_challenges[idx] + perturbator_challenge * round_challenges[idx]; - } - return next_gate_challenges; - } - - std::shared_ptr get_accumulator() { return keys_to_fold[0]; } - - /** - * @brief Instatiate the decider verification keys and the transcript. - * - * @param fold_data The data transmitted via the transcript by the prover. - */ - void prepare_for_folding(); - - /** - * @brief Instantiate the accumulator from the transcript. - * + * @brief Process the public data ϕ for the decider verification keys to be folded. */ - void receive_accumulator(const std::shared_ptr&, const std::string&); + void run_oink_verifier_on_each_incomplete_key(const std::vector&); /** - * @brief Process the public data ϕ for the keys to be folded. - * + * @brief Instatiate the vks and the transcript. */ - void receive_and_finalise_key(const std::shared_ptr&, std::string&); + void run_oink_verifier_on_one_incomplete_key(const std::shared_ptr&, std::string&); /** * @brief Run the folding protocol on the verifier side to establish whether the public data ϕ of the new @@ -107,62 +63,6 @@ template class ProtogalaxyRecursiveVerifier_ { * */ std::shared_ptr verify_folding_proof(const StdlibProof&); - - /** - * @brief Evaluates the perturbator at a given scalar, in a sequential manner for the recursive setting. - * - * @details This method is equivalent to the one in the Polynomial class for evaluating a polynomial, represented by - * coefficients in monomial basis, at a given point. The Polynomial class is used in the native verifier for - * constructing and computing the perturbator. We implement this separate functionality here in the recursive - * folding verifier to avoid instantiating the entire Polynomial class on stdlib::bn254. Furthermore, the evaluation - * needs to be done sequentially as we don't support a parallel_for in circuits. - * - */ - static FF evaluate_perturbator(std::vector coeffs, FF point) - { - FF point_acc = FF(1); - FF result = FF(0); - for (size_t i = 0; i < coeffs.size(); i++) { - result += coeffs[i] * point_acc; - point_acc *= point; - } - return result; - }; - - /** - * @brief Folds the witness commitments and verification key (part of ϕ) and stores the values in the accumulator. - * - * - */ - - void fold_commitments(std::vector lagranges, - DeciderVerificationKeys& keys, - std::shared_ptr& accumulator) - { - size_t vk_idx = 0; - for (auto& expected_vk : accumulator->verification_key->get_all()) { - std::vector commitments; - for (auto& key : keys) { - commitments.emplace_back(key->verification_key->get_all()[vk_idx]); - } - // For ultra we need to enable edgecase prevention - expected_vk = Commitment::batch_mul( - commitments, lagranges, /*max_num_bits=*/0, /*with_edgecases=*/IsUltraBuilder); - vk_idx++; - } - - size_t comm_idx = 0; - for (auto& comm : accumulator->witness_commitments.get_all()) { - std::vector commitments; - for (auto& key : keys) { - commitments.emplace_back(key->witness_commitments.get_all()[comm_idx]); - } - // For ultra we need to enable edgecase prevention - comm = Commitment::batch_mul( - commitments, lagranges, /*max_num_bits=*/0, /*with_edgecases=*/IsUltraBuilder); - comm_idx++; - } - } }; } // namespace bb::stdlib::recursion::honk \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.test.cpp index f33fbf722ec..b0eeb588f37 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/protogalaxy_recursive_verifier.test.cpp @@ -3,6 +3,7 @@ #include "barretenberg/common/test.hpp" #include "barretenberg/protogalaxy/protogalaxy_prover.hpp" #include "barretenberg/protogalaxy/protogalaxy_verifier.hpp" +#include "barretenberg/protogalaxy/prover_verifier_shared.hpp" #include "barretenberg/stdlib/hash/blake3s/blake3s.hpp" #include "barretenberg/stdlib/hash/pedersen/pedersen.hpp" #include "barretenberg/stdlib/honk_verifier/decider_recursive_verifier.hpp" @@ -169,7 +170,7 @@ template class ProtogalaxyRecursiveTests : public tes fr_ct point_ct(fr_ct(&builder, point)); auto res1 = poly.evaluate(point); - auto res2 = FoldingRecursiveVerifier::evaluate_perturbator(coeffs_ct, point_ct); + auto res2 = evaluate_perturbator(coeffs_ct, point_ct); EXPECT_EQ(res1, res2.get_value()); }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/recursive_decider_verification_keys.hpp b/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/recursive_decider_verification_keys.hpp index eadd7d8a656..6e75211df15 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/recursive_decider_verification_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/protogalaxy_verifier/recursive_decider_verification_keys.hpp @@ -35,5 +35,82 @@ template struct RecursiveDeciderVerific idx++; } } + /** + * @brief Get the precomputed commitments grouped by commitment index + * @example If the commitments are grouped as in + * VK 0 VK 1 VK 2 VK 3 + * q_c_0 q_c_1 q_c_2 q_c_3 + * q_l_0 q_l_1 q_l_2 q_l_3 + * ⋮ ⋮ ⋮ ⋮ + * + * then this function outputs this matrix of group elements as a vector of rows, + * i.e. it outputs {{q_c_0, q_c_1, q_c_2, q_c_3}, {q_l_0, q_l_1, q_l_2, q_l_3},...}. + * The "commitment index" is the index of the row. + */ + std::vector> get_precomputed_commitments() const + { + const size_t num_commitments_to_fold = _data[0]->verification_key->get_all().size(); + std::vector> result(num_commitments_to_fold, + std::vector(NUM)); + for (size_t idx = 0; auto& commitment_at_idx : result) { + for (auto [elt, key] : zip_view(commitment_at_idx, _data)) { + elt = key->verification_key->get_all()[idx]; + } + idx++; + } + return result; + } + + /** + * @brief Get the witness commitments grouped by commitment index + * @details See get_precomputed_commitments; this is essentially the same. + */ + std::vector> get_witness_commitments() const + { + const size_t num_commitments_to_fold = _data[0]->witness_commitments.get_all().size(); + std::vector> result(num_commitments_to_fold, + std::vector(NUM)); + for (size_t idx = 0; auto& commitment_at_idx : result) { + for (auto [elt, key] : zip_view(commitment_at_idx, _data)) { + elt = key->witness_commitments.get_all()[idx]; + } + idx++; + } + return result; + } + + /** + * @brief Get the alphas grouped by commitment index + * @details See get_precomputed_commitments; this is essentially the same. + */ + std::vector> get_alphas() const + { + const size_t num_alphas_to_fold = _data[0]->alphas.size(); + std::vector> result(num_alphas_to_fold, std::vector(NUM)); + for (size_t idx = 0; auto& alpha_at_idx : result) { + for (auto [elt, key] : zip_view(alpha_at_idx, _data)) { + elt = key->alphas[idx]; + } + idx++; + } + return result; + } + + /** + * @brief Get the relation parameters grouped by commitment index + * @details See get_precomputed_commitments; this is essentially the same. + */ + std::vector> get_relation_parameters() const + { + const size_t num_params_to_fold = _data[0]->relation_parameters.get_to_fold().size(); + std::vector> result(num_params_to_fold, std::vector(NUM)); + for (size_t idx = 0; auto& params_at_idx : result) { + for (auto [elt, key] : zip_view(params_at_idx, _data)) { + elt = key->relation_parameters.get_to_fold()[idx]; + } + idx++; + } + return result; + } }; } // namespace bb::stdlib::recursion::honk