3#include "../commitment_key.test.hpp"
4#include "../gemini/gemini.hpp"
5#include "../kzg/kzg.hpp"
6#include "../shplonk/shplonk.hpp"
7#include "../utils/batch_mul_native.hpp"
15#include <gtest/gtest.h>
23 static constexpr size_t log_n = 9;
24 static constexpr size_t n = 1UL <<
log_n;
33 using Fr =
typename Flavor::Curve::ScalarField;
35 using Commitment =
typename Flavor::Curve::AffineElement;
40using TestSettings = ::testing::Types<BN254Settings, GrumpkinSettings>;
47 static constexpr size_t log_n = 9;
48 static constexpr size_t n = 1UL <<
log_n;
54 using Curve =
typename TypeParam::Curve;
58 using CK =
typename TypeParam::CommitmentKey;
60 CK
ck = create_commitment_key<CK>(this->n);
69 auto mle_opening_point = this->random_evaluation_point(this->log_n);
72 this->num_polynomials,
81 auto update_batched_eval = [&](
Fr& batched_eval,
const std::vector<Fr>& evaluations,
Fr& rho_power) {
82 for (
auto& eval : evaluations) {
83 batched_eval += eval * rho_power;
89 Fr batched_evaluation(0);
90 update_batched_eval(batched_evaluation, mock_claims.
unshifted.
evals, rho_power);
94 auto compute_batched_commitment = [&](
const std::vector<Commitment>& commitments,
Fr& rho_power) {
95 GroupElement batched = GroupElement::zero();
96 for (
auto& comm : commitments) {
97 batched += comm * rho_power;
105 GroupElement batched_commitment_unshifted =
107 GroupElement batched_commitment_to_be_shifted =
111 GroupElement to_be_shifted_contribution = batched_commitment_to_be_shifted * gemini_eval_challenge.
invert();
113 GroupElement commitment_to_univariate_pos = batched_commitment_unshifted + to_be_shifted_contribution;
115 GroupElement commitment_to_univariate_neg = batched_commitment_unshifted - to_be_shifted_contribution;
118 commitment_to_univariate_pos * (shplonk_eval_challenge - gemini_eval_challenge).invert() +
119 commitment_to_univariate_neg *
120 (shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert());
123 std::vector<Commitment> commitments;
124 std::vector<Fr> scalars;
125 Fr verifier_batched_evaluation{ 0 };
127 Fr inverted_vanishing_eval_pos = (shplonk_eval_challenge - gemini_eval_challenge).invert();
128 Fr inverted_vanishing_eval_neg = (shplonk_eval_challenge + gemini_eval_challenge).invert();
130 std::vector<Fr> inverted_vanishing_evals = { inverted_vanishing_eval_pos, inverted_vanishing_eval_neg };
133 inverted_vanishing_evals, shplonk_batching_challenge, gemini_eval_challenge);
136 commitments, scalars, verifier_batched_evaluation, rho);
139 GroupElement shplemini_result = batch_mul_native<Curve>(commitments, scalars);
141 EXPECT_EQ(commitments.size(),
143 EXPECT_EQ(batched_evaluation, verifier_batched_evaluation);
148 using Curve = TypeParam::Curve;
156 using CK =
typename TypeParam::CommitmentKey;
158 CK
ck = create_commitment_key<CK>(this->n);
165 std::vector<Fr> shplonk_batching_challenge_powers =
166 compute_shplonk_batching_challenge_powers(shplonk_batching_challenge, this->log_n);
170 std::vector<Fr> mle_opening_point = this->random_evaluation_point(this->log_n);
173 this->num_polynomials,
186 auto fold_polynomials = GeminiProver::compute_fold_polynomials(this->log_n, mle_opening_point, batched);
188 std::vector<Commitment> prover_commitments;
189 for (
size_t l = 0; l < this->log_n - 1; ++l) {
190 auto commitment =
ck.commit(fold_polynomials[l]);
191 prover_commitments.emplace_back(commitment);
194 auto [A_0_pos, A_0_neg] =
197 const auto opening_claims = GeminiProver::construct_univariate_opening_claims(
200 std::vector<Fr> prover_evaluations;
201 for (
size_t l = 0; l < this->log_n; ++l) {
202 const auto& evaluation = opening_claims[l + 1].opening_pair.evaluation;
203 prover_evaluations.emplace_back(evaluation);
209 std::vector<Fr> expected_inverse_vanishing_evals;
210 expected_inverse_vanishing_evals.reserve(2 * this->log_n);
212 for (
size_t idx = 0; idx < this->log_n; idx++) {
213 expected_inverse_vanishing_evals.emplace_back((shplonk_eval_challenge - r_squares[idx]).invert());
214 expected_inverse_vanishing_evals.emplace_back((shplonk_eval_challenge + r_squares[idx]).invert());
217 Fr current_challenge{ shplonk_batching_challenge * shplonk_batching_challenge };
218 for (
size_t idx = 0; idx < prover_commitments.size(); ++idx) {
219 expected_result -= prover_commitments[idx] * current_challenge * expected_inverse_vanishing_evals[2 * idx + 2];
220 current_challenge *= shplonk_batching_challenge;
221 expected_result -= prover_commitments[idx] * current_challenge * expected_inverse_vanishing_evals[2 * idx + 3];
222 current_challenge *= shplonk_batching_challenge;
226 std::vector<Fr> inverse_vanishing_evals =
227 ShplonkVerifier::compute_inverted_gemini_denominators(shplonk_eval_challenge, r_squares);
229 Fr expected_constant_term_accumulator{ 0 };
230 std::vector<Fr> padding_indicator_array(this->log_n,
Fr{ 1 });
232 std::vector<Fr> gemini_fold_pos_evaluations =
234 expected_constant_term_accumulator,
238 expected_constant_term_accumulator);
239 std::vector<Commitment> commitments;
240 std::vector<Fr> scalars;
242 ShpleminiVerifier::batch_gemini_claims_received_from_prover(padding_indicator_array,
245 gemini_fold_pos_evaluations,
246 inverse_vanishing_evals,
247 shplonk_batching_challenge_powers,
250 expected_constant_term_accumulator);
253 GroupElement shplemini_result = batch_mul_native<Curve>(commitments, scalars);
266 using Curve = TypeParam::Curve;
271 using CK =
typename TypeParam::CommitmentKey;
274 auto prover_transcript = TypeParam::Transcript::prover_init_empty();
278 CK
ck = create_commitment_key<CK>(
std::max<size_t>(this->n, 1ULL << (log_subgroup_size + 1)));
281 ZKData zk_sumcheck_data(this->log_n, prover_transcript,
ck);
284 std::vector<Fr> mle_opening_point = this->random_evaluation_point(this->log_n);
288 this->num_polynomials,
295 zk_sumcheck_data, mle_opening_point, this->log_n);
297 prover_transcript->send_to_verifier(
"Libra:claimed_evaluation", claimed_inner_product);
301 zk_sumcheck_data, mle_opening_point, claimed_inner_product, prover_transcript,
ck);
302 small_subgroup_ipa_prover.
prove();
305 const auto opening_claim = ShpleminiProver::prove(this->n,
313 TestFixture::IPA::compute_opening_proof(this->
ck(), opening_claim, prover_transcript);
323 libra_commitments[0] =
324 verifier_transcript->template receive_from_prover<Commitment>(
"Libra:concatenation_commitment");
327 const Fr libra_total_sum = verifier_transcript->template receive_from_prover<Fr>(
"Libra:Sum");
328 const Fr libra_challenge = verifier_transcript->template get_challenge<Fr>(
"Libra:Challenge");
329 const Fr libra_evaluation = verifier_transcript->template receive_from_prover<Fr>(
"Libra:claimed_evaluation");
332 EXPECT_EQ(libra_total_sum, zk_sumcheck_data.libra_total_sum);
333 EXPECT_EQ(libra_challenge, zk_sumcheck_data.libra_challenge);
334 EXPECT_EQ(libra_evaluation, claimed_inner_product);
337 libra_commitments[1] = verifier_transcript->template receive_from_prover<Commitment>(
"Libra:grand_sum_commitment");
338 libra_commitments[2] = verifier_transcript->template receive_from_prover<Commitment>(
"Libra:quotient_commitment");
342 bool consistency_checked =
true;
345 std::vector<Fr> padding_indicator_array(this->log_n,
Fr{ 1 });
347 auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(padding_indicator_array,
350 this->vk().get_g1_identity(),
354 &consistency_checked,
360 TestFixture::IPA::reduce_verify_batch_opening_claim(batch_opening_claim, this->
vk(), verifier_transcript);
361 EXPECT_EQ(result,
true);
363 const auto pairing_points =
366 EXPECT_EQ(this->
vk().pairing_check(pairing_points[0], pairing_points[1]),
true);
378 using Curve = TypeParam::Curve;
381 using CK =
typename TypeParam::CommitmentKey;
386 CK
ck = create_commitment_key<CK>(4096);
389 std::vector<Fr> challenge = this->random_evaluation_point(this->log_n);
391 auto prover_transcript = TypeParam::Transcript::prover_init_empty();
399 mock_claims.template compute_sumcheck_opening_data<TypeParam>(
400 this->log_n, this->sumcheck_univariate_length, challenge,
ck);
403 const Fr claimed_inner_product =
406 prover_transcript->send_to_verifier(
"Libra:claimed_evaluation", claimed_inner_product);
410 zk_sumcheck_data, challenge, claimed_inner_product, prover_transcript,
ck);
411 small_subgroup_ipa_prover.
prove();
414 const auto opening_claim = ShpleminiProver::prove(this->n,
424 TestFixture::IPA::compute_opening_proof(this->
ck(), opening_claim, prover_transcript);
433 libra_commitments[0] =
434 verifier_transcript->template receive_from_prover<Commitment>(
"Libra:concatenation_commitment");
437 const Fr libra_total_sum = verifier_transcript->template receive_from_prover<Fr>(
"Libra:Sum");
438 const Fr libra_challenge = verifier_transcript->template get_challenge<Fr>(
"Libra:Challenge");
439 const Fr libra_evaluation = verifier_transcript->template receive_from_prover<Fr>(
"Libra:claimed_evaluation");
444 EXPECT_EQ(libra_evaluation, claimed_inner_product);
447 libra_commitments[1] = verifier_transcript->template receive_from_prover<Commitment>(
"Libra:grand_sum_commitment");
448 libra_commitments[2] = verifier_transcript->template receive_from_prover<Commitment>(
"Libra:quotient_commitment");
450 bool consistency_checked =
true;
453 std::vector<Fr> padding_indicator_array(this->log_n,
Fr{ 1 });
455 auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(padding_indicator_array,
458 this->vk().get_g1_identity(),
462 &consistency_checked,
470 TestFixture::IPA::reduce_verify_batch_opening_claim(batch_opening_claim, this->
vk(), verifier_transcript);
471 EXPECT_EQ(result,
true);
473 const auto pairing_points =
476 EXPECT_EQ(this->
vk().pairing_check(pairing_points[0], pairing_points[1]),
true);
488 using Curve =
typename TypeParam::Curve;
490 using CK =
typename TypeParam::CommitmentKey;
497 static constexpr size_t small_log_n = 3;
498 CK
ck = create_commitment_key<CK>(this->n);
501 auto u = this->random_evaluation_point(small_log_n);
512 const Fr tail = ((
Fr(1) - u[0]) * (
Fr(1) - u[1])).
invert();
513 poly.
at(4) = claimed_multilinear_eval * tail / u[2];
514 poly.
at(this->n - 8) = tail;
515 poly.
at(this->n - 4) = -tail * (
Fr(1) - u[2]) / u[2];
518 this->n, std::vector{
std::move(poly) }, std::vector<Fr>{ claimed_multilinear_eval },
ck);
523 const auto opening_claim =
524 ShpleminiProver::prove(this->n, mock_claims.polynomial_batcher, u,
ck, prover_transcript);
528 TestFixture::IPA::compute_opening_proof(
ck, opening_claim, prover_transcript);
536 std::vector<Fr> padding_indicator_array(small_log_n,
Fr{ 1 });
538 auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(
539 padding_indicator_array, mock_claims.claim_batcher, u, this->vk().get_g1_identity(), verifier_transcript);
544 TestFixture::IPA::reduce_verify_batch_opening_claim(batch_opening_claim, this->
vk(), verifier_transcript);
545 EXPECT_EQ(result,
true);
547 const auto pairing_points =
549 EXPECT_EQ(this->
vk().pairing_check(pairing_points[0], pairing_points[1]),
true);
560 using Curve =
typename TypeParam::Curve;
562 using CK =
typename TypeParam::CommitmentKey;
568 static constexpr size_t big_n = 1UL << 12;
569 static constexpr size_t small_log_n = 3;
570 static constexpr size_t big_ck_size = 1 << 14;
571 CK
ck = create_commitment_key<CK>(big_ck_size);
577 auto u = this->random_evaluation_point(small_log_n);
583 big_n, std::vector{
std::move(poly) }, std::vector<Fr>{ claimed_multilinear_eval },
ck);
588 const auto opening_claim = ShpleminiProver::prove(big_n, mock_claims.polynomial_batcher, u,
ck, prover_transcript);
592 TestFixture::IPA::compute_opening_proof(
ck, opening_claim, prover_transcript);
600 std::vector<Fr> padding_indicator_array(small_log_n,
Fr{ 1 });
602 auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(
603 padding_indicator_array, mock_claims.claim_batcher, u, this->vk().get_g1_identity(), verifier_transcript);
609 TestFixture::IPA::reduce_verify_batch_opening_claim(batch_opening_claim, this->
vk(), verifier_transcript),
612 const auto pairing_points =
614 EXPECT_EQ(this->
vk().pairing_check(pairing_points[0], pairing_points[1]),
false);
static std::shared_ptr< BaseTranscript > prover_init_empty()
For testing: initializes transcript with some arbitrary data so that a challenge can be generated aft...
static std::shared_ptr< BaseTranscript > verifier_init_empty(const std::shared_ptr< BaseTranscript > &transcript)
For testing: initializes transcript based on proof data then receives junk data produced by BaseTrans...
bb::CommitmentKey< Curve > CommitmentKey
Polynomial compute_batched(const Fr &challenge)
Compute batched polynomial A₀ = F + G/X as the linear combination of all polynomials to be opened.
std::pair< Polynomial, Polynomial > compute_partially_evaluated_batch_polynomials(const Fr &r_challenge)
Compute partially evaluated batched polynomials A₀(X, r) = A₀₊ = F + G/r, A₀(X, -r) = A₀₋ = F - G/r.
Gemini Verifier utility methods used by ShpleminiVerifier.
static PairingPointsType reduce_verify_batch_opening_claim(BatchOpeningClaim< Curve > &&batch_opening_claim, const std::shared_ptr< Transcript > &transcript, const size_t expected_final_msm_size=0)
Computes the input points for the pairing check needed to verify a KZG opening claim obtained from a ...
static void compute_opening_proof(const CK &ck, const ProverOpeningClaim< Curve > &opening_claim, const std::shared_ptr< Transcript > &prover_trancript)
Computes the KZG commitment to an opening proof polynomial at a single evaluation point.
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
static Polynomial random(size_t size, size_t start_index=0)
Fr & at(size_t index)
Our mutable accessor, unlike operator[]. We abuse precedent a bit to differentiate at() and operator[...
static constexpr size_t n
static constexpr size_t log_n
static constexpr size_t n
typename Flavor::Curve::ScalarField Fr
static constexpr size_t num_polynomials
typename Flavor::CommitmentKey CK
typename Flavor::Curve::AffineElement Commitment
static constexpr size_t log_n
static constexpr size_t sumcheck_univariate_length
static constexpr size_t num_shiftable
typename Flavor::Curve::Element GroupElement
IPA< typename Flavor::Curve, log_n > IPA
An efficient verifier for the evaluation proofs of multilinear polynomials and their shifts.
A Curve-agnostic ZK protocol to prove inner products of small vectors.
std::array< bb::Polynomial< FF >, NUM_SMALL_IPA_EVALUATIONS > get_witness_polynomials() const
static FF compute_claimed_inner_product(ZKSumcheckData< Flavor > &zk_sumcheck_data, const std::vector< FF > &multivariate_challenge, const size_t &log_circuit_size)
For test purposes: Compute the sum of the Libra constant term and Libra univariates evaluated at Sumc...
void prove()
Compute the derived witnesses and and commit to them.
typename Group::element Element
static constexpr size_t SUBGROUP_SIZE
typename Group::affine_element AffineElement
std::vector< Fr > powers_of_evaluation_challenge(const Fr r, const size_t num_squares)
Compute squares of folding challenge r.
std::vector< Fr > powers_of_rho(const Fr rho, const size_t num_powers)
Compute powers of challenge ρ
constexpr T get_msb(const T in)
Entry point for Barretenberg command-line interface.
::testing::Types< BN254Settings, GrumpkinSettings > TestSettings
TYPED_TEST_SUITE(ShpleminiTest, TestSettings)
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
CommitmentKey< Curve > ck
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
void compute_scalars_for_each_batch(std::span< const Fr > inverted_vanishing_evals, const Fr &nu_challenge, const Fr &r_challenge)
Compute scalars used to batch each set of claims, excluding contribution from batching challenge \rho...
void update_batch_mul_inputs_and_batched_evaluation(std::vector< Commitment > &commitments, std::vector< Fr > &scalars, Fr &batched_evaluation, const Fr &rho, Fr shplonk_batching_pos={ 0 }, Fr shplonk_batching_neg={ 0 })
Append the commitments and scalars from each batch of claims to the Shplemini, vectors which subseque...
std::vector< Commitment > commitments
Constructs random polynomials, computes commitments and corresponding evaluations.
std::vector< bb::Polynomial< Fr > > round_univariates
std::vector< Commitment > sumcheck_commitments
ClaimBatcher claim_batcher
std::vector< std::array< Fr, 3 > > sumcheck_evaluations
PolynomialBatcher polynomial_batcher
This structure is created to contain various polynomials and constants required by ZK Sumcheck.
constexpr field invert() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept