From 94339fbfc7c0c822dc1497c113d48f74a89f1bad Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 18 Sep 2024 15:51:22 +0100 Subject: [PATCH] chore: create a Gemini prover (#8622) In this PR: * make a `GeminiProver::prove` to not have to replicate all the stages of the protocol in tests (and soon in the Provers) * make the Gemini prover and verifier responsible for batching polynomials and commitments, respectively. While this is not per se part of the protocol, it does save us a lot of duplication and was implemented as part of Zeromorph as well * replace the terms `gemini_*` back to `fold_*`. Originally, I thought that having things that have a folding related naming might be confusing in the making of Protogalaxy but this data structures will not be surfaced anywhere outside the commitment_schemes folders * attempted bits of cleanup here and there --- .../commitment_key.test.hpp | 22 +--- .../commitment_schemes/gemini/gemini.cpp | 112 ++++++++++++----- .../commitment_schemes/gemini/gemini.hpp | 106 +++++++++------- .../commitment_schemes/gemini/gemini.test.cpp | 99 ++++----------- .../commitment_schemes/ipa/ipa.test.cpp | 107 ++++------------ .../commitment_schemes/kzg/kzg.test.cpp | 114 +++--------------- .../shplonk/shplemini_verifier.hpp | 12 +- .../shplonk/shplemini_verifier.test.cpp | 11 +- .../commitment_schemes/wrapper.hpp | 14 --- .../shplemini.test.cpp | 46 ++----- .../src/barretenberg/eccvm/eccvm_prover.hpp | 3 - .../barretenberg/polynomials/polynomial.hpp | 6 + .../stdlib_circuit_builders/ultra_flavor.hpp | 5 +- 13 files changed, 243 insertions(+), 414 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/commitment_schemes/wrapper.hpp diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp index 76956dd7ae9..16464cda07f 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp @@ -81,15 +81,6 @@ template class CommitmentTest : public ::testing::Test { return { x, y }; } - std::pair, Polynomial> random_claim(const size_t n) - { - auto polynomial = Polynomial::random(n); - auto opening_pair = random_eval(polynomial); - auto commitment = commit(polynomial); - auto opening_claim = OpeningClaim{ opening_pair, commitment }; - return { opening_claim, polynomial }; - }; - std::vector random_evaluation_point(const size_t num_variables) { std::vector u(num_variables); @@ -106,7 +97,6 @@ template class CommitmentTest : public ::testing::Test { Fr y_expected = witness.evaluate(x); EXPECT_EQ(y, y_expected) << "OpeningClaim: evaluations mismatch"; Commitment commitment_expected = commit(witness); - // found it EXPECT_EQ(commitment, commitment_expected) << "OpeningClaim: commitment mismatch"; } @@ -139,14 +129,12 @@ template class CommitmentTest : public ::testing::Test { * @brief Ensures that a set of opening pairs is correct by checking that evaluations are * correct by recomputing them from each witness polynomial. */ - void verify_batch_opening_pair(std::span> opening_pairs, - std::span witnesses) + void verify_batch_opening_pair(std::vector> opening_claims) { - const size_t num_pairs = opening_pairs.size(); - ASSERT_EQ(witnesses.size(), num_pairs); - - for (size_t j = 0; j < num_pairs; ++j) { - this->verify_opening_pair(opening_pairs[j], witnesses[j]); + for (auto claim : opening_claims) { + auto& [x, y] = claim.opening_pair; + Fr y_expected = claim.polynomial.evaluate(x); + EXPECT_EQ(y, y_expected) << "OpeningPair: evaluations mismatch"; } } diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp index 679857e1d66..2a9abea0c52 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp @@ -1,11 +1,6 @@ - #include "gemini.hpp" #include "barretenberg/common/thread.hpp" -#include -#include -#include - /** * @brief Protocol for opening several multi-linear polynomials at the same point. * @@ -16,7 +11,7 @@ * f₀, …, fₖ₋₁ = multilinear polynomials, * g₀, …, gₕ₋₁ = shifted multilinear polynomial, * Each gⱼ is the left-shift of some f↺ᵢ, and gⱼ points to the same memory location as fᵢ. - * v₀, …, vₖ₋₁, v↺₀, …, v↺ₕ₋₁ = multilinear evalutions s.t. fⱼ(u) = vⱼ, and gⱼ(u) = f↺ⱼ(u) = v↺ⱼ + * v₀, …, vₖ₋₁, v↺₀, …, v↺ₕ₋₁ = multilinear evalutions s.t. fⱼ(u) = vⱼ, and gⱼ(u) = f↺ⱼ(u) = v↺ⱼ * * We use a challenge ρ to create a random linear combination of all fⱼ, * and actually define A₀ = F + G↺, where @@ -43,6 +38,58 @@ * since they are linear-combinations of the commitments [fⱼ] and [gⱼ]. */ namespace bb { +template +std::vector::Claim> GeminiProver_::prove( + const std::shared_ptr>& commitment_key, + std::span multilinear_challenge, + std::span multilinear_evaluations, /* u */ + RefSpan f_polynomials, // unshifted + RefSpan g_polynomials, // to-be-shifted + std::shared_ptr& transcript) +{ + ASSERT(multilinear_evaluations.size() == f_polynomials.size() + g_polynomials.size()); + const size_t log_n = multilinear_challenge.size(); + const size_t n = 1 << log_n; + + Fr rho = transcript->template get_challenge("rho"); + std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); + + // Compute batched multivariate evaluation + Fr batched_evaluation = Fr::zero(); + for (size_t i = 0; i < rhos.size(); ++i) { + batched_evaluation += multilinear_evaluations[i] * rhos[i]; + } + + // Compute batched polynomials + Polynomial batched_unshifted(n); + Polynomial batched_to_be_shifted = Polynomial::shiftable(1 << log_n); + + const size_t num_unshifted = f_polynomials.size(); + const size_t num_to_be_shifted = g_polynomials.size(); + for (size_t i = 0; i < num_unshifted; i++) { + batched_unshifted.add_scaled(f_polynomials[i], rhos[i]); + } + for (size_t i = 0; i < num_to_be_shifted; i++) { + batched_to_be_shifted.add_scaled(g_polynomials[i], rhos[num_unshifted + i]); + } + + auto fold_polynomials = + compute_fold_polynomials(multilinear_challenge, std::move(batched_unshifted), std::move(batched_to_be_shifted)); + + for (size_t l = 0; l < log_n - 1; l++) { + transcript->send_to_verifier("Gemini:FOLD_" + std::to_string(l + 1), + commitment_key->commit(fold_polynomials[l + 2])); + } + const Fr r_challenge = transcript->template get_challenge("Gemini:r"); + std::vector claims = + compute_fold_polynomial_evaluations(multilinear_challenge, std::move(fold_polynomials), r_challenge); + + for (size_t l = 1; l <= log_n; l++) { + transcript->send_to_verifier("Gemini:a_" + std::to_string(l), claims[l].opening_pair.evaluation); + } + + return claims; +}; /** * @brief Computes d-1 fold polynomials Fold_i, i = 1, ..., d-1 @@ -53,7 +100,7 @@ namespace bb { * @return std::vector */ template -std::vector::Polynomial> GeminiProver_::compute_gemini_polynomials( +std::vector::Polynomial> GeminiProver_::compute_fold_polynomials( std::span mle_opening_point, Polynomial&& batched_unshifted, Polynomial&& batched_to_be_shifted) { const size_t num_variables = mle_opening_point.size(); // m @@ -67,12 +114,12 @@ std::vector::Polynomial> GeminiProver_::com // The first two are populated here with the batched unshifted and to-be-shifted polynomial respectively. // They will eventually contain the full batched polynomial A₀ partially evaluated at the challenges r,-r. // This function populates the other m-1 polynomials with the foldings of A₀. - std::vector gemini_polynomials; - gemini_polynomials.reserve(num_variables + 1); + std::vector fold_polynomials; + fold_polynomials.reserve(num_variables + 1); // F(X) = ∑ⱼ ρʲ fⱼ(X) and G(X) = ∑ⱼ ρᵏ⁺ʲ gⱼ(X) - Polynomial& batched_F = gemini_polynomials.emplace_back(std::move(batched_unshifted)); - Polynomial& batched_G = gemini_polynomials.emplace_back(std::move(batched_to_be_shifted)); + Polynomial& batched_F = fold_polynomials.emplace_back(std::move(batched_unshifted)); + Polynomial& batched_G = fold_polynomials.emplace_back(std::move(batched_to_be_shifted)); constexpr size_t offset_to_folded = 2; // Offset because of F an G // A₀(X) = F(X) + G↺(X) = F(X) + G(X)/X. Polynomial A_0 = batched_F; @@ -84,7 +131,7 @@ std::vector::Polynomial> GeminiProver_::com const size_t n_l = 1 << (num_variables - l - 1); // A_l_fold = Aₗ₊₁(X) = (1-uₗ)⋅even(Aₗ)(X) + uₗ⋅odd(Aₗ)(X) - gemini_polynomials.emplace_back(Polynomial(n_l)); + fold_polynomials.emplace_back(Polynomial(n_l)); } // A_l = Aₗ(X) is the polynomial being folded @@ -106,7 +153,7 @@ std::vector::Polynomial> GeminiProver_::com const Fr u_l = mle_opening_point[l]; // A_l_fold = Aₗ₊₁(X) = (1-uₗ)⋅even(Aₗ)(X) + uₗ⋅odd(Aₗ)(X) - auto A_l_fold = gemini_polynomials[l + offset_to_folded].data(); + auto A_l_fold = fold_polynomials[l + offset_to_folded].data(); parallel_for(num_used_threads, [&](size_t i) { size_t current_chunk_size = (i == (num_used_threads - 1)) ? last_chunk_size : chunk_size; @@ -123,31 +170,31 @@ std::vector::Polynomial> GeminiProver_::com A_l = A_l_fold; } - return gemini_polynomials; + return fold_polynomials; }; /** * @brief Computes/aggragates d+1 Fold polynomials and their opening pairs (challenge, evaluation) * - * @details This function assumes that, upon input, last d-1 entries in gemini_polynomials are Fold_i. + * @details This function assumes that, upon input, last d-1 entries in fold_polynomials are Fold_i. * The first two entries are assumed to be, respectively, the batched unshifted and batched to-be-shifted * polynomials F(X) = ∑ⱼ ρʲfⱼ(X) and G(X) = ∑ⱼ ρᵏ⁺ʲ gⱼ(X). This function completes the computation * of the first two Fold polynomials as F + G/r and F - G/r. It then evaluates each of the d+1 * fold polynomials at, respectively, the points r, rₗ = r^{2ˡ} for l = 0, 1, ..., d-1. * * @param mle_opening_point u = (u₀,...,uₘ₋₁) is the MLE opening point - * @param gemini_polynomials vector of polynomials whose first two elements are F(X) = ∑ⱼ ρʲfⱼ(X) + * @param fold_polynomials vector of polynomials whose first two elements are F(X) = ∑ⱼ ρʲfⱼ(X) * and G(X) = ∑ⱼ ρᵏ⁺ʲ gⱼ(X), and the next d-1 elements are Fold_i, i = 1, ..., d-1. * @param r_challenge univariate opening challenge */ template -GeminiProverOutput GeminiProver_::compute_fold_polynomial_evaluations( - std::span mle_opening_point, std::vector&& gemini_polynomials, const Fr& r_challenge) +std::vector::Claim> GeminiProver_::compute_fold_polynomial_evaluations( + std::span mle_opening_point, std::vector&& fold_polynomials, const Fr& r_challenge) { const size_t num_variables = mle_opening_point.size(); // m - Polynomial& batched_F = gemini_polynomials[0]; // F(X) = ∑ⱼ ρʲ fⱼ(X) - Polynomial& batched_G = gemini_polynomials[1]; // G(X) = ∑ⱼ ρᵏ⁺ʲ gⱼ(X) + Polynomial& batched_F = fold_polynomials[0]; // F(X) = ∑ⱼ ρʲ fⱼ(X) + Polynomial& batched_G = fold_polynomials[1]; // G(X) = ∑ⱼ ρᵏ⁺ʲ gⱼ(X) // Compute univariate opening queries rₗ = r^{2ˡ} for l = 0, 1, ..., m-1 std::vector r_squares = gemini::powers_of_evaluation_challenge(r_challenge, num_variables); @@ -156,36 +203,35 @@ GeminiProverOutput GeminiProver_::compute_fold_polynomial_evaluati Fr r_inv = r_challenge.invert(); batched_G *= r_inv; - // Construct A₀₊ = F + G/r and A₀₋ = F - G/r in place in gemini_polynomials + // Construct A₀₊ = F + G/r and A₀₋ = F - G/r in place in fold_polynomials Polynomial tmp = batched_F; - Polynomial& A_0_pos = gemini_polynomials[0]; + Polynomial& A_0_pos = fold_polynomials[0]; // A₀₊(X) = F(X) + G(X)/r, s.t. A₀₊(r) = A₀(r) A_0_pos += batched_G; // Perform a swap so that tmp = G(X)/r and A_0_neg = F(X) std::swap(tmp, batched_G); - Polynomial& A_0_neg = gemini_polynomials[1]; + Polynomial& A_0_neg = fold_polynomials[1]; // A₀₋(X) = F(X) - G(X)/r, s.t. A₀₋(-r) = A₀(-r) A_0_neg -= tmp; - std::vector> fold_poly_opening_pairs; - fold_poly_opening_pairs.reserve(num_variables + 1); + std::vector opening_claims; + opening_claims.reserve(num_variables + 1); // Compute first opening pair {r, A₀(r)} - fold_poly_opening_pairs.emplace_back( - OpeningPair{ r_challenge, gemini_polynomials[0].evaluate(r_challenge) }); - + Fr evaluation = fold_polynomials[0].evaluate(r_challenge); + opening_claims.emplace_back( + Claim{ fold_polynomials[0], { r_challenge, fold_polynomials[0].evaluate(r_challenge) } }); // Compute the remaining m opening pairs {−r^{2ˡ}, Aₗ(−r^{2ˡ})}, l = 0, ..., m-1. for (size_t l = 0; l < num_variables; ++l) { - fold_poly_opening_pairs.emplace_back( - OpeningPair{ -r_squares[l], gemini_polynomials[l + 1].evaluate(-r_squares[l]) }); + evaluation = fold_polynomials[l + 1].evaluate(-r_squares[l]); + opening_claims.emplace_back(Claim{ fold_polynomials[l + 1], { -r_squares[l], evaluation } }); } - return { fold_poly_opening_pairs, std::move(gemini_polynomials) }; + return opening_claims; }; - template class GeminiProver_; template class GeminiProver_; -}; // namespace bb +} // namespace bb diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp index bc3034bc753..e38f6891bd6 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp @@ -1,11 +1,9 @@ #pragma once -#include "../claim.hpp" +#include "barretenberg/commitment_schemes/claim.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/transcript/transcript.hpp" -#include - /** * @brief Protocol for opening several multi-linear polynomials at the same point. * @@ -57,10 +55,6 @@ namespace bb { * ] * @tparam Curve CommitmentScheme parameters */ -template struct GeminiProverOutput { - std::vector> opening_pairs; - std::vector> witnesses; -}; namespace gemini { /** @@ -102,15 +96,23 @@ template inline std::vector powers_of_evaluation_challenge(const template class GeminiProver_ { using Fr = typename Curve::ScalarField; using Polynomial = bb::Polynomial; + using Claim = ProverOpeningClaim; public: - static std::vector compute_gemini_polynomials(std::span mle_opening_point, - Polynomial&& batched_unshifted, - Polynomial&& batched_to_be_shifted); + static std::vector compute_fold_polynomials(std::span multilinear_evaluations, + Polynomial&& batched_unshifted, + Polynomial&& batched_to_be_shifted); + + static std::vector compute_fold_polynomial_evaluations(std::span multilinear_evaluations, + std::vector&& fold_polynomials, + const Fr& r_challenge); - static GeminiProverOutput compute_fold_polynomial_evaluations(std::span mle_opening_point, - std::vector&& gemini_polynomials, - const Fr& r_challenge); + static std::vector prove(const std::shared_ptr>& commitment_key, + std::span multilinear_challenge, + std::span multilinear_evaluations, + RefSpan f_polynomials, + RefSpan g_polynomials, + std::shared_ptr& transcript); }; // namespace bb template class GeminiVerifier_ { @@ -122,25 +124,45 @@ template class GeminiVerifier_ { /** * @brief Returns univariate opening claims for the Fold polynomials to be checked later * - * @param mle_opening_point the MLE evaluation point u + * @param multilinear_evaluations the MLE evaluation point u * @param batched_evaluation batched evaluation from multivariate evals at the point u - * @param batched_f batched commitment to unshifted polynomials - * @param batched_g batched commitment to to-be-shifted polynomials + * @param batched_commitment_unshifted batched commitment to unshifted polynomials + * @param batched_commitment_to_be_shifted batched commitment to to-be-shifted polynomials * @param proof commitments to the m-1 folded polynomials, and alleged evaluations. * @param transcript * @return Fold polynomial opening claims: (r, A₀(r), C₀₊), (-r, A₀(-r), C₀₋), and * (Cⱼ, Aⱼ(-r^{2ʲ}), -r^{2}), j = [1, ..., m-1] */ - static std::vector> reduce_verification(std::span mle_opening_point, /* u */ - Fr& batched_evaluation, /* all */ - GroupElement& batched_f, /* unshifted */ - GroupElement& batched_g, /* to-be-shifted */ + static std::vector> reduce_verification(std::span multilinear_challenge, + std::span multilinear_evaluations, /* u */ + RefSpan unshifted_commitments, + RefSpan to_be_shifted_commitments, auto& transcript) { - const size_t num_variables = mle_opening_point.size(); + const size_t num_variables = multilinear_challenge.size(); + + Fr rho = transcript->template get_challenge("rho"); + std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); + + GroupElement batched_commitment_unshifted = GroupElement::zero(); + GroupElement batched_commitment_to_be_shifted = GroupElement::zero(); + + Fr batched_evaluation = Fr::zero(); + for (size_t i = 0; i < multilinear_evaluations.size(); ++i) { + batched_evaluation += multilinear_evaluations[i] * rhos[i]; + } + + const size_t num_unshifted = unshifted_commitments.size(); + const size_t num_to_be_shifted = to_be_shifted_commitments.size(); + for (size_t i = 0; i < num_unshifted; i++) { + batched_commitment_unshifted += unshifted_commitments[i] * rhos[i]; + } + for (size_t i = 0; i < num_to_be_shifted; i++) { + batched_commitment_to_be_shifted += to_be_shifted_commitments[i] * rhos[num_unshifted + i]; + } // Get polynomials Fold_i, i = 1,...,m-1 from transcript - const std::vector commitments = get_gemini_commitments(num_variables, transcript); + const std::vector commitments = get_fold_commitments(num_variables, transcript); // compute vector of powers of random evaluation point r const Fr r = transcript->template get_challenge("Gemini:r"); @@ -149,12 +171,13 @@ template class GeminiVerifier_ { // Get evaluations a_i, i = 0,...,m-1 from transcript const std::vector evaluations = get_gemini_evaluations(num_variables, transcript); // Compute evaluation A₀(r) - auto a_0_pos = - compute_gemini_batched_univariate_evaluation(batched_evaluation, mle_opening_point, r_squares, evaluations); + auto a_0_pos = compute_gemini_batched_univariate_evaluation( + batched_evaluation, multilinear_challenge, r_squares, evaluations); // C₀_r_pos = ∑ⱼ ρʲ⋅[fⱼ] + r⁻¹⋅∑ⱼ ρᵏ⁺ʲ [gⱼ] // C₀_r_pos = ∑ⱼ ρʲ⋅[fⱼ] - r⁻¹⋅∑ⱼ ρᵏ⁺ʲ [gⱼ] - auto [c0_r_pos, c0_r_neg] = compute_simulated_commitments(batched_f, batched_g, r); + auto [c0_r_pos, c0_r_neg] = + compute_simulated_commitments(batched_commitment_unshifted, batched_commitment_to_be_shifted, r); std::vector> fold_polynomial_opening_claims; fold_polynomial_opening_claims.reserve(num_variables + 1); @@ -172,16 +195,16 @@ template class GeminiVerifier_ { return fold_polynomial_opening_claims; } - static std::vector get_gemini_commitments(const size_t log_circuit_size, auto& transcript) + static std::vector get_fold_commitments(const size_t log_circuit_size, auto& transcript) { - std::vector gemini_commitments; - gemini_commitments.reserve(log_circuit_size - 1); + std::vector fold_commitments; + fold_commitments.reserve(log_circuit_size - 1); for (size_t i = 0; i < log_circuit_size - 1; ++i) { const Commitment commitment = transcript->template receive_from_prover("Gemini:FOLD_" + std::to_string(i + 1)); - gemini_commitments.emplace_back(commitment); + fold_commitments.emplace_back(commitment); } - return gemini_commitments; + return fold_commitments; } static std::vector get_gemini_evaluations(const size_t log_circuit_size, auto& transcript) { @@ -246,14 +269,13 @@ template class GeminiVerifier_ { /** * @brief Computes two commitments to A₀ partially evaluated in r and -r. * - * @param batched_f batched commitment to non-shifted polynomials - * @param batched_g batched commitment to to-be-shifted polynomials + * @param batched_commitment_unshifted batched commitment to non-shifted polynomials + * @param batched_commitment_to_be_shifted batched commitment to to-be-shifted polynomials * @param r evaluation point at which we have partially evaluated A₀ at r and -r. * @return std::pair c0_r_pos, c0_r_neg */ - static std::pair compute_simulated_commitments(GroupElement& batched_f, - GroupElement& batched_g, - Fr r) + static std::pair compute_simulated_commitments( + GroupElement& batched_commitment_unshifted, GroupElement& batched_commitment_to_be_shifted, Fr r) { // C₀ᵣ₊ = [F] + r⁻¹⋅[G] GroupElement C0_r_pos; @@ -265,7 +287,7 @@ template class GeminiVerifier_ { // TODO(#673): The following if-else represents the stldib/native code paths. Once the "native" verifier is // achieved through a builder Simulator, the stdlib codepath should become the only codepath. if constexpr (Curve::is_stdlib_type) { - std::vector commitments = { batched_f, batched_g }; + std::vector commitments = { batched_commitment_unshifted, batched_commitment_to_be_shifted }; auto builder = r.get_context(); auto one = Fr(builder, 1); // TODO(#707): these batch muls include the use of 1 as a scalar. This is handled appropriately as a non-mul @@ -274,12 +296,12 @@ template class GeminiVerifier_ { C0_r_pos = GroupElement::batch_mul(commitments, { one, r_inv }); C0_r_neg = GroupElement::batch_mul(commitments, { one, -r_inv }); } else { - C0_r_pos = batched_f; - C0_r_neg = batched_f; - if (!batched_g.is_point_at_infinity()) { - batched_g = batched_g * r_inv; - C0_r_pos += batched_g; - C0_r_neg -= batched_g; + C0_r_pos = batched_commitment_unshifted; + C0_r_neg = batched_commitment_unshifted; + if (!batched_commitment_to_be_shifted.is_point_at_infinity()) { + batched_commitment_to_be_shifted = batched_commitment_to_be_shifted * r_inv; + C0_r_pos += batched_commitment_to_be_shifted; + C0_r_neg -= batched_commitment_to_be_shifted; } } 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 1da66356c64..881e70769cf 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp @@ -3,9 +3,6 @@ #include "../commitment_key.test.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/transcript/transcript.hpp" -#include -#include -#include using namespace bb; @@ -16,67 +13,27 @@ template class GeminiTest : public CommitmentTest { using GroupElement = typename Curve::Element; public: - void execute_gemini_and_verify_claims(size_t log_n, - std::vector multilinear_evaluation_point, - std::vector multilinear_evaluations, - std::vector> multilinear_polynomials, - std::vector> multilinear_polynomials_to_be_shifted, - std::vector multilinear_commitments, - std::vector multilinear_commitments_to_be_shifted) + void execute_gemini_and_verify_claims(std::vector& multilinear_evaluation_point, + std::vector& multilinear_evaluations, + std::vector>& multilinear_polynomials, + std::vector>& multilinear_polynomials_to_be_shifted, + std::vector& multilinear_commitments, + std::vector& multilinear_commitments_to_be_shifted) { auto prover_transcript = NativeTranscript::prover_init_empty(); - const Fr rho = Fr::random_element(); - - std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); - - // Compute batched multivariate evaluation - Fr batched_evaluation = Fr::zero(); - for (size_t i = 0; i < multilinear_evaluations.size(); ++i) { - batched_evaluation += multilinear_evaluations[i] * rhos[i]; - } - - Polynomial batched_unshifted(1 << log_n); - Polynomial batched_to_be_shifted = Polynomial::shiftable(1 << log_n); - GroupElement batched_commitment_unshifted = GroupElement::zero(); - GroupElement batched_commitment_to_be_shifted = GroupElement::zero(); - const size_t num_unshifted = multilinear_polynomials.size(); - const size_t num_shifted = multilinear_polynomials_to_be_shifted.size(); - for (size_t i = 0; i < num_unshifted; ++i) { - batched_unshifted.add_scaled(multilinear_polynomials[i], rhos[i]); - batched_commitment_unshifted += multilinear_commitments[i] * rhos[i]; - } - for (size_t i = 0; i < num_shifted; ++i) { - size_t rho_idx = num_unshifted + i; - batched_to_be_shifted.add_scaled(multilinear_polynomials_to_be_shifted[i], rhos[rho_idx]); - batched_commitment_to_be_shifted += multilinear_commitments_to_be_shifted[i] * rhos[rho_idx]; - } - // Compute: // - (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 gemini_polynomials = GeminiProver::compute_gemini_polynomials( - multilinear_evaluation_point, std::move(batched_unshifted), std::move(batched_to_be_shifted)); - - for (size_t l = 0; l < log_n - 1; ++l) { - std::string label = "FOLD_" + std::to_string(l + 1); - auto commitment = this->ck()->commit(gemini_polynomials[l + 2]); - prover_transcript->send_to_verifier(label, commitment); - } - - const Fr r_challenge = prover_transcript->get_challenge("Gemini:r"); - - auto prover_output = GeminiProver::compute_fold_polynomial_evaluations( - multilinear_evaluation_point, std::move(gemini_polynomials), r_challenge); - - for (size_t l = 0; l < log_n; ++l) { - std::string label = "Gemini:a_" + std::to_string(l); - const auto& evaluation = prover_output.opening_pairs[l + 1].evaluation; - prover_transcript->send_to_verifier(label, evaluation); - } + auto prover_output = GeminiProver::prove(this->commitment_key, + multilinear_evaluation_point, + multilinear_evaluations, + RefVector(multilinear_polynomials), + RefVector(multilinear_polynomials_to_be_shifted), + prover_transcript); // Check that the Fold polynomials have been evaluated correctly in the prover - this->verify_batch_opening_pair(prover_output.opening_pairs, prover_output.witnesses); + this->verify_batch_opening_pair(prover_output); auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript); @@ -84,19 +41,17 @@ 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_claim = GeminiVerifier::reduce_verification(multilinear_evaluation_point, - batched_evaluation, - batched_commitment_unshifted, - batched_commitment_to_be_shifted, - verifier_transcript); + auto verifier_claims = GeminiVerifier::reduce_verification(multilinear_evaluation_point, + multilinear_evaluations, + RefVector(multilinear_commitments), + RefVector(multilinear_commitments_to_be_shifted), + verifier_transcript); // Check equality of the opening pairs computed by prover and verifier - for (size_t i = 0; i < (log_n + 1); ++i) { - ASSERT_EQ(prover_output.opening_pairs[i], verifier_claim[i].opening_pair); + for (auto [prover_claim, verifier_claim] : zip_view(prover_output, verifier_claims)) { + ASSERT_EQ(prover_claim.opening_pair, verifier_claim.opening_pair); + this->verify_opening_claim(verifier_claim, prover_claim.polynomial); } - - // Explicitly verify the claims computed by the verfier - this->verify_batch_opening_claim(verifier_claim, prover_output.witnesses); } }; @@ -123,8 +78,7 @@ TYPED_TEST(GeminiTest, Single) std::vector multilinear_commitments = { commitment }; std::vector multilinear_commitments_to_be_shifted = {}; - this->execute_gemini_and_verify_claims(log_n, - u, + this->execute_gemini_and_verify_claims(u, multilinear_evaluations, multilinear_polynomials, multilinear_polynomials_to_be_shifted, @@ -155,8 +109,7 @@ TYPED_TEST(GeminiTest, SingleShift) std::vector multilinear_commitments = {}; std::vector multilinear_commitments_to_be_shifted = { commitment }; - this->execute_gemini_and_verify_claims(log_n, - u, + this->execute_gemini_and_verify_claims(u, multilinear_evaluations, multilinear_polynomials, multilinear_polynomials_to_be_shifted, @@ -190,8 +143,7 @@ TYPED_TEST(GeminiTest, Double) std::vector multilinear_commitments = { commitment1, commitment2 }; std::vector multilinear_commitments_to_be_shifted = {}; - this->execute_gemini_and_verify_claims(log_n, - u, + this->execute_gemini_and_verify_claims(u, multilinear_evaluations, multilinear_polynomials, multilinear_polynomials_to_be_shifted, @@ -226,8 +178,7 @@ TYPED_TEST(GeminiTest, DoubleWithShift) std::vector multilinear_commitments = { commitment1, commitment2 }; std::vector multilinear_commitments_to_be_shifted = { commitment2 }; - this->execute_gemini_and_verify_claims(log_n, - u, + this->execute_gemini_and_verify_claims(u, multilinear_evaluations, multilinear_polynomials, multilinear_polynomials_to_be_shifted, 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 c8ad9c652db..eb448f4e709 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp @@ -244,8 +244,6 @@ TEST_F(IPATest, GeminiShplonkIPAWithShift) const size_t n = 8; const size_t log_n = 3; - Fr rho = Fr::random_element(); - // Generate multilinear polynomials, their commitments (genuine and mocked) and evaluations (genuine) at a random // point. auto mle_opening_point = this->random_evaluation_point(log_n); // sometimes denoted 'u' @@ -261,59 +259,29 @@ TEST_F(IPATest, GeminiShplonkIPAWithShift) std::vector multilinear_evaluations = { eval1, eval2, eval2_shift }; - std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); - - Fr batched_evaluation = Fr::zero(); - for (size_t i = 0; i < rhos.size(); ++i) { - batched_evaluation += multilinear_evaluations[i] * rhos[i]; - } - - Polynomial batched_unshifted(n); - Polynomial batched_to_be_shifted = Polynomial::shiftable(n); - batched_unshifted.add_scaled(poly1, rhos[0]); - batched_unshifted.add_scaled(poly2, rhos[1]); - batched_to_be_shifted.add_scaled(poly2, rhos[2]); - - GroupElement batched_commitment_unshifted = GroupElement::zero(); - GroupElement batched_commitment_to_be_shifted = GroupElement::zero(); - batched_commitment_unshifted = commitment1 * rhos[0] + commitment2 * rhos[1]; - batched_commitment_to_be_shifted = commitment2 * rhos[2]; - auto prover_transcript = NativeTranscript::prover_init_empty(); - auto gemini_polynomials = GeminiProver::compute_gemini_polynomials( - mle_opening_point, std::move(batched_unshifted), std::move(batched_to_be_shifted)); + // Run the full prover PCS protocol: - for (size_t l = 0; l < log_n - 1; ++l) { - std::string label = "FOLD_" + std::to_string(l + 1); - auto commitment = this->ck()->commit(gemini_polynomials[l + 2]); - prover_transcript->send_to_verifier(label, commitment); - } - - const Fr r_challenge = prover_transcript->template get_challenge("Gemini:r"); - - const auto [gemini_opening_pairs, gemini_witnesses] = GeminiProver::compute_fold_polynomial_evaluations( - mle_opening_point, std::move(gemini_polynomials), r_challenge); + // Compute: + // - (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(this->ck(), + mle_opening_point, + multilinear_evaluations, + RefArray{ poly1, poly2 }, + RefArray{ poly2 }, + prover_transcript); - std::vector> opening_claims; - - for (size_t l = 0; l < log_n; ++l) { - std::string label = "Gemini:a_" + std::to_string(l); - const auto& evaluation = gemini_opening_pairs[l + 1].evaluation; - prover_transcript->send_to_verifier(label, evaluation); - opening_claims.push_back({ gemini_witnesses[l], gemini_opening_pairs[l] }); - } - opening_claims.push_back({ gemini_witnesses[log_n], gemini_opening_pairs[log_n] }); - - const auto opening_claim = ShplonkProver::prove(this->ck(), opening_claims, prover_transcript); + const auto opening_claim = ShplonkProver::prove(this->ck(), prover_opening_claims, prover_transcript); IPA::compute_opening_proof(this->ck(), opening_claim, prover_transcript); auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_transcript); auto gemini_verifier_claim = GeminiVerifier::reduce_verification(mle_opening_point, - batched_evaluation, - batched_commitment_unshifted, - batched_commitment_to_be_shifted, + multilinear_evaluations, + RefArray{ commitment1, commitment2 }, + RefArray{ commitment2 }, verifier_transcript); const auto shplonk_verifier_claim = @@ -348,45 +316,20 @@ TEST_F(IPATest, ShpleminiIPAWithShift) std::vector multilinear_evaluations = { eval1, eval2, eval2_shift }; auto prover_transcript = NativeTranscript::prover_init_empty(); - Fr rho = prover_transcript->template get_challenge("rho"); - std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); - - Fr batched_evaluation = Fr::zero(); - for (size_t i = 0; i < rhos.size(); ++i) { - batched_evaluation += multilinear_evaluations[i] * rhos[i]; - } - - Polynomial batched_unshifted(n); - Polynomial batched_to_be_shifted = Polynomial::shiftable(n); - batched_unshifted.add_scaled(poly1, rhos[0]); - batched_unshifted.add_scaled(poly2, rhos[1]); - batched_to_be_shifted.add_scaled(poly2, rhos[2]); - - auto gemini_polynomials = GeminiProver::compute_gemini_polynomials( - mle_opening_point, std::move(batched_unshifted), std::move(batched_to_be_shifted)); - for (size_t l = 0; l < log_n - 1; ++l) { - std::string label = "FOLD_" + std::to_string(l + 1); - auto commitment = this->ck()->commit(gemini_polynomials[l + 2]); - prover_transcript->send_to_verifier(label, commitment); - } - - const Fr r_challenge = prover_transcript->template get_challenge("Gemini:r"); - - const auto [gemini_opening_pairs, gemini_witnesses] = GeminiProver::compute_fold_polynomial_evaluations( - mle_opening_point, std::move(gemini_polynomials), r_challenge); + // Run the full prover PCS protocol: - std::vector> opening_claims; - - for (size_t l = 0; l < log_n; ++l) { - std::string label = "Gemini:a_" + std::to_string(l); - const auto& evaluation = gemini_opening_pairs[l + 1].evaluation; - prover_transcript->send_to_verifier(label, evaluation); - opening_claims.push_back({ gemini_witnesses[l], gemini_opening_pairs[l] }); - } - opening_claims.push_back({ gemini_witnesses[log_n], gemini_opening_pairs[log_n] }); + // Compute: + // - (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(this->ck(), + mle_opening_point, + multilinear_evaluations, + RefArray{ poly1, poly2 }, + RefArray{ poly2 }, + prover_transcript); - const auto opening_claim = ShplonkProver::prove(this->ck(), opening_claims, prover_transcript); + const auto opening_claim = ShplonkProver::prove(this->ck(), prover_opening_claims, prover_transcript); IPA::compute_opening_proof(this->ck(), opening_claim, prover_transcript); auto verifier_transcript = NativeTranscript::verifier_init_empty(prover_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 ded35bb6a42..60f41bdb7f5 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp @@ -69,8 +69,6 @@ TYPED_TEST(KZGTest, GeminiShplonkKzgWithShift) const size_t n = 16; const size_t log_n = 4; - Fr rho = Fr::random_element(); - // Generate multilinear polynomials, their commitments (genuine and mocked) and evaluations (genuine) at a random // point. auto mle_opening_point = this->random_evaluation_point(log_n); // sometimes denoted 'u' @@ -87,27 +85,6 @@ TYPED_TEST(KZGTest, GeminiShplonkKzgWithShift) // Collect multilinear evaluations for input to prover std::vector multilinear_evaluations = { eval1, eval2, eval2_shift }; - std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); - - // Compute batched multivariate evaluation - Fr batched_evaluation = Fr::zero(); - for (size_t i = 0; i < rhos.size(); ++i) { - batched_evaluation += multilinear_evaluations[i] * rhos[i]; - } - - // Compute batched polynomials - Polynomial batched_unshifted(n); - Polynomial batched_to_be_shifted = Polynomial::shiftable(n); - batched_unshifted.add_scaled(poly1, rhos[0]); - batched_unshifted.add_scaled(poly2, rhos[1]); - batched_to_be_shifted.add_scaled(poly2, rhos[2]); - - // Compute batched commitments - GroupElement batched_commitment_unshifted = GroupElement::zero(); - GroupElement batched_commitment_to_be_shifted = GroupElement::zero(); - batched_commitment_unshifted = commitment1 * rhos[0] + commitment2 * rhos[1]; - batched_commitment_to_be_shifted = commitment2 * rhos[2]; - auto prover_transcript = NativeTranscript::prover_init_empty(); // Run the full prover PCS protocol: @@ -115,33 +92,17 @@ TYPED_TEST(KZGTest, GeminiShplonkKzgWithShift) // Compute: // - (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 gemini_polynomials = GeminiProver::compute_gemini_polynomials( - mle_opening_point, std::move(batched_unshifted), std::move(batched_to_be_shifted)); - - for (size_t l = 0; l < log_n - 1; ++l) { - std::string label = "FOLD_" + std::to_string(l + 1); - auto commitment = this->ck()->commit(gemini_polynomials[l + 2]); - prover_transcript->send_to_verifier(label, commitment); - } - - const Fr r_challenge = prover_transcript->template get_challenge("Gemini:r"); - - const auto [gemini_opening_pairs, gemini_witnesses] = GeminiProver::compute_fold_polynomial_evaluations( - mle_opening_point, std::move(gemini_polynomials), r_challenge); - - std::vector> opening_claims; - for (size_t l = 0; l < log_n; ++l) { - std::string label = "Gemini:a_" + std::to_string(l); - const auto& evaluation = gemini_opening_pairs[l + 1].evaluation; - prover_transcript->send_to_verifier(label, evaluation); - opening_claims.push_back({ gemini_witnesses[l], gemini_opening_pairs[l] }); - } - opening_claims.push_back({ gemini_witnesses[log_n], gemini_opening_pairs[log_n] }); + auto prover_opening_claims = GeminiProver::prove(this->ck(), + mle_opening_point, + multilinear_evaluations, + RefArray{ poly1, poly2 }, + RefArray{ poly2 }, + prover_transcript); // Shplonk prover output: // - opening pair: (z_challenge, 0) // - witness: polynomial Q - Q_z - const auto opening_claim = ShplonkProver::prove(this->ck(), opening_claims, prover_transcript); + const auto opening_claim = ShplonkProver::prove(this->ck(), prover_opening_claims, prover_transcript); // KZG prover: // - Adds commitment [W] to transcript @@ -154,9 +115,9 @@ TYPED_TEST(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, - batched_evaluation, - batched_commitment_unshifted, - batched_commitment_to_be_shifted, + multilinear_evaluations, + RefArray{ commitment1, commitment2 }, + RefArray{ commitment2 }, verifier_transcript); // Shplonk verifier claim: commitment [Q] - [Q_z], opening point (z_challenge, 0) @@ -179,15 +140,11 @@ TYPED_TEST(KZGTest, ShpleminiKzgWithShift) using ShpleminiVerifier = ShpleminiVerifier_; using KZG = KZG; using Fr = typename TypeParam::ScalarField; - using GroupElement = typename TypeParam::Element; using Commitment = typename TypeParam::AffineElement; using Polynomial = typename bb::Polynomial; const size_t n = 16; const size_t log_n = 4; - auto prover_transcript = NativeTranscript::prover_init_empty(); - // Get batching challenge - Fr rho = prover_transcript->template get_challenge("rho"); // Generate multilinear polynomials, their commitments (genuine and mocked) and evaluations (genuine) at a random // point. auto mle_opening_point = this->random_evaluation_point(log_n); // sometimes denoted 'u' @@ -205,59 +162,24 @@ TYPED_TEST(KZGTest, ShpleminiKzgWithShift) // Collect multilinear evaluations for input to prover std::vector multilinear_evaluations = { eval1, eval2, eval2_shift }; - std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); - - // Compute batched multivariate evaluation - Fr batched_evaluation = Fr::zero(); - for (size_t i = 0; i < rhos.size(); ++i) { - batched_evaluation += multilinear_evaluations[i] * rhos[i]; - } - - // Compute batched polynomials - Polynomial batched_unshifted(n); - Polynomial batched_to_be_shifted = Polynomial::shiftable(n); - batched_unshifted.add_scaled(poly1, rhos[0]); - batched_unshifted.add_scaled(poly2, rhos[1]); - batched_to_be_shifted.add_scaled(poly2, rhos[2]); - - // Compute batched commitments - GroupElement batched_commitment_unshifted = GroupElement::zero(); - GroupElement batched_commitment_to_be_shifted = GroupElement::zero(); - batched_commitment_unshifted = commitment1 * rhos[0] + commitment2 * rhos[1]; - batched_commitment_to_be_shifted = commitment2 * rhos[2]; + auto prover_transcript = NativeTranscript::prover_init_empty(); // Run the full prover PCS protocol: // Compute: // - (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 gemini_polynomials = GeminiProver::compute_gemini_polynomials( - mle_opening_point, std::move(batched_unshifted), std::move(batched_to_be_shifted)); - - for (size_t l = 0; l < log_n - 1; ++l) { - std::string label = "FOLD_" + std::to_string(l + 1); - auto commitment = this->ck()->commit(gemini_polynomials[l + 2]); - prover_transcript->send_to_verifier(label, commitment); - } - - const Fr r_challenge = prover_transcript->template get_challenge("Gemini:r"); - - const auto [gemini_opening_pairs, gemini_witnesses] = GeminiProver::compute_fold_polynomial_evaluations( - mle_opening_point, std::move(gemini_polynomials), r_challenge); - - std::vector> opening_claims; - for (size_t l = 0; l < log_n; ++l) { - std::string label = "Gemini:a_" + std::to_string(l); - const auto& evaluation = gemini_opening_pairs[l + 1].evaluation; - prover_transcript->send_to_verifier(label, evaluation); - opening_claims.push_back({ gemini_witnesses[l], gemini_opening_pairs[l] }); - } - opening_claims.push_back({ gemini_witnesses[log_n], gemini_opening_pairs[log_n] }); + auto prover_opening_claims = GeminiProver::prove(this->ck(), + mle_opening_point, + multilinear_evaluations, + RefArray{ poly1, poly2 }, + RefArray{ poly2 }, + prover_transcript); // Shplonk prover output: // - opening pair: (z_challenge, 0) // - witness: polynomial Q - Q_z - const auto opening_claim = ShplonkProver::prove(this->ck(), opening_claims, prover_transcript); + const auto opening_claim = ShplonkProver::prove(this->ck(), prover_opening_claims, prover_transcript); // KZG prover: // - Adds commitment [W] to transcript 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 5ca984a148f..721d65a2cc0 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.hpp @@ -92,8 +92,8 @@ template class ShpleminiVerifier_ { // Process Gemini transcript data: // - Get Gemini commitments (com(A₁), com(A₂), … , com(Aₙ₋₁)) - const std::vector gemini_commitments = - GeminiVerifier::get_gemini_commitments(log_circuit_size, transcript); + const std::vector fold_commitments = + GeminiVerifier::get_fold_commitments(log_circuit_size, transcript); // - Get Gemini evaluation challenge for Aᵢ, i = 0, … , d−1 const Fr gemini_evaluation_challenge = transcript->template get_challenge("Gemini:r"); // - Get evaluations (A₀(−r), A₁(−r²), ... , Aₙ₋₁(−r²⁽ⁿ⁻¹⁾)) @@ -151,7 +151,7 @@ template class ShpleminiVerifier_ { // Place the commitments to Gemini Aᵢ to the vector of commitments, compute the contributions from // Aᵢ(−r²ⁱ) for i=1, … , n−1 to the constant term accumulator, add corresponding scalars batch_gemini_claims_received_from_prover(log_circuit_size, - gemini_commitments, + fold_commitments, gemini_evaluations, inverse_vanishing_evals, shplonk_batching_challenge, @@ -282,7 +282,7 @@ template class ShpleminiVerifier_ { * and adds them to the 'constant_term_accumulator'. * * @param log_circuit_size The logarithm of the circuit size, determining the depth of the Gemini protocol. - * @param gemini_commitments A vector containing the commitments to the Gemini fold polynomials \f$ A_i \f$. + * @param fold_commitments A vector containing the commitments to the Gemini fold polynomials \f$ A_i \f$. * @param gemini_evaluations A vector containing the evaluations of the Gemini fold polynomials \f$ A_i \f$ at * points \f$ -r^{2^i} \f$. * @param inverse_vanishing_evals A vector containing the inverse evaluations of the vanishing polynomial. @@ -292,7 +292,7 @@ template class ShpleminiVerifier_ { * @param constant_term_accumulator The accumulator for the summands of the constant term. */ static void batch_gemini_claims_received_from_prover(const size_t log_circuit_size, - const std::vector& gemini_commitments, + const std::vector& fold_commitments, const std::vector& gemini_evaluations, const std::vector& inverse_vanishing_evals, const Fr& shplonk_batching_challenge, @@ -312,7 +312,7 @@ template class ShpleminiVerifier_ { // Update the batching challenge current_batching_challenge *= shplonk_batching_challenge; // Move com(Aᵢ) to the 'commitments' vector - commitments.emplace_back(std::move(gemini_commitments[j])); + commitments.emplace_back(std::move(fold_commitments[j])); } } }; 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 5fdade707b1..c19a9bbcb7d 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 @@ -164,22 +164,21 @@ TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching) // Compute: // - (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 gemini_polynomials = GeminiProver::compute_gemini_polynomials( + auto fold_polynomials = GeminiProver::compute_fold_polynomials( mle_opening_point, std::move(batched_unshifted), std::move(batched_to_be_shifted)); std::vector prover_commitments; for (size_t l = 0; l < log_n - 1; ++l) { - auto commitment = this->ck()->commit(gemini_polynomials[l + 2]); + auto commitment = this->ck()->commit(fold_polynomials[l + 2]); prover_commitments.emplace_back(commitment); } - const auto [gemini_opening_pairs, gemini_witnesses] = GeminiProver::compute_fold_polynomial_evaluations( - mle_opening_point, std::move(gemini_polynomials), gemini_eval_challenge); + const auto opening_claims = GeminiProver::compute_fold_polynomial_evaluations( + mle_opening_point, std::move(fold_polynomials), gemini_eval_challenge); std::vector prover_evaluations; - std::vector> opening_claims; for (size_t l = 0; l < log_n; ++l) { - const auto& evaluation = gemini_opening_pairs[l + 1].evaluation; + const auto& evaluation = opening_claims[l + 1].opening_pair.evaluation; prover_evaluations.emplace_back(evaluation); } diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/wrapper.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/wrapper.hpp deleted file mode 100644 index ded625f8e39..00000000000 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/wrapper.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "barretenberg/ecc/curves/bn254/g1.hpp" -#include "gemini/gemini.hpp" - -namespace bb { - -struct OpeningProof { - std::vector gemini; - bb::g1::affine_element shplonk; - bb::g1::affine_element kzg; -}; - -} // namespace bb 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 050a2603972..bbc04a799b7 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp @@ -90,49 +90,17 @@ TEST(ShpleminiRecursionTest, ProveAndVerifySingle) // Initialize an empty NativeTranscript auto prover_transcript = NativeTranscript::prover_init_empty(); - - NativeFr rho = prover_transcript->template get_challenge("rho"); - std::vector rhos = gemini::powers_of_rho(rho, NUM_SHIFTED + NUM_UNSHIFTED); - // Batch the unshifted polynomials and the to-be-shifted polynomials using ρ - Polynomial batched_poly_unshifted(N); - size_t poly_idx = 0; - for (auto& unshifted_poly : f_polynomials) { - batched_poly_unshifted.add_scaled(unshifted_poly, rhos[poly_idx]); - ++poly_idx; - } - - Polynomial batched_poly_to_be_shifted = Polynomial::shiftable(N); // batched to-be-shifted polynomials - for (auto& to_be_shifted_poly : g_polynomials) { - batched_poly_to_be_shifted.add_scaled(to_be_shifted_poly, rhos[poly_idx]); - ++poly_idx; - }; - - // Compute d-1 polynomials Fold^(i), i = 1, ..., d-1. - auto fold_polynomials = GeminiProver::compute_gemini_polynomials( - u_challenge, std::move(batched_poly_unshifted), std::move(batched_poly_to_be_shifted)); - // Comute and add to trasnscript the commitments [Fold^(i)], i = 1, ..., d-1 - for (size_t l = 0; l < log_circuit_size - 1; ++l) { - NativeCommitment current_commitment = commitment_key->commit(fold_polynomials[l + 2]); - prover_transcript->send_to_verifier("Gemini:FOLD_" + std::to_string(l + 1), current_commitment); - } - const NativeFr r_challenge = prover_transcript->template get_challenge("Gemini:r"); - - const auto [gemini_opening_pairs, gemini_witnesses] = - GeminiProver::compute_fold_polynomial_evaluations(u_challenge, std::move(fold_polynomials), r_challenge); - - std::vector> opening_claims; - for (size_t l = 0; l < log_circuit_size; ++l) { - std::string label = "Gemini:a_" + std::to_string(l); - const auto& evaluation = gemini_opening_pairs[l + 1].evaluation; - prover_transcript->send_to_verifier(label, evaluation); - opening_claims.push_back({ gemini_witnesses[l], gemini_opening_pairs[l] }); - } - opening_claims.push_back({ gemini_witnesses[log_circuit_size], gemini_opening_pairs[log_circuit_size] }); + auto prover_opening_claims = GeminiProver::prove(commitment_key, + u_challenge, + claimed_evaluations, + RefVector(f_polynomials), + RefVector(g_polynomials), + prover_transcript); // Shplonk prover output: // - opening pair: (z_challenge, 0) // - witness: polynomial Q - Q_z - ShplonkProver::prove(commitment_key, opening_claims, prover_transcript); + ShplonkProver::prove(commitment_key, prover_opening_claims, prover_transcript); Builder builder; StdlibProof stdlib_proof = bb::convert_proof_to_witness(&builder, prover_transcript->proof_data); diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp index 52d243ca06c..6a01c6af112 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.hpp @@ -53,9 +53,6 @@ class ECCVMProver { CommitmentLabels commitment_labels; - // Container for d + 1 Fold polynomials produced by Gemini - std::vector gemini_polynomials; - Polynomial batched_quotient_Q; // batched quotient poly computed by Shplonk FF nu_challenge; // needed in both Shplonk rounds diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp index fa6608456c5..9ed1c255b2c 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp @@ -69,6 +69,12 @@ template class Polynomial { : Polynomial(coefficients, coefficients.size()) {} + /** + * @brief Utility to efficiently construct a shift from the original polynomial. + * + * @param virtual_size the size of the polynomial to be shifted + * @return Polynomial + */ static Polynomial shiftable(size_t virtual_size) { return Polynomial(/*actual size*/ virtual_size - 1, virtual_size, /*shiftable offset*/ 1); diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp index 2bb9cb89721..fe5dbe526c9 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/ultra_flavor.hpp @@ -38,8 +38,9 @@ class UltraFlavor { // Indicates that this flavor runs with non-ZK Sumcheck. static constexpr bool HasZK = false; static constexpr size_t NUM_WIRES = CircuitBuilder::NUM_WIRES; - // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often - // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`. + // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (witness polynomials, + // precomputed polynomials and shifts). We often need containers of this size to hold related data, so we choose a + // name more agnostic than `NUM_POLYNOMIALS`. static constexpr size_t NUM_ALL_ENTITIES = 44; // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name.