From 859f33d4c25f4926fb499622912853c998b209cf Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 18 Sep 2024 10:48:41 +0000 Subject: [PATCH 1/5] create a gemini prover and cleanup --- barretenberg/cpp/CMakePresets.json | 2 +- .../commitment_key.test.hpp | 12 +- .../commitment_schemes/gemini/gemini.cpp | 93 +++- .../commitment_schemes/gemini/gemini.hpp | 94 ++-- .../commitment_schemes/gemini/gemini.test.cpp | 85 +--- .../commitment_schemes/ipa/ipa.test.cpp | 111 ++--- .../commitment_schemes/kzg/kzg.test.cpp | 116 +---- .../shplonk/shplemini_verifier.test.cpp | 454 +++++++++--------- .../commitment_schemes/wrapper.hpp | 14 - .../shplemini.test.cpp | 6 +- .../barretenberg/polynomials/polynomial.hpp | 7 + .../stdlib_circuit_builders/ultra_flavor.hpp | 5 +- 12 files changed, 447 insertions(+), 552 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/commitment_schemes/wrapper.hpp diff --git a/barretenberg/cpp/CMakePresets.json b/barretenberg/cpp/CMakePresets.json index 140b5780ed0..b45ca9cea38 100644 --- a/barretenberg/cpp/CMakePresets.json +++ b/barretenberg/cpp/CMakePresets.json @@ -98,7 +98,7 @@ "displayName": "Debugging build with Clang-16", "description": "Build with globally installed Clang-16 in debug mode", "inherits": "clang16", - "binaryDir": "build-debug", + "binaryDir": "build", "environment": { "CMAKE_BUILD_TYPE": "Debug", "CFLAGS": "-gdwarf-4", 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..d40cf153d54 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp @@ -139,14 +139,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..1518dcf4e15 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp @@ -1,10 +1,8 @@ - #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 +14,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 +41,55 @@ * 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()); + 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]; + } + + size_t log_n = multilinear_challenge.size(); + size_t n = 1 << log_n; + // Compute batched polynomials + Polynomial batched_unshifted(n); + // TODO(mara): use shiftable, after you understand how it works + 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]); + } + + // log_n + 2 + auto fold_polynomials = + compute_fold_polynomials(multilinear_challenge, std::move(batched_unshifted), std::move(batched_to_be_shifted)); + + // Commit to the folded polynomials (except the first two, explain why the first two are left out) and send the + // commitment to the verifier + 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"); + return compute_fold_polynomial_evaluations( + multilinear_challenge, std::move(fold_polynomials), r_challenge, transcript); +}; /** * @brief Computes d-1 fold polynomials Fold_i, i = 1, ..., d-1 @@ -53,9 +100,10 @@ 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 const size_t num_threads = get_num_cpus_pow2(); @@ -141,13 +189,16 @@ std::vector::Polynomial> GeminiProver_::com * @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, + std::shared_ptr& transcript) { 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 +207,36 @@ 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]); + transcript->send_to_verifier("Gemini:a_" + std::to_string(l + 1), evaluation); + 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..89c1dc8acf9 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp @@ -1,6 +1,6 @@ #pragma once -#include "../claim.hpp" +#include "barretenberg/commitment_schemes/claim.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/transcript/transcript.hpp" @@ -57,10 +57,6 @@ namespace bb { * ] * @tparam Curve CommitmentScheme parameters */ -template struct GeminiProverOutput { - std::vector> opening_pairs; - std::vector> witnesses; -}; namespace gemini { /** @@ -102,15 +98,25 @@ 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&& gemini_polynomials, + const Fr& r_challenge, + std::shared_ptr& transcript); - static GeminiProverOutput compute_fold_polynomial_evaluations(std::span mle_opening_point, - std::vector&& gemini_polynomials, - const Fr& r_challenge); + // TODO(Mara): consider if we should template this by transcript to use with a test transcript + 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,22 +128,42 @@ 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); @@ -149,12 +175,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); @@ -246,14 +273,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 +291,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 +300,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..a7a7a86b483 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.test.cpp @@ -16,67 +16,28 @@ 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([[maybe_unused]] 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) { 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 +45,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); } }; 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..5905b5a7288 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp @@ -77,8 +77,8 @@ TEST_F(IPATest, OpenZeroPolynomial) EXPECT_TRUE(result); } -// This test makes sure that even if the whole vector \vec{b} generated from the x, at which we open the polynomial, is -// zero, IPA behaves +// This test makes sure that even if the whole vector \vec{b} generated from the x, at which we open the polynomial, +// is zero, IPA behaves TEST_F(IPATest, OpenAtZero) { using IPA = IPA; @@ -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..92e7f2614e6 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,13 @@ TYPED_TEST(KZGTest, ShpleminiKzgWithShift) using ShpleminiVerifier = ShpleminiVerifier_; using KZG = KZG; using Fr = typename TypeParam::ScalarField; - using GroupElement = typename TypeParam::Element; + // 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 +164,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.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.test.cpp index 45292861fae..c04359b5a2a 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 @@ -1,228 +1,228 @@ -#include "shplemini_verifier.hpp" -#include "../commitment_key.test.hpp" -#include "../gemini/gemini.hpp" -#include "../kzg/kzg.hpp" -#include "../shplonk/shplonk.hpp" -#include "../utils/batch_mul_native.hpp" -#include "barretenberg/commitment_schemes/claim.hpp" -#include "barretenberg/ecc/curves/bn254/g1.hpp" - -#include -#include - -namespace bb { - -template class ShpleminiTest : public CommitmentTest { - public: - using Fr = typename Curve::ScalarField; - using Commitment = typename Curve::AffineElement; - using GroupElement = typename Curve::Element; - using Polynomial = bb::Polynomial; -}; - -using CurveTypes = ::testing::Types; - -TYPED_TEST_SUITE(ShpleminiTest, CurveTypes); - -// This test checks that batch_multivariate_opening_claims method operates correctly -TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching) -{ - using ShpleminiVerifier = ShpleminiVerifier_; - using Fr = typename TypeParam::ScalarField; - using GroupElement = typename TypeParam::Element; - using Commitment = typename TypeParam::AffineElement; - using Polynomial = typename bb::Polynomial; - using Utils = CommitmentSchemesUtils; - - const size_t n = 16; - const size_t log_n = 4; - - // Generate mock challenges - Fr rho = Fr::random_element(); - Fr gemini_eval_challenge = Fr::random_element(); - Fr shplonk_batching_challenge = Fr::random_element(); - Fr shplonk_eval_challenge = Fr::random_element(); - - // Generate multilinear polynomials and compute their commitments - auto mle_opening_point = this->random_evaluation_point(log_n); - auto poly1 = Polynomial::random(n); - auto poly2 = Polynomial::random(n, /*shiftable*/ 1); - Polynomial poly3(n); - - Commitment commitment1 = this->commit(poly1); - Commitment commitment2 = this->commit(poly2); - Commitment commitment3 = this->commit(poly3); - EXPECT_TRUE(commitment3.is_point_at_infinity()); - - std::vector unshifted_commitments = { commitment1, commitment2, commitment3 }; - std::vector shifted_commitments = { commitment2, commitment3 }; - - // Evaluate the polynomials at the multivariate challenge, poly3 is not evaluated, because it is 0. - auto eval1 = poly1.evaluate_mle(mle_opening_point); - auto eval2 = poly2.evaluate_mle(mle_opening_point); - Fr eval3{ 0 }; - Fr eval3_shift{ 0 }; - auto eval2_shift = poly2.evaluate_mle(mle_opening_point, true); - - // Collect multilinear evaluations - std::vector multilinear_evaluations = { eval1, eval2, eval3, eval2_shift, eval3_shift }; - std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); - - // Compute batched multivariate evaluation - Fr batched_evaluation = - std::inner_product(multilinear_evaluations.begin(), multilinear_evaluations.end(), rhos.begin(), Fr::zero()); - - // Compute batched commitments manually - GroupElement batched_commitment_unshifted = commitment1 * rhos[0] + commitment2 * rhos[1] + commitment3 * rhos[2]; - GroupElement batched_commitment_to_be_shifted = commitment2 * rhos[3] + commitment3 * rhos[4]; - - // Compute expected result manually - GroupElement commitment_to_univariate = - batched_commitment_unshifted + batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); - GroupElement commitment_to_univariate_neg = - batched_commitment_unshifted - batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); - - GroupElement expected_result = - commitment_to_univariate * (shplonk_eval_challenge - gemini_eval_challenge).invert() + - commitment_to_univariate_neg * - (shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert()); - - // Run the ShepliminiVerifier batching method - std::vector commitments; - std::vector scalars; - Fr verifier_batched_evaluation{ 0 }; - - Fr unshifted_scalar = (shplonk_eval_challenge - gemini_eval_challenge).invert() + - shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert(); - - Fr shifted_scalar = gemini_eval_challenge.invert() * - ((shplonk_eval_challenge - gemini_eval_challenge).invert() - - shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert()); - - ShpleminiVerifier::batch_multivariate_opening_claims(RefVector(unshifted_commitments), - RefVector(shifted_commitments), - RefVector(multilinear_evaluations), - rho, - unshifted_scalar, - shifted_scalar, - commitments, - scalars, - verifier_batched_evaluation); - - // Final pairing check - GroupElement shplemini_result = Utils::batch_mul_native(commitments, scalars); - - EXPECT_EQ(commitments.size(), unshifted_commitments.size() + shifted_commitments.size()); - EXPECT_EQ(batched_evaluation, verifier_batched_evaluation); - EXPECT_EQ(-expected_result, shplemini_result); -} - -TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching) -{ - using GeminiProver = GeminiProver_; - using ShpleminiVerifier = ShpleminiVerifier_; - using ShplonkVerifier = ShplonkVerifier_; - using Fr = typename TypeParam::ScalarField; - using GroupElement = typename TypeParam::Element; - using Commitment = typename TypeParam::AffineElement; - using Polynomial = typename bb::Polynomial; - using Utils = CommitmentSchemesUtils; - - const size_t n = 16; - const size_t log_n = 4; - - // Generate mock challenges - Fr rho = Fr::random_element(); - Fr gemini_eval_challenge = Fr::random_element(); - Fr shplonk_batching_challenge = Fr::random_element(); - Fr shplonk_eval_challenge = Fr::random_element(); - - // Generate multilinear polynomials and compute their commitments - auto mle_opening_point = this->random_evaluation_point(log_n); - auto poly1 = Polynomial::random(n); - auto poly2 = Polynomial::random(n, /*shiftable*/ 1); - Polynomial poly3 = Polynomial::shiftable(n); - - // Evaluate the polynomials at the multivariate challenge, poly3 is not evaluated, because it is 0. - auto eval1 = poly1.evaluate_mle(mle_opening_point); - auto eval2 = poly2.evaluate_mle(mle_opening_point); - Fr eval3{ 0 }; - Fr eval3_shift{ 0 }; - auto eval2_shift = poly2.evaluate_mle(mle_opening_point, true); - - // Collect multilinear evaluations - std::vector multilinear_evaluations = { eval1, eval2, eval3, eval2_shift, eval3_shift }; - std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); - - 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_unshifted.add_scaled(poly3, rhos[2]); - batched_to_be_shifted.add_scaled(poly2, rhos[3]); - batched_to_be_shifted.add_scaled(poly3, rhos[4]); - - // 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)); - - std::vector prover_commitments; - for (size_t l = 0; l < log_n - 1; ++l) { - auto commitment = this->ck()->commit(gemini_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); - - 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; - prover_evaluations.emplace_back(evaluation); - } - - std::vector r_squares = gemini::powers_of_evaluation_challenge(gemini_eval_challenge, log_n); - - GroupElement expected_result = GroupElement::zero(); - std::vector expected_inverse_vanishing_evals(log_n + 1); - // Compute expected inverses - expected_inverse_vanishing_evals[0] = (shplonk_eval_challenge - r_squares[0]).invert(); - expected_inverse_vanishing_evals[1] = (shplonk_eval_challenge + r_squares[0]).invert(); - expected_inverse_vanishing_evals[2] = (shplonk_eval_challenge + r_squares[1]).invert(); - expected_inverse_vanishing_evals[3] = (shplonk_eval_challenge + r_squares[2]).invert(); - expected_inverse_vanishing_evals[4] = (shplonk_eval_challenge + r_squares[3]).invert(); - - Fr current_challenge{ shplonk_batching_challenge * shplonk_batching_challenge }; - for (size_t idx = 0; idx < prover_commitments.size(); ++idx) { - expected_result -= prover_commitments[idx] * current_challenge * expected_inverse_vanishing_evals[idx + 2]; - current_challenge *= shplonk_batching_challenge; - } - - // Run the ShepliminiVerifier batching method - std::vector inverse_vanishing_evals = - ShplonkVerifier::compute_inverted_gemini_denominators(log_n + 1, shplonk_eval_challenge, r_squares); - - std::vector commitments; - std::vector scalars; - Fr expected_constant_term_accumulator{ 0 }; - - ShpleminiVerifier::batch_gemini_claims_received_from_prover(log_n, - prover_commitments, - prover_evaluations, - inverse_vanishing_evals, - shplonk_batching_challenge, - commitments, - scalars, - expected_constant_term_accumulator); - - EXPECT_EQ(commitments.size(), prover_commitments.size()); - // Compute the group element using the output of Shplemini method - GroupElement shplemini_result = Utils::batch_mul_native(commitments, scalars); - - EXPECT_EQ(shplemini_result, expected_result); -} -} // namespace bb +// #include "shplemini_verifier.hpp" +// #include "../commitment_key.test.hpp" +// #include "../gemini/gemini.hpp" +// #include "../kzg/kzg.hpp" +// #include "../shplonk/shplonk.hpp" +// #include "../utils/batch_mul_native.hpp" +// #include "barretenberg/commitment_schemes/claim.hpp" +// #include "barretenberg/ecc/curves/bn254/g1.hpp" + +// #include +// #include + +// namespace bb { + +// template class ShpleminiTest : public CommitmentTest { +// public: +// using Fr = typename Curve::ScalarField; +// using Commitment = typename Curve::AffineElement; +// using GroupElement = typename Curve::Element; +// using Polynomial = bb::Polynomial; +// }; + +// using CurveTypes = ::testing::Types; + +// TYPED_TEST_SUITE(ShpleminiTest, CurveTypes); + +// // This test checks that batch_multivariate_opening_claims method operates correctly +// TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching) +// { +// using ShpleminiVerifier = ShpleminiVerifier_; +// using Fr = typename TypeParam::ScalarField; +// using GroupElement = typename TypeParam::Element; +// using Commitment = typename TypeParam::AffineElement; +// using Polynomial = typename bb::Polynomial; +// using Utils = CommitmentSchemesUtils; + +// const size_t n = 16; +// const size_t log_n = 4; + +// // Generate mock challenges +// Fr rho = Fr::random_element(); +// Fr gemini_eval_challenge = Fr::random_element(); +// Fr shplonk_batching_challenge = Fr::random_element(); +// Fr shplonk_eval_challenge = Fr::random_element(); + +// // Generate multilinear polynomials and compute their commitments +// auto mle_opening_point = this->random_evaluation_point(log_n); +// auto poly1 = Polynomial::random(n); +// auto poly2 = Polynomial::random(n, /*shiftable*/ 1); +// Polynomial poly3(n); + +// Commitment commitment1 = this->commit(poly1); +// Commitment commitment2 = this->commit(poly2); +// Commitment commitment3 = this->commit(poly3); +// EXPECT_TRUE(commitment3.is_point_at_infinity()); + +// std::vector unshifted_commitments = { commitment1, commitment2, commitment3 }; +// std::vector shifted_commitments = { commitment2, commitment3 }; + +// // Evaluate the polynomials at the multivariate challenge, poly3 is not evaluated, because it is 0. +// auto eval1 = poly1.evaluate_mle(mle_opening_point); +// auto eval2 = poly2.evaluate_mle(mle_opening_point); +// Fr eval3{ 0 }; +// Fr eval3_shift{ 0 }; +// auto eval2_shift = poly2.evaluate_mle(mle_opening_point, true); + +// // Collect multilinear evaluations +// std::vector multilinear_evaluations = { eval1, eval2, eval3, eval2_shift, eval3_shift }; +// std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); + +// // Compute batched multivariate evaluation +// Fr batched_evaluation = +// std::inner_product(multilinear_evaluations.begin(), multilinear_evaluations.end(), rhos.begin(), Fr::zero()); + +// // Compute batched commitments manually +// GroupElement batched_commitment_unshifted = commitment1 * rhos[0] + commitment2 * rhos[1] + commitment3 * +// rhos[2]; GroupElement batched_commitment_to_be_shifted = commitment2 * rhos[3] + commitment3 * rhos[4]; + +// // Compute expected result manually +// GroupElement commitment_to_univariate = +// batched_commitment_unshifted + batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); +// GroupElement commitment_to_univariate_neg = +// batched_commitment_unshifted - batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); + +// GroupElement expected_result = +// commitment_to_univariate * (shplonk_eval_challenge - gemini_eval_challenge).invert() + +// commitment_to_univariate_neg * +// (shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert()); + +// // Run the ShepliminiVerifier batching method +// std::vector commitments; +// std::vector scalars; +// Fr verifier_batched_evaluation{ 0 }; + +// Fr unshifted_scalar = (shplonk_eval_challenge - gemini_eval_challenge).invert() + +// shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert(); + +// Fr shifted_scalar = gemini_eval_challenge.invert() * +// ((shplonk_eval_challenge - gemini_eval_challenge).invert() - +// shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert()); + +// ShpleminiVerifier::batch_multivariate_opening_claims(RefVector(unshifted_commitments), +// RefVector(shifted_commitments), +// RefVector(multilinear_evaluations), +// rho, +// unshifted_scalar, +// shifted_scalar, +// commitments, +// scalars, +// verifier_batched_evaluation); + +// // Final pairing check +// GroupElement shplemini_result = Utils::batch_mul_native(commitments, scalars); + +// EXPECT_EQ(commitments.size(), unshifted_commitments.size() + shifted_commitments.size()); +// EXPECT_EQ(batched_evaluation, verifier_batched_evaluation); +// EXPECT_EQ(-expected_result, shplemini_result); +// } + +// TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching) +// { +// using GeminiProver = GeminiProver_; +// using ShpleminiVerifier = ShpleminiVerifier_; +// using ShplonkVerifier = ShplonkVerifier_; +// using Fr = typename TypeParam::ScalarField; +// using GroupElement = typename TypeParam::Element; +// using Commitment = typename TypeParam::AffineElement; +// using Polynomial = typename bb::Polynomial; +// using Utils = CommitmentSchemesUtils; + +// const size_t n = 16; +// const size_t log_n = 4; + +// // Generate mock challenges +// Fr rho = Fr::random_element(); +// Fr gemini_eval_challenge = Fr::random_element(); +// Fr shplonk_batching_challenge = Fr::random_element(); +// Fr shplonk_eval_challenge = Fr::random_element(); + +// // Generate multilinear polynomials and compute their commitments +// auto mle_opening_point = this->random_evaluation_point(log_n); +// auto poly1 = Polynomial::random(n); +// auto poly2 = Polynomial::random(n, /*shiftable*/ 1); +// Polynomial poly3 = Polynomial::shiftable(n); + +// // Evaluate the polynomials at the multivariate challenge, poly3 is not evaluated, because it is 0. +// auto eval1 = poly1.evaluate_mle(mle_opening_point); +// auto eval2 = poly2.evaluate_mle(mle_opening_point); +// Fr eval3{ 0 }; +// Fr eval3_shift{ 0 }; +// auto eval2_shift = poly2.evaluate_mle(mle_opening_point, true); + +// // Collect multilinear evaluations +// std::vector multilinear_evaluations = { eval1, eval2, eval3, eval2_shift, eval3_shift }; +// std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); + +// 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_unshifted.add_scaled(poly3, rhos[2]); +// batched_to_be_shifted.add_scaled(poly2, rhos[3]); +// batched_to_be_shifted.add_scaled(poly3, rhos[4]); + +// // 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_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]); +// 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); + +// 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; +// prover_evaluations.emplace_back(evaluation); +// } + +// std::vector r_squares = gemini::powers_of_evaluation_challenge(gemini_eval_challenge, log_n); + +// GroupElement expected_result = GroupElement::zero(); +// std::vector expected_inverse_vanishing_evals(log_n + 1); +// // Compute expected inverses +// expected_inverse_vanishing_evals[0] = (shplonk_eval_challenge - r_squares[0]).invert(); +// expected_inverse_vanishing_evals[1] = (shplonk_eval_challenge + r_squares[0]).invert(); +// expected_inverse_vanishing_evals[2] = (shplonk_eval_challenge + r_squares[1]).invert(); +// expected_inverse_vanishing_evals[3] = (shplonk_eval_challenge + r_squares[2]).invert(); +// expected_inverse_vanishing_evals[4] = (shplonk_eval_challenge + r_squares[3]).invert(); + +// Fr current_challenge{ shplonk_batching_challenge * shplonk_batching_challenge }; +// for (size_t idx = 0; idx < prover_commitments.size(); ++idx) { +// expected_result -= prover_commitments[idx] * current_challenge * expected_inverse_vanishing_evals[idx + 2]; +// current_challenge *= shplonk_batching_challenge; +// } + +// // Run the ShepliminiVerifier batching method +// std::vector inverse_vanishing_evals = +// ShplonkVerifier::compute_inverted_gemini_denominators(log_n + 1, shplonk_eval_challenge, r_squares); + +// std::vector commitments; +// std::vector scalars; +// Fr expected_constant_term_accumulator{ 0 }; + +// ShpleminiVerifier::batch_gemini_claims_received_from_prover(log_n, +// prover_commitments, +// prover_evaluations, +// inverse_vanishing_evals, +// shplonk_batching_challenge, +// commitments, +// scalars, +// expected_constant_term_accumulator); + +// EXPECT_EQ(commitments.size(), prover_commitments.size()); +// // Compute the group element using the output of Shplemini method +// GroupElement shplemini_result = Utils::batch_mul_native(commitments, scalars); + +// EXPECT_EQ(shplemini_result, expected_result); +// } +// } // namespace bb 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..e1ef297a388 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes_recursion/shplemini.test.cpp @@ -108,7 +108,7 @@ TEST(ShpleminiRecursionTest, ProveAndVerifySingle) }; // Compute d-1 polynomials Fold^(i), i = 1, ..., d-1. - auto fold_polynomials = GeminiProver::compute_gemini_polynomials( + auto fold_polynomials = GeminiProver::compute_fold_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) { @@ -117,8 +117,8 @@ TEST(ShpleminiRecursionTest, ProveAndVerifySingle) } 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); + const auto [gemini_opening_pairs, gemini_witnesses] = GeminiProver::compute_fold_polynomial_evaluations( + u_challenge, std::move(fold_polynomials), r_challenge, prover_transcript); std::vector> opening_claims; for (size_t l = 0; l < log_circuit_size; ++l) { diff --git a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp index fa6608456c5..894be20c83e 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp @@ -69,6 +69,13 @@ template class Polynomial { : Polynomial(coefficients, coefficients.size()) {} + /** + * @brief Utility to efficiently construct a shift from the original polynomial. + * + * @details We define the shift of a polynomial F(X) as G(X) = F(X) / X. + * @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. From 7dd17f0c2c40e289c3576213e53854bc1bf4f376 Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 18 Sep 2024 13:06:12 +0000 Subject: [PATCH 2/5] fix shplemini --- .../commitment_schemes/gemini/gemini.cpp | 14 +- .../commitment_schemes/gemini/gemini.hpp | 3 +- .../shplonk/shplemini_verifier.test.cpp | 453 +++++++++--------- .../shplemini.test.cpp | 46 +- .../barretenberg/polynomials/polynomial.hpp | 1 - 5 files changed, 241 insertions(+), 276 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp index 1518dcf4e15..3fe4d8425ef 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp @@ -87,8 +87,12 @@ std::vector::Claim> GeminiProver_::prove( commitment_key->commit(fold_polynomials[l + 2])); } const Fr r_challenge = transcript->template get_challenge("Gemini:r"); - return compute_fold_polynomial_evaluations( - multilinear_challenge, std::move(fold_polynomials), r_challenge, transcript); + 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; }; /** @@ -190,10 +194,7 @@ std::vector::Polynomial> GeminiProver_::com */ template std::vector::Claim> GeminiProver_::compute_fold_polynomial_evaluations( - std::span mle_opening_point, - std::vector&& fold_polynomials, - const Fr& r_challenge, - std::shared_ptr& transcript) + std::span mle_opening_point, std::vector&& fold_polynomials, const Fr& r_challenge) { const size_t num_variables = mle_opening_point.size(); // m @@ -231,7 +232,6 @@ std::vector::Claim> GeminiProver_::compute_ // Compute the remaining m opening pairs {−r^{2ˡ}, Aₗ(−r^{2ˡ})}, l = 0, ..., m-1. for (size_t l = 0; l < num_variables; ++l) { evaluation = fold_polynomials[l + 1].evaluate(-r_squares[l]); - transcript->send_to_verifier("Gemini:a_" + std::to_string(l + 1), evaluation); opening_claims.emplace_back(Claim{ fold_polynomials[l + 1], { -r_squares[l], evaluation } }); } diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp index 89c1dc8acf9..e6d19e0dddb 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp @@ -107,8 +107,7 @@ template class GeminiProver_ { static std::vector compute_fold_polynomial_evaluations(std::span multilinear_evaluations, std::vector&& gemini_polynomials, - const Fr& r_challenge, - std::shared_ptr& transcript); + const Fr& r_challenge); // TODO(Mara): consider if we should template this by transcript to use with a test transcript static std::vector prove(const std::shared_ptr>& commitment_key, 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 c04359b5a2a..194c9f7d361 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 @@ -1,228 +1,227 @@ -// #include "shplemini_verifier.hpp" -// #include "../commitment_key.test.hpp" -// #include "../gemini/gemini.hpp" -// #include "../kzg/kzg.hpp" -// #include "../shplonk/shplonk.hpp" -// #include "../utils/batch_mul_native.hpp" -// #include "barretenberg/commitment_schemes/claim.hpp" -// #include "barretenberg/ecc/curves/bn254/g1.hpp" - -// #include -// #include - -// namespace bb { - -// template class ShpleminiTest : public CommitmentTest { -// public: -// using Fr = typename Curve::ScalarField; -// using Commitment = typename Curve::AffineElement; -// using GroupElement = typename Curve::Element; -// using Polynomial = bb::Polynomial; -// }; - -// using CurveTypes = ::testing::Types; - -// TYPED_TEST_SUITE(ShpleminiTest, CurveTypes); - -// // This test checks that batch_multivariate_opening_claims method operates correctly -// TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching) -// { -// using ShpleminiVerifier = ShpleminiVerifier_; -// using Fr = typename TypeParam::ScalarField; -// using GroupElement = typename TypeParam::Element; -// using Commitment = typename TypeParam::AffineElement; -// using Polynomial = typename bb::Polynomial; -// using Utils = CommitmentSchemesUtils; - -// const size_t n = 16; -// const size_t log_n = 4; - -// // Generate mock challenges -// Fr rho = Fr::random_element(); -// Fr gemini_eval_challenge = Fr::random_element(); -// Fr shplonk_batching_challenge = Fr::random_element(); -// Fr shplonk_eval_challenge = Fr::random_element(); - -// // Generate multilinear polynomials and compute their commitments -// auto mle_opening_point = this->random_evaluation_point(log_n); -// auto poly1 = Polynomial::random(n); -// auto poly2 = Polynomial::random(n, /*shiftable*/ 1); -// Polynomial poly3(n); - -// Commitment commitment1 = this->commit(poly1); -// Commitment commitment2 = this->commit(poly2); -// Commitment commitment3 = this->commit(poly3); -// EXPECT_TRUE(commitment3.is_point_at_infinity()); - -// std::vector unshifted_commitments = { commitment1, commitment2, commitment3 }; -// std::vector shifted_commitments = { commitment2, commitment3 }; - -// // Evaluate the polynomials at the multivariate challenge, poly3 is not evaluated, because it is 0. -// auto eval1 = poly1.evaluate_mle(mle_opening_point); -// auto eval2 = poly2.evaluate_mle(mle_opening_point); -// Fr eval3{ 0 }; -// Fr eval3_shift{ 0 }; -// auto eval2_shift = poly2.evaluate_mle(mle_opening_point, true); - -// // Collect multilinear evaluations -// std::vector multilinear_evaluations = { eval1, eval2, eval3, eval2_shift, eval3_shift }; -// std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); - -// // Compute batched multivariate evaluation -// Fr batched_evaluation = -// std::inner_product(multilinear_evaluations.begin(), multilinear_evaluations.end(), rhos.begin(), Fr::zero()); - -// // Compute batched commitments manually -// GroupElement batched_commitment_unshifted = commitment1 * rhos[0] + commitment2 * rhos[1] + commitment3 * -// rhos[2]; GroupElement batched_commitment_to_be_shifted = commitment2 * rhos[3] + commitment3 * rhos[4]; - -// // Compute expected result manually -// GroupElement commitment_to_univariate = -// batched_commitment_unshifted + batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); -// GroupElement commitment_to_univariate_neg = -// batched_commitment_unshifted - batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); - -// GroupElement expected_result = -// commitment_to_univariate * (shplonk_eval_challenge - gemini_eval_challenge).invert() + -// commitment_to_univariate_neg * -// (shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert()); - -// // Run the ShepliminiVerifier batching method -// std::vector commitments; -// std::vector scalars; -// Fr verifier_batched_evaluation{ 0 }; - -// Fr unshifted_scalar = (shplonk_eval_challenge - gemini_eval_challenge).invert() + -// shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert(); - -// Fr shifted_scalar = gemini_eval_challenge.invert() * -// ((shplonk_eval_challenge - gemini_eval_challenge).invert() - -// shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert()); - -// ShpleminiVerifier::batch_multivariate_opening_claims(RefVector(unshifted_commitments), -// RefVector(shifted_commitments), -// RefVector(multilinear_evaluations), -// rho, -// unshifted_scalar, -// shifted_scalar, -// commitments, -// scalars, -// verifier_batched_evaluation); - -// // Final pairing check -// GroupElement shplemini_result = Utils::batch_mul_native(commitments, scalars); - -// EXPECT_EQ(commitments.size(), unshifted_commitments.size() + shifted_commitments.size()); -// EXPECT_EQ(batched_evaluation, verifier_batched_evaluation); -// EXPECT_EQ(-expected_result, shplemini_result); -// } - -// TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching) -// { -// using GeminiProver = GeminiProver_; -// using ShpleminiVerifier = ShpleminiVerifier_; -// using ShplonkVerifier = ShplonkVerifier_; -// using Fr = typename TypeParam::ScalarField; -// using GroupElement = typename TypeParam::Element; -// using Commitment = typename TypeParam::AffineElement; -// using Polynomial = typename bb::Polynomial; -// using Utils = CommitmentSchemesUtils; - -// const size_t n = 16; -// const size_t log_n = 4; - -// // Generate mock challenges -// Fr rho = Fr::random_element(); -// Fr gemini_eval_challenge = Fr::random_element(); -// Fr shplonk_batching_challenge = Fr::random_element(); -// Fr shplonk_eval_challenge = Fr::random_element(); - -// // Generate multilinear polynomials and compute their commitments -// auto mle_opening_point = this->random_evaluation_point(log_n); -// auto poly1 = Polynomial::random(n); -// auto poly2 = Polynomial::random(n, /*shiftable*/ 1); -// Polynomial poly3 = Polynomial::shiftable(n); - -// // Evaluate the polynomials at the multivariate challenge, poly3 is not evaluated, because it is 0. -// auto eval1 = poly1.evaluate_mle(mle_opening_point); -// auto eval2 = poly2.evaluate_mle(mle_opening_point); -// Fr eval3{ 0 }; -// Fr eval3_shift{ 0 }; -// auto eval2_shift = poly2.evaluate_mle(mle_opening_point, true); - -// // Collect multilinear evaluations -// std::vector multilinear_evaluations = { eval1, eval2, eval3, eval2_shift, eval3_shift }; -// std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); - -// 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_unshifted.add_scaled(poly3, rhos[2]); -// batched_to_be_shifted.add_scaled(poly2, rhos[3]); -// batched_to_be_shifted.add_scaled(poly3, rhos[4]); - -// // 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_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]); -// 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); - -// 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; -// prover_evaluations.emplace_back(evaluation); -// } - -// std::vector r_squares = gemini::powers_of_evaluation_challenge(gemini_eval_challenge, log_n); - -// GroupElement expected_result = GroupElement::zero(); -// std::vector expected_inverse_vanishing_evals(log_n + 1); -// // Compute expected inverses -// expected_inverse_vanishing_evals[0] = (shplonk_eval_challenge - r_squares[0]).invert(); -// expected_inverse_vanishing_evals[1] = (shplonk_eval_challenge + r_squares[0]).invert(); -// expected_inverse_vanishing_evals[2] = (shplonk_eval_challenge + r_squares[1]).invert(); -// expected_inverse_vanishing_evals[3] = (shplonk_eval_challenge + r_squares[2]).invert(); -// expected_inverse_vanishing_evals[4] = (shplonk_eval_challenge + r_squares[3]).invert(); - -// Fr current_challenge{ shplonk_batching_challenge * shplonk_batching_challenge }; -// for (size_t idx = 0; idx < prover_commitments.size(); ++idx) { -// expected_result -= prover_commitments[idx] * current_challenge * expected_inverse_vanishing_evals[idx + 2]; -// current_challenge *= shplonk_batching_challenge; -// } - -// // Run the ShepliminiVerifier batching method -// std::vector inverse_vanishing_evals = -// ShplonkVerifier::compute_inverted_gemini_denominators(log_n + 1, shplonk_eval_challenge, r_squares); - -// std::vector commitments; -// std::vector scalars; -// Fr expected_constant_term_accumulator{ 0 }; - -// ShpleminiVerifier::batch_gemini_claims_received_from_prover(log_n, -// prover_commitments, -// prover_evaluations, -// inverse_vanishing_evals, -// shplonk_batching_challenge, -// commitments, -// scalars, -// expected_constant_term_accumulator); - -// EXPECT_EQ(commitments.size(), prover_commitments.size()); -// // Compute the group element using the output of Shplemini method -// GroupElement shplemini_result = Utils::batch_mul_native(commitments, scalars); - -// EXPECT_EQ(shplemini_result, expected_result); -// } -// } // namespace bb +#include "shplemini_verifier.hpp" +#include "../commitment_key.test.hpp" +#include "../gemini/gemini.hpp" +#include "../kzg/kzg.hpp" +#include "../shplonk/shplonk.hpp" +#include "../utils/batch_mul_native.hpp" +#include "barretenberg/commitment_schemes/claim.hpp" +#include "barretenberg/ecc/curves/bn254/g1.hpp" + +#include +#include + +namespace bb { + +template class ShpleminiTest : public CommitmentTest { + public: + using Fr = typename Curve::ScalarField; + using Commitment = typename Curve::AffineElement; + using GroupElement = typename Curve::Element; + using Polynomial = bb::Polynomial; +}; + +using CurveTypes = ::testing::Types; + +TYPED_TEST_SUITE(ShpleminiTest, CurveTypes); + +// This test checks that batch_multivariate_opening_claims method operates correctly +TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching) +{ + using ShpleminiVerifier = ShpleminiVerifier_; + using Fr = typename TypeParam::ScalarField; + using GroupElement = typename TypeParam::Element; + using Commitment = typename TypeParam::AffineElement; + using Polynomial = typename bb::Polynomial; + using Utils = CommitmentSchemesUtils; + + const size_t n = 16; + const size_t log_n = 4; + + // Generate mock challenges + Fr rho = Fr::random_element(); + Fr gemini_eval_challenge = Fr::random_element(); + Fr shplonk_batching_challenge = Fr::random_element(); + Fr shplonk_eval_challenge = Fr::random_element(); + + // Generate multilinear polynomials and compute their commitments + auto mle_opening_point = this->random_evaluation_point(log_n); + auto poly1 = Polynomial::random(n); + auto poly2 = Polynomial::random(n, /*shiftable*/ 1); + Polynomial poly3(n); + + Commitment commitment1 = this->commit(poly1); + Commitment commitment2 = this->commit(poly2); + Commitment commitment3 = this->commit(poly3); + EXPECT_TRUE(commitment3.is_point_at_infinity()); + + std::vector unshifted_commitments = { commitment1, commitment2, commitment3 }; + std::vector shifted_commitments = { commitment2, commitment3 }; + + // Evaluate the polynomials at the multivariate challenge, poly3 is not evaluated, because it is 0. + auto eval1 = poly1.evaluate_mle(mle_opening_point); + auto eval2 = poly2.evaluate_mle(mle_opening_point); + Fr eval3{ 0 }; + Fr eval3_shift{ 0 }; + auto eval2_shift = poly2.evaluate_mle(mle_opening_point, true); + + // Collect multilinear evaluations + std::vector multilinear_evaluations = { eval1, eval2, eval3, eval2_shift, eval3_shift }; + std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); + + // Compute batched multivariate evaluation + Fr batched_evaluation = + std::inner_product(multilinear_evaluations.begin(), multilinear_evaluations.end(), rhos.begin(), Fr::zero()); + + // Compute batched commitments manually + GroupElement batched_commitment_unshifted = commitment1 * rhos[0] + commitment2 * rhos[1] + commitment3 * rhos[2]; + GroupElement batched_commitment_to_be_shifted = commitment2 * rhos[3] + commitment3 * rhos[4]; + + // Compute expected result manually + GroupElement commitment_to_univariate = + batched_commitment_unshifted + batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); + GroupElement commitment_to_univariate_neg = + batched_commitment_unshifted - batched_commitment_to_be_shifted * gemini_eval_challenge.invert(); + + GroupElement expected_result = + commitment_to_univariate * (shplonk_eval_challenge - gemini_eval_challenge).invert() + + commitment_to_univariate_neg * + (shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert()); + + // Run the ShepliminiVerifier batching method + std::vector commitments; + std::vector scalars; + Fr verifier_batched_evaluation{ 0 }; + + Fr unshifted_scalar = (shplonk_eval_challenge - gemini_eval_challenge).invert() + + shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert(); + + Fr shifted_scalar = gemini_eval_challenge.invert() * + ((shplonk_eval_challenge - gemini_eval_challenge).invert() - + shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert()); + + ShpleminiVerifier::batch_multivariate_opening_claims(RefVector(unshifted_commitments), + RefVector(shifted_commitments), + RefVector(multilinear_evaluations), + rho, + unshifted_scalar, + shifted_scalar, + commitments, + scalars, + verifier_batched_evaluation); + + // Final pairing check + GroupElement shplemini_result = Utils::batch_mul_native(commitments, scalars); + + EXPECT_EQ(commitments.size(), unshifted_commitments.size() + shifted_commitments.size()); + EXPECT_EQ(batched_evaluation, verifier_batched_evaluation); + EXPECT_EQ(-expected_result, shplemini_result); +} + +TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching) +{ + using GeminiProver = GeminiProver_; + using ShpleminiVerifier = ShpleminiVerifier_; + using ShplonkVerifier = ShplonkVerifier_; + using Fr = typename TypeParam::ScalarField; + using GroupElement = typename TypeParam::Element; + using Commitment = typename TypeParam::AffineElement; + using Polynomial = typename bb::Polynomial; + using Utils = CommitmentSchemesUtils; + + const size_t n = 16; + const size_t log_n = 4; + + // Generate mock challenges + Fr rho = Fr::random_element(); + Fr gemini_eval_challenge = Fr::random_element(); + Fr shplonk_batching_challenge = Fr::random_element(); + Fr shplonk_eval_challenge = Fr::random_element(); + + // Generate multilinear polynomials and compute their commitments + auto mle_opening_point = this->random_evaluation_point(log_n); + auto poly1 = Polynomial::random(n); + auto poly2 = Polynomial::random(n, /*shiftable*/ 1); + Polynomial poly3 = Polynomial::shiftable(n); + + // Evaluate the polynomials at the multivariate challenge, poly3 is not evaluated, because it is 0. + auto eval1 = poly1.evaluate_mle(mle_opening_point); + auto eval2 = poly2.evaluate_mle(mle_opening_point); + Fr eval3{ 0 }; + Fr eval3_shift{ 0 }; + auto eval2_shift = poly2.evaluate_mle(mle_opening_point, true); + + // Collect multilinear evaluations + std::vector multilinear_evaluations = { eval1, eval2, eval3, eval2_shift, eval3_shift }; + std::vector rhos = gemini::powers_of_rho(rho, multilinear_evaluations.size()); + + 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_unshifted.add_scaled(poly3, rhos[2]); + batched_to_be_shifted.add_scaled(poly2, rhos[3]); + batched_to_be_shifted.add_scaled(poly3, rhos[4]); + + // 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_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]); + prover_commitments.emplace_back(commitment); + } + + const auto opening_claims = GeminiProver::compute_fold_polynomial_evaluations( + mle_opening_point, std::move(gemini_polynomials), gemini_eval_challenge); + + std::vector prover_evaluations; + for (size_t l = 0; l < log_n; ++l) { + const auto& evaluation = opening_claims[l + 1].opening_pair.evaluation; + prover_evaluations.emplace_back(evaluation); + } + + std::vector r_squares = gemini::powers_of_evaluation_challenge(gemini_eval_challenge, log_n); + + GroupElement expected_result = GroupElement::zero(); + std::vector expected_inverse_vanishing_evals(log_n + 1); + // Compute expected inverses + expected_inverse_vanishing_evals[0] = (shplonk_eval_challenge - r_squares[0]).invert(); + expected_inverse_vanishing_evals[1] = (shplonk_eval_challenge + r_squares[0]).invert(); + expected_inverse_vanishing_evals[2] = (shplonk_eval_challenge + r_squares[1]).invert(); + expected_inverse_vanishing_evals[3] = (shplonk_eval_challenge + r_squares[2]).invert(); + expected_inverse_vanishing_evals[4] = (shplonk_eval_challenge + r_squares[3]).invert(); + + Fr current_challenge{ shplonk_batching_challenge * shplonk_batching_challenge }; + for (size_t idx = 0; idx < prover_commitments.size(); ++idx) { + expected_result -= prover_commitments[idx] * current_challenge * expected_inverse_vanishing_evals[idx + 2]; + current_challenge *= shplonk_batching_challenge; + } + + // Run the ShepliminiVerifier batching method + std::vector inverse_vanishing_evals = + ShplonkVerifier::compute_inverted_gemini_denominators(log_n + 1, shplonk_eval_challenge, r_squares); + + std::vector commitments; + std::vector scalars; + Fr expected_constant_term_accumulator{ 0 }; + + ShpleminiVerifier::batch_gemini_claims_received_from_prover(log_n, + prover_commitments, + prover_evaluations, + inverse_vanishing_evals, + shplonk_batching_challenge, + commitments, + scalars, + expected_constant_term_accumulator); + + EXPECT_EQ(commitments.size(), prover_commitments.size()); + // Compute the group element using the output of Shplemini method + GroupElement shplemini_result = Utils::batch_mul_native(commitments, scalars); + + EXPECT_EQ(shplemini_result, expected_result); +} +} // 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 e1ef297a388..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_fold_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, prover_transcript); - - 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/polynomials/polynomial.hpp b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp index 894be20c83e..9ed1c255b2c 100644 --- a/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp +++ b/barretenberg/cpp/src/barretenberg/polynomials/polynomial.hpp @@ -72,7 +72,6 @@ template class Polynomial { /** * @brief Utility to efficiently construct a shift from the original polynomial. * - * @details We define the shift of a polynomial F(X) as G(X) = F(X) / X. * @param virtual_size the size of the polynomial to be shifted * @return Polynomial */ From 1f5c083051da4b5f470757f03e2185451bde1109 Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 18 Sep 2024 13:26:53 +0000 Subject: [PATCH 3/5] cleanup --- .../commitment_schemes/gemini/gemini.cpp | 33 ++++++++----------- .../commitment_schemes/gemini/gemini.hpp | 16 ++++----- .../commitment_schemes/gemini/gemini.test.cpp | 18 +++------- .../shplonk/shplemini_verifier.hpp | 12 +++---- .../shplonk/shplemini_verifier.test.cpp | 6 ++-- .../src/barretenberg/eccvm/eccvm_prover.hpp | 3 -- 6 files changed, 35 insertions(+), 53 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp index 3fe4d8425ef..2a9abea0c52 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.cpp @@ -1,9 +1,6 @@ #include "gemini.hpp" #include "barretenberg/common/thread.hpp" -#include -#include - /** * @brief Protocol for opening several multi-linear polynomials at the same point. * @@ -51,6 +48,9 @@ std::vector::Claim> GeminiProver_::prove( 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()); @@ -60,11 +60,8 @@ std::vector::Claim> GeminiProver_::prove( batched_evaluation += multilinear_evaluations[i] * rhos[i]; } - size_t log_n = multilinear_challenge.size(); - size_t n = 1 << log_n; // Compute batched polynomials Polynomial batched_unshifted(n); - // TODO(mara): use shiftable, after you understand how it works Polynomial batched_to_be_shifted = Polynomial::shiftable(1 << log_n); const size_t num_unshifted = f_polynomials.size(); @@ -76,12 +73,9 @@ std::vector::Claim> GeminiProver_::prove( batched_to_be_shifted.add_scaled(g_polynomials[i], rhos[num_unshifted + i]); } - // log_n + 2 auto fold_polynomials = compute_fold_polynomials(multilinear_challenge, std::move(batched_unshifted), std::move(batched_to_be_shifted)); - // Commit to the folded polynomials (except the first two, explain why the first two are left out) and send the - // commitment to the verifier 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])); @@ -89,9 +83,11 @@ std::vector::Claim> GeminiProver_::prove( 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; }; @@ -107,7 +103,6 @@ template 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 const size_t num_threads = get_num_cpus_pow2(); @@ -119,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; @@ -136,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 @@ -158,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; @@ -175,20 +170,20 @@ 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 */ diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp index e6d19e0dddb..9e208baf4a1 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp @@ -4,8 +4,6 @@ #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/transcript/transcript.hpp" -#include - /** * @brief Protocol for opening several multi-linear polynomials at the same point. * @@ -106,7 +104,7 @@ template class GeminiProver_ { Polynomial&& batched_to_be_shifted); static std::vector compute_fold_polynomial_evaluations(std::span multilinear_evaluations, - std::vector&& gemini_polynomials, + std::vector&& fold_polynomials, const Fr& r_challenge); // TODO(Mara): consider if we should template this by transcript to use with a test transcript @@ -165,7 +163,7 @@ template class GeminiVerifier_ { } // 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"); @@ -198,16 +196,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) { 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 a7a7a86b483..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,8 +13,7 @@ template class GeminiTest : public CommitmentTest { using GroupElement = typename Curve::Element; public: - void execute_gemini_and_verify_claims([[maybe_unused]] size_t log_n, - std::vector& multilinear_evaluation_point, + 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, @@ -82,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, @@ -114,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, @@ -149,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, @@ -185,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/shplonk/shplemini_verifier.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.hpp index 53893f7b0cb..842e91f8b53 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/shplonk/shplemini_verifier.hpp @@ -93,8 +93,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²⁽ⁿ⁻¹⁾)) @@ -152,7 +152,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, @@ -283,7 +283,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. @@ -293,7 +293,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, @@ -313,7 +313,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 194c9f7d361..01f9961127a 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 @@ -166,17 +166,17 @@ 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_fold_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 opening_claims = GeminiProver::compute_fold_polynomial_evaluations( - mle_opening_point, std::move(gemini_polynomials), gemini_eval_challenge); + mle_opening_point, std::move(fold_polynomials), gemini_eval_challenge); std::vector prover_evaluations; for (size_t l = 0; l < log_n; ++l) { 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 From 318f98b1132cc477ce28bd709686604f8ab74e1d Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 18 Sep 2024 13:33:16 +0000 Subject: [PATCH 4/5] more cleanup --- barretenberg/cpp/CMakePresets.json | 2 +- .../commitment_schemes/commitment_key.test.hpp | 17 ----------------- .../commitment_schemes/ipa/ipa.test.cpp | 4 ++-- .../commitment_schemes/kzg/kzg.test.cpp | 2 -- 4 files changed, 3 insertions(+), 22 deletions(-) diff --git a/barretenberg/cpp/CMakePresets.json b/barretenberg/cpp/CMakePresets.json index f841f6954b9..643e4590ae2 100644 --- a/barretenberg/cpp/CMakePresets.json +++ b/barretenberg/cpp/CMakePresets.json @@ -98,7 +98,7 @@ "displayName": "Debugging build with Clang-16", "description": "Build with globally installed Clang-16 in debug mode", "inherits": "clang16", - "binaryDir": "build", + "binaryDir": "build-debug", "environment": { "CMAKE_BUILD_TYPE": "Debug", "CFLAGS": "-gdwarf-4", 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 d40cf153d54..27ec8408c12 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,17 +97,9 @@ 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"; } - void verify_opening_pair(const OpeningPair& opening_pair, const Polynomial& witness) - { - auto& [x, y] = opening_pair; - Fr y_expected = witness.evaluate(x); - EXPECT_EQ(y, y_expected) << "OpeningPair: evaluations mismatch"; - } - /** * @brief Ensures that a 'BatchOpeningClaim' is correct by checking that * - all evaluations are correct by recomputing them from each witness polynomial. 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 5905b5a7288..eb448f4e709 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/ipa/ipa.test.cpp @@ -77,8 +77,8 @@ TEST_F(IPATest, OpenZeroPolynomial) EXPECT_TRUE(result); } -// This test makes sure that even if the whole vector \vec{b} generated from the x, at which we open the polynomial, -// is zero, IPA behaves +// This test makes sure that even if the whole vector \vec{b} generated from the x, at which we open the polynomial, is +// zero, IPA behaves TEST_F(IPATest, OpenAtZero) { using IPA = IPA; 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 92e7f2614e6..60f41bdb7f5 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/kzg/kzg.test.cpp @@ -140,13 +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; - // 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' From d3bd8a8617dfcf0b2e4684e6c07657b88dacbf19 Mon Sep 17 00:00:00 2001 From: maramihali Date: Wed, 18 Sep 2024 13:48:37 +0000 Subject: [PATCH 5/5] wops, I forgot to commit an undo for a function removal --- .../commitment_schemes/commitment_key.test.hpp | 7 +++++++ .../src/barretenberg/commitment_schemes/gemini/gemini.hpp | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) 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 27ec8408c12..16464cda07f 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/commitment_key.test.hpp @@ -100,6 +100,13 @@ template class CommitmentTest : public ::testing::Test { EXPECT_EQ(commitment, commitment_expected) << "OpeningClaim: commitment mismatch"; } + void verify_opening_pair(const OpeningPair& opening_pair, const Polynomial& witness) + { + auto& [x, y] = opening_pair; + Fr y_expected = witness.evaluate(x); + EXPECT_EQ(y, y_expected) << "OpeningPair: evaluations mismatch"; + } + /** * @brief Ensures that a 'BatchOpeningClaim' is correct by checking that * - all evaluations are correct by recomputing them from each witness polynomial. diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp index 9e208baf4a1..e38f6891bd6 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/gemini/gemini.hpp @@ -107,7 +107,6 @@ template class GeminiProver_ { std::vector&& fold_polynomials, const Fr& r_challenge); - // TODO(Mara): consider if we should template this by transcript to use with a test transcript static std::vector prove(const std::shared_ptr>& commitment_key, std::span multilinear_challenge, std::span multilinear_evaluations,