Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
shplemini.test.cpp
Go to the documentation of this file.
1
2#include "shplemini.hpp"
3#include "../gemini/gemini.hpp"
4#include "../kzg/kzg.hpp"
5#include "../pcs_test_utils.hpp"
6#include "../shplonk/shplonk.hpp"
13
14#include <gtest/gtest.h>
15#include <vector>
16
17namespace bb {
18
19template <class Flavor> class ShpleminiTest : public CommitmentTest<typename Flavor::Curve> {
20 public:
21 // Size of the test polynomials
22 static constexpr size_t log_n = 9;
23 static constexpr size_t n = 1UL << log_n;
24 // Total number of random polynomials in each test
25 static constexpr size_t num_polynomials = 7;
26 // Number of shiftable polynomials
27 static constexpr size_t num_shiftable = 2;
28
29 // The length of the mock sumcheck univariates.
30 static constexpr size_t sumcheck_univariate_length = 24;
31
32 using Fr = typename Flavor::Curve::ScalarField;
33 using GroupElement = typename Flavor::Curve::Element;
34 using Commitment = typename Flavor::Curve::AffineElement;
35 using CK = typename Flavor::CommitmentKey;
37
38 // Witness polynomials array: [0]=Concatenated(G), [1]=GrandSum(A), [2]=unused, [3]=Quotient(Q)
39 enum class TamperedPolynomial : size_t { None = SIZE_MAX, Concatenated = 0, GrandSum = 1, Quotient = 3 };
40
41 // libra_commitments array: [0]=Concatenated, [1]=GrandSum, [2]=Quotient
42 enum class TamperedCommitment : size_t { None = SIZE_MAX, Concatenated = 0, GrandSum = 1, Quotient = 2 };
43};
44
45using TestSettings = ::testing::Types<BN254Settings, GrumpkinSettings>;
46
48
49// Non-template test fixture for KZG-specific tests
50class ShpleminiKZGTest : public CommitmentTest<curve::BN254> {
51 public:
52 static constexpr size_t log_n = 9;
53 static constexpr size_t n = 1UL << log_n;
54};
55
56// This test checks that batch_multivariate_opening_claims method operates correctly
57TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
58{
59 using Curve = typename TypeParam::Curve;
60 using Fr = typename Curve::ScalarField;
61 using GroupElement = typename Curve::Element;
62 using Commitment = typename Curve::AffineElement;
63 using CK = typename TypeParam::CommitmentKey;
64
65 CK ck = create_commitment_key<CK>(this->n);
66
67 // Generate mock challenges
68 Fr rho = Fr::random_element();
69 Fr gemini_eval_challenge = Fr::random_element();
70 Fr shplonk_batching_challenge = Fr::random_element();
71 Fr shplonk_eval_challenge = Fr::random_element();
72
73 // Generate multilinear polynomials and compute their commitments
74 auto mle_opening_point = this->random_evaluation_point(this->log_n);
75
76 MockClaimGenerator<Curve> mock_claims(this->n,
77 /*num_polynomials*/ this->num_polynomials,
78 /*num_to_be_shifted*/ this->num_shiftable,
79 mle_opening_point,
80 ck);
81
82 // Collect multilinear evaluations
83 std::vector<Fr> rhos = gemini::powers_of_rho(rho, this->num_polynomials + this->num_shiftable);
84
85 // Lambda to compute batched multivariate evaluation
86 auto update_batched_eval = [&](Fr& batched_eval, const std::vector<Fr>& evaluations, Fr& rho_power) {
87 for (auto& eval : evaluations) {
88 batched_eval += eval * rho_power;
89 rho_power *= rho;
90 }
91 };
92
93 Fr rho_power(1);
94 Fr batched_evaluation(0);
95 update_batched_eval(batched_evaluation, mock_claims.unshifted.evals, rho_power);
96 update_batched_eval(batched_evaluation, mock_claims.to_be_shifted.evals, rho_power);
97
98 // Lambda to compute batched commitment
99 auto compute_batched_commitment = [&](const std::vector<Commitment>& commitments, Fr& rho_power) {
100 GroupElement batched = GroupElement::zero();
101 for (auto& comm : commitments) {
102 batched += comm * rho_power;
103 rho_power *= rho;
104 }
105 return batched;
106 };
107
108 // Compute batched commitments manually
109 rho_power = Fr(1);
110 GroupElement batched_commitment_unshifted =
111 compute_batched_commitment(mock_claims.unshifted.commitments, rho_power);
112 GroupElement batched_commitment_to_be_shifted =
113 compute_batched_commitment(mock_claims.to_be_shifted.commitments, rho_power);
114
115 // Compute expected result manually
116 GroupElement to_be_shifted_contribution = batched_commitment_to_be_shifted * gemini_eval_challenge.invert();
117
118 GroupElement commitment_to_univariate_pos = batched_commitment_unshifted + to_be_shifted_contribution;
119
120 GroupElement commitment_to_univariate_neg = batched_commitment_unshifted - to_be_shifted_contribution;
121
122 GroupElement expected_result =
123 commitment_to_univariate_pos * (shplonk_eval_challenge - gemini_eval_challenge).invert() +
124 commitment_to_univariate_neg *
125 (shplonk_batching_challenge * (shplonk_eval_challenge + gemini_eval_challenge).invert());
126
127 // Run the ShepliminiVerifier batching method
128 std::vector<Commitment> commitments;
129 std::vector<Fr> scalars;
130 Fr verifier_batched_evaluation{ 0 };
131
132 Fr inverted_vanishing_eval_pos = (shplonk_eval_challenge - gemini_eval_challenge).invert();
133 Fr inverted_vanishing_eval_neg = (shplonk_eval_challenge + gemini_eval_challenge).invert();
134
135 std::vector<Fr> inverted_vanishing_evals = { inverted_vanishing_eval_pos, inverted_vanishing_eval_neg };
136
138 inverted_vanishing_evals, shplonk_batching_challenge, gemini_eval_challenge);
139
141 commitments, scalars, verifier_batched_evaluation, rho);
142
143 // Final pairing check
144 GroupElement shplemini_result = GroupElement::batch_mul(commitments, scalars);
145
146 EXPECT_EQ(commitments.size(),
147 mock_claims.unshifted.commitments.size() + mock_claims.to_be_shifted.commitments.size());
148 EXPECT_EQ(batched_evaluation, verifier_batched_evaluation);
149 EXPECT_EQ(-expected_result, shplemini_result);
150}
151TYPED_TEST(ShpleminiTest, CorrectnessOfGeminiClaimBatching)
152{
153 using Curve = TypeParam::Curve;
154 using GeminiProver = GeminiProver_<Curve>;
155 using ShpleminiVerifier = ShpleminiVerifier_<Curve>;
156 using ShplonkVerifier = ShplonkVerifier_<Curve>;
157 using Fr = typename Curve::ScalarField;
158 using GroupElement = typename Curve::Element;
159 using Commitment = typename Curve::AffineElement;
160 using Polynomial = typename bb::Polynomial<Fr>;
161 using CK = typename TypeParam::CommitmentKey;
162
163 CK ck = create_commitment_key<CK>(this->n);
164
165 // Generate mock challenges
166 Fr rho = Fr::random_element();
167 Fr gemini_eval_challenge = Fr::random_element();
168 Fr shplonk_batching_challenge = Fr::random_element();
169
170 std::vector<Fr> shplonk_batching_challenge_powers =
171 compute_shplonk_batching_challenge_powers(shplonk_batching_challenge, this->log_n);
172
173 Fr shplonk_eval_challenge = Fr::random_element();
174
175 std::vector<Fr> mle_opening_point = this->random_evaluation_point(this->log_n);
176
177 MockClaimGenerator<Curve> mock_claims(this->n,
178 /*num_polynomials*/ this->num_polynomials,
179 /*num_to_be_shifted*/ this->num_shiftable,
180 mle_opening_point,
181 ck);
182
183 // Collect multilinear evaluations
184 std::vector<Fr> rhos = gemini::powers_of_rho(rho, this->num_polynomials + this->num_shiftable);
185
186 Polynomial batched = mock_claims.polynomial_batcher.compute_batched(rho);
187
188 // Compute:
189 // - (d+1) opening pairs: {r, \hat{a}_0}, {-r^{2^i}, a_i}, i = 0, ..., d-1
190 // - (d+1) Fold polynomials Fold_{r}^(0), Fold_{-r}^(0), and Fold^(i), i = 0, ..., d-1
191 auto fold_polynomials = GeminiProver::compute_fold_polynomials(this->log_n, mle_opening_point, batched);
192
193 std::vector<Commitment> prover_commitments;
194 for (size_t l = 0; l < this->log_n - 1; ++l) {
195 auto commitment = ck.commit(fold_polynomials[l]);
196 prover_commitments.emplace_back(commitment);
197 }
198
199 auto [A_0_pos, A_0_neg] =
200 mock_claims.polynomial_batcher.compute_partially_evaluated_batch_polynomials(gemini_eval_challenge);
201
202 const auto opening_claims = GeminiProver::construct_univariate_opening_claims(
203 this->log_n, std::move(A_0_pos), std::move(A_0_neg), std::move(fold_polynomials), gemini_eval_challenge);
204
205 std::vector<Fr> prover_evaluations;
206 for (size_t l = 0; l < this->log_n; ++l) {
207 const auto& evaluation = opening_claims[l + 1].opening_pair.evaluation;
208 prover_evaluations.emplace_back(evaluation);
209 }
210
211 std::vector<Fr> r_squares = gemini::powers_of_evaluation_challenge(gemini_eval_challenge, this->log_n);
212
213 GroupElement expected_result = GroupElement::zero();
214 std::vector<Fr> expected_inverse_vanishing_evals;
215 expected_inverse_vanishing_evals.reserve(2 * this->log_n);
216 // Compute expected inverses
217 for (size_t idx = 0; idx < this->log_n; idx++) {
218 expected_inverse_vanishing_evals.emplace_back((shplonk_eval_challenge - r_squares[idx]).invert());
219 expected_inverse_vanishing_evals.emplace_back((shplonk_eval_challenge + r_squares[idx]).invert());
220 }
221
222 Fr current_challenge{ shplonk_batching_challenge * shplonk_batching_challenge };
223 for (size_t idx = 0; idx < prover_commitments.size(); ++idx) {
224 expected_result -= prover_commitments[idx] * current_challenge * expected_inverse_vanishing_evals[2 * idx + 2];
225 current_challenge *= shplonk_batching_challenge;
226 expected_result -= prover_commitments[idx] * current_challenge * expected_inverse_vanishing_evals[2 * idx + 3];
227 current_challenge *= shplonk_batching_challenge;
228 }
229
230 // Run the ShepliminiVerifier batching method
231 std::vector<Fr> inverse_vanishing_evals =
232 ShplonkVerifier::compute_inverted_gemini_denominators(shplonk_eval_challenge, r_squares);
233
234 Fr expected_constant_term_accumulator{ 0 };
235
236 std::vector<Fr> gemini_fold_pos_evaluations = GeminiVerifier_<Curve>::compute_fold_pos_evaluations(
237 expected_constant_term_accumulator, mle_opening_point, r_squares, prover_evaluations);
238 std::vector<Commitment> commitments;
239 std::vector<Fr> scalars;
240
241 ShpleminiVerifier::batch_gemini_claims_received_from_prover(prover_commitments,
242 prover_evaluations,
243 gemini_fold_pos_evaluations,
244 inverse_vanishing_evals,
245 shplonk_batching_challenge_powers,
246 commitments,
247 scalars,
248 expected_constant_term_accumulator);
249
250 // Compute the group element using the output of Shplemini method
251 GroupElement shplemini_result = GroupElement::batch_mul(commitments, scalars);
252
253 EXPECT_EQ(shplemini_result, expected_result);
254}
255
261TYPED_TEST(ShpleminiTest, ShpleminiZKNoSumcheckOpenings)
262{
263 using ZKData = ZKSumcheckData<TypeParam>;
264 using Curve = TypeParam::Curve;
265 using ShpleminiProver = ShpleminiProver_<Curve>;
266 constexpr bool HasZK = true;
267 using ShpleminiVerifier = ShpleminiVerifier_<Curve, HasZK>;
268 using Fr = typename Curve::ScalarField;
269 using Commitment = typename Curve::AffineElement;
270 using CK = typename TypeParam::CommitmentKey;
271
272 // Initialize transcript and commitment key
273 auto prover_transcript = TypeParam::Transcript::test_prover_init_empty();
274
275 // SmallSubgroupIPAProver requires at least CURVE::SUBGROUP_SIZE + 3 elements in the ck.
276 static constexpr size_t log_subgroup_size = static_cast<size_t>(numeric::get_msb(Curve::SUBGROUP_SIZE));
277 CK ck = create_commitment_key<CK>(std::max<size_t>(this->n, 1ULL << (log_subgroup_size + 1)));
278
279 // Generate Libra polynomials, compute masked concatenated Libra polynomial, commit to it
280 ZKData zk_sumcheck_data(this->log_n, prover_transcript, ck);
281
282 // Generate multivariate challenge
283 std::vector<Fr> mle_opening_point = this->random_evaluation_point(this->log_n);
284
285 // Generate random prover polynomials, compute their evaluations and commitments
286 MockClaimGenerator<Curve> mock_claims(this->n,
287 /*num_polynomials*/ this->num_polynomials,
288 /*num_to_be_shifted*/ this->num_shiftable,
289 mle_opening_point,
290 ck);
291
292 // Compute the sum of the Libra constant term and Libra univariates evaluated at Sumcheck challenges
294 zk_sumcheck_data, mle_opening_point, this->log_n);
295
296 prover_transcript->send_to_verifier("Libra:claimed_evaluation", claimed_inner_product);
297
298 // Instantiate SmallSubgroupIPAProver, this prover sends commitments to Big Sum and Quotient polynomials
299 SmallSubgroupIPAProver<TypeParam> small_subgroup_ipa_prover(
300 zk_sumcheck_data, mle_opening_point, claimed_inner_product, prover_transcript, ck);
301 small_subgroup_ipa_prover.prove();
302
303 // Reduce to KZG or IPA based on the curve used in the test Flavor
304 const auto opening_claim = ShpleminiProver::prove(this->n,
305 mock_claims.polynomial_batcher,
306 mle_opening_point,
307 ck,
308 prover_transcript,
309 small_subgroup_ipa_prover.get_witness_polynomials());
310
312 TestFixture::IPA::compute_opening_proof(this->ck(), opening_claim, prover_transcript);
313 } else {
314 KZG<Curve>::compute_opening_proof(this->ck(), opening_claim, prover_transcript);
315 }
316
317 // Initialize verifier's transcript
318 auto verifier_transcript = NativeTranscript::test_verifier_init_empty(prover_transcript);
319
320 // Start populating Verifier's array of Libra commitments
321 std::array<Commitment, NUM_LIBRA_COMMITMENTS> libra_commitments = {};
322 libra_commitments[0] =
323 verifier_transcript->template receive_from_prover<Commitment>("Libra:concatenation_commitment");
324
325 // Place Libra data to the transcript
326 const Fr libra_total_sum = verifier_transcript->template receive_from_prover<Fr>("Libra:Sum");
327 const Fr libra_challenge = verifier_transcript->template get_challenge<Fr>("Libra:Challenge");
328 const Fr libra_evaluation = verifier_transcript->template receive_from_prover<Fr>("Libra:claimed_evaluation");
329
330 // Check that transcript is consistent
331 EXPECT_EQ(libra_total_sum, zk_sumcheck_data.libra_total_sum);
332 EXPECT_EQ(libra_challenge, zk_sumcheck_data.libra_challenge);
333 EXPECT_EQ(libra_evaluation, claimed_inner_product);
334
335 // Finalize the array of Libra/SmallSubgroupIpa commitments
336 libra_commitments[1] = verifier_transcript->template receive_from_prover<Commitment>("Libra:grand_sum_commitment");
337 libra_commitments[2] = verifier_transcript->template receive_from_prover<Commitment>("Libra:quotient_commitment");
338
339 // Run Shplemini
340 auto [batch_opening_claim, consistency_checked] =
341 ShpleminiVerifier::compute_batch_opening_claim(mock_claims.claim_batcher,
342 mle_opening_point,
343 this->vk().get_g1_identity(),
344 verifier_transcript,
345 {},
346 libra_commitments,
347 libra_evaluation);
348 // Verify claim using KZG or IPA
350 auto result =
351 TestFixture::IPA::reduce_verify_batch_opening_claim(batch_opening_claim, this->vk(), verifier_transcript);
352 EXPECT_EQ(result, true);
353 } else {
354 const auto pairing_points =
355 KZG<Curve>::reduce_verify_batch_opening_claim(std::move(batch_opening_claim), verifier_transcript);
356 // Final pairing check: e([Q] - [Q_z] + z[W], [1]_2) = e([W], [x]_2)
357 EXPECT_EQ(pairing_points.check(), true);
358 }
359 EXPECT_EQ(consistency_checked, true);
360}
361
368TYPED_TEST(ShpleminiTest, ShpleminiZKWithSumcheckOpenings)
369{
370 using Curve = TypeParam::Curve;
371 using Fr = typename Curve::ScalarField;
372 using Commitment = typename Curve::AffineElement;
373 using CK = typename TypeParam::CommitmentKey;
374
375 using ShpleminiProver = ShpleminiProver_<Curve>;
376 constexpr bool HasZK = true;
377 using ShpleminiVerifier = ShpleminiVerifier_<Curve, HasZK>;
378
379 CK ck = create_commitment_key<CK>(4096);
380
381 // Generate Sumcheck challenge
382 std::vector<Fr> challenge = this->random_evaluation_point(this->log_n);
383
384 auto prover_transcript = TypeParam::Transcript::test_prover_init_empty();
385
386 // Generate masking polynomials for Sumcheck Round Univariates
387 ZKSumcheckData<TypeParam> zk_sumcheck_data(this->log_n, prover_transcript, ck);
388 // Generate mock witness
389 MockClaimGenerator<Curve> mock_claims(this->n, 1);
390
391 // Generate valid sumcheck polynomials of given length
392 mock_claims.template compute_sumcheck_opening_data<TypeParam>(
393 this->log_n, this->sumcheck_univariate_length, challenge, ck);
394
395 // Compute the sum of the Libra constant term and Libra univariates evaluated at Sumcheck challenges
396 const Fr claimed_inner_product =
397 SmallSubgroupIPAProver<TypeParam>::compute_claimed_inner_product(zk_sumcheck_data, challenge, this->log_n);
398
399 prover_transcript->send_to_verifier("Libra:claimed_evaluation", claimed_inner_product);
400
401 // Instantiate SmallSubgroupIPAProver, this prover sends commitments to Big Sum and Quotient polynomials
402 SmallSubgroupIPAProver<TypeParam> small_subgroup_ipa_prover(
403 zk_sumcheck_data, challenge, claimed_inner_product, prover_transcript, ck);
404 small_subgroup_ipa_prover.prove();
405
406 // Reduce proving to a single claimed fed to KZG or IPA
407 const auto opening_claim = ShpleminiProver::prove(this->n,
408 mock_claims.polynomial_batcher,
409 challenge,
410 ck,
411 prover_transcript,
412 small_subgroup_ipa_prover.get_witness_polynomials(),
413 mock_claims.round_univariates,
414 mock_claims.sumcheck_evaluations);
415
417 TestFixture::IPA::compute_opening_proof(this->ck(), opening_claim, prover_transcript);
418 } else {
419 KZG<Curve>::compute_opening_proof(this->ck(), opening_claim, prover_transcript);
420 }
421
422 // Initialize verifier's transcript
423 auto verifier_transcript = NativeTranscript::test_verifier_init_empty(prover_transcript);
424
425 std::array<Commitment, NUM_LIBRA_COMMITMENTS> libra_commitments = {};
426 libra_commitments[0] =
427 verifier_transcript->template receive_from_prover<Commitment>("Libra:concatenation_commitment");
428
429 // Place Libra data to the transcript
430 const Fr libra_total_sum = verifier_transcript->template receive_from_prover<Fr>("Libra:Sum");
431 const Fr libra_challenge = verifier_transcript->template get_challenge<Fr>("Libra:Challenge");
432 const Fr libra_evaluation = verifier_transcript->template receive_from_prover<Fr>("Libra:claimed_evaluation");
433
434 // Check that transcript is consistent
435 EXPECT_EQ(libra_total_sum, zk_sumcheck_data.libra_total_sum);
436 EXPECT_EQ(libra_challenge, zk_sumcheck_data.libra_challenge);
437 EXPECT_EQ(libra_evaluation, claimed_inner_product);
438
439 // Finalize the array of Libra/SmallSubgroupIpa commitments
440 libra_commitments[1] = verifier_transcript->template receive_from_prover<Commitment>("Libra:grand_sum_commitment");
441 libra_commitments[2] = verifier_transcript->template receive_from_prover<Commitment>("Libra:quotient_commitment");
442
443 // Run Shplemini
444 auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(mock_claims.claim_batcher,
445 challenge,
446 this->vk().get_g1_identity(),
447 verifier_transcript,
448 {},
449 libra_commitments,
450 libra_evaluation,
451 mock_claims.sumcheck_commitments,
452 mock_claims.sumcheck_evaluations)
453 .batch_opening_claim;
454 // Verify claim using KZG or IPA
456 auto result =
457 TestFixture::IPA::reduce_verify_batch_opening_claim(batch_opening_claim, this->vk(), verifier_transcript);
458 EXPECT_EQ(result, true);
459 } else {
460 const auto pairing_points =
461 KZG<Curve>::reduce_verify_batch_opening_claim(std::move(batch_opening_claim), verifier_transcript);
462 // Final pairing check: e([Q] - [Q_z] + z[W], [1]_2) = e([W], [x]_2)
463 EXPECT_EQ(pairing_points.check(), true);
464 }
465}
466
473TYPED_TEST(ShpleminiTest, HighDegreeAttackAccept)
474{
475 // In debug builds, the coarse-form field assertion can intermittently fire during intermediate
476 // arithmetic when processing deliberately oversized polynomials. Suppress assertions to warnings.
478
479 using Curve = typename TypeParam::Curve;
480 using Fr = typename Curve::ScalarField;
481 using CK = typename TypeParam::CommitmentKey;
482 using ShpleminiProver = ShpleminiProver_<Curve>;
483 using ShpleminiVerifier = ShpleminiVerifier_<Curve>;
485
486 // Use the fixture's n (1 << 9 = 512) as the polynomial size
487 // small_log_n = 3 means we fold to a constant after 3 rounds
488 static constexpr size_t small_log_n = 3;
489 CK ck = create_commitment_key<CK>(this->n);
490
491 // Sample public opening point (u_0, u_1, u_2)
492 auto u = this->random_evaluation_point(small_log_n);
493
494 // Choose a claimed eval at `u`
495 Fr claimed_multilinear_eval = Fr::random_element();
496
497 // poly is of high degrees (up to n), as the SRS allows for it
498 Polynomial poly(this->n);
499
500 // Define poly to be of a specific form such that after small_log_n folds with u, it becomes a constant equal to
501 // claimed_multilinear_eval. The non-zero coefficients are at indices that fold correctly.
502 // For n = 512, small_log_n = 3: indices 4, 504, 508 work (instead of 4, 4088, 4092 for n = 4096)
503 const Fr tail = ((Fr(1) - u[0]) * (Fr(1) - u[1])).invert();
504 poly.at(4) = claimed_multilinear_eval * tail / u[2];
505 poly.at(this->n - 8) = tail; // 504 for n=512
506 poly.at(this->n - 4) = -tail * (Fr(1) - u[2]) / u[2]; // 508 for n=512
507
508 MockClaimGenerator<Curve> mock_claims(
509 this->n, std::vector{ std::move(poly) }, std::vector<Fr>{ claimed_multilinear_eval }, ck);
510
511 auto prover_transcript = NativeTranscript::test_prover_init_empty();
512
513 // Run Shplemini prover
514 const auto opening_claim =
515 ShpleminiProver::prove(this->n, mock_claims.polynomial_batcher, u, ck, prover_transcript);
516
517 // Run KZG/IPA prover
519 TestFixture::IPA::compute_opening_proof(ck, opening_claim, prover_transcript);
520 } else {
521 KZG<Curve>::compute_opening_proof(ck, opening_claim, prover_transcript);
522 }
523
524 // Verifier side
525 auto verifier_transcript = NativeTranscript::test_verifier_init_empty(prover_transcript);
526
527 auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(
528 mock_claims.claim_batcher, u, this->vk().get_g1_identity(), verifier_transcript)
529 .batch_opening_claim;
530
531 // Verify claim - should succeed because the polynomial was crafted to fold correctly
533 auto result =
534 TestFixture::IPA::reduce_verify_batch_opening_claim(batch_opening_claim, this->vk(), verifier_transcript);
535 EXPECT_EQ(result, true);
536 } else {
537 const auto pairing_points =
538 KZG<Curve>::reduce_verify_batch_opening_claim(std::move(batch_opening_claim), verifier_transcript);
539 EXPECT_EQ(pairing_points.check(), true);
540 }
541}
542
548TYPED_TEST(ShpleminiTest, HighDegreeAttackReject)
549{
550 // In debug builds, the coarse-form field assertion can intermittently fire during intermediate
551 // arithmetic when processing deliberately oversized polynomials. Suppress assertions to warnings
552 // for this adversarial test so the test can complete and verify the pairing check fails.
554
555 using Curve = typename TypeParam::Curve;
556 using Fr = typename Curve::ScalarField;
557 using CK = typename TypeParam::CommitmentKey;
558 using ShpleminiProver = ShpleminiProver_<Curve>;
559 using ShpleminiVerifier = ShpleminiVerifier_<Curve>;
561
562 // Use a larger SRS size to allow committing to high degree polynomials
563 static constexpr size_t big_n = 1UL << 12;
564 static constexpr size_t small_log_n = 3;
565 static constexpr size_t big_ck_size = 1 << 14;
566 CK ck = create_commitment_key<CK>(big_ck_size);
567
568 // Random high degree polynomial
569 Polynomial poly = Polynomial::random(big_n);
570
571 // Sample public opening point (u_0, u_1, u_2)
572 auto u = this->random_evaluation_point(small_log_n);
573
574 // Choose a random claimed eval at `u` (likely wrong)
575 Fr claimed_multilinear_eval = Fr::random_element();
576
577 MockClaimGenerator<Curve> mock_claims(
578 big_n, std::vector{ std::move(poly) }, std::vector<Fr>{ claimed_multilinear_eval }, ck);
579
580 auto prover_transcript = NativeTranscript::test_prover_init_empty();
581
582 // Run Shplemini prover
583 const auto opening_claim = ShpleminiProver::prove(big_n, mock_claims.polynomial_batcher, u, ck, prover_transcript);
584
585 // Run KZG/IPA prover
587 TestFixture::IPA::compute_opening_proof(ck, opening_claim, prover_transcript);
588 } else {
589 KZG<Curve>::compute_opening_proof(ck, opening_claim, prover_transcript);
590 }
591
592 // Verifier side
593 auto verifier_transcript = NativeTranscript::test_verifier_init_empty(prover_transcript);
594
595 auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(
596 mock_claims.claim_batcher, u, this->vk().get_g1_identity(), verifier_transcript)
597 .batch_opening_claim;
598
599 // Verify claim - should fail because the random polynomial doesn't fold correctly
601 // IPA verification failure normally throws, but with BB_DISABLE_ASSERTS the assertion
602 // becomes a warning and the function may return false instead of throwing.
603 auto result =
604 TestFixture::IPA::reduce_verify_batch_opening_claim(batch_opening_claim, this->vk(), verifier_transcript);
605 EXPECT_EQ(result, false);
606 } else {
607 const auto pairing_points =
608 KZG<Curve>::reduce_verify_batch_opening_claim(std::move(batch_opening_claim), verifier_transcript);
609 EXPECT_EQ(pairing_points.check(), false);
610 }
611}
612
631TYPED_TEST(ShpleminiTest, ToBeShiftedNonZeroConstantTermRejected)
632{
633 using Curve = typename TypeParam::Curve;
634 using Fr = typename Curve::ScalarField;
635 using GroupElement = typename Curve::Element;
636 using Commitment = typename Curve::AffineElement;
637 using CK = typename TypeParam::CommitmentKey;
638 using ShpleminiProver = ShpleminiProver_<Curve>;
639 using ShpleminiVerifier = ShpleminiVerifier_<Curve>;
640
641 CK ck = create_commitment_key<CK>(this->n);
642
643 auto mle_opening_point = this->random_evaluation_point(this->log_n);
644
645 MockClaimGenerator<Curve> mock_claims(this->n,
646 /*num_polynomials*/ this->num_polynomials,
647 /*num_to_be_shifted*/ this->num_shiftable,
648 mle_opening_point,
649 ck);
650
651 auto prover_transcript = NativeTranscript::test_prover_init_empty();
652
653 const auto opening_claim =
654 ShpleminiProver::prove(this->n, mock_claims.polynomial_batcher, mle_opening_point, ck, prover_transcript);
655
656 // For KZG, run the opening proof now: KZG never binds the claim into Fiat-Shamir, so the
657 // verifier can be handed a tampered claim later without affecting the prover transcript.
658 // For IPA, defer the opening proof until after the tampered batched claim is available; the
659 // adversarial prover hashes that claim into its FS buffer to match the verifier (see below).
661 KZG<Curve>::compute_opening_proof(ck, opening_claim, prover_transcript);
662 }
663
664 // Simulate adversary: replace the first to-be-shifted commitment with com(p + c * delta_0),
665 // i.e. add c * [1]_1 to it. The shifted MLE evaluation is unchanged (shifting drops the [0]
666 // coefficient). The unshifted MLE evaluation of p + c * delta_0 differs from the unshifted MLE
667 // evaluation of p by c * prod_i (1 - u_i); update the unshifted counterpart claim accordingly
668 // so that any rejection cannot be attributed to a stale unshifted-side mismatch.
669 const Fr c = Fr::random_element();
670 const Commitment g1_identity = this->vk().get_g1_identity();
671 const auto tampered = Commitment(GroupElement(mock_claims.to_be_shifted.commitments[0]) + g1_identity * c);
672
673 Fr lagrange0_at_u = Fr(1);
674 for (const auto& u_i : mle_opening_point) {
675 lagrange0_at_u *= (Fr(1) - u_i);
676 }
677 const size_t unshifted_idx = this->num_polynomials - this->num_shiftable; // first to-be-shifted in unshifted batch
678 mock_claims.to_be_shifted.commitments[0] = tampered;
679 mock_claims.unshifted.commitments[unshifted_idx] = tampered;
680 mock_claims.unshifted.evals[unshifted_idx] += c * lagrange0_at_u;
681
682 auto verifier_transcript = NativeTranscript::test_verifier_init_empty(prover_transcript);
683
684 auto batch_opening_claim = ShpleminiVerifier::compute_batch_opening_claim(
685 mock_claims.claim_batcher, mle_opening_point, g1_identity, verifier_transcript)
686 .batch_opening_claim;
687
689 // Adversarial IPA prover: stage the prover transcript with the same reduced claim the
690 // verifier will hash via add_claim_to_hash_buffer, then fold the honest polynomial. This
691 // keeps prover/verifier FS in sync so the rejection isolates the inner-product relation
692 // rather than transcript divergence.
693 const auto reduced = TestFixture::IPA::reduce_batch_opening_claim(batch_opening_claim);
694 prover_transcript->add_to_hash_buffer("IPA:commitment", reduced.commitment);
695 prover_transcript->add_to_hash_buffer("IPA:challenge", reduced.opening_pair.challenge);
696 prover_transcript->add_to_hash_buffer("IPA:evaluation", reduced.opening_pair.evaluation);
697 TestFixture::IPA::compute_opening_proof_internal(ck, opening_claim, prover_transcript);
698
699 // The verifier transcript was initialized before the IPA prover wrote its bytes; refresh
700 // its view of proof_data so the IPA verifier can read them.
701 verifier_transcript->test_get_proof_data() = prover_transcript->test_get_proof_data();
702
703 auto result =
704 TestFixture::IPA::reduce_verify_batch_opening_claim(batch_opening_claim, this->vk(), verifier_transcript);
705 EXPECT_EQ(result, false);
706 } else {
707 const auto pairing_points =
708 KZG<Curve>::reduce_verify_batch_opening_claim(std::move(batch_opening_claim), verifier_transcript);
709 EXPECT_EQ(pairing_points.check(), false);
710 }
711
712 // Confirm the rejection is not an artifact of transcript divergence: a fresh challenge with
713 // the same label drawn from both transcripts must agree. For KZG this is automatic (the
714 // claim is never hashed into FS). For IPA we matched the prover and verifier hash buffers
715 // explicitly above; if this check fails, the rejection above could be attributed to the
716 // prover and verifier consuming different challenges rather than the PCS check itself.
717 EXPECT_EQ(prover_transcript->template get_challenge<Fr>("transcript_sync_check"),
718 verifier_transcript->template get_challenge<Fr>("transcript_sync_check"));
719}
720
726TYPED_TEST(ShpleminiTest, LibraConsistencyCheckFailsOnCorruptedEvaluation)
727{
728 using ZKData = ZKSumcheckData<TypeParam>;
729 using Curve = typename TypeParam::Curve;
730 using ShpleminiProver = ShpleminiProver_<Curve>;
731 constexpr bool HasZK = true;
732 using ShpleminiVerifier = ShpleminiVerifier_<Curve, HasZK>;
733 using Fr = typename Curve::ScalarField;
734 using Commitment = typename Curve::AffineElement;
735 using CK = typename TypeParam::CommitmentKey;
736
737 // Initialize transcript and commitment key
738 auto prover_transcript = TypeParam::Transcript::test_prover_init_empty();
739
740 // SmallSubgroupIPAProver requires at least CURVE::SUBGROUP_SIZE + 3 elements in the ck.
741 static constexpr size_t log_subgroup_size = static_cast<size_t>(numeric::get_msb(Curve::SUBGROUP_SIZE));
742 CK ck = create_commitment_key<CK>(std::max<size_t>(this->n, 1ULL << (log_subgroup_size + 1)));
743
744 // Generate Libra polynomials, compute masked concatenated Libra polynomial, commit to it
745 ZKData zk_sumcheck_data(this->log_n, prover_transcript, ck);
746
747 // Generate multivariate challenge
748 std::vector<Fr> mle_opening_point = this->random_evaluation_point(this->log_n);
749
750 // Generate random prover polynomials, compute their evaluations and commitments
751 MockClaimGenerator<Curve> mock_claims(this->n,
752 /*num_polynomials*/ this->num_polynomials,
753 /*num_to_be_shifted*/ this->num_shiftable,
754 mle_opening_point,
755 ck);
756
757 // Compute the correct sum of the Libra constant term and Libra univariates evaluated at Sumcheck challenges
759 zk_sumcheck_data, mle_opening_point, this->log_n);
760
761 // CORRUPT: Malicious prover sends a corrupted evaluation via the transcript
762 const Fr corrupted_inner_product = claimed_inner_product + Fr::random_element();
763 prover_transcript->send_to_verifier("Libra:claimed_evaluation", corrupted_inner_product);
764
765 // Instantiate SmallSubgroupIPAProver with the CORRECT value (prover's internal state is correct,
766 // but the value sent to verifier is corrupted - simulating a cheating prover)
767 SmallSubgroupIPAProver<TypeParam> small_subgroup_ipa_prover(
768 zk_sumcheck_data, mle_opening_point, corrupted_inner_product, prover_transcript, ck);
769 small_subgroup_ipa_prover.prove();
770
771 // Reduce to KZG or IPA based on the curve used in the test Flavor
772 const auto opening_claim = ShpleminiProver::prove(this->n,
773 mock_claims.polynomial_batcher,
774 mle_opening_point,
775 ck,
776 prover_transcript,
777 small_subgroup_ipa_prover.get_witness_polynomials());
778
780 TestFixture::IPA::compute_opening_proof(this->ck(), opening_claim, prover_transcript);
781 } else {
782 KZG<Curve>::compute_opening_proof(this->ck(), opening_claim, prover_transcript);
783 }
784
785 // Initialize verifier's transcript
786 auto verifier_transcript = NativeTranscript::test_verifier_init_empty(prover_transcript);
787
788 // Start populating Verifier's array of Libra commitments
789 std::array<Commitment, NUM_LIBRA_COMMITMENTS> libra_commitments = {};
790 libra_commitments[0] =
791 verifier_transcript->template receive_from_prover<Commitment>("Libra:concatenation_commitment");
792
793 // Place Libra data to the transcript
794 [[maybe_unused]] const Fr libra_total_sum = verifier_transcript->template receive_from_prover<Fr>("Libra:Sum");
795 [[maybe_unused]] const Fr libra_challenge = verifier_transcript->template get_challenge<Fr>("Libra:Challenge");
796 // Verifier receives the CORRUPTED evaluation from the transcript
797 const Fr libra_evaluation = verifier_transcript->template receive_from_prover<Fr>("Libra:claimed_evaluation");
798
799 // Finalize the array of Libra/SmallSubgroupIpa commitments
800 libra_commitments[1] = verifier_transcript->template receive_from_prover<Commitment>("Libra:grand_sum_commitment");
801 libra_commitments[2] = verifier_transcript->template receive_from_prover<Commitment>("Libra:quotient_commitment");
802
803 // Run Shplemini - verifier uses the corrupted evaluation received from the transcript
804 auto shplemini_output = ShpleminiVerifier::compute_batch_opening_claim(mock_claims.claim_batcher,
805 mle_opening_point,
806 this->vk().get_g1_identity(),
807 verifier_transcript,
808 {},
809 libra_commitments,
810 libra_evaluation);
811
812 // Verify that consistency_checked is false due to corrupted Libra evaluation
813 EXPECT_FALSE(shplemini_output.consistency_checked);
814}
815
823template <typename TypeParam>
825 typename ShpleminiTest<TypeParam>::TamperedPolynomial tamper_polynomial,
826 typename ShpleminiTest<TypeParam>::TamperedCommitment tamper_commitment,
827 bool expected_consistency_checked)
828{
829 using TamperedPolynomial = typename ShpleminiTest<TypeParam>::TamperedPolynomial;
830 using TamperedCommitment = typename ShpleminiTest<TypeParam>::TamperedCommitment;
831 using ZKData = ZKSumcheckData<TypeParam>;
832 using Curve = typename TypeParam::Curve;
833 using ShpleminiProver = ShpleminiProver_<Curve>;
834 constexpr bool HasZK = true;
835 using ShpleminiVerifier = ShpleminiVerifier_<Curve, HasZK>;
836 using Fr = typename Curve::ScalarField;
837 using Commitment = typename Curve::AffineElement;
838 using CK = typename TypeParam::CommitmentKey;
839
840 auto prover_transcript = TypeParam::Transcript::test_prover_init_empty();
841
842 static constexpr size_t log_subgroup_size = static_cast<size_t>(numeric::get_msb(Curve::SUBGROUP_SIZE));
843 CK ck = create_commitment_key<CK>(std::max<size_t>(test->n, 1ULL << (log_subgroup_size + 1)));
844
845 ZKData zk_sumcheck_data(test->log_n, prover_transcript, ck);
846 std::vector<Fr> mle_opening_point = test->random_evaluation_point(test->log_n);
847
848 MockClaimGenerator<Curve> mock_claims(test->n, test->num_polynomials, test->num_shiftable, mle_opening_point, ck);
849
851 zk_sumcheck_data, mle_opening_point, test->log_n);
852
853 prover_transcript->send_to_verifier("Libra:claimed_evaluation", claimed_inner_product);
854
855 SmallSubgroupIPAProver<TypeParam> small_subgroup_ipa_prover(
856 zk_sumcheck_data, mle_opening_point, claimed_inner_product, prover_transcript, ck);
857 small_subgroup_ipa_prover.prove();
858
859 auto witness_polynomials = small_subgroup_ipa_prover.get_witness_polynomials();
860
861 // Optionally tamper with a witness polynomial
862 if (tamper_polynomial != TamperedPolynomial::None) {
863 witness_polynomials[static_cast<size_t>(tamper_polynomial)].at(0) += Fr::random_element();
864 }
865
866 const auto opening_claim = ShpleminiProver::prove(
867 test->n, mock_claims.polynomial_batcher, mle_opening_point, ck, prover_transcript, witness_polynomials);
868
870 ShpleminiTest<TypeParam>::IPA::compute_opening_proof(test->ck(), opening_claim, prover_transcript);
871 } else {
872 KZG<Curve>::compute_opening_proof(test->ck(), opening_claim, prover_transcript);
873 }
874
875 auto verifier_transcript = NativeTranscript::test_verifier_init_empty(prover_transcript);
876
877 std::array<Commitment, NUM_LIBRA_COMMITMENTS> libra_commitments = {};
878 libra_commitments[0] =
879 verifier_transcript->template receive_from_prover<Commitment>("Libra:concatenation_commitment");
880
881 [[maybe_unused]] const Fr libra_total_sum = verifier_transcript->template receive_from_prover<Fr>("Libra:Sum");
882 [[maybe_unused]] const Fr libra_challenge = verifier_transcript->template get_challenge<Fr>("Libra:Challenge");
883 const Fr libra_evaluation = verifier_transcript->template receive_from_prover<Fr>("Libra:claimed_evaluation");
884
885 libra_commitments[1] = verifier_transcript->template receive_from_prover<Commitment>("Libra:grand_sum_commitment");
886 libra_commitments[2] = verifier_transcript->template receive_from_prover<Commitment>("Libra:quotient_commitment");
887
888 // Optionally tamper with a commitment
889 if (tamper_commitment != TamperedCommitment::None) {
890 auto idx = static_cast<size_t>(tamper_commitment);
891 libra_commitments[idx] = libra_commitments[idx] + Commitment::one();
892 }
893
894 auto [batch_opening_claim, consistency_checked] =
895 ShpleminiVerifier::compute_batch_opening_claim(mock_claims.claim_batcher,
896 mle_opening_point,
897 test->vk().get_g1_identity(),
898 verifier_transcript,
899 {},
900 libra_commitments,
901 libra_evaluation);
902
903 EXPECT_EQ(consistency_checked, expected_consistency_checked);
904
905 // PCS verification should always fail when tampering occurred
908 batch_opening_claim, test->vk(), verifier_transcript));
909 } else {
910 const auto pairing_points =
911 KZG<Curve>::reduce_verify_batch_opening_claim(std::move(batch_opening_claim), verifier_transcript);
912 EXPECT_FALSE(pairing_points.check());
913 }
914}
915
919TYPED_TEST(ShpleminiTest, LibraQuotientPolynomialTamperingCausesVerificationFailure)
920{
921 using TamperedPolynomial = typename TestFixture::TamperedPolynomial;
922 using TamperedCommitment = typename TestFixture::TamperedCommitment;
923 // Consistency check fails because Q(r) is wrong
925 this, TamperedPolynomial::Quotient, TamperedCommitment::None, /*expected_consistency_checked=*/false);
926}
927
931TYPED_TEST(ShpleminiTest, LibraQuotientCommitmentTamperingCausesVerificationFailure)
932{
933 using TamperedPolynomial = typename TestFixture::TamperedPolynomial;
934 using TamperedCommitment = typename TestFixture::TamperedCommitment;
935 // Consistency check passes because evaluations are honest
937 this, TamperedPolynomial::None, TamperedCommitment::Quotient, /*expected_consistency_checked=*/true);
938}
939
943TYPED_TEST(ShpleminiTest, LibraGrandSumPolynomialTamperingCausesVerificationFailure)
944{
945 using TamperedPolynomial = typename TestFixture::TamperedPolynomial;
946 using TamperedCommitment = typename TestFixture::TamperedCommitment;
947 // Consistency check fails because A(r) and A(g*r) are wrong
949 this, TamperedPolynomial::GrandSum, TamperedCommitment::None, /*expected_consistency_checked=*/false);
950}
951
955TYPED_TEST(ShpleminiTest, LibraGrandSumCommitmentTamperingCausesVerificationFailure)
956{
957 using TamperedPolynomial = typename TestFixture::TamperedPolynomial;
958 using TamperedCommitment = typename TestFixture::TamperedCommitment;
959 // Consistency check passes because evaluations are honest
961 this, TamperedPolynomial::None, TamperedCommitment::GrandSum, /*expected_consistency_checked=*/true);
962}
963
967TYPED_TEST(ShpleminiTest, LibraConcatenatedPolynomialTamperingCausesVerificationFailure)
968{
969 using TamperedPolynomial = typename TestFixture::TamperedPolynomial;
970 using TamperedCommitment = typename TestFixture::TamperedCommitment;
971 // Consistency check fails because G(r) is wrong
973 this, TamperedPolynomial::Concatenated, TamperedCommitment::None, /*expected_consistency_checked=*/false);
974}
975
979TYPED_TEST(ShpleminiTest, LibraConcatenatedCommitmentTamperingCausesVerificationFailure)
980{
981 using TamperedPolynomial = typename TestFixture::TamperedPolynomial;
982 using TamperedCommitment = typename TestFixture::TamperedCommitment;
983 // Consistency check passes because evaluations are honest
985 this, TamperedPolynomial::None, TamperedCommitment::Concatenated, /*expected_consistency_checked=*/true);
986}
987
988} // namespace bb
#define BB_DISABLE_ASSERTS()
Definition assert.hpp:33
static std::shared_ptr< BaseTranscript > test_prover_init_empty()
For testing: initializes transcript with some arbitrary data so that a challenge can be generated aft...
static std::shared_ptr< BaseTranscript > test_verifier_init_empty(const std::shared_ptr< BaseTranscript > &transcript)
For testing: initializes transcript based on proof data then receives junk data produced by BaseTrans...
std::vector< Fr > random_evaluation_point(const size_t num_variables)
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,...
Definition gemini.hpp:181
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.
Definition gemini.hpp:248
static std::vector< Fr > compute_fold_pos_evaluations(const Fr &batched_evaluation, std::span< const Fr > evaluation_point, std::span< const Fr > challenge_powers, std::span< const Fr > fold_neg_evals)
Compute .
Definition gemini.hpp:369
IPA (inner product argument) commitment scheme class.
Definition ipa.hpp:86
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 ...
Definition kzg.hpp:131
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.
Definition kzg.hpp:43
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
Shplonk Verifier.
Definition shplonk.hpp:331
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
Definition grumpkin.hpp:63
static constexpr size_t SUBGROUP_SIZE
Definition grumpkin.hpp:72
typename Group::affine_element AffineElement
Definition grumpkin.hpp:64
bool expected_result
std::vector< Fr > powers_of_evaluation_challenge(const Fr &r, const size_t num_squares)
Compute squares of folding challenge r.
Definition gemini.hpp:96
std::vector< Fr > powers_of_rho(const Fr &rho, const size_t num_powers)
Compute powers of challenge ρ
Definition gemini.hpp:76
constexpr T get_msb(const T in)
Definition get_msb.hpp:50
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
::testing::Types< BN254Settings, GrumpkinSettings > TestSettings
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
void run_libra_tampering_test(ShpleminiTest< TypeParam > *test, typename ShpleminiTest< TypeParam >::TamperedPolynomial tamper_polynomial, typename ShpleminiTest< TypeParam >::TamperedCommitment tamper_commitment, bool expected_consistency_checked)
Helper to run a Libra tampering test with configurable tampering options.
CommitmentKey< Curve > ck
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Curve::ScalarField Fr
void update_batch_mul_inputs_and_batched_evaluation(std::vector< Commitment > &commitments, std::vector< Fr > &scalars, Fr &batched_evaluation, const Fr &rho)
Append the commitments and scalars from each batch of claims to the Shplemini vectors which subsequen...
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...
Constructs random polynomials, computes commitments and corresponding evaluations.
std::vector< bb::Polynomial< Fr > > round_univariates
std::vector< Commitment > sumcheck_commitments
std::vector< std::array< Fr, 3 > > sumcheck_evaluations
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