diff --git a/barretenberg/cpp/src/CMakeLists.txt b/barretenberg/cpp/src/CMakeLists.txt index 0091837f26e..00b99bcb269 100644 --- a/barretenberg/cpp/src/CMakeLists.txt +++ b/barretenberg/cpp/src/CMakeLists.txt @@ -26,6 +26,8 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 18) # We target clang18 and need this, eventually warning should be fixed or this will be unconditional. add_compile_options(-Wno-vla-cxx-extension) + # This gets in the way of a valid designated initializer pattern (i.e. MyClass my_class{ .my_member = init_value }) + add_compile_options(-Wno-missing-field-initializers) endif() endif() diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/claim_batcher.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/claim_batcher.hpp new file mode 100644 index 00000000000..db2e6992bb3 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/claim_batcher.hpp @@ -0,0 +1,128 @@ +#pragma once +#include "barretenberg/common/ref_vector.hpp" +#include + +namespace bb { + +/** + * @brief Logic to support batching opening claims for unshifted and shifted polynomials in Shplemini + * @details Stores references to the commitments/evaluations of unshifted and shifted polynomials to be batched + * opened via Shplemini. Aggregates the commitments and batching scalars for each batch into the corresponding + * containers for Shplemini. Computes the batched evaluation. Contains logic for computing the per-batch scalars + * used to batch each set of claims (see details below). + * @note This class performs the actual batching of the evaluations but not of the commitments. The latter are + * simply appended to a larger container, along with the scalars used to batch them. This is because Shplemini + * is optimized to perform a single batch mul that includes all commitments from each stage of the PCS. See + * description of ShpleminiVerifier for more details. + * + */ +template struct ClaimBatcher_ { + using Fr = typename Curve::ScalarField; + using Commitment = typename Curve::AffineElement; + + struct Batch { + RefVector commitments; + RefVector evaluations; + // scalar used for batching the claims, excluding the power of batching challenge \rho + Fr scalar = 0; + }; + + std::optional unshifted; // commitments and evaluations of unshifted polynomials + std::optional shifted; // commitments of to-be-shifted-by-1 polys, evals of their shifts + std::optional right_shifted_by_k; // commitments of to-be-right-shifted-by-k polys, evals of their shifts + + Batch get_unshifted() { return (unshifted) ? *unshifted : Batch{}; } + Batch get_shifted() { return (shifted) ? *shifted : Batch{}; } + Batch get_right_shifted_by_k() { return (right_shifted_by_k) ? *right_shifted_by_k : Batch{}; } + + size_t k_shift_magnitude = 0; // magnitude of right-shift-by-k (assumed even) + + Fr get_unshifted_batch_scalar() const { return unshifted ? unshifted->scalar : Fr{ 0 }; } + + /** + * @brief Compute scalars used to batch each set of claims, excluding contribution from batching challenge \rho + * @details Computes scalars s_0, s_1, s_2 given by + * \f[ + * - s_0 = \left(\frac{1}{z-r} + \nu \times \frac{1}{z+r}\right) \f], + * - s_1 = \frac{1}{r} \times \left(\frac{1}{z-r} - \nu \times \frac{1}{z+r}\right) + * - s_2 = r^{k} \times \left(\frac{1}{z-r} + \nu \times \frac{1}{z+r}\right) + * \f] + * where the scalars used to batch the claims are given by + * \f[ + * \left( + * - s_0, + * \ldots, + * - \rho^{i+k-1} \times s_0, + * - \rho^{i+k} \times s_1, + * \ldots, + * - \rho^{k+m-1} \times s_1 + * \right) + * \f] + * + * @param inverse_vanishing_eval_pos 1/(z-r) + * @param inverse_vanishing_eval_neg 1/(z+r) + * @param nu_challenge ν (shplonk batching challenge) + * @param r_challenge r (gemini evaluation challenge) + */ + void compute_scalars_for_each_batch(const Fr& inverse_vanishing_eval_pos, + const Fr& inverse_vanishing_eval_neg, + const Fr& nu_challenge, + const Fr& r_challenge) + { + if (unshifted) { + // (1/(z−r) + ν/(z+r)) + unshifted->scalar = inverse_vanishing_eval_pos + nu_challenge * inverse_vanishing_eval_neg; + } + if (shifted) { + // r⁻¹ ⋅ (1/(z−r) − ν/(z+r)) + shifted->scalar = + r_challenge.invert() * (inverse_vanishing_eval_pos - nu_challenge * inverse_vanishing_eval_neg); + } + if (right_shifted_by_k) { + // r^k ⋅ (1/(z−r) + ν/(z+r)) + right_shifted_by_k->scalar = r_challenge.pow(k_shift_magnitude) * + (inverse_vanishing_eval_pos + nu_challenge * inverse_vanishing_eval_neg); + } + } + + /** + * @brief Append the commitments and scalars from each batch of claims to the Shplemini batch mul input vectors; + * update the batched evaluation and the running batching challenge (power of rho) in place. + * + * @param commitments commitment inputs to the single Shplemini batch mul + * @param scalars scalar inputs to the single Shplemini batch mul + * @param batched_evaluation running batched evaluation of the committed multilinear polynomials + * @param rho multivariate batching challenge \rho + * @param rho_power current power of \rho used in the batching scalar + */ + void update_batch_mul_inputs_and_batched_evaluation(std::vector& commitments, + std::vector& scalars, + Fr& batched_evaluation, + const Fr& rho, + Fr& rho_power) + { + // Append the commitments/scalars from a given batch to the corresponding containers; update the batched + // evaluation and the running batching challenge in place + auto aggregate_claim_data_and_update_batched_evaluation = [&](const Batch& batch, Fr& rho_power) { + for (auto [commitment, evaluation] : zip_view(batch.commitments, batch.evaluations)) { + commitments.emplace_back(std::move(commitment)); + scalars.emplace_back(-batch.scalar * rho_power); + batched_evaluation += evaluation * rho_power; + rho_power *= rho; + } + }; + + // Incorporate the claim data from each batch of claims that is present + if (unshifted) { + aggregate_claim_data_and_update_batched_evaluation(*unshifted, rho_power); + } + if (shifted) { + aggregate_claim_data_and_update_batched_evaluation(*shifted, rho_power); + } + if (right_shifted_by_k) { + aggregate_claim_data_and_update_batched_evaluation(*right_shifted_by_k, rho_power); + } + } +}; + +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp index 7b4aaf0f035..ab4c5b9df1b 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp @@ -1,6 +1,7 @@ #pragma once #include "barretenberg/commitment_schemes/claim.hpp" +#include "barretenberg/commitment_schemes/claim_batcher.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/transcript/transcript.hpp" @@ -104,11 +105,12 @@ template class GeminiProver_ { * @brief Class responsible for computation of the batched multilinear polynomials required by the Gemini protocol * @details Opening multivariate polynomials using Gemini requires the computation of three batched polynomials. The * first, here denoted A₀, is a linear combination of all polynomials to be opened. If we denote the linear - * combinations (based on challenge rho) of the unshifted and the to-be-shited-by-1 polynomials by F and G, - * respectively, then A₀ = F + G/X. This polynomial is "folded" in Gemini to produce d-1 univariate polynomials - * Fold_i, i = 1, ..., d-1. The second and third are the partially evaluated batched polynomials A₀₊ = F + G/r, and - * A₀₋ = F - G/r. These are required in order to prove the opening of shifted polynomials G_i/X from the commitments - * to their unshifted counterparts G_i. + * combinations (based on challenge rho) of the unshifted, to-be-shifted-by-1, and to-be-right-shifted-by-k + * polynomials by F, G, and H respectively, then A₀ = F + G/X + X^k*H. (Note: 'k' is assumed even and thus a factor + * (-1)^k in not needed for the evaluation at -r). This polynomial is "folded" in Gemini to produce d-1 univariate + * polynomials Fold_i, i = 1, ..., d-1. The second and third are the partially evaluated batched polynomials A₀₊ = F + * + G/r + r^K*H, and A₀₋ = F - G/r + r^K*H. These are required in order to prove the opening of shifted polynomials + * G_i/X, X^k*H_i and from the commitments to their unshifted counterparts G_i and H_i. * @note TODO(https://github.com/AztecProtocol/barretenberg/issues/1223): There are certain operations herein that * could be made more efficient by e.g. reusing already initialized polynomials, possibly at the expense of clarity. */ @@ -122,9 +124,13 @@ template class GeminiProver_ { RefVector unshifted; // set of unshifted polynomials RefVector to_be_shifted_by_one; // set of polynomials to be left shifted by 1 + RefVector to_be_shifted_by_k; // set of polynomials to be right shifted by k + + size_t k_shift_magnitude = 0; // magnitude of right-shift-by-k (assumed even) Polynomial batched_unshifted; // linear combination of unshifted polynomials Polynomial batched_to_be_shifted_by_one; // linear combination of to-be-shifted polynomials + Polynomial batched_to_be_shifted_by_k; // linear combination of to-be-shifted-by-k polynomials public: PolynomialBatcher(const size_t full_batched_size) @@ -135,10 +141,17 @@ template class GeminiProver_ { bool has_unshifted() const { return unshifted.size() > 0; } bool has_to_be_shifted_by_one() const { return to_be_shifted_by_one.size() > 0; } + bool has_to_be_shifted_by_k() const { return to_be_shifted_by_k.size() > 0; } // Set references to the polynomials to be batched void set_unshifted(RefVector polynomials) { unshifted = polynomials; } void set_to_be_shifted_by_one(RefVector polynomials) { to_be_shifted_by_one = polynomials; } + void set_to_be_shifted_by_k(RefVector polynomials, const size_t shift_magnitude) + { + ASSERT(k_shift_magnitude % 2 == 0); // k must be even for the formulas herein to be valid + to_be_shifted_by_k = polynomials; + k_shift_magnitude = shift_magnitude; + } // Initialize the random polynomial used to add randomness to the batched polynomials for ZK void set_random_polynomial(Polynomial&& random) @@ -169,19 +182,26 @@ template class GeminiProver_ { // if necessary, add randomness to the full batched polynomial for ZK if (has_random_polynomial) { - full_batched += random_polynomial; + full_batched += random_polynomial; // A₀ += rand } // compute the linear combination F of the unshifted polynomials if (has_unshifted()) { batch(batched_unshifted, unshifted); - full_batched += batched_unshifted; // A₀ = F + full_batched += batched_unshifted; // A₀ += F } // compute the linear combination G of the to-be-shifted polynomials if (has_to_be_shifted_by_one()) { batch(batched_to_be_shifted_by_one, to_be_shifted_by_one); - full_batched += batched_to_be_shifted_by_one.shifted(); // A₀ = F + G/X + full_batched += batched_to_be_shifted_by_one.shifted(); // A₀ += G/X + } + + // compute the linear combination H of the to-be-shifted-by-k polynomials + if (has_to_be_shifted_by_k()) { + batched_to_be_shifted_by_k = Polynomial(full_batched_size - k_shift_magnitude, full_batched_size, 0); + batch(batched_to_be_shifted_by_k, to_be_shifted_by_k); + full_batched += batched_to_be_shifted_by_k.right_shifted(k_shift_magnitude); // A₀ += X^k * H } return full_batched; @@ -206,14 +226,20 @@ template class GeminiProver_ { A_0_pos += batched_unshifted; // A₀₊ += F } + if (has_to_be_shifted_by_k()) { + Fr r_pow_k = r_challenge.pow(k_shift_magnitude); // r^k + batched_to_be_shifted_by_k *= r_pow_k; + A_0_pos += batched_to_be_shifted_by_k; // A₀₊ += r^k * H + } + Polynomial A_0_neg = A_0_pos; if (has_to_be_shifted_by_one()) { Fr r_inv = r_challenge.invert(); // r⁻¹ batched_to_be_shifted_by_one *= r_inv; // G = G/r - A_0_pos += batched_to_be_shifted_by_one; // A₀₊ = F + G/r - A_0_neg -= batched_to_be_shifted_by_one; // A₀₋ = F - G/r + A_0_pos += batched_to_be_shifted_by_one; // A₀₊ += G/r + A_0_neg -= batched_to_be_shifted_by_one; // A₀₋ -= G/r } return { A_0_pos, A_0_neg }; @@ -252,6 +278,7 @@ template class GeminiVerifier_ { using Fr = typename Curve::ScalarField; using GroupElement = typename Curve::Element; using Commitment = typename Curve::AffineElement; + using ClaimBatcher = ClaimBatcher_; public: /** @@ -268,10 +295,7 @@ template class GeminiVerifier_ { */ static std::vector> reduce_verification( std::span multilinear_challenge, - RefSpan unshifted_evaluations, - RefSpan shifted_evaluations, - RefSpan unshifted_commitments, - RefSpan to_be_shifted_commitments, + ClaimBatcher& claim_batcher, auto& transcript, const std::vector>& concatenation_group_commitments = {}, RefSpan concatenated_evaluations = {}) @@ -288,13 +312,15 @@ template class GeminiVerifier_ { Fr batched_evaluation = Fr(0); Fr batching_scalar = Fr(1); - for (auto [eval, comm] : zip_view(unshifted_evaluations, unshifted_commitments)) { + for (auto [eval, comm] : + zip_view(claim_batcher.get_unshifted().evaluations, claim_batcher.get_unshifted().commitments)) { batched_evaluation += eval * batching_scalar; batched_commitment_unshifted += comm * batching_scalar; batching_scalar *= rho; } - for (auto [eval, comm] : zip_view(shifted_evaluations, to_be_shifted_commitments)) { + for (auto [eval, comm] : + zip_view(claim_batcher.get_shifted().evaluations, claim_batcher.get_shifted().commitments)) { batched_evaluation += eval * batching_scalar; batched_commitment_to_be_shifted += comm * batching_scalar; batching_scalar *= rho; diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp index 8d93f1ec5b6..060db23f561 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp @@ -8,7 +8,6 @@ using namespace bb; template class GeminiTest : public CommitmentTest { using GeminiProver = GeminiProver_; - using PolynomialBatcher = GeminiProver::PolynomialBatcher; using GeminiVerifier = GeminiVerifier_; using Fr = typename Curve::ScalarField; using Commitment = typename Curve::AffineElement; @@ -30,7 +29,7 @@ template class GeminiTest : public CommitmentTest { } void execute_gemini_and_verify_claims(std::vector& multilinear_evaluation_point, - MockWitnessGenerator instance_witness) + MockClaimGenerator mock_claims) { auto prover_transcript = NativeTranscript::prover_init_empty(); @@ -38,7 +37,7 @@ template class GeminiTest : public CommitmentTest { // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1 // - (d+1) Fold polynomials Fold_{r}^(0), Fold_{-r}^(0), and Fold^(i), i = 0, ..., d-1 auto prover_output = GeminiProver::prove( - this->n, instance_witness.polynomial_batcher, multilinear_evaluation_point, ck, prover_transcript); + this->n, mock_claims.polynomial_batcher, multilinear_evaluation_point, ck, prover_transcript); // Check that the Fold polynomials have been evaluated correctly in the prover this->verify_batch_opening_pair(prover_output); @@ -49,13 +48,8 @@ template class GeminiTest : public CommitmentTest { // - Single opening pair: {r, \hat{a}_0} // - 2 partially evaluated Fold polynomial commitments [Fold_{r}^(0)] and [Fold_{-r}^(0)] // Aggregate: d+1 opening pairs and d+1 Fold poly commitments into verifier claim - auto verifier_claims = - GeminiVerifier::reduce_verification(multilinear_evaluation_point, - RefVector(instance_witness.unshifted_evals), - RefVector(instance_witness.shifted_evals), - RefVector(instance_witness.unshifted_commitments), - RefVector(instance_witness.to_be_shifted_commitments), - verifier_transcript); + auto verifier_claims = GeminiVerifier::reduce_verification( + multilinear_evaluation_point, mock_claims.claim_batcher, verifier_transcript); // Check equality of the opening pairs computed by prover and verifier for (auto [prover_claim, verifier_claim] : zip_view(prover_output, verifier_claims)) { @@ -66,7 +60,7 @@ template class GeminiTest : public CommitmentTest { void execute_gemini_and_verify_claims_with_concatenation( std::vector& multilinear_evaluation_point, - MockWitnessGenerator instance_witness, + MockClaimGenerator mock_claims, RefSpan> concatenated_polynomials = {}, RefSpan concatenated_evaluations = {}, const std::vector>>& groups_to_be_concatenated = {}, @@ -79,7 +73,7 @@ template class GeminiTest : public CommitmentTest { // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1 // - (d+1) Fold polynomials Fold_{r}^(0), Fold_{-r}^(0), and Fold^(i), i = 0, ..., d-1 auto prover_output = GeminiProver::prove(this->n, - instance_witness.polynomial_batcher, + mock_claims.polynomial_batcher, multilinear_evaluation_point, ck, prover_transcript, @@ -95,15 +89,11 @@ template class GeminiTest : public CommitmentTest { // - Single opening pair: {r, \hat{a}_0} // - 2 partially evaluated Fold polynomial commitments [Fold_{r}^(0)] and [Fold_{-r}^(0)] // Aggregate: d+1 opening pairs and d+1 Fold poly commitments into verifier claim - auto verifier_claims = - GeminiVerifier::reduce_verification(multilinear_evaluation_point, - RefVector(instance_witness.unshifted_evals), - RefVector(instance_witness.shifted_evals), - RefVector(instance_witness.unshifted_commitments), - RefVector(instance_witness.to_be_shifted_commitments), - verifier_transcript, - concatenation_group_commitments, - concatenated_evaluations); + auto verifier_claims = GeminiVerifier::reduce_verification(multilinear_evaluation_point, + mock_claims.claim_batcher, + verifier_transcript, + concatenation_group_commitments, + concatenated_evaluations); // Check equality of the opening pairs computed by prover and verifier for (auto [prover_claim, verifier_claim] : zip_view(prover_output, verifier_claims)) { @@ -119,18 +109,20 @@ TYPED_TEST_SUITE(GeminiTest, ParamsTypes); TYPED_TEST(GeminiTest, Single) { auto u = this->random_evaluation_point(this->log_n); - auto instance_witness = MockWitnessGenerator(this->n, 1, 0, u, this->ck); + MockClaimGenerator mock_claims( + this->n, /*num_polynomials*/ 1, /*num_to_be_shifted*/ 0, /*num_to_be_right_shifted_by_k*/ 0, u, this->ck); - this->execute_gemini_and_verify_claims(u, instance_witness); + this->execute_gemini_and_verify_claims(u, mock_claims); } TYPED_TEST(GeminiTest, SingleShift) { auto u = this->random_evaluation_point(this->log_n); - auto instance_witness = MockWitnessGenerator(this->n, 0, 1, u, this->ck); + MockClaimGenerator mock_claims( + this->n, /*num_polynomials*/ 1, /*num_to_be_shifted*/ 1, /*num_to_be_right_shifted_by_k*/ 0, u, this->ck); - this->execute_gemini_and_verify_claims(u, instance_witness); + this->execute_gemini_and_verify_claims(u, mock_claims); } TYPED_TEST(GeminiTest, Double) @@ -138,9 +130,10 @@ TYPED_TEST(GeminiTest, Double) auto u = this->random_evaluation_point(this->log_n); - auto instance_witness = MockWitnessGenerator(this->n, 2, 0, u, this->ck); + MockClaimGenerator mock_claims( + this->n, /*num_polynomials*/ 2, /*num_to_be_shifted*/ 0, /*num_to_be_right_shifted_by_k*/ 0, u, this->ck); - this->execute_gemini_and_verify_claims(u, instance_witness); + this->execute_gemini_and_verify_claims(u, mock_claims); } TYPED_TEST(GeminiTest, DoubleWithShift) @@ -148,23 +141,25 @@ TYPED_TEST(GeminiTest, DoubleWithShift) auto u = this->random_evaluation_point(this->log_n); - auto instance_witness = MockWitnessGenerator(this->n, 2, 1, u, this->ck); + MockClaimGenerator mock_claims( + this->n, /*num_polynomials*/ 2, /*num_to_be_shifted*/ 1, /*num_to_be_right_shifted_by_k*/ 0, u, this->ck); - this->execute_gemini_and_verify_claims(u, instance_witness); + this->execute_gemini_and_verify_claims(u, mock_claims); } TYPED_TEST(GeminiTest, DoubleWithShiftAndConcatenation) { auto u = this->random_evaluation_point(this->log_n); - auto instance_witness = MockWitnessGenerator(this->n, 2, 0, u, this->ck); + MockClaimGenerator mock_claims( + this->n, /*num_polynomials*/ 2, /*num_to_be_shifted*/ 0, /*num_to_be_right_shifted_by_k*/ 0, u, this->ck); auto [concatenation_groups, concatenated_polynomials, c_evaluations, concatenation_groups_commitments] = generate_concatenation_inputs(u, /*num_concatenated=*/3, /*concatenation_index=*/2, this->ck); this->execute_gemini_and_verify_claims_with_concatenation( u, - instance_witness, + mock_claims, RefVector(concatenated_polynomials), RefVector(c_evaluations), to_vector_of_ref_vectors(concatenation_groups), diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp index 1f874317870..3da495da900 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp @@ -24,8 +24,8 @@ class IPATest : public CommitmentTest { using GeminiProver = GeminiProver_; using GeminiVerifier = GeminiVerifier_; using ShpleminiVerifier = ShpleminiVerifier_; - using ClaimBatcher = ShpleminiVerifier::ClaimBatcher; - using ClaimBatch = ShpleminiVerifier::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; static std::shared_ptr ck; static std::shared_ptr vk; @@ -248,7 +248,12 @@ TEST_F(IPATest, GeminiShplonkIPAWithShift) // point. auto mle_opening_point = this->random_evaluation_point(small_log_n); // sometimes denoted 'u' - auto instance_witness = MockWitnessGenerator(small_n, 2, 0, mle_opening_point, ck); + MockClaimGenerator mock_claims(small_n, + /*num_polynomials*/ 2, + /*num_to_be_shifted*/ 0, + /*num_to_be_right_shifted_by_k*/ 0, + mle_opening_point, + ck); auto prover_transcript = NativeTranscript::prover_init_empty(); @@ -257,7 +262,7 @@ TEST_F(IPATest, GeminiShplonkIPAWithShift) // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1 // - (d+1) Fold polynomials Fold_{r}^(0), Fold_{-r}^(0), and Fold^(i), i = 0, ..., d-1 auto prover_opening_claims = - GeminiProver::prove(small_n, instance_witness.polynomial_batcher, mle_opening_point, ck, prover_transcript); + GeminiProver::prove(small_n, mock_claims.polynomial_batcher, mle_opening_point, ck, prover_transcript); const auto opening_claim = ShplonkProver::prove(ck, prover_opening_claims, prover_transcript); PCS::compute_opening_proof(ck, opening_claim, prover_transcript); @@ -265,12 +270,7 @@ TEST_F(IPATest, GeminiShplonkIPAWithShift) auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript); auto gemini_verifier_claim = - GeminiVerifier::reduce_verification(mle_opening_point, - RefVector(instance_witness.unshifted_evals), - RefVector(instance_witness.shifted_evals), - RefVector(instance_witness.unshifted_commitments), - RefVector(instance_witness.to_be_shifted_commitments), - verifier_transcript); + GeminiVerifier::reduce_verification(mle_opening_point, mock_claims.claim_batcher, verifier_transcript); const auto shplonk_verifier_claim = ShplonkVerifier::reduce_verification(vk->get_g1_identity(), gemini_verifier_claim, verifier_transcript); @@ -283,7 +283,12 @@ TEST_F(IPATest, ShpleminiIPAWithShift) // Generate multilinear polynomials, their commitments (genuine and mocked) and evaluations (genuine) at a random // point. auto mle_opening_point = this->random_evaluation_point(small_log_n); // sometimes denoted 'u' - auto instance_witness = MockWitnessGenerator(small_n, 2, 0, mle_opening_point, ck); + MockClaimGenerator mock_claims(small_n, + /*num_polynomials*/ 2, + /*num_to_be_shifted*/ 0, + /*num_to_be_right_shifted_by_k*/ 0, + mle_opening_point, + ck); auto prover_transcript = NativeTranscript::prover_init_empty(); // Run the full prover PCS protocol: @@ -292,14 +297,14 @@ TEST_F(IPATest, ShpleminiIPAWithShift) // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1 // - (d+1) Fold polynomials Fold_{r}^(0), Fold_{-r}^(0), and Fold^(i), i = 0, ..., d-1 auto prover_opening_claims = - GeminiProver::prove(small_n, instance_witness.polynomial_batcher, mle_opening_point, ck, prover_transcript); + GeminiProver::prove(small_n, mock_claims.polynomial_batcher, mle_opening_point, ck, prover_transcript); const auto opening_claim = ShplonkProver::prove(ck, prover_opening_claims, prover_transcript); PCS::compute_opening_proof(ck, opening_claim, prover_transcript); auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript); const auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim( - small_n, instance_witness.claim_batcher, mle_opening_point, vk->get_g1_identity(), verifier_transcript); + small_n, mock_claims.claim_batcher, mle_opening_point, vk->get_g1_identity(), verifier_transcript); auto result = PCS::reduce_verify_batch_opening_claim(batch_opening_claim, vk, verifier_transcript); // auto result = PCS::reduce_verify(vk, shplonk_verifier_claim, verifier_transcript); @@ -315,7 +320,12 @@ TEST_F(IPATest, ShpleminiIPAShiftsRemoval) // Generate multilinear polynomials, their commitments (genuine and mocked) and evaluations (genuine) at a random // point. auto mle_opening_point = this->random_evaluation_point(small_log_n); // sometimes denoted 'u' - auto instance_witness = MockWitnessGenerator(small_n, 4, 2, mle_opening_point, ck); + MockClaimGenerator mock_claims(small_n, + /*num_polynomials*/ 4, + /*num_to_be_shifted*/ 2, + /*num_to_be_right_shifted_by_k*/ 0, + mle_opening_point, + ck); auto prover_transcript = NativeTranscript::prover_init_empty(); @@ -325,7 +335,7 @@ TEST_F(IPATest, ShpleminiIPAShiftsRemoval) // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1 // - (d+1) Fold polynomials Fold_{r}^(0), Fold_{-r}^(0), and Fold^(i), i = 0, ..., d-1 auto prover_opening_claims = - GeminiProver::prove(small_n, instance_witness.polynomial_batcher, mle_opening_point, ck, prover_transcript); + GeminiProver::prove(small_n, mock_claims.polynomial_batcher, mle_opening_point, ck, prover_transcript); const auto opening_claim = ShplonkProver::prove(ck, prover_opening_claims, prover_transcript); PCS::compute_opening_proof(ck, opening_claim, prover_transcript); @@ -346,7 +356,7 @@ TEST_F(IPATest, ShpleminiIPAShiftsRemoval) auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript); const auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(small_n, - instance_witness.claim_batcher, + mock_claims.claim_batcher, mle_opening_point, vk->get_g1_identity(), verifier_transcript, diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp index 0284c50ed1e..5bac7124bcd 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp @@ -105,7 +105,12 @@ TEST_F(KZGTest, GeminiShplonkKzgWithShift) // point. std::vector mle_opening_point = random_evaluation_point(log_n); // sometimes denoted 'u' - auto instance_witness = MockWitnessGenerator(n, 2, 1, mle_opening_point, ck); + MockClaimGenerator mock_claims(n, + /*num_polynomials*/ 2, + /*num_to_be_shifted*/ 1, + /*num_to_be_right_shifted_by_k*/ 0, + mle_opening_point, + ck); auto prover_transcript = NativeTranscript::prover_init_empty(); @@ -115,7 +120,7 @@ TEST_F(KZGTest, GeminiShplonkKzgWithShift) // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1 // - (d+1) Fold polynomials Fold_{r}^(0), Fold_{-r}^(0), and Fold^(i), i = 0, ..., d-1 auto prover_opening_claims = - GeminiProver::prove(n, instance_witness.polynomial_batcher, mle_opening_point, ck, prover_transcript); + GeminiProver::prove(n, mock_claims.polynomial_batcher, mle_opening_point, ck, prover_transcript); // Shplonk prover output: // - opening pair: (z_challenge, 0) @@ -133,12 +138,7 @@ TEST_F(KZGTest, GeminiShplonkKzgWithShift) // Gemini verifier output: // - claim: d+1 commitments to Fold_{r}^(0), Fold_{-r}^(0), Fold^(l), d+1 evaluations a_0_pos, a_l, l = 0:d-1 auto gemini_verifier_claim = - GeminiVerifier::reduce_verification(mle_opening_point, - RefVector(instance_witness.unshifted_evals), - RefVector(instance_witness.shifted_evals), - RefVector(instance_witness.unshifted_commitments), - RefVector(instance_witness.to_be_shifted_commitments), - verifier_transcript); + GeminiVerifier::reduce_verification(mle_opening_point, mock_claims.claim_batcher, verifier_transcript); // Shplonk verifier claim: commitment [Q] - [Q_z], opening point (z_challenge, 0) const auto shplonk_verifier_claim = @@ -159,7 +159,12 @@ TEST_F(KZGTest, ShpleminiKzgWithShift) // point. std::vector mle_opening_point = random_evaluation_point(log_n); // sometimes denoted 'u' - auto instance_witness = MockWitnessGenerator(n, 4, 2, mle_opening_point, ck); + MockClaimGenerator mock_claims(n, + /*num_polynomials*/ 4, + /*num_to_be_shifted*/ 2, + /*num_to_be_right_shifted_by_k*/ 0, + mle_opening_point, + ck); auto prover_transcript = NativeTranscript::prover_init_empty(); @@ -169,7 +174,7 @@ TEST_F(KZGTest, ShpleminiKzgWithShift) // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1 // - (d+1) Fold polynomials Fold_{r}^(0), Fold_{-r}^(0), and Fold^(i), i = 0, ..., d-1 auto prover_opening_claims = - GeminiProver::prove(n, instance_witness.polynomial_batcher, mle_opening_point, ck, prover_transcript); + GeminiProver::prove(n, mock_claims.polynomial_batcher, mle_opening_point, ck, prover_transcript); // Shplonk prover output: // - opening pair: (z_challenge, 0) @@ -187,7 +192,7 @@ TEST_F(KZGTest, ShpleminiKzgWithShift) // Gemini verifier output: // - claim: d+1 commitments to Fold_{r}^(0), Fold_{-r}^(0), Fold^(l), d+1 evaluations a_0_pos, a_l, l = 0:d-1 const auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim( - n, instance_witness.claim_batcher, mle_opening_point, vk->get_g1_identity(), verifier_transcript); + n, mock_claims.claim_batcher, mle_opening_point, vk->get_g1_identity(), verifier_transcript); const auto pairing_points = PCS::reduce_verify_batch_opening_claim(batch_opening_claim, verifier_transcript); // Final pairing check: e([Q] - [Q_z] + z[W], [1]_2) = e([W], [x]_2) @@ -200,7 +205,12 @@ TEST_F(KZGTest, ShpleminiKzgWithShiftAndConcatenation) std::vector mle_opening_point = random_evaluation_point(log_n); // sometimes denoted 'u' // Generate multilinear polynomials, their commitments (genuine and mocked) and evaluations (genuine) at a random // point. - auto instance_witness = MockWitnessGenerator(n, 4, 2, mle_opening_point, ck); + MockClaimGenerator mock_claims(n, + /*num_polynomials*/ 4, + /*num_to_be_shifted*/ 2, + /*num_to_be_right_shifted_by_k*/ 0, + mle_opening_point, + ck); auto [concatenation_groups, concatenated_polynomials, c_evaluations, concatenation_groups_commitments] = generate_concatenation_inputs(mle_opening_point, /*num_concatenated=*/3, /*concatenation_index=*/2, ck); @@ -213,7 +223,7 @@ TEST_F(KZGTest, ShpleminiKzgWithShiftAndConcatenation) // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1 // - (d+1) Fold polynomials Fold_{r}^(0), Fold_{-r}^(0), and Fold^(i), i = 0, ..., d-1 const auto prover_opening_claims = GeminiProver::prove(n, - instance_witness.polynomial_batcher, + mock_claims.polynomial_batcher, mle_opening_point, ck, prover_transcript, @@ -237,7 +247,7 @@ TEST_F(KZGTest, ShpleminiKzgWithShiftAndConcatenation) // - claim: d+1 commitments to Fold_{r}^(0), Fold_{-r}^(0), Fold^(l), d+1 evaluations a_0_pos, a_l, l = 0:d-1 const auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(n, - instance_witness.claim_batcher, + mock_claims.claim_batcher, mle_opening_point, vk->get_g1_identity(), verifier_transcript, @@ -260,7 +270,12 @@ TEST_F(KZGTest, ShpleminiKzgShiftsRemoval) std::vector mle_opening_point = random_evaluation_point(log_n); // sometimes denoted 'u' // Generate multilinear polynomials, their commitments (genuine and mocked) and evaluations (genuine) at a random // point. - auto instance_witness = MockWitnessGenerator(n, 4, 2, mle_opening_point, ck); + MockClaimGenerator mock_claims(n, + /*num_polynomials*/ 4, + /*num_to_be_shifted*/ 2, + /*num_to_be_right_shifted_by_k*/ 0, + mle_opening_point, + ck); auto prover_transcript = NativeTranscript::prover_init_empty(); @@ -270,7 +285,7 @@ TEST_F(KZGTest, ShpleminiKzgShiftsRemoval) // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1 // - (d+1) Fold polynomials Fold_{r}^(0), Fold_{-r}^(0), and Fold^(i), i = 0, ..., d-1 const auto prover_opening_claims = - GeminiProver::prove(n, instance_witness.polynomial_batcher, mle_opening_point, ck, prover_transcript); + GeminiProver::prove(n, mock_claims.polynomial_batcher, mle_opening_point, ck, prover_transcript); // Shplonk prover output: // - opening pair: (z_challenge, 0) @@ -301,7 +316,7 @@ TEST_F(KZGTest, ShpleminiKzgShiftsRemoval) // Gemini verifier output: // - claim: d+1 commitments to Fold_{r}^(0), Fold_{-r}^(0), Fold^(l), d+1 evaluations a_0_pos, a_l, l = 0:d-1 const auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(n, - instance_witness.claim_batcher, + mock_claims.claim_batcher, mle_opening_point, vk->get_g1_identity(), verifier_transcript, diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini.hpp index 5611885640a..040c32cce97 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini.hpp @@ -1,5 +1,6 @@ #pragma once #include "barretenberg/commitment_schemes/claim.hpp" +#include "barretenberg/commitment_schemes/claim_batcher.hpp" #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/gemini/gemini_impl.hpp" #include "barretenberg/commitment_schemes/shplonk/shplonk.hpp" @@ -194,110 +195,9 @@ template class ShpleminiVerifier_ { using VK = VerifierCommitmentKey; using ShplonkVerifier = ShplonkVerifier_; using GeminiVerifier = GeminiVerifier_; + using ClaimBatcher = ClaimBatcher_; public: - struct ClaimBatch { - RefVector commitments; - RefVector evaluations; - // scalar used for batching the claims, excluding the power of batching challenge \rho - Fr scalar = 0; - }; - - /** - * @brief Logic to support batching opening claims for unshifted and shifted polynomials in Shplemini - * @details Stores references to the commitments/evaluations of unshifted and shifted polynomials to be batched - * opened via Shplemini. Aggregates the commitments and batching scalars for each batch into the corresponding - * containers for Shplemini. Computes the batched evaluation. Contains logic for computing the per-batch scalars - * used to batch each set of claims (see details below). - * @note This class performs the actual batching of the evaluations but not of the commitments. The latter are - * simply appended to a larger container, along with the scalars used to batch them. This is because Shplemini - * is optimized to perform a single batch mul that includes all commitments from each stage of the PCS. See - * description of ShpleminiVerifier for more details. - * - */ - struct ClaimBatcher { - std::optional unshifted; // commitments and evaluations of unshifted polynomials - std::optional shifted; // commitments of to-be-shifted-by-1 polys, evals of their shifts - - Fr get_unshifted_batch_scalar() const { return unshifted ? unshifted->scalar : Fr{ 0 }; } - - /** - * @brief Compute scalars used to batch each set of claims, excluding contribution from batching challenge \rho - * @details Computes scalars s_0 and s_1 given by - * \f[ - * - s_0 = \left(\frac{1}{z-r} + \nu \times \frac{1}{z+r}\right) \f], - * - s_1 = \left(\frac{1}{z-r} - \nu \times \frac{1}{z+r}\right) - * \f] - * where the scalars used to batch the claims are given by - * \f[ - * \left( - * - s_0, - * \ldots, - * - \rho^{i+k-1} \times s_0, - * - \rho^{i+k} \times \frac{1}{r} \times s_1, - * \ldots, - * - \rho^{k+m-1} \times \frac{1}{r} \times s_1 - * \right) - * \f] - * - * @param inverse_vanishing_eval_pos 1/(z-r) - * @param inverse_vanishing_eval_neg 1/(z+r) - * @param nu_challenge ν (shplonk batching challenge) - * @param r_challenge r (gemini evaluation challenge) - */ - void compute_scalars_for_each_batch(const Fr& inverse_vanishing_eval_pos, - const Fr& inverse_vanishing_eval_neg, - const Fr& nu_challenge, - const Fr& r_challenge) - { - if (unshifted) { - // (1/(z−r) + ν/(z+r)) - unshifted->scalar = inverse_vanishing_eval_pos + nu_challenge * inverse_vanishing_eval_neg; - } - if (shifted) { - // r⁻¹ ⋅ (1/(z−r) − ν/(z+r)) - shifted->scalar = - r_challenge.invert() * (inverse_vanishing_eval_pos - nu_challenge * inverse_vanishing_eval_neg); - } - } - - /** - * @brief Append the commitments and scalars from each batch of claims to the Shplemini batch mul input vectors; - * update the batched evaluation and the running batching challenge (power of rho) in place. - * - * @param commitments commitment inputs to the single Shplemini batch mul - * @param scalars scalar inputs to the single Shplemini batch mul - * @param batched_evaluation running batched evaluation of the committed multilinear polynomials - * @param rho multivariate batching challenge \rho - * @param rho_power current power of \rho used in the batching scalar - */ - void update_batch_mul_inputs_and_batched_evaluation(std::vector& commitments, - std::vector& scalars, - Fr& batched_evaluation, - const Fr& rho, - Fr& rho_power) - { - // Append the commitments/scalars from a given batch to the corresponding containers; update the batched - // evaluation and the running batching challenge in place - auto aggregate_claim_data_and_update_batched_evaluation = [&](const ClaimBatch& batch, Fr& rho_power) { - for (auto [commitment, evaluation] : zip_view(batch.commitments, batch.evaluations)) { - commitments.emplace_back(std::move(commitment)); - scalars.emplace_back(-batch.scalar * rho_power); - batched_evaluation += evaluation * rho_power; - rho_power *= rho; - } - }; - - // Incorporate the claim data from each batch of claims that is present - if (unshifted) { - aggregate_claim_data_and_update_batched_evaluation(*unshifted, rho_power); - } - if (shifted) { - aggregate_claim_data_and_update_batched_evaluation(*shifted, rho_power); - } - } - }; - template static BatchOpeningClaim compute_batch_opening_claim( const Fr N, @@ -391,8 +291,8 @@ template class ShpleminiVerifier_ { // Compute the additional factors to be multiplied with unshifted and shifted commitments when lazily // reconstructing the commitment of Q_z - claim_batcher.compute_scalars_for_each_batch(inverse_vanishing_evals[0], - inverse_vanishing_evals[1], + claim_batcher.compute_scalars_for_each_batch(inverse_vanishing_evals[0], // 1/(z − r) + inverse_vanishing_evals[1], // 1/(z + r) shplonk_batching_challenge, gemini_evaluation_challenge); diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini.test.cpp index aa79bf451c7..eeb5b0fbb59 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini.test.cpp @@ -23,9 +23,11 @@ template class ShpleminiTest : public CommitmentTestrandom_evaluation_point(this->log_n); - auto pcs_instance_witness = - MockWitnessGenerator(this->n, this->num_polynomials, this->num_shiftable, mle_opening_point, ck); + MockClaimGenerator mock_claims(this->n, + /*num_polynomials*/ this->num_polynomials, + /*num_to_be_shifted*/ this->num_shiftable, + /*num_to_be_right_shifted_by_k*/ this->num_right_shiftable_by_k, + mle_opening_point, + ck); // Collect multilinear evaluations std::vector rhos = gemini::powers_of_rho(rho, this->num_polynomials + this->num_shiftable); - // Compute batched multivariate evaluation - Fr batched_evaluation = Fr(0); - size_t idx = 0; - for (auto& eval : pcs_instance_witness.unshifted_evals) { - batched_evaluation += eval * rhos[idx]; - idx++; - } - - for (auto& eval : pcs_instance_witness.shifted_evals) { - batched_evaluation += eval * rhos[idx]; - idx++; - } + // Lambda to compute batched multivariate evaluation + auto update_batched_eval = [&](Fr& batched_eval, const std::vector& evaluations, Fr& rho_power) { + for (auto& eval : evaluations) { + batched_eval += eval * rho_power; + rho_power *= rho; + } + }; + + Fr rho_power(1); + Fr batched_evaluation(0); + update_batched_eval(batched_evaluation, mock_claims.unshifted.evals, rho_power); + update_batched_eval(batched_evaluation, mock_claims.to_be_shifted.evals, rho_power); + update_batched_eval(batched_evaluation, mock_claims.to_be_right_shifted_by_k.evals, rho_power); + + // Lambda to compute batched commitment + auto compute_batched_commitment = [&](const std::vector& commitments, Fr& rho_power) { + GroupElement batched = GroupElement::zero(); + for (auto& comm : commitments) { + batched += comm * rho_power; + rho_power *= rho; + } + return batched; + }; // Compute batched commitments manually - idx = 0; - GroupElement batched_commitment_unshifted = GroupElement::zero(); - for (auto& comm : pcs_instance_witness.unshifted_commitments) { - batched_commitment_unshifted += comm * rhos[idx]; - idx++; - } - - GroupElement batched_commitment_to_be_shifted = GroupElement::zero(); - for (auto& comm : pcs_instance_witness.to_be_shifted_commitments) { - batched_commitment_to_be_shifted += comm * rhos[idx]; - idx++; - } + rho_power = Fr(1); + GroupElement batched_commitment_unshifted = + compute_batched_commitment(mock_claims.unshifted.commitments, rho_power); + GroupElement batched_commitment_to_be_shifted = + compute_batched_commitment(mock_claims.to_be_shifted.commitments, rho_power); + GroupElement batched_commitment_to_be_right_shifted_by_k = + compute_batched_commitment(mock_claims.to_be_right_shifted_by_k.commitments, rho_power); // Compute expected result manually - GroupElement commitment_to_univariate = - batched_commitment_unshifted + batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); + GroupElement to_be_right_shifted_by_k_contribution = + batched_commitment_to_be_right_shifted_by_k * + gemini_eval_challenge.pow(mock_claims.claim_batcher.k_shift_magnitude); + GroupElement to_be_shifted_contribution = batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); + + GroupElement commitment_to_univariate_pos = + batched_commitment_unshifted + to_be_right_shifted_by_k_contribution + to_be_shifted_contribution; + GroupElement commitment_to_univariate_neg = - batched_commitment_unshifted - batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); + batched_commitment_unshifted + to_be_right_shifted_by_k_contribution - to_be_shifted_contribution; GroupElement expected_result = - commitment_to_univariate * (shplonk_eval_challenge - gemini_eval_challenge).invert() + + commitment_to_univariate_pos * (shplonk_eval_challenge - gemini_eval_challenge).invert() + commitment_to_univariate_neg * (shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert()); @@ -145,18 +163,18 @@ TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching) Fr inverted_vanishing_eval_pos = (shplonk_eval_challenge - gemini_eval_challenge).invert(); Fr inverted_vanishing_eval_neg = (shplonk_eval_challenge + gemini_eval_challenge).invert(); - pcs_instance_witness.claim_batcher.compute_scalars_for_each_batch( + mock_claims.claim_batcher.compute_scalars_for_each_batch( inverted_vanishing_eval_pos, inverted_vanishing_eval_neg, shplonk_batching_challenge, gemini_eval_challenge); ShpleminiVerifier::batch_multivariate_opening_claims( - pcs_instance_witness.claim_batcher, rho, commitments, scalars, verifier_batched_evaluation); + mock_claims.claim_batcher, rho, commitments, scalars, verifier_batched_evaluation); // Final pairing check GroupElement shplemini_result = batch_mul_native(commitments, scalars); EXPECT_EQ(commitments.size(), - pcs_instance_witness.unshifted_commitments.size() + - pcs_instance_witness.to_be_shifted_commitments.size()); + mock_claims.unshifted.commitments.size() + mock_claims.to_be_shifted.commitments.size() + + mock_claims.to_be_right_shifted_by_k.commitments.size()); EXPECT_EQ(batched_evaluation, verifier_batched_evaluation); EXPECT_EQ(-expected_result, shplemini_result); } @@ -164,7 +182,6 @@ TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching) { using Curve = TypeParam::Curve; using GeminiProver = GeminiProver_; - using PolynomialBatcher = GeminiProver::PolynomialBatcher; using ShpleminiVerifier = ShpleminiVerifier_; using ShplonkVerifier = ShplonkVerifier_; using Fr = typename Curve::ScalarField; @@ -183,18 +200,18 @@ TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching) std::vector mle_opening_point = this->random_evaluation_point(this->log_n); - auto pcs_instance_witness = - MockWitnessGenerator(this->n, this->num_polynomials, this->num_shiftable, mle_opening_point, ck); + MockClaimGenerator mock_claims(this->n, + /*num_polynomials*/ this->num_polynomials, + /*num_to_be_shifted*/ this->num_shiftable, + /*num_to_be_right_shifted_by_k*/ this->num_right_shiftable_by_k, + mle_opening_point, + ck); // Collect multilinear evaluations std::vector rhos = gemini::powers_of_rho(rho, this->num_polynomials + this->num_shiftable); - PolynomialBatcher polynomial_batcher(this->n); - polynomial_batcher.set_unshifted(RefVector(pcs_instance_witness.unshifted_polynomials)); - polynomial_batcher.set_to_be_shifted_by_one(RefVector(pcs_instance_witness.to_be_shifted_polynomials)); - Fr running_scalar = Fr(1); - Polynomial batched = polynomial_batcher.compute_batched(rho, running_scalar); + Polynomial batched = mock_claims.polynomial_batcher.compute_batched(rho, running_scalar); // Compute: // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1 @@ -208,7 +225,7 @@ TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching) } auto [A_0_pos, A_0_neg] = GeminiProver::compute_partially_evaluated_batch_polynomials( - this->log_n, polynomial_batcher, gemini_eval_challenge); + this->log_n, mock_claims.polynomial_batcher, gemini_eval_challenge); const auto opening_claims = GeminiProver::construct_univariate_opening_claims( this->log_n, std::move(A_0_pos), std::move(A_0_neg), std::move(fold_polynomials), gemini_eval_challenge); @@ -272,7 +289,6 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKNoSumcheckOpenings) using Fr = typename Curve::ScalarField; using Commitment = typename Curve::AffineElement; using CK = typename TypeParam::CommitmentKey; - using PolynomialBatcher = GeminiProver_::PolynomialBatcher; // Initialize transcript and commitment key auto prover_transcript = TypeParam::Transcript::prover_init_empty(); @@ -291,8 +307,12 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKNoSumcheckOpenings) const_size_mle_opening_point.begin() + this->log_n); // Generate random prover polynomials, compute their evaluations and commitments - MockWitnessGenerator pcs_instance_witness( - this->n, this->num_polynomials, this->num_shiftable, mle_opening_point, ck); + MockClaimGenerator mock_claims(this->n, + /*num_polynomials*/ this->num_polynomials, + /*num_to_be_shifted*/ this->num_shiftable, + /*num_to_be_right_shifted_by_k*/ this->num_right_shiftable_by_k, + mle_opening_point, + ck); // Compute the sum of the Libra constant term and Libra univariates evaluated at Sumcheck challenges const Fr claimed_inner_product = SmallSubgroupIPAProver::compute_claimed_inner_product( @@ -304,13 +324,9 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKNoSumcheckOpenings) SmallSubgroupIPAProver small_subgroup_ipa_prover( zk_sumcheck_data, const_size_mle_opening_point, claimed_inner_product, prover_transcript, ck); - PolynomialBatcher polynomial_batcher(this->n); - polynomial_batcher.set_unshifted(RefVector(pcs_instance_witness.unshifted_polynomials)); - polynomial_batcher.set_to_be_shifted_by_one(RefVector(pcs_instance_witness.to_be_shifted_polynomials)); - // Reduce to KZG or IPA based on the curve used in the test Flavor const auto opening_claim = ShpleminiProver::prove(this->n, - polynomial_batcher, + mock_claims.polynomial_batcher, const_size_mle_opening_point, ck, prover_transcript, @@ -350,7 +366,7 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKNoSumcheckOpenings) // Run Shplemini const auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(this->n, - pcs_instance_witness.claim_batcher, + mock_claims.claim_batcher, const_size_mle_opening_point, this->vk()->get_g1_identity(), verifier_transcript, @@ -387,7 +403,6 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKWithSumcheckOpenings) using ShpleminiProver = ShpleminiProver_; using ShpleminiVerifier = ShpleminiVerifier_; - using PolynomialBatcher = GeminiProver_::PolynomialBatcher; std::shared_ptr ck = create_commitment_key(4096); @@ -400,10 +415,10 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKWithSumcheckOpenings) // Generate masking polynomials for Sumcheck Round Univariates ZKSumcheckData zk_sumcheck_data(this->log_n, prover_transcript, ck); // Generate mock witness - MockWitnessGenerator pcs_instance_witness(this->n, 1); + MockClaimGenerator mock_claims(this->n, 1); // Generate valid sumcheck polynomials of given length - pcs_instance_witness.template compute_sumcheck_opening_data( + mock_claims.template compute_sumcheck_opening_data( this->n, this->log_n, this->sumcheck_univariate_length, challenge, ck); // Compute the sum of the Libra constant term and Libra univariates evaluated at Sumcheck challenges @@ -416,19 +431,15 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKWithSumcheckOpenings) SmallSubgroupIPAProver small_subgroup_ipa_prover( zk_sumcheck_data, challenge, claimed_inner_product, prover_transcript, ck); - PolynomialBatcher polynomial_batcher(this->n); - polynomial_batcher.set_unshifted(RefVector(pcs_instance_witness.unshifted_polynomials)); - polynomial_batcher.set_to_be_shifted_by_one(RefVector(pcs_instance_witness.to_be_shifted_polynomials)); - // Reduce proving to a single claimed fed to KZG or IPA const auto opening_claim = ShpleminiProver::prove(this->n, - polynomial_batcher, + mock_claims.polynomial_batcher, challenge, ck, prover_transcript, small_subgroup_ipa_prover.get_witness_polynomials(), - pcs_instance_witness.round_univariates, - pcs_instance_witness.sumcheck_evaluations); + mock_claims.round_univariates, + mock_claims.sumcheck_evaluations); if constexpr (std::is_same_v) { IPA::compute_opening_proof(this->ck(), opening_claim, prover_transcript); @@ -460,19 +471,18 @@ TYPED_TEST(ShpleminiTest, ShpleminiZKWithSumcheckOpenings) bool consistency_checked = true; // Run Shplemini - const auto batch_opening_claim = - ShpleminiVerifier::compute_batch_opening_claim(this->n, - pcs_instance_witness.claim_batcher, - challenge, - this->vk()->get_g1_identity(), - verifier_transcript, - {}, - true, - &consistency_checked, - libra_commitments, - libra_evaluation, - pcs_instance_witness.sumcheck_commitments, - pcs_instance_witness.sumcheck_evaluations); + const auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(this->n, + mock_claims.claim_batcher, + challenge, + this->vk()->get_g1_identity(), + verifier_transcript, + {}, + true, + &consistency_checked, + libra_commitments, + libra_evaluation, + mock_claims.sumcheck_commitments, + mock_claims.sumcheck_evaluations); // Verify claim using KZG or IPA if constexpr (std::is_same_v) { auto result = diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/mock_witness_generator.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/mock_witness_generator.hpp index d0740f21bdd..d9603643861 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/mock_witness_generator.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/utils/mock_witness_generator.hpp @@ -13,24 +13,30 @@ namespace bb { * * @tparam Curve */ -template struct MockWitnessGenerator { +template struct MockClaimGenerator { public: using CommitmentKey = bb::CommitmentKey; using Fr = typename Curve::ScalarField; using Commitment = typename Curve::AffineElement; using Polynomial = bb::Polynomial; using PolynomialBatcher = bb::GeminiProver_::PolynomialBatcher; - using ClaimBatcher = bb::ShpleminiVerifier_::ClaimBatcher; - using ClaimBatch = bb::ShpleminiVerifier_::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; std::shared_ptr ck; - std::vector unshifted_polynomials = {}; - std::vector to_be_shifted_polynomials; + + struct ClaimData { + std::vector polys; + std::vector commitments; + std::vector evals; + }; + + ClaimData unshifted; + ClaimData to_be_shifted; + ClaimData to_be_right_shifted_by_k; + std::vector const_size_mle_opening_point; - std::vector unshifted_commitments = {}; - std::vector to_be_shifted_commitments; - std::vector unshifted_evals = {}; - std::vector shifted_evals; + PolynomialBatcher polynomial_batcher; ClaimBatcher claim_batcher; @@ -39,71 +45,87 @@ template struct MockWitnessGenerator { std::vector sumcheck_commitments; std::vector> sumcheck_evaluations; - MockWitnessGenerator(const size_t n, - const size_t num_polynomials, - const size_t num_shiftable, - const std::vector& mle_opening_point, - std::shared_ptr& commitment_key) + static constexpr size_t k_magnitude = 6; // mock shift magnitude for right-shift-by-k (assumed even) + + /** + * @brief Construct claim data for a set of random polynomials with the specified type + * @note All to-be-shifted polynomials have an unshifted counterpart so the total number of claims is + * num_polynomials + num_to_be_shifted + * + * @param poly_size size of mock polynomials + * @param num_polynomials total number of unique polynomials + * @param num_to_be_shifted number of polynomials to-be-shifted + * @param mle_opening_point + * @param commitment_key + */ + MockClaimGenerator(const size_t poly_size, + const size_t num_polynomials, + const size_t num_to_be_shifted, + const size_t num_to_be_right_shifted_by_k, + const std::vector& mle_opening_point, + std::shared_ptr& commitment_key) : ck(commitment_key) // Initialize the commitment key - , unshifted_polynomials(num_polynomials) - , to_be_shifted_polynomials(num_shiftable) - , polynomial_batcher(n) - - { - construct_instance_and_witnesses(n, mle_opening_point); - } + , polynomial_batcher(poly_size) - void construct_instance_and_witnesses(size_t n, const std::vector& mle_opening_point) { - - const size_t num_unshifted = unshifted_polynomials.size() - to_be_shifted_polynomials.size(); - - // Constructs polynomials that are not shifted - if (!unshifted_polynomials.empty()) { - for (size_t idx = 0; idx < num_unshifted; idx++) { - unshifted_polynomials[idx] = Polynomial::random(n); - unshifted_commitments.push_back(ck->commit(unshifted_polynomials[idx])); - unshifted_evals.push_back(unshifted_polynomials[idx].evaluate_mle(mle_opening_point)); - } + const size_t total_num_to_be_shifted = num_to_be_shifted + num_to_be_right_shifted_by_k; + ASSERT(num_polynomials >= total_num_to_be_shifted); + const size_t num_not_to_be_shifted = num_polynomials - total_num_to_be_shifted; + + // Construct claim data for polynomials that are NOT to be shifted + for (size_t idx = 0; idx < num_not_to_be_shifted; idx++) { + Polynomial poly = Polynomial::random(poly_size); + unshifted.commitments.push_back(ck->commit(poly)); + unshifted.evals.push_back(poly.evaluate_mle(mle_opening_point)); + unshifted.polys.push_back(std::move(poly)); } - // Constructs polynomials that are being shifted - for (auto& poly : to_be_shifted_polynomials) { - poly = Polynomial::random(n, /*shiftable*/ 1); - const Commitment comm = this->ck->commit(poly); - to_be_shifted_commitments.push_back(comm); - shifted_evals.push_back(poly.evaluate_mle(mle_opening_point, true)); + // Construct claim data for polynomials that are to-be-shifted + for (size_t idx = 0; idx < num_to_be_shifted; idx++) { + Polynomial poly = Polynomial::random(poly_size, /*shiftable*/ 1); + Commitment commitment = ck->commit(poly); + to_be_shifted.commitments.push_back(commitment); + to_be_shifted.evals.push_back(poly.shifted().evaluate_mle(mle_opening_point)); + to_be_shifted.polys.push_back(poly.share()); + // Populate the unshifted counterpart in the unshifted claims + unshifted.commitments.push_back(commitment); + unshifted.evals.push_back(poly.evaluate_mle(mle_opening_point)); + unshifted.polys.push_back(std::move(poly)); } - size_t idx = num_unshifted; - - // Add unshifted evaluations of shiftable polynomials - if (!unshifted_polynomials.empty()) { - for (const auto& [poly, comm] : zip_view(to_be_shifted_polynomials, to_be_shifted_commitments)) { - unshifted_polynomials[idx] = poly; - unshifted_commitments.push_back(comm); - unshifted_evals.push_back(poly.evaluate_mle(mle_opening_point)); - idx++; - } + // Construct claim data for polynomials that are to-be-right-shifted-by-k + for (size_t idx = 0; idx < num_to_be_right_shifted_by_k; idx++) { + Polynomial poly = Polynomial::random(poly_size - k_magnitude, poly_size, 0); + Commitment commitment = ck->commit(poly); + to_be_right_shifted_by_k.commitments.push_back(commitment); + to_be_right_shifted_by_k.evals.push_back(poly.right_shifted(k_magnitude).evaluate_mle(mle_opening_point)); + to_be_right_shifted_by_k.polys.push_back(poly.share()); + // Populate the unshifted counterpart in the unshifted claims + unshifted.commitments.push_back(commitment); + unshifted.evals.push_back(poly.evaluate_mle(mle_opening_point)); + unshifted.polys.push_back(std::move(poly)); } - polynomial_batcher.set_unshifted(RefVector(unshifted_polynomials)); - polynomial_batcher.set_to_be_shifted_by_one(RefVector(to_be_shifted_polynomials)); + polynomial_batcher.set_unshifted(RefVector(unshifted.polys)); + polynomial_batcher.set_to_be_shifted_by_one(RefVector(to_be_shifted.polys)); + polynomial_batcher.set_to_be_shifted_by_k(RefVector(to_be_right_shifted_by_k.polys), k_magnitude); claim_batcher = - ClaimBatcher{ .unshifted = ClaimBatch{ RefVector(unshifted_commitments), RefVector(unshifted_evals) }, - .shifted = ClaimBatch{ RefVector(to_be_shifted_commitments), RefVector(shifted_evals) } }; + ClaimBatcher{ .unshifted = ClaimBatch{ RefVector(unshifted.commitments), RefVector(unshifted.evals) }, + .shifted = ClaimBatch{ RefVector(to_be_shifted.commitments), RefVector(to_be_shifted.evals) }, + .right_shifted_by_k = ClaimBatch{ RefVector(to_be_right_shifted_by_k.commitments), + RefVector(to_be_right_shifted_by_k.evals) }, + .k_shift_magnitude = k_magnitude }; } // Generate zero polynomials to test edge cases in PCS - MockWitnessGenerator(const size_t n, const size_t num_zero_polynomials) - : unshifted_polynomials(num_zero_polynomials) - , polynomial_batcher(n) + MockClaimGenerator(const size_t n, const size_t num_zero_polynomials) + : polynomial_batcher(n) { for (size_t idx = 0; idx < num_zero_polynomials; idx++) { - unshifted_polynomials[idx] = Polynomial(n); - unshifted_commitments.push_back(Commitment::infinity()); - unshifted_evals.push_back(Fr(0)); + unshifted.polys.emplace_back(n); + unshifted.commitments.push_back(Commitment::infinity()); + unshifted.evals.push_back(Fr(0)); } } diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp index b38c38f94bd..221e5cebc4d 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp @@ -5,6 +5,7 @@ #include "barretenberg/commitment_schemes/ipa/ipa.hpp" #include "barretenberg/commitment_schemes/kzg/kzg.hpp" #include "barretenberg/commitment_schemes/shplonk/shplonk.hpp" +#include "barretenberg/commitment_schemes/utils/mock_witness_generator.hpp" #include "barretenberg/srs/global_crs.hpp" #include "barretenberg/stdlib/primitives/curves/bn254.hpp" #include "barretenberg/stdlib/primitives/curves/grumpkin.hpp" @@ -30,7 +31,6 @@ TEST(ShpleminiRecursionTest, ProveAndVerifySingle) using Curve = typename stdlib::bn254; using NativeCurve = typename Curve::NativeCurve; using Commitment = typename Curve::AffineElement; - using NativeCommitment = typename Curve::AffineElementNative; using NativeCurve = typename Curve::NativeCurve; using NativePCS = std::conditional_t, KZG, IPA>; using CommitmentKey = typename NativePCS::CK; @@ -38,61 +38,32 @@ TEST(ShpleminiRecursionTest, ProveAndVerifySingle) using ShpleminiVerifier = ShpleminiVerifier_; using Fr = typename Curve::ScalarField; using NativeFr = typename Curve::NativeCurve::ScalarField; - using Polynomial = bb::Polynomial; using Transcript = bb::BaseTranscript>; - using PolynomialBatcher = GeminiProver_::PolynomialBatcher; - using ClaimBatcher = ShpleminiVerifier::ClaimBatcher; - using ClaimBatch = ShpleminiVerifier::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; + using MockClaimGen = MockClaimGenerator; srs::init_crs_factory(bb::srs::get_ignition_crs_path()); auto run_shplemini = [](size_t log_circuit_size) { size_t N = 1 << log_circuit_size; - constexpr size_t NUM_UNSHIFTED = 2; - constexpr size_t NUM_SHIFTED = 1; + constexpr size_t NUM_POLYS = 5; + constexpr size_t NUM_SHIFTED = 2; + constexpr size_t NUM_RIGHT_SHIFTED_BY_K = 1; + + auto commitment_key = std::make_shared(16384); + std::vector u_challenge(log_circuit_size); for (size_t idx = 0; idx < log_circuit_size; ++idx) { u_challenge[idx] = NativeFr::random_element(&shplemini_engine); }; - // Construct some random multilinear polynomials f_i and their evaluations v_i = f_i(u) - std::vector f_polynomials; // unshifted polynomials - std::vector v_evaluations; - for (size_t i = 0; i < NUM_UNSHIFTED; ++i) { - f_polynomials.emplace_back(Polynomial::random(N, /*shiftable*/ 1)); - v_evaluations.emplace_back(f_polynomials[i].evaluate_mle(u_challenge)); - } - - // Construct some "shifted" multilinear polynomials h_i as the left-shift-by-1 of f_i - std::vector g_polynomials; // to-be-shifted polynomials - std::vector h_polynomials; // shifts of the to-be-shifted polynomials - std::vector w_evaluations; - if constexpr (NUM_SHIFTED > 0) { - for (size_t i = 0; i < NUM_SHIFTED; ++i) { - g_polynomials.emplace_back(f_polynomials[i]); - h_polynomials.emplace_back(g_polynomials[i].shifted()); - w_evaluations.emplace_back(f_polynomials[i].evaluate_mle(u_challenge, true)); - } - } - // Compute commitments [f_i] - std::vector f_commitments; - auto commitment_key = std::make_shared(16384); - for (size_t i = 0; i < NUM_UNSHIFTED; ++i) { - f_commitments.emplace_back(commitment_key->commit(f_polynomials[i])); - } - // Construct container of commitments of the "to-be-shifted" polynomials [g_i] (= [f_i]) - std::vector g_commitments; - for (size_t i = 0; i < NUM_SHIFTED; ++i) { - g_commitments.emplace_back(f_commitments[i]); - } - - PolynomialBatcher polynomial_batcher(N); - polynomial_batcher.set_unshifted(RefVector(f_polynomials)); - polynomial_batcher.set_to_be_shifted_by_one(RefVector(g_polynomials)); + // Construct mock multivariate polynomial opening claims + MockClaimGen mock_claims(N, NUM_POLYS, NUM_SHIFTED, NUM_RIGHT_SHIFTED_BY_K, u_challenge, commitment_key); // Initialize an empty NativeTranscript auto prover_transcript = NativeTranscript::prover_init_empty(); auto prover_opening_claims = - ShpleminiProver::prove(N, polynomial_batcher, u_challenge, commitment_key, prover_transcript); + ShpleminiProver::prove(N, mock_claims.polynomial_batcher, u_challenge, commitment_key, prover_transcript); KZG::compute_opening_proof(commitment_key, prover_opening_claims, prover_transcript); Builder builder; StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(&builder, prover_transcript->proof_data); @@ -118,10 +89,16 @@ TEST(ShpleminiRecursionTest, ProveAndVerifySingle) }); return elements_in_circuit; }; - auto stdlib_f_commitments = commitments_to_witnesses(f_commitments); - auto stdlib_g_commitments = commitments_to_witnesses(g_commitments); - auto stdlib_v_evaluations = elements_to_witness(v_evaluations); - auto stdlib_w_evaluations = elements_to_witness(w_evaluations); + auto stdlib_unshifted_commitments = + commitments_to_witnesses(mock_claims.claim_batcher.get_unshifted().commitments); + auto stdlib_to_be_shifted_commitments = + commitments_to_witnesses(mock_claims.claim_batcher.get_shifted().commitments); + auto stdlib_to_be_right_shifted_commitments = + commitments_to_witnesses(mock_claims.claim_batcher.get_right_shifted_by_k().commitments); + auto stdlib_unshifted_evaluations = elements_to_witness(mock_claims.claim_batcher.get_unshifted().evaluations); + auto stdlib_shifted_evaluations = elements_to_witness(mock_claims.claim_batcher.get_shifted().evaluations); + auto stdlib_right_shifted_evaluations = + elements_to_witness(mock_claims.claim_batcher.get_right_shifted_by_k().evaluations); std::vector u_challenge_in_circuit; u_challenge_in_circuit.reserve(CONST_PROOF_SIZE_LOG_N); @@ -138,8 +115,11 @@ TEST(ShpleminiRecursionTest, ProveAndVerifySingle) }); ClaimBatcher claim_batcher{ - .unshifted = ClaimBatch{ RefVector(stdlib_f_commitments), RefVector(stdlib_v_evaluations) }, - .shifted = ClaimBatch{ RefVector(stdlib_g_commitments), RefVector(stdlib_w_evaluations) } + .unshifted = ClaimBatch{ RefVector(stdlib_unshifted_commitments), RefVector(stdlib_unshifted_evaluations) }, + .shifted = ClaimBatch{ RefVector(stdlib_to_be_shifted_commitments), RefVector(stdlib_shifted_evaluations) }, + .right_shifted_by_k = ClaimBatch{ RefVector(stdlib_to_be_right_shifted_commitments), + RefVector(stdlib_right_shifted_evaluations) }, + .k_shift_magnitude = MockClaimGen::k_magnitude }; const auto opening_claim = ShpleminiVerifier::compute_batch_opening_claim(Fr::from_witness(&builder, N), diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp index a1cbe3aaec0..8a7d43f880b 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_verifier.cpp @@ -14,8 +14,8 @@ bool ECCVMVerifier::verify_proof(const ECCVMProof& proof) using Shplemini = ShpleminiVerifier_; using Shplonk = ShplonkVerifier_; using OpeningClaim = OpeningClaim; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; RelationParameters relation_parameters; transcript = std::make_shared(proof.pre_ipa_proof); diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.cpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.cpp index d85fd78eb5f..7730c839586 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.cpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.cpp @@ -345,6 +345,17 @@ template Polynomial Polynomial::shifted() const return result; } +template Polynomial Polynomial::right_shifted(const size_t magnitude) const +{ + // ensure that at least the last magnitude-many coefficients are virtual 0's + ASSERT((coefficients_.end_ + magnitude) <= virtual_size()); + Polynomial result; + result.coefficients_ = coefficients_; + result.coefficients_.start_ += magnitude; + result.coefficients_.end_ += magnitude; + return result; +} + template class Polynomial; template class Polynomial; } // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp index fdb196d06f8..077bc78f85e 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp @@ -162,6 +162,12 @@ template class Polynomial { */ Polynomial shifted() const; + /** + * @brief Returns a Polynomial equal to the right-shift-by-magnitude of self. + * @note Resulting Polynomial shares the memory of that used to generate it + */ + Polynomial right_shifted(const size_t magnitude) const; + /** * @brief evaluate multi-linear extension p(X_0,…,X_{n-1}) = \sum_i a_i*L_i(X_0,…,X_{n-1}) at u = * (u_0,…,u_{n-1}) If the polynomial is embedded into a lower dimension k; + const size_t SIZE = 10; + const size_t VIRTUAL_SIZE = 20; + const size_t START_IDX = 2; + const size_t SHIFT_MAGNITUDE = 5; + auto poly = Polynomial::random(SIZE, VIRTUAL_SIZE, START_IDX); + + // Instantiate the shift via the right_shifted method + auto poly_shifted = poly.right_shifted(SHIFT_MAGNITUDE); + + EXPECT_EQ(poly_shifted.size(), poly.size()); + EXPECT_EQ(poly_shifted.virtual_size(), poly.virtual_size()); + + // The shift is indeed the shift + for (size_t i = 0; i < SIZE; ++i) { + EXPECT_EQ(poly_shifted.get(i + SHIFT_MAGNITUDE), poly.get(i)); + } + + // If I change the original polynomial, the shift is updated accordingly + poly.at(3) = 25; + for (size_t i = 0; i < SIZE; ++i) { + EXPECT_EQ(poly_shifted.get(i + SHIFT_MAGNITUDE), poly.get(i)); + } +} + // Simple test/demonstration of share functionality TEST(Polynomial, Share) { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.cpp index d7d8e00884b..101dc7067a7 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/eccvm_verifier/eccvm_recursive_verifier.cpp @@ -25,8 +25,8 @@ ECCVMRecursiveVerifier_::verify_proof(const ECCVMProof& proof) using Shplemini = ShpleminiVerifier_; using Shplonk = ShplonkVerifier_; using OpeningClaim = OpeningClaim; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; RelationParameters relation_parameters; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.cpp index 1905d90f959..ad6f36b99d8 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/decider_recursive_verifier.cpp @@ -18,8 +18,8 @@ std::array DeciderRecursiveVerifier_:: using Shplemini = ::bb::ShpleminiVerifier_; using VerifierCommitments = typename Flavor::VerifierCommitments; using Transcript = typename Flavor::Transcript; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof); transcript = std::make_shared(stdlib_proof); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp index a6967859ae1..f5bda8819bc 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/honk_verifier/ultra_recursive_verifier.cpp @@ -45,8 +45,8 @@ UltraRecursiveVerifier_::Output UltraRecursiveVerifier_::verify_ using Shplemini = ::bb::ShpleminiVerifier_; using VerifierCommitments = typename Flavor::VerifierCommitments; using Transcript = typename Flavor::Transcript; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; Output output; StdlibProof honk_proof; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp index 6b9caf746de..b0a13bb542e 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/translator_vm_verifier/translator_recursive_verifier.cpp @@ -65,8 +65,8 @@ std::array TranslatorRecursiveVerifier_; using VerifierCommitments = typename Flavor::VerifierCommitments; using CommitmentLabels = typename Flavor::CommitmentLabels; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; StdlibProof stdlib_proof = bb::convert_native_proof_to_stdlib(builder, proof); transcript->load_proof(stdlib_proof); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp index 49088ace522..fbc029c55b0 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/translator_verifier.cpp @@ -52,8 +52,8 @@ bool TranslatorVerifier::verify_proof(const HonkProof& proof) using Curve = typename Flavor::Curve; using PCS = typename Flavor::PCS; using Shplemini = ShpleminiVerifier_; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; batching_challenge_v = transcript->template get_challenge("Translation:batching_challenge"); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp index 7f5055fe9d7..3a09dd19619 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/decider_verifier.cpp @@ -40,8 +40,8 @@ template bool DeciderVerifier_::verify() using Curve = typename Flavor::Curve; using Shplemini = ShpleminiVerifier_; using VerifierCommitments = typename Flavor::VerifierCommitments; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; VerifierCommitments commitments{ accumulator->verification_key, accumulator->witness_commitments }; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp index 6af41ec7aad..9f2e6a04322 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/recursive_verifier.cpp @@ -78,8 +78,8 @@ AvmRecursiveVerifier_::AggregationObject AvmRecursiveVerifier_:: using RelationParams = ::bb::RelationParameters; using Transcript = typename Flavor::Transcript; using Shplemini = ::bb::ShpleminiVerifier_; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; transcript = std::make_shared(stdlib_proof); diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/generated/verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/generated/verifier.cpp index 5a82de706b8..3a6c8e6da99 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/generated/verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/generated/verifier.cpp @@ -45,8 +45,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vector; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; RelationParameters relation_parameters; diff --git a/barretenberg/cpp/src/barretenberg/vm2/generated/verifier.cpp b/barretenberg/cpp/src/barretenberg/vm2/generated/verifier.cpp index 5708f60727e..d90cc798f6a 100644 --- a/barretenberg/cpp/src/barretenberg/vm2/generated/verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm2/generated/verifier.cpp @@ -45,8 +45,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vector; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; RelationParameters relation_parameters; diff --git a/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs index 79dac1b3ee5..dd5f3f112f2 100644 --- a/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/recursive_verifier.cpp.hbs @@ -78,8 +78,8 @@ AvmRecursiveVerifier_::AggregationObject AvmRecursiveVerifier_:: using RelationParams = ::bb::RelationParameters; using Transcript = typename Flavor::Transcript; using Shplemini = ::bb::ShpleminiVerifier_; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; transcript = std::make_shared(stdlib_proof); diff --git a/bb-pilcom/bb-pil-backend/templates/verifier.cpp.hbs b/bb-pilcom/bb-pil-backend/templates/verifier.cpp.hbs index 9f77f234bde..28a9894940b 100644 --- a/bb-pilcom/bb-pil-backend/templates/verifier.cpp.hbs +++ b/bb-pilcom/bb-pil-backend/templates/verifier.cpp.hbs @@ -45,8 +45,8 @@ bool AvmVerifier::verify_proof(const HonkProof& proof, const std::vector; - using ClaimBatcher = Shplemini::ClaimBatcher; - using ClaimBatch = Shplemini::ClaimBatch; + using ClaimBatcher = ClaimBatcher_; + using ClaimBatch = ClaimBatcher::Batch; RelationParameters relation_parameters;