Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
shplemini.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Khashayar], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
20
21namespace bb {
22
23template <typename Curve> class ShpleminiProver_ {
24 public:
25 using FF = typename Curve::ScalarField;
26 using GroupElement = typename Curve::Element;
30
35
36 template <typename Transcript>
37 static OpeningClaim prove(size_t circuit_size,
38 PolynomialBatcher& polynomial_batcher,
39 std::span<FF> multilinear_challenge,
40 const CommitmentKey<Curve>& commitment_key,
41 const std::shared_ptr<Transcript>& transcript,
42 const std::array<Polynomial, NUM_SMALL_IPA_COMMITMENTS>& libra_polynomials = {},
43 const std::vector<Polynomial>& sumcheck_round_univariates = {},
44 const std::vector<std::array<FF, 3>>& sumcheck_round_evaluations = {})
45 {
46 BB_BENCH_NAME("ShpleminiProver::prove");
47 // While Shplemini is not templated on Flavor, we derive the ZK flag from the presence of the Libra
48 // polynomials. They are either all populated (ZK) or all empty (non-ZK); assert this consistency so a
49 // partially-populated array cannot silently take the wrong path based on entry [0] alone.
50 const bool has_zk = (libra_polynomials[0].size() > 0);
51 for (const auto& libra_poly : libra_polynomials) {
52 BB_ASSERT((libra_poly.size() > 0) == has_zk,
53 "ShpleminiProver: libra_polynomials must be either all populated (ZK) or all empty (non-ZK)");
54 }
55
56 // When padding is enabled, the size of the multilinear challenge may be bigger than the log of `circuit_size`.
57 const size_t virtual_log_n = multilinear_challenge.size();
58
60 circuit_size, polynomial_batcher, multilinear_challenge, commitment_key, transcript, has_zk);
61 // Create opening claims for Libra masking univariates and Sumcheck Round Univariates
62 std::vector<OpeningClaim> libra_opening_claims;
63
64 if (has_zk) {
65 const auto gemini_r = opening_claims[0].opening_pair.challenge;
66 libra_opening_claims = compute_libra_opening_claims(gemini_r, libra_polynomials, transcript);
67 }
68
69 // Currently, only used in the joint BatchedHonkTranslator PCS.
70 std::vector<OpeningClaim> sumcheck_round_claims;
71
72 if (!sumcheck_round_univariates.empty()) {
73 sumcheck_round_claims = compute_sumcheck_round_claims(
74 circuit_size, multilinear_challenge, sumcheck_round_univariates, sumcheck_round_evaluations);
75 }
76
78 commitment_key, opening_claims, transcript, libra_opening_claims, sumcheck_round_claims, virtual_log_n);
79 };
80
86 template <typename Transcript>
88 const FF gemini_r,
90 const std::shared_ptr<Transcript>& transcript)
91 {
92 const auto claims =
93 make_small_ipa_prover_opening_claims<Curve>(libra_polynomials, gemini_r, "Libra:", transcript);
94 return std::vector<OpeningClaim>(claims.begin(), claims.end());
95 }
96
103 size_t circuit_size,
104 std::span<FF> multilinear_challenge,
105 const std::vector<Polynomial>& sumcheck_round_univariates,
106 const std::vector<std::array<FF, 3>>& sumcheck_round_evaluations)
107 {
108 std::vector<OpeningClaim> sumcheck_round_claims = {};
109
110 const size_t log_n = numeric::get_msb(circuit_size);
111 for (size_t idx = 0; idx < log_n; idx++) {
112 const std::vector<FF> evaluation_points = { FF(0), FF(1), multilinear_challenge[idx] };
113 size_t eval_idx = 0;
114 OpeningClaim new_claim;
115 new_claim.polynomial = sumcheck_round_univariates[idx];
116
117 for (auto& eval_point : evaluation_points) {
118 new_claim.opening_pair.challenge = eval_point;
119 new_claim.opening_pair.evaluation = sumcheck_round_evaluations[idx][eval_idx];
120 sumcheck_round_claims.push_back(new_claim);
121 eval_idx++;
122 }
123 }
124
125 return sumcheck_round_claims;
126 }
127};
128
157template <typename Curve, bool HasZK> struct ShpleminiVerifierOutput_ {
159};
164
165// `HasGeminiMasking` controls whether the flavor commits to a `gemini_masking_poly` whose
166// commitment is interleaved between Shplonk:Q and the first AllEntities commitment. Defaults to
167// `HasZK` so legacy ZK flavors (UltraZK, etc.) keep the original layout; flavors that opt out
168// (e.g. MegaZKFlavor — translator provides masking in the joint Chonk flow) set this to false
169// at the call site.
170template <typename Curve, bool HasZK = false, bool HasGeminiMasking = HasZK> class ShpleminiVerifier_ {
171 using Fr = typename Curve::ScalarField;
172 using GroupElement = typename Curve::Element;
179
180 public:
205 template <typename Transcript>
207 ClaimBatcher& claim_batcher,
208 const std::vector<Fr>& multivariate_challenge,
209 const Commitment& g1_identity,
210 const std::shared_ptr<Transcript>& transcript,
211 const RepeatedCommitmentsData& repeated_commitments = {},
212 const std::array<Commitment, NUM_SMALL_IPA_COMMITMENTS>& libra_commitments = {},
213 const Fr& libra_univariate_evaluation = Fr{ 0 },
214 const std::vector<Commitment>& sumcheck_round_commitments = {},
215 const std::vector<std::array<Fr, 3>>& sumcheck_round_evaluations = {})
216
217 {
218 const size_t virtual_log_n = multivariate_challenge.size();
219
220 // An empty multivariate challenge yields virtual_log_n == 0, which underflows the `virtual_log_n - 1`
221 // computations in the Gemini fold/evaluation loops below. Reject it before that can happen.
222 if (virtual_log_n == 0) {
223 throw_or_abort("Shplemini: multivariate_challenge must be non-empty");
224 }
225
226 BB_ASSERT(sumcheck_round_commitments.empty() == sumcheck_round_evaluations.empty(),
227 "Shplemini: sumcheck_round_commitments and sumcheck_round_evaluations must be consistently empty");
228 const bool committed_sumcheck = !sumcheck_round_evaluations.empty();
229
230 Fr batched_evaluation = Fr{ 0 };
231
232 // Get the challenge ρ to batch commitments to multilinear polynomials and their shifts
233 const Fr gemini_batching_challenge = transcript->template get_challenge<Fr>("rho");
234
235 // Process Gemini transcript data:
236 // - Get Gemini commitments (com(A₁), com(A₂), … , com(Aₙ₋₁))
237 const std::vector<Commitment> fold_commitments =
238 GeminiVerifier::get_fold_commitments(virtual_log_n, transcript);
239 // - Get Gemini evaluation challenge r, that is used to open the Gemini fold polynomials Aᵢ, i = 0, … , d−1 on
240 // r^{2^i}
241 const Fr gemini_evaluation_challenge = transcript->template get_challenge<Fr>("Gemini:r");
242
243 // - Get negative fold evaluations (A₀(−r), A₁(−r²), ... , Aₙ₋₁(−r²⁽ⁿ⁻¹⁾))
244 std::vector<Fr> gemini_fold_neg_evaluations = GeminiVerifier::get_gemini_evaluations(virtual_log_n, transcript);
245
246 // - Compute vector (r, r², ... , r^{2^{d-1}}), where d = log_n
247 const std::vector<Fr> gemini_eval_challenge_powers =
248 gemini::powers_of_evaluation_challenge(gemini_evaluation_challenge, virtual_log_n);
249
251 // For ZK, receive the transcript-carried SmallSubgroupIPA evaluations.
252 if constexpr (HasZK) {
253 libra_evaluations = receive_small_ipa_evaluations<Curve>("Libra:", transcript);
254 }
255
256 // Process Shplonk transcript data:
257 // - Get Shplonk batching challenge
258 const Fr shplonk_batching_challenge = transcript->template get_challenge<Fr>("Shplonk:nu");
259
260 // Compute the powers of ν that are required for batching Gemini, SmallSubgroupIPA, and committed sumcheck
261 // univariate opening claims.
262 const std::vector<Fr> shplonk_batching_challenge_powers = compute_shplonk_batching_challenge_powers(
263 shplonk_batching_challenge, virtual_log_n, HasZK, committed_sumcheck);
264 // - Get the quotient commitment for the Shplonk batching of Gemini opening claims
265 const auto Q_commitment = transcript->template receive_from_prover<Commitment>("Shplonk:Q");
266
267 // Start populating the vector (Q, f₀, ... , fₖ₋₁, g₀, ... , gₘ₋₁, com(A₁), ... , com(A_{d-1}), [1]₁) where fᵢ
268 // are the k commitments to unshifted polynomials and gⱼ are the m commitments to shifted polynomials
269 std::vector<Commitment> commitments{ Q_commitment };
270
271 // Get Shplonk opening point z
272 const Fr shplonk_evaluation_challenge = transcript->template get_challenge<Fr>("Shplonk:z");
273
274 // OriginTag false positive: All evaluations received above are PCS-bound.
275 // The prover cannot choose them freely because they must satisfy the batched opening equation
276 // verified by the pairing check. Tag them with the shplonk evaluation challenge.
277 if constexpr (Curve::is_stdlib_type) {
278 const auto challenge_tag = shplonk_evaluation_challenge.get_origin_tag();
279 // Tag the Gemini fold evaluations
280 for (auto& eval : gemini_fold_neg_evaluations) {
281 eval.set_origin_tag(challenge_tag);
282 }
283 }
284
285 // Start computing the scalar to be multiplied by [1]₁
286 Fr constant_term_accumulator = Fr(0);
287
288 // Initialize the vector of scalars placing the scalar 1 corresponding to Q_commitment
289 std::vector<Fr> scalars;
290
291 scalars.emplace_back(Fr(1));
292
293 // Compute 1/(z − r), 1/(z + r), 1/(z - r²), 1/(z + r²), … , 1/(z - r^{2^{d-1}}), 1/(z + r^{2^{d-1}})
294 // These represent the denominators of the summand terms in Shplonk partially evaluated polynomial Q_z
295 const std::vector<Fr> inverse_vanishing_evals = ShplonkVerifier::compute_inverted_gemini_denominators(
296 shplonk_evaluation_challenge, gemini_eval_challenge_powers);
297
298 // Compute the additional factors to be multiplied with unshifted and shifted commitments when lazily
299 // reconstructing the commitment of Q_z
300 // For unshifted values, the scalar is computed as (1/(z−r) + ν/(z+r))
301 // For shifted values, the scalar is computed as r⁻¹ ⋅ (1/(z−r) − ν/(z+r))
302 claim_batcher.compute_scalars_for_each_batch(
303 inverse_vanishing_evals, shplonk_batching_challenge, gemini_evaluation_challenge);
304
305 // Place the commitments to prover polynomials in the commitments vector. Compute the evaluation of the
306 // batched multilinear polynomial. Populate the vector of scalars for the final batch mul
308 commitments, scalars, batched_evaluation, gemini_batching_challenge);
309
310 // Reconstruct Aᵢ(r²ⁱ) for i=0, ..., d - 1 from the batched evaluation of the multilinear polynomials and
311 // Aᵢ(−r²ⁱ) for i = 0, ..., d - 1.
312 const std::vector<Fr> gemini_fold_pos_evaluations = GeminiVerifier_<Curve>::compute_fold_pos_evaluations(
313 batched_evaluation, multivariate_challenge, gemini_eval_challenge_powers, gemini_fold_neg_evaluations);
314
315 // Place the commitments to Gemini fold polynomials Aᵢ in the vector of batch_mul commitments, compute the
316 // contributions from Aᵢ(−r²ⁱ) for i=1, … , d − 1 to the constant term accumulator, add corresponding scalars
317 // for the batch mul
319 gemini_fold_neg_evaluations,
320 gemini_fold_pos_evaluations,
321 inverse_vanishing_evals,
322 shplonk_batching_challenge_powers,
323 commitments,
324 scalars,
325 constant_term_accumulator);
326 const Fr a_0_pos = gemini_fold_pos_evaluations[0];
327 // Add contributions from A₀₊(r) and A₀₋(-r) to constant_term_accumulator:
328 // Add A₀₊(r)/(z−r) to the constant term accumulator
329 constant_term_accumulator += a_0_pos * inverse_vanishing_evals[0];
330 // Add A₀₋(-r)/(z+r) to the constant term accumulator
331 constant_term_accumulator +=
332 gemini_fold_neg_evaluations[0] * shplonk_batching_challenge * inverse_vanishing_evals[1];
333
334 remove_repeated_commitments(commitments, scalars, repeated_commitments, HasGeminiMasking);
335 // An optional boolean flag for SmallSubgroupIPAVerifier to check the consistency of the Libra evaluations
336 bool consistency_checked = true;
337 // For ZK flavors, the sumcheck output contains the evaluations of Libra univariates that submitted to the
338 // ShpleminiVerifier, otherwise this argument is set to be empty
339 if constexpr (HasZK) {
340 batch_small_ipa_opening_claims(virtual_log_n,
341 commitments,
342 scalars,
343 constant_term_accumulator,
344 libra_commitments,
345 libra_evaluations,
346 gemini_evaluation_challenge,
347 shplonk_batching_challenge_powers,
348 shplonk_evaluation_challenge);
349
351 libra_evaluations, gemini_evaluation_challenge, multivariate_challenge, libra_univariate_evaluation);
352 }
353
354 // Used in the joint BatchedHonkTranslator PCS. The nu power offset in batch_sumcheck_round_claims
355 // assumes ZK claims (NUM_SMALL_IPA_OPENING_CLAIMS) precede sumcheck round claims in the batching order.
356 if (committed_sumcheck) {
357 if constexpr (!HasZK) {
358 throw_or_abort("Shplemini: committed sumcheck requires ZK for correct nu power indexing");
359 }
360 batch_sumcheck_round_claims(commitments,
361 scalars,
362 constant_term_accumulator,
363 multivariate_challenge,
364 shplonk_batching_challenge_powers,
365 shplonk_evaluation_challenge,
366 sumcheck_round_commitments,
367 sumcheck_round_evaluations);
368 }
369
370 // Finalize the batch opening claim
371 commitments.emplace_back(g1_identity);
372 scalars.emplace_back(constant_term_accumulator);
373
374 BatchOpeningClaim<Curve> batch_opening_claim{ std::move(commitments),
375 std::move(scalars),
376 shplonk_evaluation_challenge };
377 ShpleminiVerifierOutput output = [&]() {
378 if constexpr (HasZK) {
379 return ShpleminiVerifierOutput{ batch_opening_claim, consistency_checked };
380 } else {
381 return ShpleminiVerifierOutput{ batch_opening_claim };
382 }
383 }();
384 return output;
385 };
386
428 static void batch_gemini_claims_received_from_prover(const std::vector<Commitment>& fold_commitments,
429 std::span<const Fr> gemini_neg_evaluations,
430 std::span<const Fr> gemini_pos_evaluations,
431 std::span<const Fr> inverse_vanishing_evals,
432 std::span<const Fr> shplonk_batching_challenge_powers,
433 std::vector<Commitment>& commitments,
434 std::vector<Fr>& scalars,
435 Fr& constant_term_accumulator)
436 {
437 const size_t virtual_log_n = gemini_neg_evaluations.size();
438 // Start from 1, because the commitment to A_0 is reconstructed from the commitments to the multilinear
439 // polynomials. The corresponding evaluations are also handled separately.
440 for (size_t j = 1; j < virtual_log_n; ++j) {
441 // The index of 1/ (z - r^{2^{j}}) in the vector of inverted Gemini denominators
442 const size_t pos_index = 2 * j;
443 // The index of 1/ (z + r^{2^{j}}) in the vector of inverted Gemini denominators
444 const size_t neg_index = (2 * j) + 1;
445
446 // Compute the "positive" scaling factor (ν^{2j}) / (z - r^{2^{j}})
447 Fr scaling_factor_pos = shplonk_batching_challenge_powers[pos_index] * inverse_vanishing_evals[pos_index];
448 // Compute the "negative" scaling factor (ν^{2j+1}) / (z + r^{2^{j}})
449 Fr scaling_factor_neg = shplonk_batching_challenge_powers[neg_index] * inverse_vanishing_evals[neg_index];
450
451 // Accumulate the const term contribution given by
452 // v^{2j} * A_j(r^{2^j}) /(z - r^{2^j}) + v^{2j+1} * A_j(-r^{2^j}) /(z+ r^{2^j})
453 constant_term_accumulator +=
454 scaling_factor_neg * gemini_neg_evaluations[j] + scaling_factor_pos * gemini_pos_evaluations[j];
455
456 // Place the scaling factor to the 'scalars' vector
457 scalars.emplace_back(-(scaling_factor_neg + scaling_factor_pos));
458 // Move com(Aᵢ) to the 'commitments' vector
459 commitments.emplace_back(std::move(fold_commitments[j - 1]));
460 }
461 }
462
473 static void remove_repeated_commitments(std::vector<Commitment>& commitments,
474 std::vector<Fr>& scalars,
475 const RepeatedCommitmentsData& repeated_commitments,
476 bool has_gemini_masking_commitment)
477 {
478 // The commitments/scalars vectors start with Shplonk:Q (and Gemini:masking_poly_comm when
479 // the flavor commits to a per-circuit masking polynomial) before the prover polynomial
480 // commitments, so offset the AllEntities indices accordingly.
481 const size_t offset = has_gemini_masking_commitment ? 2 : 1;
482
483 const auto& r1 = repeated_commitments.first;
484 const auto& r2 = repeated_commitments.second;
485 const size_t first_original_start = r1.original_start + offset;
486 const size_t first_duplicate_start = r1.duplicate_start + offset;
487 const size_t second_original_start = r2.original_start + offset;
488 const size_t second_duplicate_start = r2.duplicate_start + offset;
489
490 // Fold duplicate scalars into their originals
491 for (size_t i = 0; i < r1.count; i++) {
492 scalars[i + first_original_start] = scalars[i + first_original_start] + scalars[i + first_duplicate_start];
493 }
494 for (size_t i = 0; i < r2.count; i++) {
495 scalars[i + second_original_start] =
496 scalars[i + second_original_start] + scalars[i + second_duplicate_start];
497 }
498
499 // Erase the duplicate entries (higher-index range first to preserve lower indices)
500 // Each erase shifts elements down, so duplicate_start always points to the next duplicate;
501 // the original at original_start + i is unaffected since we erase higher-index ranges first.
502 // Commitment equality (original == duplicate) is verified by per-flavor
503 // RepeatedCommitmentsIndicesCorrect tests rather than at runtime here.
504 auto erase_range = [&](size_t duplicate_start, [[maybe_unused]] size_t original_start, size_t count) {
505 for (size_t i = 0; i < count; ++i) {
506 scalars.erase(scalars.begin() + static_cast<std::ptrdiff_t>(duplicate_start));
507 commitments.erase(commitments.begin() + static_cast<std::ptrdiff_t>(duplicate_start));
508 }
509 };
510 if (second_duplicate_start > first_duplicate_start) {
511 erase_range(second_duplicate_start, second_original_start, r2.count);
512 erase_range(first_duplicate_start, first_original_start, r1.count);
513 } else {
514 erase_range(first_duplicate_start, first_original_start, r1.count);
515 erase_range(second_duplicate_start, second_original_start, r2.count);
516 }
517 }
518
537 const size_t virtual_log_n,
538 std::vector<Commitment>& commitments,
539 std::vector<Fr>& scalars,
540 Fr& constant_term_accumulator,
541 const std::array<Commitment, NUM_SMALL_IPA_COMMITMENTS>& libra_commitments,
542 const std::array<Fr, NUM_SMALL_IPA_OPENING_CLAIMS>& libra_evaluations,
543 const Fr& gemini_evaluation_challenge,
544 const std::vector<Fr>& shplonk_batching_challenge_powers,
545 const Fr& shplonk_evaluation_challenge)
546
547 {
548 // add Libra commitments to the vector of commitments
549 for (size_t idx = 0; idx < libra_commitments.size(); idx++) {
550 commitments.push_back(libra_commitments[idx]);
551 }
552
553 const auto denominators = compute_shplonk_denominators_for_small_ipa<Curve>(shplonk_evaluation_challenge,
554 gemini_evaluation_challenge);
555
556 // Compute per-claim batching scalars and group them by commitment via SMALL_IPA_CLAIMS[i].commitment_index, so
557 // claims that hit the same commitment fold into a single scalar mul (e.g. all three openings of [A]).
559 for (size_t idx = 0; idx < NUM_SMALL_IPA_OPENING_CLAIMS; idx++) {
560 const Fr scaling_factor = denominators[idx] * shplonk_batching_challenge_powers[2 * virtual_log_n + idx];
561 grouped_scalars[SMALL_IPA_CLAIMS[idx].commitment_index] -= scaling_factor;
562 constant_term_accumulator += scaling_factor * libra_evaluations[idx];
563 }
564 for (const Fr& s : grouped_scalars) {
565 scalars.push_back(s);
566 }
567 }
568
612 static void batch_sumcheck_round_claims(std::vector<Commitment>& commitments,
613 std::vector<Fr>& scalars,
614 Fr& constant_term_accumulator,
615 const std::vector<Fr>& multilinear_challenge,
616 const std::vector<Fr>& shplonk_batching_challenge_powers,
617 const Fr& shplonk_evaluation_challenge,
618 const std::vector<Commitment>& sumcheck_round_commitments,
619 const std::vector<std::array<Fr, 3>>& sumcheck_round_evaluations)
620 {
621
622 std::vector<Fr> denominators;
623 denominators.reserve(multilinear_challenge.size());
624
625 // The number of Gemini claims is equal to `2 * log_n` and `log_n` is equal to the size of
626 // `multilinear_challenge`, as this method is never used with padding.
627 const size_t num_gemini_claims = 2 * multilinear_challenge.size();
628 // Denominators for the opening claims at 0 and 1. Need to be computed only once as opposed to the claims at the
629 // sumcheck round challenges.
630 std::array<Fr, 2> const_denominators;
631
632 const_denominators[0] = Fr(1) / (shplonk_evaluation_challenge);
633 const_denominators[1] = Fr(1) / (shplonk_evaluation_challenge - Fr{ 1 });
634
635 // Compute the denominators corresponding to the evaluation claims at the round challenges and add the
636 // commitments to the sumcheck round univariates to the vector of commitments
637 for (const auto& [challenge, comm] : zip_view(multilinear_challenge, sumcheck_round_commitments)) {
638 denominators.push_back(shplonk_evaluation_challenge - challenge);
639 commitments.push_back(comm);
640 }
641
642 // Invert denominators
643 if constexpr (!Curve::is_stdlib_type) {
644 Fr::batch_invert(denominators);
645 } else {
646 for (auto& denominator : denominators) {
647 denominator = Fr{ 1 } / denominator;
648 }
649 }
650
651 // Each commitment to a sumcheck round univariate [S_i] is multiplied by the sum of three scalars corresponding
652 // to the evaluations at 0, 1, and the round challenge u_i.
653 // Compute the power of `shplonk_batching_challenge` to add sumcheck univariate commitments and evaluations to
654 // the batch.
655 size_t power = num_gemini_claims + NUM_SMALL_IPA_OPENING_CLAIMS;
656 for (const auto& [eval_array, denominator] : zip_view(sumcheck_round_evaluations, denominators)) {
657 // Initialize batched_scalar corresponding to 3 evaluations claims
658 Fr batched_scalar = Fr(0);
659 Fr const_term_contribution = Fr(0);
660 // Compute the contribution from the evaluations at 0 and 1
661 for (size_t idx = 0; idx < 2; idx++) {
662 Fr current_scaling_factor = const_denominators[idx] * shplonk_batching_challenge_powers[power++];
663 batched_scalar -= current_scaling_factor;
664 const_term_contribution += current_scaling_factor * eval_array[idx];
665 }
666
667 // Compute the contribution from the evaluation at the challenge u_i
668 Fr current_scaling_factor = denominator * shplonk_batching_challenge_powers[power++];
669 batched_scalar -= current_scaling_factor;
670 const_term_contribution += current_scaling_factor * eval_array[2];
671
672 // Update Shplonk constant term accumulator
673 constant_term_accumulator += const_term_contribution;
674 scalars.push_back(batched_scalar);
675 }
676 };
677};
678} // namespace bb
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:264
CommitmentKey object over a pairing group 𝔾₁.
Class responsible for computation of the batched multilinear polynomials required by the Gemini proto...
Definition gemini.hpp:129
static std::vector< Claim > prove(size_t circuit_size, PolynomialBatcher &polynomial_batcher, std::span< Fr > multilinear_challenge, const CommitmentKey< Curve > &commitment_key, const std::shared_ptr< Transcript > &transcript, bool has_zk=false)
Gemini Verifier utility methods used by ShpleminiVerifier.
Definition gemini.hpp:249
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:318
static std::vector< Commitment > get_fold_commitments(const size_t virtual_log_n, auto &transcript)
Receive the fold commitments from the prover. This method is used by Shplemini where padding may be e...
Definition gemini.hpp:262
static std::vector< Fr > get_gemini_evaluations(const size_t virtual_log_n, auto &transcript)
Receive the fold evaluations from the prover. This method is used by Shplemini where padding may be e...
Definition gemini.hpp:283
Polynomial p and an opening pair (r,v) such that p(r) = v.
Definition claim.hpp:36
Polynomial polynomial
Definition claim.hpp:41
OpeningPair< Curve > opening_pair
Definition claim.hpp:42
typename Curve::Element GroupElement
Definition shplemini.hpp:26
static std::vector< OpeningClaim > compute_libra_opening_claims(const FF gemini_r, const std::array< Polynomial, NUM_SMALL_IPA_COMMITMENTS > &libra_polynomials, const std::shared_ptr< Transcript > &transcript)
For ZK Flavors: Evaluate the polynomials used in SmallSubgroupIPA argument, send the evaluations to t...
Definition shplemini.hpp:87
typename Curve::AffineElement Commitment
Definition shplemini.hpp:27
typename Curve::ScalarField FF
Definition shplemini.hpp:25
static std::vector< OpeningClaim > compute_sumcheck_round_claims(size_t circuit_size, std::span< FF > multilinear_challenge, const std::vector< Polynomial > &sumcheck_round_univariates, const std::vector< std::array< FF, 3 > > &sumcheck_round_evaluations)
Create a vector of 3*log_n opening claims for the evaluations of Sumcheck Round Univariates at 0,...
static OpeningClaim prove(size_t circuit_size, PolynomialBatcher &polynomial_batcher, std::span< FF > multilinear_challenge, const CommitmentKey< Curve > &commitment_key, const std::shared_ptr< Transcript > &transcript, const std::array< Polynomial, NUM_SMALL_IPA_COMMITMENTS > &libra_polynomials={}, const std::vector< Polynomial > &sumcheck_round_univariates={}, const std::vector< std::array< FF, 3 > > &sumcheck_round_evaluations={})
Definition shplemini.hpp:37
typename Curve::Element GroupElement
typename Curve::AffineElement Commitment
static void remove_repeated_commitments(std::vector< Commitment > &commitments, std::vector< Fr > &scalars, const RepeatedCommitmentsData &repeated_commitments, bool has_gemini_masking_commitment)
Combines scalars of repeating commitments to reduce the number of scalar multiplications performed by...
static void batch_sumcheck_round_claims(std::vector< Commitment > &commitments, std::vector< Fr > &scalars, Fr &constant_term_accumulator, const std::vector< Fr > &multilinear_challenge, const std::vector< Fr > &shplonk_batching_challenge_powers, const Fr &shplonk_evaluation_challenge, const std::vector< Commitment > &sumcheck_round_commitments, const std::vector< std::array< Fr, 3 > > &sumcheck_round_evaluations)
Adds the Sumcheck data into the Shplemini BatchOpeningClaim.
typename Curve::ScalarField Fr
static ShpleminiVerifierOutput compute_batch_opening_claim(ClaimBatcher &claim_batcher, const std::vector< Fr > &multivariate_challenge, const Commitment &g1_identity, const std::shared_ptr< Transcript > &transcript, const RepeatedCommitmentsData &repeated_commitments={}, const std::array< Commitment, NUM_SMALL_IPA_COMMITMENTS > &libra_commitments={}, const Fr &libra_univariate_evaluation=Fr{ 0 }, const std::vector< Commitment > &sumcheck_round_commitments={}, const std::vector< std::array< Fr, 3 > > &sumcheck_round_evaluations={})
This method receives commitments to all prover polynomials, their claimed evaluations,...
ShpleminiVerifierOutput_< Curve, HasZK > ShpleminiVerifierOutput
static void batch_small_ipa_opening_claims(const size_t virtual_log_n, std::vector< Commitment > &commitments, std::vector< Fr > &scalars, Fr &constant_term_accumulator, const std::array< Commitment, NUM_SMALL_IPA_COMMITMENTS > &libra_commitments, const std::array< Fr, NUM_SMALL_IPA_OPENING_CLAIMS > &libra_evaluations, const Fr &gemini_evaluation_challenge, const std::vector< Fr > &shplonk_batching_challenge_powers, const Fr &shplonk_evaluation_challenge)
Add the opening data corresponding to Libra masking univariates to the batched opening claim.
static void batch_gemini_claims_received_from_prover(const std::vector< Commitment > &fold_commitments, std::span< const Fr > gemini_neg_evaluations, std::span< const Fr > gemini_pos_evaluations, std::span< const Fr > inverse_vanishing_evals, std::span< const Fr > shplonk_batching_challenge_powers, std::vector< Commitment > &commitments, std::vector< Fr > &scalars, Fr &constant_term_accumulator)
Place fold polynomial commitments to commitments and compute the corresponding scalar multipliers.
Shplonk Prover.
Definition shplonk.hpp:38
static ProverOpeningClaim< Curve > prove(const CommitmentKey< Curve > &commitment_key, std::span< ProverOpeningClaim< Curve > > opening_claims, const std::shared_ptr< Transcript > &transcript, std::span< ProverOpeningClaim< Curve > > libra_opening_claims={}, std::span< ProverOpeningClaim< Curve > > sumcheck_round_claims={}, const size_t virtual_log_n=0)
Definition shplonk.hpp:307
Shplonk Verifier.
Definition shplonk.hpp:367
static std::vector< Fr > compute_inverted_gemini_denominators(const Fr &shplonk_eval_challenge, const std::vector< Fr > &gemini_eval_challenge_powers)
Computes .
Definition shplonk.hpp:592
static bool check_libra_evaluations_consistency(const std::array< FF, NUM_SMALL_IPA_OPENING_CLAIMS > &libra_evaluations, const FF &gemini_evaluation_challenge, const std::vector< FF > &multilinear_challenge, const FF &inner_product_eval_claim)
A method required by ZKSumcheck. The challenge polynomial is concatenated from the powers of the sumc...
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
typename Group::element Element
Definition grumpkin.hpp:63
static constexpr bool is_stdlib_type
Definition grumpkin.hpp:67
typename Group::affine_element AffineElement
Definition grumpkin.hpp:64
ssize_t offset
Definition engine.cpp:62
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
constexpr T get_msb(const T in)
Definition get_msb.hpp:50
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr auto SMALL_IPA_CLAIMS
The five SmallSubgroupIPA opening claims, in transcript order.
constexpr size_t NUM_SMALL_IPA_OPENING_CLAIMS
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
This file contains part of the logic for the Origin Tag mechanism that tracks the use of in-circuit p...
An accumulator consisting of the Shplonk evaluation challenge and vectors of commitments and scalars.
Definition claim.hpp:156
Logic to support batching opening claims for unshifted and shifted polynomials in Shplemini.
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...
BatchOpeningClaim< Curve > batch_opening_claim
An efficient verifier for the evaluation proofs of multilinear polynomials and their shifts.
BatchOpeningClaim< Curve > batch_opening_claim
static void batch_invert(C &coeffs) noexcept
Batch invert a collection of field elements using Montgomery's trick.
void throw_or_abort(std::string const &err)