From 22734beec2ca7836cac276ffae4843e63a53ff24 Mon Sep 17 00:00:00 2001 From: codygunton Date: Tue, 10 Sep 2024 19:40:54 +0000 Subject: [PATCH 01/16] compute lagrange values using a function --- .../protogalaxy/protogalaxy_verifier.cpp | 72 +++++++++++-------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 868ba89c9c25..06aa19c06400 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -35,10 +35,43 @@ void ProtogalaxyVerifier_::run_oink_verifier_on_each_in } } +template +std::tuple> compute_lagrange_vanishing_polynomial_evaluations(const FF& combiner_challenge) +{ + static_assert(NUM < 5); + static constexpr FF inverse_two = FF(2).invert(); + + std::array lagranges; + FF vanishing_polynomial_at_challenge; + if constexpr (NUM == 2) { + vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); + lagranges = { FF(1) - combiner_challenge, combiner_challenge }; + } else if constexpr (NUM == 3) { + vanishing_polynomial_at_challenge = + combiner_challenge * (combiner_challenge - FF(1)) * (combiner_challenge - FF(2)); + lagranges = { (FF(1) - combiner_challenge) * (FF(2) - combiner_challenge) * inverse_two, + combiner_challenge * (FF(2) - combiner_challenge), + combiner_challenge * (combiner_challenge - FF(1)) * inverse_two }; + } else if constexpr (NUM == 4) { + static constexpr FF inverse_six = FF(6).invert(); + vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)) * + (combiner_challenge - FF(2)) * (combiner_challenge - FF(3)); + lagranges = { (FF(1) - combiner_challenge) * (FF(2) - combiner_challenge) * (FF(3) - combiner_challenge) * + inverse_six, + combiner_challenge * (FF(2) - combiner_challenge) * (FF(3) - combiner_challenge) * inverse_two, + combiner_challenge * (combiner_challenge - FF(1)) * (FF(3) - combiner_challenge) * inverse_two, + combiner_challenge * (combiner_challenge - FF(1)) * (combiner_challenge - FF(2)) * inverse_six }; + } + return std::make_tuple(vanishing_polynomial_at_challenge, lagranges); +} + template std::shared_ptr ProtogalaxyVerifier_< DeciderVerificationKeys>::verify_folding_proof(const std::vector& proof) { + static constexpr size_t BATCHED_EXTENDED_LENGTH = DeciderVerificationKeys::BATCHED_EXTENDED_LENGTH; + static constexpr size_t NUM_KEYS = DeciderVerificationKeys::NUM; + run_oink_verifier_on_each_incomplete_key(proof); const FF delta = transcript->template get_challenge("delta"); @@ -61,40 +94,17 @@ std::shared_ptr ProtogalaxyVerifier const FF perturbator_evaluation = perturbator.evaluate(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)); + std::array combiner_quotient_evals; + size_t idx = 0; + for (auto& val : combiner_quotient_evals) { + val = transcript->template receive_from_prover("combiner_quotient_" + std::to_string(idx++)); } - const Univariate - combiner_quotient(combiner_quotient_evals); + const Univariate combiner_quotient(combiner_quotient_evals); const FF combiner_challenge = transcript->template get_challenge("combiner_quotient_challenge"); const FF combiner_quotient_evaluation = combiner_quotient.evaluate(combiner_challenge); - constexpr FF inverse_two = FF(2).invert(); - FF vanishing_polynomial_at_challenge; - std::array lagranges; - if constexpr (DeciderVerificationKeys::NUM == 2) { - vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); - lagranges = { FF(1) - combiner_challenge, combiner_challenge }; - } else if constexpr (DeciderVerificationKeys::NUM == 3) { - vanishing_polynomial_at_challenge = - combiner_challenge * (combiner_challenge - FF(1)) * (combiner_challenge - FF(2)); - lagranges = { (FF(1) - combiner_challenge) * (FF(2) - combiner_challenge) * inverse_two, - combiner_challenge * (FF(2) - combiner_challenge), - combiner_challenge * (combiner_challenge - FF(1)) * inverse_two }; - } else if constexpr (DeciderVerificationKeys::NUM == 4) { - constexpr FF inverse_six = FF(6).invert(); - vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)) * - (combiner_challenge - FF(2)) * (combiner_challenge - FF(3)); - lagranges = { (FF(1) - combiner_challenge) * (FF(2) - combiner_challenge) * (FF(3) - combiner_challenge) * - inverse_six, - combiner_challenge * (FF(2) - combiner_challenge) * (FF(3) - combiner_challenge) * inverse_two, - combiner_challenge * (combiner_challenge - FF(1)) * (FF(3) - combiner_challenge) * inverse_two, - combiner_challenge * (combiner_challenge - FF(1)) * (combiner_challenge - FF(2)) * inverse_six }; - } - static_assert(DeciderVerificationKeys::NUM < 5); + auto [vanishing_polynomial_at_challenge, lagranges] = + compute_lagrange_vanishing_polynomial_evaluations(combiner_challenge); // TODO(https://github.com/AztecProtocol/barretenberg/issues/881): bad pattern auto next_accumulator = std::make_shared(); @@ -142,7 +152,7 @@ std::shared_ptr ProtogalaxyVerifier alpha_idx++; } auto& expected_parameters = next_accumulator->relation_parameters; - for (size_t vk_idx = 0; vk_idx < DeciderVerificationKeys::NUM; vk_idx++) { + for (size_t vk_idx = 0; vk_idx < NUM_KEYS; vk_idx++) { auto& key = keys_to_fold[vk_idx]; expected_parameters.eta += key->relation_parameters.eta * lagranges[vk_idx]; expected_parameters.eta_two += key->relation_parameters.eta_two * lagranges[vk_idx]; From b02be349adca3e2b09b0aa3a0fb8ea814e3cc53e Mon Sep 17 00:00:00 2001 From: codygunton Date: Tue, 10 Sep 2024 20:00:03 +0000 Subject: [PATCH 02/16] Revert std::move removal --- .../src/barretenberg/ultra_honk/decider_verification_key.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verification_key.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verification_key.hpp index 289ec5467100..562b1a595619 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verification_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verification_key.hpp @@ -35,7 +35,7 @@ template class DeciderVerificationKey_ { DeciderVerificationKey_() = default; DeciderVerificationKey_(std::shared_ptr vk) - : verification_key(vk) + : verification_key(std::move(vk)) {} MSGPACK_FIELDS(verification_key, From 49bc83ce6ad7e588b2bf077ed7272be13095079f Mon Sep 17 00:00:00 2001 From: codygunton Date: Tue, 10 Sep 2024 20:42:07 +0000 Subject: [PATCH 03/16] Refactor batch_mul and use it --- .../commitment_schemes/ipa/ipa.hpp | 3 +- .../commitment_schemes/kzg/kzg.hpp | 3 +- .../shplonk/shplemini_verifier.hpp | 1 - .../shplonk/shplemini_verifier.test.cpp | 6 +- .../utils/batch_mul_native.hpp | 58 +++++++++---------- .../zeromorph/zeromorph.hpp | 5 +- .../protogalaxy/protogalaxy_verifier.cpp | 14 ++--- .../barretenberg/ultra_honk/decider_keys.hpp | 11 ++++ 8 files changed, 48 insertions(+), 53 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp index 129e5265480d..53d1ed7c172e 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.hpp @@ -593,7 +593,6 @@ template class IPA { static OpeningClaim reduce_batch_opening_claim( const BatchOpeningClaim& batch_opening_claim) { - using Utils = CommitmentSchemesUtils; // Extract batch_mul arguments from the accumulator const auto& commitments = batch_opening_claim.commitments; const auto& scalars = batch_opening_claim.scalars; @@ -604,7 +603,7 @@ template class IPA { shplonk_output_commitment = GroupElement::batch_mul(commitments, scalars, /*max_num_bits=*/0, /*with_edgecases=*/true); } else { - shplonk_output_commitment = Utils::batch_mul_native(commitments, scalars); + shplonk_output_commitment = batch_mul_native(commitments, scalars); } // Output an opening claim to be verified by the IPA opening protocol return { { shplonk_eval_challenge, Fr(0) }, shplonk_output_commitment }; diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp index 0fab4113fab5..955a9da9fe1f 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.hpp @@ -108,7 +108,6 @@ template class KZG { static VerifierAccumulator reduce_verify_batch_opening_claim(BatchOpeningClaim batch_opening_claim, const std::shared_ptr& transcript) { - using Utils = CommitmentSchemesUtils; auto quotient_commitment = transcript->template receive_from_prover("KZG:W"); // The pairing check can be expressed as @@ -125,7 +124,7 @@ template class KZG { /*max_num_bits=*/0, /*with_edgecases=*/true); } else { - P_0 = Utils::batch_mul_native(batch_opening_claim.commitments, batch_opening_claim.scalars); + P_0 = batch_mul_native(batch_opening_claim.commitments, batch_opening_claim.scalars); } auto P_1 = -quotient_commitment; diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.hpp index 53893f7b0cb7..5ca984a148fb 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.hpp @@ -3,7 +3,6 @@ #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/gemini/gemini.hpp" #include "barretenberg/commitment_schemes/shplonk/shplonk.hpp" -#include "barretenberg/commitment_schemes/utils/batch_mul_native.hpp" #include "barretenberg/commitment_schemes/verification_key.hpp" #include "barretenberg/transcript/transcript.hpp" diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.test.cpp index 45292861fae7..5fdade707b19 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.test.cpp @@ -33,7 +33,6 @@ TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching) using GroupElement = typename TypeParam::Element; using Commitment = typename TypeParam::AffineElement; using Polynomial = typename bb::Polynomial; - using Utils = CommitmentSchemesUtils; const size_t n = 16; const size_t log_n = 4; @@ -111,7 +110,7 @@ TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching) verifier_batched_evaluation); // Final pairing check - GroupElement shplemini_result = Utils::batch_mul_native(commitments, scalars); + GroupElement shplemini_result = batch_mul_native(commitments, scalars); EXPECT_EQ(commitments.size(), unshifted_commitments.size() + shifted_commitments.size()); EXPECT_EQ(batched_evaluation, verifier_batched_evaluation); @@ -127,7 +126,6 @@ TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching) using GroupElement = typename TypeParam::Element; using Commitment = typename TypeParam::AffineElement; using Polynomial = typename bb::Polynomial; - using Utils = CommitmentSchemesUtils; const size_t n = 16; const size_t log_n = 4; @@ -221,7 +219,7 @@ TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching) EXPECT_EQ(commitments.size(), prover_commitments.size()); // Compute the group element using the output of Shplemini method - GroupElement shplemini_result = Utils::batch_mul_native(commitments, scalars); + GroupElement shplemini_result = batch_mul_native(commitments, scalars); EXPECT_EQ(shplemini_result, expected_result); } diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/batch_mul_native.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/batch_mul_native.hpp index 59970ea6d0b6..7ae350363e4a 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/batch_mul_native.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/batch_mul_native.hpp @@ -4,40 +4,34 @@ #include namespace bb { -template class CommitmentSchemesUtils { +/** + * @brief Utility for native batch multiplication of group elements + * @note This is used only for native verification and is not optimized for efficiency + */ +template +static Commitment batch_mul_native(const std::vector& _points, const std::vector& _scalars) +{ + std::vector points; + std::vector scalars; + for (size_t i = 0; i < _points.size(); ++i) { + const auto& point = _points[i]; + const auto& scalar = _scalars[i]; - public: - using Commitment = typename Curve::AffineElement; - using FF = typename Curve::ScalarField; - - /** - * @brief Utility for native batch multiplication of group elements - * @note This is used only for native verification and is not optimized for efficiency - */ - static Commitment batch_mul_native(const std::vector& _points, const std::vector& _scalars) - { - std::vector points; - std::vector scalars; - for (size_t i = 0; i < _points.size(); ++i) { - const auto& point = _points[i]; - const auto& scalar = _scalars[i]; - - // TODO: Special handling of point at infinity here due to incorrect serialization. - if (!scalar.is_zero() && !point.is_point_at_infinity() && !point.y.is_zero()) { - points.emplace_back(point); - scalars.emplace_back(scalar); - } + // TODO: Special handling of point at infinity here due to incorrect serialization. + if (!scalar.is_zero() && !point.is_point_at_infinity() && !point.y.is_zero()) { + points.emplace_back(point); + scalars.emplace_back(scalar); } + } - if (points.empty()) { - return Commitment::infinity(); - } + if (points.empty()) { + return Commitment::infinity(); + } - auto result = points[0] * scalars[0]; - for (size_t idx = 1; idx < scalars.size(); ++idx) { - result = result + points[idx] * scalars[idx]; - } - return result; + auto result = points[0] * scalars[0]; + for (size_t idx = 1; idx < scalars.size(); ++idx) { + result = result + points[idx] * scalars[idx]; } -}; -} // namespace bb \ No newline at end of file + return result; +} +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp index 659fa2be2712..e1ee3b92fcdf 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp @@ -469,7 +469,6 @@ template class ZeroMorphProver_ { template class ZeroMorphVerifier_ { using FF = typename Curve::ScalarField; using Commitment = typename Curve::AffineElement; - using Utils = CommitmentSchemesUtils; public: /** @@ -549,7 +548,7 @@ template class ZeroMorphVerifier_ { return Commitment::batch_mul(commitments, scalars); } } else { - return Utils::batch_mul_native(commitments, scalars); + return batch_mul_native(commitments, scalars); } } @@ -705,7 +704,7 @@ template class ZeroMorphVerifier_ { return Commitment::batch_mul(commitments, scalars); } } else { - return Utils::batch_mul_native(commitments, scalars); + return batch_mul_native(commitments, scalars); } } diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 06aa19c06400..85d22fcc893d 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -1,4 +1,5 @@ #include "protogalaxy_verifier.hpp" +#include "barretenberg/commitment_schemes/utils/batch_mul_native.hpp" #include "barretenberg/plonk_honk_shared/library/grand_product_delta.hpp" #include "barretenberg/protogalaxy/prover_verifier_shared.hpp" #include "barretenberg/ultra_honk/oink_verifier.hpp" @@ -36,12 +37,12 @@ void ProtogalaxyVerifier_::run_oink_verifier_on_each_in } template -std::tuple> compute_lagrange_vanishing_polynomial_evaluations(const FF& combiner_challenge) +std::tuple> compute_lagrange_vanishing_polynomial_evaluations(const FF& combiner_challenge) { static_assert(NUM < 5); static constexpr FF inverse_two = FF(2).invert(); - std::array lagranges; + std::vector lagranges(NUM); FF vanishing_polynomial_at_challenge; if constexpr (NUM == 2) { vanishing_polynomial_at_challenge = combiner_challenge * (combiner_challenge - FF(1)); @@ -112,13 +113,8 @@ std::shared_ptr ProtogalaxyVerifier next_accumulator->is_accumulator = true; size_t commitment_idx = 0; - for (auto& expected_vk : next_accumulator->verification_key->get_all()) { - size_t vk_idx = 0; - expected_vk = Commitment::infinity(); - for (auto& key : keys_to_fold) { - expected_vk = expected_vk + key->verification_key->get_all()[commitment_idx] * lagranges[vk_idx]; - vk_idx++; - } + for (auto& folded_commitment : next_accumulator->verification_key->get_all()) { + folded_commitment = batch_mul_native(keys_to_fold.get_commitments_at_index(commitment_idx), lagranges); commitment_idx++; } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index 882950d95db7..65d1dad03c1d 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -86,6 +86,7 @@ template struct DeciderProvingKeys_ { template struct DeciderVerificationKeys_ { static_assert(NUM_ > 1, "Must have at least two decider verification keys."); using Flavor = Flavor_; + using Commitment = typename Flavor_::Commitment; using VerificationKey = typename Flavor::VerificationKey; using DeciderVK = DeciderVerificationKey_; using ArrayType = std::array, NUM_>; @@ -106,5 +107,15 @@ template struct DeciderVerificationKeys_ { _data[idx] = std::move(data[idx]); } }; + + std::vector get_commitments_at_index(const size_t idx) const + { + std::vector result(NUM); + for (auto [elt, key] : zip_view(result, _data)) { + elt = key->verification_key->get_all()[idx]; + } + + return result; + } }; } // namespace bb From 44680f17f1ada89596f0c0ad2e4350cc485d740e Mon Sep 17 00:00:00 2001 From: codygunton Date: Tue, 10 Sep 2024 20:54:28 +0000 Subject: [PATCH 04/16] Use batch_mul for witness commiemtnets --- .../protogalaxy/protogalaxy_verifier.cpp | 14 +++++--------- .../src/barretenberg/ultra_honk/decider_keys.hpp | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 85d22fcc893d..8438972eed0b 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -114,7 +114,8 @@ std::shared_ptr ProtogalaxyVerifier size_t commitment_idx = 0; for (auto& folded_commitment : next_accumulator->verification_key->get_all()) { - folded_commitment = batch_mul_native(keys_to_fold.get_commitments_at_index(commitment_idx), lagranges); + folded_commitment = + batch_mul_native(keys_to_fold.get_precomputed_commitments_at_index(commitment_idx), lagranges); commitment_idx++; } @@ -125,15 +126,10 @@ std::shared_ptr ProtogalaxyVerifier update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); // Compute ϕ - auto& acc_witness_commitments = next_accumulator->witness_commitments; + commitment_idx = 0; - for (auto& comm : acc_witness_commitments.get_all()) { - comm = Commitment::infinity(); - size_t vk_idx = 0; - for (auto& key : keys_to_fold) { - comm = comm + key->witness_commitments.get_all()[commitment_idx] * lagranges[vk_idx]; - vk_idx++; - } + for (auto& folded_commitment : next_accumulator->witness_commitments.get_all()) { + folded_commitment = batch_mul_native(keys_to_fold.get_witness_commitments_at_index(commitment_idx), lagranges); commitment_idx++; } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index 65d1dad03c1d..541879e79a27 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -98,8 +98,8 @@ template struct DeciderVerificationKeys_ { std::shared_ptr const& operator[](size_t idx) const { return _data[idx]; } typename ArrayType::iterator begin() { return _data.begin(); }; typename ArrayType::iterator end() { return _data.end(); }; - DeciderVerificationKeys_() = default; + DeciderVerificationKeys_() = default; DeciderVerificationKeys_(const std::vector>& data) { ASSERT(data.size() == NUM); @@ -108,7 +108,7 @@ template struct DeciderVerificationKeys_ { } }; - std::vector get_commitments_at_index(const size_t idx) const + std::vector get_precomputed_commitments_at_index(const size_t idx) const { std::vector result(NUM); for (auto [elt, key] : zip_view(result, _data)) { @@ -117,5 +117,15 @@ template struct DeciderVerificationKeys_ { return result; } + + std::vector get_witness_commitments_at_index(const size_t idx) const + { + std::vector result(NUM); + for (auto [elt, key] : zip_view(result, _data)) { + elt = key->witness_commitments->get_all()[idx]; + } + + return result; + } }; } // namespace bb From 71d59b5e90937912b569e688f542190c80fbda34 Mon Sep 17 00:00:00 2001 From: codygunton Date: Tue, 10 Sep 2024 21:15:46 +0000 Subject: [PATCH 05/16] Fix compilation --- barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index 541879e79a27..55d5d736665f 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -122,7 +122,7 @@ template struct DeciderVerificationKeys_ { { std::vector result(NUM); for (auto [elt, key] : zip_view(result, _data)) { - elt = key->witness_commitments->get_all()[idx]; + elt = key->witness_commitments.get_all()[idx]; } return result; From 5bc0082b25fe08c007e3bf1d3fa45a4395aaf3c7 Mon Sep 17 00:00:00 2001 From: codygunton Date: Tue, 10 Sep 2024 21:24:05 +0000 Subject: [PATCH 06/16] Add and edit comments --- .../src/barretenberg/ultra_honk/decider_keys.hpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index 55d5d736665f..0736603b0b19 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -43,9 +43,9 @@ template struct DeciderProvingKeys_ { * PK 0 PK 1 PK 2 PK 3 * q_c q_l q_r ... q_c q_l q_r ... q_c q_l q_r ... q_c q_l q_r ... * * * * * * * * * - * * * * * * * * * * a_1 a_2 a_3 ... b_1 b_2 b_3 ... c_1 c_2 c_3 ... d_1 d_2 d_3 ... * * * * * * * * * + * ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ * * and the function returns the univariates [{a_1, b_1, c_1, d_1}, {a_2, b_2, c_2, d_2}, ...] * @@ -108,6 +108,16 @@ template struct DeciderVerificationKeys_ { } }; + /** + * @brief Get the precomputed commitments at a given index + * @example if the row idx is 2, and there are 4 decider verification keys + * VK 0 VK 1 VK 2 VK 3 + * q_c q_c q_c q_c + * * * * * + * a_1 b_1 c_1 d_1 + * * * * * + * then the function outputs the vector of group elements {a_1, b_1, c_1, d_1} + */ std::vector get_precomputed_commitments_at_index(const size_t idx) const { std::vector result(NUM); @@ -118,6 +128,10 @@ template struct DeciderVerificationKeys_ { return result; } + /** + * @brief Get the witness commitments at a given index + * @details This is similar to get_precomputed_commitments_at_index, but for witness commitments. + */ std::vector get_witness_commitments_at_index(const size_t idx) const { std::vector result(NUM); From 45e67977086d72026cfe5e80e299d5d26360132e Mon Sep 17 00:00:00 2001 From: codygunton Date: Tue, 10 Sep 2024 21:28:39 +0000 Subject: [PATCH 07/16] Shuffle to match prover --- .../protogalaxy/protogalaxy_prover_impl.hpp | 4 +- .../protogalaxy/protogalaxy_verifier.cpp | 45 ++++++++++--------- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp index 37365af01566..be6dd529fe5f 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp @@ -125,11 +125,9 @@ FoldingResult ProtogalaxyProver_template get_challenge("combiner_quotient_challenge"); FoldingResult result{ .accumulator = keys[0], .proof = std::move(transcript->proof_data) }; - - // TODO(https://github.com/AztecProtocol/barretenberg/issues/881): bad pattern result.accumulator->is_accumulator = true; - // Compute the next target sum + // Compute the next target sum (for its use; must be computed by the verifier) auto [vanishing_polynomial_at_challenge, lagranges] = Fun::compute_vanishing_polynomial_and_lagranges(combiner_challenge); result.accumulator->target_sum = perturbator_evaluation * lagranges[0] + diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 8438972eed0b..aefcd02c92d9 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -37,7 +37,7 @@ void ProtogalaxyVerifier_::run_oink_verifier_on_each_in } template -std::tuple> compute_lagrange_vanishing_polynomial_evaluations(const FF& combiner_challenge) +std::tuple> compute_vanishing_polynomial_and_lagrange_evaluations(const FF& combiner_challenge) { static_assert(NUM < 5); static constexpr FF inverse_two = FF(2).invert(); @@ -73,14 +73,14 @@ std::shared_ptr ProtogalaxyVerifier static constexpr size_t BATCHED_EXTENDED_LENGTH = DeciderVerificationKeys::BATCHED_EXTENDED_LENGTH; static constexpr size_t NUM_KEYS = DeciderVerificationKeys::NUM; + const std::shared_ptr& accumulator = keys_to_fold[0]; + const size_t log_circuit_size = static_cast(accumulator->verification_key->log_circuit_size); + run_oink_verifier_on_each_incomplete_key(proof); + // Perturbator round const FF delta = transcript->template get_challenge("delta"); - const std::shared_ptr& accumulator = keys_to_fold[0]; // WORKTODO: move - - const size_t log_circuit_size = static_cast(accumulator->verification_key->log_circuit_size); 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 <= log_circuit_size; idx++) { @@ -88,51 +88,52 @@ std::shared_ptr ProtogalaxyVerifier 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; const Polynomial perturbator(perturbator_coeffs); - const FF perturbator_challenge = transcript->template get_challenge("perturbator_challenge"); const FF perturbator_evaluation = perturbator.evaluate(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; + 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. size_t idx = 0; for (auto& val : combiner_quotient_evals) { val = transcript->template receive_from_prover("combiner_quotient_" + std::to_string(idx++)); } - const Univariate combiner_quotient(combiner_quotient_evals); + + // Folding const FF combiner_challenge = transcript->template get_challenge("combiner_quotient_challenge"); + const Univariate combiner_quotient(combiner_quotient_evals); const FF combiner_quotient_evaluation = combiner_quotient.evaluate(combiner_challenge); - auto [vanishing_polynomial_at_challenge, lagranges] = - compute_lagrange_vanishing_polynomial_evaluations(combiner_challenge); - - // TODO(https://github.com/AztecProtocol/barretenberg/issues/881): bad pattern auto next_accumulator = std::make_shared(); next_accumulator->verification_key = std::make_shared(*accumulator->verification_key); next_accumulator->is_accumulator = true; + // Compute next folding parameters + const auto [vanishing_polynomial_at_challenge, lagranges] = + compute_vanishing_polynomial_and_lagrange_evaluations(combiner_challenge); + next_accumulator->target_sum = + perturbator_evaluation * lagranges[0] + vanishing_polynomial_at_challenge * combiner_quotient_evaluation; + next_accumulator->gate_challenges = // note: known already in previous round + update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); + + // // Fold the commitments size_t commitment_idx = 0; for (auto& folded_commitment : next_accumulator->verification_key->get_all()) { folded_commitment = batch_mul_native(keys_to_fold.get_precomputed_commitments_at_index(commitment_idx), lagranges); commitment_idx++; } - - // Compute next folding parameters - next_accumulator->target_sum = - perturbator_evaluation * lagranges[0] + vanishing_polynomial_at_challenge * combiner_quotient_evaluation; - next_accumulator->gate_challenges = - update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); - - // Compute ϕ - commitment_idx = 0; for (auto& folded_commitment : next_accumulator->witness_commitments.get_all()) { folded_commitment = batch_mul_native(keys_to_fold.get_witness_commitments_at_index(commitment_idx), lagranges); commitment_idx++; } + // Fold the relation parameters size_t alpha_idx = 0; for (auto& alpha : next_accumulator->alphas) { alpha = FF(0); From d75f2be4fba0ed044c178b35d5ddede7010926a6 Mon Sep 17 00:00:00 2001 From: codygunton Date: Tue, 10 Sep 2024 21:49:59 +0000 Subject: [PATCH 08/16] Fold alphas [no-ci] --- .../utils/batch_mul_native.hpp | 14 +++++++++++ .../protogalaxy/protogalaxy_verifier.cpp | 24 +++++++------------ .../barretenberg/ultra_honk/decider_keys.hpp | 15 ++++++++++++ 3 files changed, 38 insertions(+), 15 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/batch_mul_native.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/batch_mul_native.hpp index 7ae350363e4a..507e2a6d2ba8 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/batch_mul_native.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/batch_mul_native.hpp @@ -34,4 +34,18 @@ static Commitment batch_mul_native(const std::vector& _points, const } return result; } + +/** + * @brief Utility for native batch multiplication of group elements + * @note This is used only for native verification and is not optimized for efficiency + */ +template static FF linear_combination(const std::vector& as, const std::vector& bs) +{ + FF result = as[0] * bs[0]; + for (size_t idx = 1; idx < as.size(); ++idx) { + result += as[idx] * bs[idx]; + } + return result; +} + } // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index aefcd02c92d9..0b8ce58db3e8 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -121,28 +121,22 @@ std::shared_ptr ProtogalaxyVerifier update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); // // Fold the commitments - size_t commitment_idx = 0; + idx = 0; for (auto& folded_commitment : next_accumulator->verification_key->get_all()) { - folded_commitment = - batch_mul_native(keys_to_fold.get_precomputed_commitments_at_index(commitment_idx), lagranges); - commitment_idx++; + folded_commitment = batch_mul_native(keys_to_fold.get_precomputed_commitments_at_index(idx), lagranges); + idx++; } - commitment_idx = 0; + idx = 0; for (auto& folded_commitment : next_accumulator->witness_commitments.get_all()) { - folded_commitment = batch_mul_native(keys_to_fold.get_witness_commitments_at_index(commitment_idx), lagranges); - commitment_idx++; + folded_commitment = batch_mul_native(keys_to_fold.get_witness_commitments_at_index(idx), lagranges); + idx++; } // Fold the relation parameters - size_t alpha_idx = 0; + 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++; + alpha = linear_combination(keys_to_fold.get_alphas_at_index(idx), lagranges); + idx++; } auto& expected_parameters = next_accumulator->relation_parameters; for (size_t vk_idx = 0; vk_idx < NUM_KEYS; vk_idx++) { diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index 0736603b0b19..c39ebe74d37d 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -86,6 +86,7 @@ template struct DeciderProvingKeys_ { template struct DeciderVerificationKeys_ { static_assert(NUM_ > 1, "Must have at least two decider verification keys."); using Flavor = Flavor_; + using FF = typename Flavor_::FF; using Commitment = typename Flavor_::Commitment; using VerificationKey = typename Flavor::VerificationKey; using DeciderVK = DeciderVerificationKey_; @@ -141,5 +142,19 @@ template struct DeciderVerificationKeys_ { return result; } + + /** + * @brief Get the witness commitments at a given index + * @details This is similar to get_precomputed_commitments_at_index, but for witness commitments. + */ + std::vector get_alphas_at_index(const size_t idx) const + { + std::vector result(NUM); + for (auto [elt, key] : zip_view(result, _data)) { + elt = key->alphas[idx]; + } + + return result; + } }; } // namespace bb From c08828f5660a8115a6172561bcaf55bd13a241c0 Mon Sep 17 00:00:00 2001 From: codygunton Date: Wed, 11 Sep 2024 16:30:28 +0000 Subject: [PATCH 09/16] Fix regression --- .../src/barretenberg/ultra_honk/decider_verification_key.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verification_key.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verification_key.hpp index 562b1a595619..289ec5467100 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verification_key.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verification_key.hpp @@ -35,7 +35,7 @@ template class DeciderVerificationKey_ { DeciderVerificationKey_() = default; DeciderVerificationKey_(std::shared_ptr vk) - : verification_key(std::move(vk)) + : verification_key(vk) {} MSGPACK_FIELDS(verification_key, From 49271d3bb13f0fecf423489af8d3c04d2710fbea Mon Sep 17 00:00:00 2001 From: codygunton Date: Wed, 11 Sep 2024 16:31:14 +0000 Subject: [PATCH 10/16] Clarify comment --- .../src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp index be6dd529fe5f..b4276d58b7b9 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_prover_impl.hpp @@ -127,7 +127,7 @@ FoldingResult ProtogalaxyProver_ result{ .accumulator = keys[0], .proof = std::move(transcript->proof_data) }; result.accumulator->is_accumulator = true; - // Compute the next target sum (for its use; must be computed by the verifier) + // Compute the next target sum (for its own use; verifier must compute its own values) auto [vanishing_polynomial_at_challenge, lagranges] = Fun::compute_vanishing_polynomial_and_lagranges(combiner_challenge); result.accumulator->target_sum = perturbator_evaluation * lagranges[0] + From 94551f55a2762ce650df7d573f2b50ad21759418 Mon Sep 17 00:00:00 2001 From: codygunton Date: Thu, 12 Sep 2024 04:09:20 +0000 Subject: [PATCH 11/16] Fix manifest discrepancy --- .../cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 0b8ce58db3e8..33c4432a00b8 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -98,7 +98,7 @@ std::shared_ptr ProtogalaxyVerifier 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. - size_t idx = 0; + size_t idx = DeciderVerificationKeys::NUM; for (auto& val : combiner_quotient_evals) { val = transcript->template receive_from_prover("combiner_quotient_" + std::to_string(idx++)); } From 70d85b2e8f5deedd4dc4abd9d3e4a7c9e4dcee06 Mon Sep 17 00:00:00 2001 From: codygunton Date: Thu, 12 Sep 2024 04:41:44 +0000 Subject: [PATCH 12/16] Fix randomness in test to debug relation params --- .../protogalaxy/protogalaxy_verifier.cpp | 4 ++++ .../protogalaxy_recursive_verifier.test.cpp | 24 ++++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 33c4432a00b8..d38842ca7a4d 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -151,6 +151,10 @@ std::shared_ptr ProtogalaxyVerifier key->relation_parameters.lookup_grand_product_delta * lagranges[vk_idx]; } + for (auto& param : next_accumulator->relation_parameters.get_to_fold()) { + info(param); + }; + return next_accumulator; } 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 cb5012bbaec2..44cb1400580d 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 @@ -14,6 +14,8 @@ #include "barretenberg/ultra_honk/ultra_prover.hpp" #include "barretenberg/ultra_honk/ultra_verifier.hpp" +auto& engine = bb::numeric::get_debug_randomness(); + namespace bb::stdlib::recursion::honk { template class ProtogalaxyRecursiveTests : public testing::Test { public: @@ -72,11 +74,11 @@ template class ProtogalaxyRecursiveTests : public tes // Create 2^log_n many add gates based on input log num gates const size_t num_gates = 1 << log_num_gates; for (size_t i = 0; i < num_gates; ++i) { - fr a = fr::random_element(); + fr a = fr::random_element(&engine); uint32_t a_idx = builder.add_variable(a); - fr b = fr::random_element(); - fr c = fr::random_element(); + fr b = fr::random_element(&engine); + fr c = fr::random_element(&engine); fr d = a + b + c; uint32_t b_idx = builder.add_variable(b); uint32_t c_idx = builder.add_variable(c); @@ -86,9 +88,9 @@ template class ProtogalaxyRecursiveTests : public tes } // Define some additional non-trivial but arbitrary circuit logic - fr_ct a(public_witness_ct(&builder, fr::random_element())); - fr_ct b(public_witness_ct(&builder, fr::random_element())); - fr_ct c(public_witness_ct(&builder, fr::random_element())); + fr_ct a(public_witness_ct(&builder, fr::random_element(&engine))); + fr_ct b(public_witness_ct(&builder, fr::random_element(&engine))); + fr_ct c(public_witness_ct(&builder, fr::random_element(&engine))); for (size_t i = 0; i < 32; ++i) { a = (a * b) + b + a; @@ -98,7 +100,7 @@ template class ProtogalaxyRecursiveTests : public tes byte_array_ct to_hash(&builder, "nonsense test data"); blake3s(to_hash); - fr bigfield_data = fr::random_element(); + fr bigfield_data = fr::random_element(&engine); fr bigfield_data_a{ bigfield_data.data[0], bigfield_data.data[1], 0, 0 }; fr bigfield_data_b{ bigfield_data.data[2], bigfield_data.data[3], 0, 0 }; @@ -158,12 +160,12 @@ template class ProtogalaxyRecursiveTests : public tes std::vector coeffs; std::vector coeffs_ct; for (size_t idx = 0; idx < 8; idx++) { - auto el = fr::random_element(); + auto el = fr::random_element(&engine); coeffs.emplace_back(el); coeffs_ct.emplace_back(fr_ct(&builder, el)); } Polynomial poly(coeffs); - fr point = fr::random_element(); + fr point = fr::random_element(&engine); fr_ct point_ct(fr_ct(&builder, point)); auto res1 = poly.evaluate(point); @@ -333,7 +335,7 @@ template class ProtogalaxyRecursiveTests : public tes auto [prover_accumulator, verifier_accumulator] = fold_and_verify_native(); // Tamper with the accumulator by changing the target sum - verifier_accumulator->target_sum = FF::random_element(); + verifier_accumulator->target_sum = FF::random_element(&engine); // Create a decider proof for accumulator obtained through folding InnerDeciderProver decider_prover(prover_accumulator); @@ -361,7 +363,7 @@ template class ProtogalaxyRecursiveTests : public tes auto verification_key = std::make_shared(prover_inst->proving_key); auto verifier_inst = std::make_shared(verification_key); - prover_accumulator->proving_key.polynomials.w_l.at(1) = FF::random_element(); + prover_accumulator->proving_key.polynomials.w_l.at(1) = FF::random_element(&engine); // Generate a folding proof with the incorrect polynomials which would result in the prover having the wrong // target sum From 5dd7c417d1410b81c367ad4eb126e66817ceaf4f Mon Sep 17 00:00:00 2001 From: codygunton Date: Thu, 12 Sep 2024 04:50:49 +0000 Subject: [PATCH 13/16] Fold relation parameters --- .../protogalaxy/protogalaxy_verifier.cpp | 19 ++++--------------- .../barretenberg/ultra_honk/decider_keys.hpp | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index d38842ca7a4d..ccb2de72dcb0 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -138,22 +138,11 @@ std::shared_ptr ProtogalaxyVerifier alpha = linear_combination(keys_to_fold.get_alphas_at_index(idx), lagranges); idx++; } - auto& expected_parameters = next_accumulator->relation_parameters; - for (size_t vk_idx = 0; vk_idx < NUM_KEYS; vk_idx++) { - auto& key = keys_to_fold[vk_idx]; - expected_parameters.eta += key->relation_parameters.eta * lagranges[vk_idx]; - expected_parameters.eta_two += key->relation_parameters.eta_two * lagranges[vk_idx]; - expected_parameters.eta_three += key->relation_parameters.eta_three * lagranges[vk_idx]; - expected_parameters.beta += key->relation_parameters.beta * lagranges[vk_idx]; - expected_parameters.gamma += key->relation_parameters.gamma * lagranges[vk_idx]; - expected_parameters.public_input_delta += key->relation_parameters.public_input_delta * lagranges[vk_idx]; - expected_parameters.lookup_grand_product_delta += - key->relation_parameters.lookup_grand_product_delta * lagranges[vk_idx]; - } - + idx = 0; for (auto& param : next_accumulator->relation_parameters.get_to_fold()) { - info(param); - }; + param = linear_combination(keys_to_fold.get_relation_parameters_at_index(idx), lagranges); + idx++; + } return next_accumulator; } diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index c39ebe74d37d..57cd46d73244 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -156,5 +156,19 @@ template struct DeciderVerificationKeys_ { return result; } + + /** + * @brief Get the witness commitments at a given index + * @details This is similar to get_precomputed_commitments_at_index, but for witness commitments. + */ + std::vector get_relation_parameters_at_index(const size_t idx) const + { + std::vector result(NUM); + for (auto [elt, key] : zip_view(result, _data)) { + elt = key->relation_parameters.get_to_fold()[idx]; + } + + return result; + } }; } // namespace bb From 4130cca25eea81cd285515ee5701aad9ac4d60d5 Mon Sep 17 00:00:00 2001 From: codygunton Date: Thu, 12 Sep 2024 05:29:15 +0000 Subject: [PATCH 14/16] Better organization of loop --- .../protogalaxy/protogalaxy_verifier.cpp | 7 +++---- .../barretenberg/ultra_honk/decider_keys.hpp | 17 ++++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index ccb2de72dcb0..ad2b3892ecb1 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -138,10 +138,9 @@ std::shared_ptr ProtogalaxyVerifier alpha = linear_combination(keys_to_fold.get_alphas_at_index(idx), lagranges); idx++; } - idx = 0; - for (auto& param : next_accumulator->relation_parameters.get_to_fold()) { - param = linear_combination(keys_to_fold.get_relation_parameters_at_index(idx), lagranges); - idx++; + for (auto [combination, to_combine] : + zip_view(next_accumulator->relation_parameters.get_to_fold(), keys_to_fold.get_relation_parameters())) { + combination = linear_combination(to_combine, lagranges); } return next_accumulator; diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index 57cd46d73244..e41a24084d14 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -158,16 +158,19 @@ template struct DeciderVerificationKeys_ { } /** - * @brief Get the witness commitments at a given index - * @details This is similar to get_precomputed_commitments_at_index, but for witness commitments. + * @brief Get the relation parameters at a given index + * @details This is similar to get_precomputed_commitments_at_index, but for relation parameters. */ - std::vector get_relation_parameters_at_index(const size_t idx) const + std::vector> get_relation_parameters() const { - std::vector result(NUM); - for (auto [elt, key] : zip_view(result, _data)) { - elt = key->relation_parameters.get_to_fold()[idx]; + 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; } }; From bf4d429f36d6fa130ef77d8f734df2cebd8f1f66 Mon Sep 17 00:00:00 2001 From: codygunton Date: Thu, 12 Sep 2024 13:30:03 +0000 Subject: [PATCH 15/16] Do it for alphas --- .../protogalaxy/protogalaxy_verifier.cpp | 6 ++---- .../barretenberg/ultra_honk/decider_keys.hpp | 21 +++++++------------ 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index ad2b3892ecb1..8c9c5349f24a 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -133,10 +133,8 @@ std::shared_ptr ProtogalaxyVerifier } // Fold the relation parameters - idx = 0; - for (auto& alpha : next_accumulator->alphas) { - alpha = linear_combination(keys_to_fold.get_alphas_at_index(idx), lagranges); - idx++; + for (auto [combination, to_combine] : zip_view(next_accumulator->alphas, keys_to_fold.get_alphas())) { + combination = linear_combination(to_combine, lagranges); } for (auto [combination, to_combine] : zip_view(next_accumulator->relation_parameters.get_to_fold(), keys_to_fold.get_relation_parameters())) { diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index e41a24084d14..780a6225c528 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -143,24 +143,19 @@ template struct DeciderVerificationKeys_ { return result; } - /** - * @brief Get the witness commitments at a given index - * @details This is similar to get_precomputed_commitments_at_index, but for witness commitments. - */ - std::vector get_alphas_at_index(const size_t idx) const + std::vector> get_alphas() const { - std::vector result(NUM); - for (auto [elt, key] : zip_view(result, _data)) { - elt = key->alphas[idx]; + 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 at a given index - * @details This is similar to get_precomputed_commitments_at_index, but for relation parameters. - */ std::vector> get_relation_parameters() const { const size_t num_params_to_fold = _data[0]->relation_parameters.get_to_fold().size(); From 6c553f712210bce1e275f263b3310df329945242 Mon Sep 17 00:00:00 2001 From: codygunton Date: Thu, 12 Sep 2024 14:14:06 +0000 Subject: [PATCH 16/16] Finish folding rewrite --- .../protogalaxy/protogalaxy_verifier.cpp | 17 +++--- .../barretenberg/ultra_honk/decider_keys.hpp | 56 ++++++++++++------- 2 files changed, 43 insertions(+), 30 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp index 8c9c5349f24a..91e9b3bc9f54 100644 --- a/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/protogalaxy/protogalaxy_verifier.cpp @@ -98,8 +98,7 @@ std::shared_ptr ProtogalaxyVerifier 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. - size_t idx = DeciderVerificationKeys::NUM; - for (auto& val : combiner_quotient_evals) { + for (size_t idx = DeciderVerificationKeys::NUM; auto& val : combiner_quotient_evals) { val = transcript->template receive_from_prover("combiner_quotient_" + std::to_string(idx++)); } @@ -121,15 +120,13 @@ std::shared_ptr ProtogalaxyVerifier update_gate_challenges(perturbator_challenge, accumulator->gate_challenges, deltas); // // Fold the commitments - idx = 0; - for (auto& folded_commitment : next_accumulator->verification_key->get_all()) { - folded_commitment = batch_mul_native(keys_to_fold.get_precomputed_commitments_at_index(idx), lagranges); - idx++; + for (auto [combination, to_combine] : + zip_view(next_accumulator->verification_key->get_all(), keys_to_fold.get_precomputed_commitments())) { + combination = batch_mul_native(to_combine, lagranges); } - idx = 0; - for (auto& folded_commitment : next_accumulator->witness_commitments.get_all()) { - folded_commitment = batch_mul_native(keys_to_fold.get_witness_commitments_at_index(idx), lagranges); - idx++; + for (auto [combination, to_combine] : + zip_view(next_accumulator->witness_commitments.get_all(), keys_to_fold.get_witness_commitments())) { + combination = batch_mul_native(to_combine, lagranges); } // Fold the relation parameters diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp index 780a6225c528..e6ef907c6224 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_keys.hpp @@ -110,39 +110,51 @@ template struct DeciderVerificationKeys_ { }; /** - * @brief Get the precomputed commitments at a given index - * @example if the row idx is 2, and there are 4 decider verification keys - * VK 0 VK 1 VK 2 VK 3 - * q_c q_c q_c q_c - * * * * * - * a_1 b_1 c_1 d_1 - * * * * * - * then the function outputs the vector of group elements {a_1, b_1, c_1, d_1} + * @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 output this matrix of group elements as a vector of rows, + * i.e. it ouptuts {{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_at_index(const size_t idx) const + std::vector> get_precomputed_commitments() const { - std::vector result(NUM); - for (auto [elt, key] : zip_view(result, _data)) { - elt = key->verification_key->get_all()[idx]; + 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 at a given index - * @details This is similar to get_precomputed_commitments_at_index, but for witness commitments. + * @brief Get the witness commitments grouped by commitment index + * @details See get_precomputed_commitments; this is essentially the same. */ - std::vector get_witness_commitments_at_index(const size_t idx) const + std::vector> get_witness_commitments() const { - std::vector result(NUM); - for (auto [elt, key] : zip_view(result, _data)) { - elt = key->witness_commitments.get_all()[idx]; + 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(); @@ -156,6 +168,10 @@ template struct DeciderVerificationKeys_ { 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();