Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
sumcheck.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
16#include "sumcheck_round.hpp"
17
18namespace bb {
19
24template <typename Flavor, bool IsGrumpkin = IsGrumpkinFlavor<Flavor>> struct RoundUnivariateHandler {
25 using FF = typename Flavor::FF;
29
30 std::shared_ptr<Transcript> transcript;
31
32 RoundUnivariateHandler(std::shared_ptr<Transcript> transcript)
33 : transcript(std::move(transcript))
34 {}
35
36 void process_round_univariate(size_t round_idx,
38 {
39 transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(round_idx), round_univariate);
40 }
41
42 void finalize_last_round(size_t /*multivariate_d*/,
44 const FF& /*last_challenge*/)
45 {}
46
49};
50
54template <typename Flavor> struct RoundUnivariateHandler<Flavor, true> {
55 using FF = typename Flavor::FF;
59
60 std::shared_ptr<Transcript> transcript;
62 std::vector<FF> eval_domain;
65
66 RoundUnivariateHandler(std::shared_ptr<Transcript> transcript)
67 : transcript(std::move(transcript))
69 {
70 // Compute the vector {0, 1, \ldots, BATCHED_RELATION_PARTIAL_LENGTH-1} needed to transform
71 // the round univariates from Lagrange to monomial basis
72 for (size_t idx = 0; idx < BATCHED_RELATION_PARTIAL_LENGTH; idx++) {
73 eval_domain.push_back(FF(idx));
74 }
75 }
76
77 void process_round_univariate(size_t round_idx,
79 {
80 const std::string idx = std::to_string(round_idx);
81
82 // Transform to monomial form and commit to it
83 Polynomial<FF> round_poly_monomial(
84 eval_domain, std::span<FF>(round_univariate.evaluations), BATCHED_RELATION_PARTIAL_LENGTH);
85 transcript->send_to_verifier("Sumcheck:univariate_comm_" + idx, ck.commit(round_poly_monomial));
86
87 // Store round univariate in monomial, as it is required by Shplemini
88 round_univariates.push_back(std::move(round_poly_monomial));
89
90 // Send the evaluations of the round univariate at 0 and 1
91 transcript->send_to_verifier("Sumcheck:univariate_" + idx + "_eval_0", round_univariate.value_at(0));
92 transcript->send_to_verifier("Sumcheck:univariate_" + idx + "_eval_1", round_univariate.value_at(1));
93
94 // Store the evaluations to be used by ShpleminiProver.
95 round_evaluations.push_back({ round_univariate.value_at(0), round_univariate.value_at(1), FF(0) });
96 if (round_idx > 0) {
97 round_evaluations[round_idx - 1][2] = round_univariate.value_at(0) + round_univariate.value_at(1);
98 }
99 }
100
101 void finalize_last_round(size_t multivariate_d,
103 const FF& last_challenge)
104 {
105 round_evaluations[multivariate_d - 1][2] = round_univariate.evaluate(last_challenge);
106 }
107
108 std::vector<std::array<FF, 3>> get_evaluations() { return round_evaluations; }
109 std::vector<Polynomial<FF>> get_univariates() { return round_univariates; }
110};
111
116template <typename Flavor, bool HasZK = Flavor::HasZK> struct VerifierZKCorrectionHandler {
117 using FF = typename Flavor::FF;
120
121 std::shared_ptr<Transcript> transcript;
124
125 // Construct a handler which will handle all the evaluations/
126 VerifierZKCorrectionHandler(std::shared_ptr<Transcript> transcript)
127 : transcript(std::move(transcript))
128 {}
129
131
132 void apply_zk_corrections(FF& /*full_honk_purported_value*/,
133 const std::vector<FF>& /*multivariate_challenge*/,
134 const std::vector<FF>& /*padding_indicator_array*/)
135 {}
136
138};
139
143template <typename Flavor> struct VerifierZKCorrectionHandler<Flavor, true> {
144 using FF = typename Flavor::FF;
147
148 std::shared_ptr<Transcript> transcript;
149 FF libra_total_sum = FF{ 0 };
152
153 // If running zero-knowledge sumcheck the target total sum is corrected by the claimed sum of libra masking
154 // multivariate over the hypercube
155 VerifierZKCorrectionHandler(std::shared_ptr<Transcript> transcript)
156 : transcript(std::move(transcript))
157 , libra_total_sum(this->transcript->template receive_from_prover<FF>("Libra:Sum"))
158 , libra_challenge(this->transcript->template get_challenge<FF>("Libra:Challenge"))
159 {}
160
161 void initialize_target_sum(SumcheckRound& round) { round.target_total_sum = libra_total_sum * libra_challenge; }
162
163 void apply_zk_corrections(FF& full_honk_purported_value,
164 std::vector<FF>& multivariate_challenge,
165 const std::vector<FF>& padding_indicator_array)
166 {
167 if constexpr (UseRowDisablingPolynomial<Flavor>) {
168 // Compute the evaluations of the polynomial (1 - \sum L_i) where the sum is for i corresponding to the
169 // rows where all sumcheck relations are disabled
170 // i.e. compute the term $1 - \prod_{i=2}^{d-1} u_i$
171 full_honk_purported_value *=
172 RowDisablingPolynomial<FF>::evaluate_at_challenge(multivariate_challenge, padding_indicator_array);
173 }
174
175 // Get the claimed evaluation of the Libra multivariate evaluated at the sumcheck challenge
176 libra_evaluation = transcript->template receive_from_prover<FF>("Libra:claimed_evaluation");
177 full_honk_purported_value += libra_evaluation * libra_challenge;
178 }
179
181};
182
289template <typename Flavor> class SumcheckProver {
290 public:
291 using FF = typename Flavor::FF;
292 // PartiallyEvaluatedMultivariates OR ProverPolynomials
293 // both inherit from AllEntities
301
308
309 // this constant specifies the number of coefficients of libra polynomials, and evaluations of round univariate
311
313
314 // The size of the hypercube, i.e. \f$ 2^d\f$.
315 const size_t multivariate_n;
316 // The number of variables
317 const size_t multivariate_d;
318 // A reference to all prover multilinear polynomials.
320
321 std::shared_ptr<Transcript> transcript;
322 // Contains the core sumcheck methods such as `compute_univariate`.
324 // An array of size NUM_SUBRELATIONS-1 containing challenges or consecutive powers of a single challenge that
325 // separate linearly independent subrelation.
327 // pow_β(X₀, ..., X_{d−1}) = ∏ₖ₌₀^{d−1} (1 − Xₖ + Xₖ ⋅ βₖ)
328 std::vector<FF> gate_challenges;
329 // Contains various challenges, such as `beta` and `gamma` used in the Grand Product argument.
331
332 // Determines the number of rounds in the sumcheck (may include padding rounds, i.e. >= multivariate_d).
334
335 std::vector<FF> multivariate_challenge;
336
337 // For computing eq polymomials in Multilinear Batching Flavor
338 std::vector<FF> accumulator_challenge = {};
339 std::vector<FF> instance_challenge = {};
341
343
354
355 // SumcheckProver constructor for MultilinearBatchingFlavor.
357 ProverPolynomials& prover_polynomials,
358 std::shared_ptr<Transcript> transcript,
359 const FF& relation_separator,
360 const size_t virtual_log_n,
361 const std::vector<FF>& accumulator_challenge,
362 const std::vector<FF>& instance_challenge)
365 , full_polynomials(prover_polynomials)
366 , transcript(std::move(transcript))
368 , alphas(initialize_relation_separator<FF, Flavor::NUM_SUBRELATIONS - 1>(relation_separator))
369 , gate_challenges({})
373
374 // SumcheckProver constructor for the Flavors that generate a single challenge `alpha` and use its powers as
375 // subrelation seperator challenges.
377 ProverPolynomials& prover_polynomials,
378 std::shared_ptr<Transcript> transcript,
379 const FF& alpha,
380 const std::vector<FF>& gate_challenges,
382 const size_t virtual_log_n)
385 , full_polynomials(prover_polynomials)
386 , transcript(std::move(transcript))
388 , alphas(initialize_relation_separator<FF, Flavor::NUM_SUBRELATIONS - 1>(alpha))
399 {
400 vinfo("starting sumcheck rounds...");
401
402 // Given gate challenges β = (β₀, ..., β_{d−1}) and d = `multivariate_d`, compute the evaluations of
403 // GateSeparator_β (X₀, ..., X_{d−1}) = ∏ₖ₌₀^{d−1} (1 − Xₖ + Xₖ · βₖ)
404 // on the boolean hypercube.
406
408 // In the first round, we compute the first univariate polynomial and populate the book-keeping table of
409 // #partially_evaluated_polynomials, which has \f$ n/2 \f$ rows and \f$ N \f$ columns.
410 auto round_univariate =
411 round.compute_univariate(full_polynomials, relation_parameters, gate_separators, alphas);
412 // Initialize the partially evaluated polynomials which will be used in the following rounds.
413 // This will use the information in the structured full polynomials to save memory if possible.
415
416 {
417 BB_BENCH_NAME("rest of sumcheck round 1");
418
419 // Place the evaluations of the round univariate into transcript.
420 transcript->send_to_verifier("Sumcheck:univariate_0", round_univariate);
421 FF round_challenge = transcript->template get_challenge<FF>("Sumcheck:u_0");
422 multivariate_challenge.emplace_back(round_challenge);
423 // Prepare sumcheck book-keeping table for the next round
424 partially_evaluate(full_polynomials, round_challenge);
425
426 gate_separators.partially_evaluate(round_challenge);
427 round.round_size = round.round_size >> 1; // TODO(#224)(Cody): Maybe partially_evaluate should do this and
428 // release memory? // All but final round
429 // We operate on partially_evaluated_polynomials in place.
430 }
431 for (size_t round_idx = 1; round_idx < multivariate_d; round_idx++) {
432 BB_BENCH_NAME("sumcheck loop");
433
434 // Write the round univariate to the transcript
435 round_univariate =
436 round.compute_univariate(partially_evaluated_polynomials, relation_parameters, gate_separators, alphas);
437 // Place evaluations of Sumcheck Round Univariate in the transcript
438 transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(round_idx), round_univariate);
439 FF round_challenge = transcript->template get_challenge<FF>("Sumcheck:u_" + std::to_string(round_idx));
440 multivariate_challenge.emplace_back(round_challenge);
441 // Prepare sumcheck book-keeping table for the next round.
443 gate_separators.partially_evaluate(round_challenge);
444 round.round_size = round.round_size >> 1;
445 }
446 vinfo("completed ", multivariate_d, " rounds of sumcheck");
447
449 // If required, extend prover's multilinear polynomials in `multivariate_d` variables by zero to get multilinear
450 // polynomials in `virtual_log_n` variables.
451 for (size_t k = multivariate_d; k < virtual_log_n; ++k) {
452 if constexpr (isMultilinearBatchingFlavor) {
453 // We need to specify the evaluation at index 1 for eq polynomials
454 std::vector<FF> index_1_challenge(virtual_log_n);
455 for (size_t i = 0; i < k; i++) {
456 index_1_challenge[i] = multivariate_challenge[i];
457 }
458 index_1_challenge[k] = FF(1);
459 if (partially_evaluated_polynomials.w_evaluations_accumulator.size() == 1) {
460
461 // We need to reallocate the polynomials
462 auto new_polynomial =
463 Polynomial<FF>(2, partially_evaluated_polynomials.w_evaluations_accumulator.virtual_size());
464 new_polynomial.at(0) = partially_evaluated_polynomials.w_evaluations_accumulator.at(0);
465 partially_evaluated_polynomials.w_evaluations_accumulator = new_polynomial;
466 }
467 if (partially_evaluated_polynomials.w_evaluations_instance.size() == 1) {
468 // We need to reallocate the polynomials
469 auto new_polynomial =
470 Polynomial<FF>(2, partially_evaluated_polynomials.w_evaluations_instance.virtual_size());
471 new_polynomial.at(0) = partially_evaluated_polynomials.w_evaluations_instance.at(0);
472 partially_evaluated_polynomials.w_evaluations_instance = new_polynomial;
473 }
474 partially_evaluated_polynomials.w_evaluations_accumulator.at(1) =
476 partially_evaluated_polynomials.w_evaluations_instance.at(1) =
478 index_1_challenge[k] = FF(0);
479 }
480 // Compute the contribution from the extensions by zero. It is sufficient to evaluate the main constraint at
481 // `MAX_PARTIAL_RELATION_LENGTH` points.
482 const auto virtual_round_univariate = round.compute_virtual_contribution(
484
485 transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(k), virtual_round_univariate);
486
487 const FF round_challenge = transcript->template get_challenge<FF>("Sumcheck:u_" + std::to_string(k));
488 multivariate_challenge.emplace_back(round_challenge);
489
490 // Update the book-keeping table of partial evaluations of the prover polynomials extended by zero.
491 for (auto& poly : partially_evaluated_polynomials.get_all()) {
492 // Avoid bad access if polynomials are set to be of size 0, which can happen in AVM.
493 if (poly.size() > 0) {
494 if (poly.size() == 1) {
495 poly.at(0) *= (FF(1) - round_challenge);
496 } else if (poly.size() == 2) {
497 // Here we handle the eq polynomial case
498 poly.at(0) = poly.at(0) * (FF(1) - round_challenge) + poly.at(1) * round_challenge;
499 poly.at(1) = 0;
500 } else {
501 BB_ASSERT_EQ(true, false, "Polynomial size is not 1 or 2");
502 }
503 }
504 }
505 virtual_gate_separator.partially_evaluate(round_challenge);
506 }
507
509 transcript->send_to_verifier("Sumcheck:evaluations", multivariate_evaluations.get_all());
510 // For ZK Flavors: the evaluations of Libra univariates are included in the Sumcheck Output
511
513 .claimed_evaluations = multivariate_evaluations };
514 vinfo("finished sumcheck");
515 };
516
524 SumcheckOutput<Flavor> prove(ZKData& zk_sumcheck_data)
525 requires Flavor::HasZK
526 {
528 vinfo("starting sumcheck rounds...");
529 // Given gate challenges β = (β₀, ..., β_{d−1}) and d = `multivariate_d`, compute the evaluations of
530 // GateSeparator_β (X₀, ..., X_{d−1}) = ∏ₖ₌₀^{d−1} (1 − Xₖ + Xₖ · βₖ)
531 // on the boolean hypercube.
533
535 size_t round_idx = 0;
536 // In the first round, we compute the first univariate polynomial and populate the book-keeping table of
537 // #partially_evaluated_polynomials, which has \f$ n/2 \f$ rows and \f$ N \f$ columns.
538
539 // Compute the round univariate
540 auto round_univariate =
541 round.compute_univariate(full_polynomials, relation_parameters, gate_separators, alphas);
542
543 // Add the contribution from the Libra univariates
544 auto hiding_univariate = round.compute_libra_univariate(zk_sumcheck_data, round_idx);
545 round_univariate += hiding_univariate;
546
547 // Subtract the contribution from the disabled rows
548 if constexpr (UseRowDisablingPolynomial<Flavor>) {
549 round_univariate -= round.compute_disabled_contribution(
551 }
552
553 // Initialize the partially evaluated polynomials which will be used in the following rounds.
554 // This will use the information in the structured full polynomials to save memory if possible.
556
557 {
558 BB_BENCH_NAME("rest of sumcheck round 1");
559
560 handler.process_round_univariate(round_idx, round_univariate);
561
562 const FF round_challenge = transcript->template get_challenge<FF>("Sumcheck:u_0");
563
564 multivariate_challenge.emplace_back(round_challenge);
565 // Prepare sumcheck book-keeping table for the next round
566 partially_evaluate(full_polynomials, round_challenge);
567 // Prepare ZK Sumcheck data for the next round
568 zk_sumcheck_data.update_zk_sumcheck_data(round_challenge, round_idx);
569 row_disabling_polynomial.update_evaluations(round_challenge, round_idx);
570 gate_separators.partially_evaluate(round_challenge);
571 round.round_size = round.round_size >> 1; // TODO(#224)(Cody): Maybe partially_evaluate should do this and
572 // release memory? // All but final round
573 // We operate on partially_evaluated_polynomials in place.
574 }
575 for (size_t round_idx = 1; round_idx < multivariate_d; round_idx++) {
576 BB_BENCH_NAME("sumcheck loop");
577
578 // Computes the round univariate in two parts: first the contribution necessary to hide the polynomial and
579 // account for having randomness at the end of the trace and then the contribution from the full
580 // relation. Note: we compute the hiding univariate first as the `compute_univariate` method prepares
581 // relevant data structures for the next round
582 round_univariate =
583 round.compute_univariate(partially_evaluated_polynomials, relation_parameters, gate_separators, alphas);
584 hiding_univariate = round.compute_libra_univariate(zk_sumcheck_data, round_idx);
585 // Add the contribution from the Libra univariates
586 round_univariate += hiding_univariate;
587 // Subtract the contribution from the disabled rows
588 if constexpr (UseRowDisablingPolynomial<Flavor>) {
589 round_univariate -= round.compute_disabled_contribution(partially_evaluated_polynomials,
591 gate_separators,
592 alphas,
593 round_idx,
595 }
596
597 handler.process_round_univariate(round_idx, round_univariate);
598
599 const FF round_challenge =
600 transcript->template get_challenge<FF>("Sumcheck:u_" + std::to_string(round_idx));
601 multivariate_challenge.emplace_back(round_challenge);
602 // Prepare sumcheck book-keeping table for the next round.
604 // Prepare evaluation masking and libra structures for the next round (for ZK Flavors)
605 zk_sumcheck_data.update_zk_sumcheck_data(round_challenge, round_idx);
606 row_disabling_polynomial.update_evaluations(round_challenge, round_idx);
607
608 gate_separators.partially_evaluate(round_challenge);
609 round.round_size = round.round_size >> 1;
610 }
611
612 handler.finalize_last_round(multivariate_d, round_univariate, multivariate_challenge[multivariate_d - 1]);
613
614 vinfo("completed ", multivariate_d, " rounds of sumcheck");
615
616 // Zero univariates are used to pad the proof to the fixed size virtual_log_n.
618 for (size_t idx = multivariate_d; idx < virtual_log_n; idx++) {
619 transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(idx), zero_univariate);
620
621 FF round_challenge = transcript->template get_challenge<FF>("Sumcheck:u_" + std::to_string(idx));
622 multivariate_challenge.emplace_back(round_challenge);
623 }
624
625 // Claimed evaluations of Prover polynomials are extracted and added to the transcript. When Flavor has ZK, the
626 // evaluations of all witnesses are masked.
628 transcript->send_to_verifier("Sumcheck:evaluations", multivariate_evaluations.get_all());
629
630 // The evaluations of Libra uninvariates at \f$ g_0(u_0), \ldots, g_{d-1} (u_{d-1}) \f$ are added to the
631 // transcript.
632 FF libra_evaluation = zk_sumcheck_data.constant_term;
633 for (const auto& libra_eval : zk_sumcheck_data.libra_evaluations) {
634 libra_evaluation += libra_eval;
635 }
636 transcript->send_to_verifier("Libra:claimed_evaluation", libra_evaluation);
637
638 // The sum of the Libra constant term and the evaluations of Libra univariates at corresponding sumcheck
639 // challenges is included in the Sumcheck Output
640 return SumcheckOutput<Flavor>{ .challenge = multivariate_challenge,
641 .claimed_evaluations = multivariate_evaluations,
642 .claimed_libra_evaluation = libra_evaluation,
643 .round_univariates = handler.get_univariates(),
644 .round_univariate_evaluations = handler.get_evaluations() };
645 vinfo("finished sumcheck");
646 };
647
682 void partially_evaluate(auto& polynomials, const FF& round_challenge)
683 {
684 auto pep_view = partially_evaluated_polynomials.get_all();
685 auto poly_view = polynomials.get_all();
686 // after the first round, operate in place on partially_evaluated_polynomials
687 parallel_for(poly_view.size(), [&](size_t j) {
688 const auto& poly = poly_view[j];
689 // The polynomial is shorter than the round size.
690 size_t limit = poly.end_index();
691 for (size_t i = 0; i < limit; i += 2) {
692 pep_view[j].at(i >> 1) = poly[i] + round_challenge * (poly[i + 1] - poly[i]);
693 }
694
695 // We resize pep_view[j] to have the exact size required for the next round which is
696 // CEIL(limit/2). This has the effect to reduce the limit in next round and also to
697 // virtually zeroize any leftover values beyond the limit (in-place computation).
698 // This is important to zeroize leftover values to not mess up with compute_univariate().
699 // Note that the virtual size of pep_view[j] remains unchanged.
700 pep_view[j].shrink_end_index((limit / 2) + (limit % 2));
701 });
702 };
707 template <typename PolynomialT, std::size_t N>
708 void partially_evaluate(std::array<PolynomialT, N>& polynomials, const FF& round_challenge)
709 {
710 auto pep_view = partially_evaluated_polynomials.get_all();
711 // after the first round, operate in place on partially_evaluated_polynomials
712 parallel_for(polynomials.size(), [&](size_t j) {
713 const auto& poly = polynomials[j];
714 // The polynomial is shorter than the round size.
715 size_t limit = poly.end_index();
716 for (size_t i = 0; i < limit; i += 2) {
717 pep_view[j].at(i >> 1) = poly[i] + round_challenge * (poly[i + 1] - poly[i]);
718 }
719
720 // We resize pep_view[j] to have the exact size required for the next round which is
721 // CEIL(limit/2). This has the effect to reduce the limit in next round and also to
722 // virtually zeroize any leftover values beyond the limit (in-place computation).
723 // This is important to zeroize leftover values to not mess up with compute_univariate().
724 // Note that the virtual size of pep_view[j] remains unchanged.
725 pep_view[j].shrink_end_index((limit / 2) + (limit % 2));
726 });
727 };
728
741 {
742 ClaimedEvaluations multivariate_evaluations;
743 for (auto [eval, poly] :
744 zip_view(multivariate_evaluations.get_all(), partially_evaluated_polynomials.get_all())) {
745 eval = poly[0];
746 };
747 return multivariate_evaluations;
748 };
749};
786template <typename Flavor> class SumcheckVerifier {
787
788 public:
790 using FF = typename Flavor::FF;
797 // For ZK Flavors: the verifier obtains a vector of evaluations of \f$ d \f$ univariate polynomials and uses them to
798 // compute full_honk_relation_purported_value
799 using ClaimedLibraEvaluations = typename std::vector<FF>;
803
808 static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = Flavor::BATCHED_RELATION_PARTIAL_LENGTH;
813 static constexpr size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES;
814
815 std::shared_ptr<Transcript> transcript;
817
818 // Determines number of rounds in the sumcheck (may include padding rounds)
820
821 // An array of size NUM_SUBRELATIONS-1 containing challenges or consecutive powers of a single challenge that
822 // separate linearly independent subrelation.
824
825 explicit SumcheckVerifier(std::shared_ptr<Transcript> transcript,
826 const FF& alpha,
827 size_t virtual_log_n,
828 FF target_sum = 0)
829 : transcript(std::move(transcript))
830 , round(target_sum)
831 , virtual_log_n(virtual_log_n)
832 , alphas(initialize_relation_separator<FF, Flavor::NUM_SUBRELATIONS - 1>(alpha)) {};
845 const std::vector<FF>& gate_challenges,
846 const std::vector<FF>& padding_indicator_array)
847 {
848 bb::GateSeparatorPolynomial<FF> gate_separators(gate_challenges);
849 // Construct a ZKHandler to handle all the libra related information in the transcript
850 VerifierZKCorrectionHandler<Flavor> zk_correction_handler(transcript);
851
852 // Correct the target sum in the round in the ZK case
853 zk_correction_handler.initialize_target_sum(round);
854
855 std::vector<FF> multivariate_challenge;
856 multivariate_challenge.reserve(virtual_log_n);
857
858 // Process univariate consistancy check rounds
859 // For ECCVM we ensure the consistencies by populating an vector of claimed evaluations that will be checked in
860 // the PCS rounds
861 // For other flavors, we perform the sumcheck univariate consistency check
862
863 bool verified = true;
864 for (size_t round_idx = 0; round_idx < virtual_log_n; round_idx++) {
865 round.process_round(
866 transcript, multivariate_challenge, gate_separators, padding_indicator_array[round_idx], round_idx);
867 verified = verified && !round.round_failed;
868 }
869
870 // Populate claimed evaluations at the challenge
871 ClaimedEvaluations purported_evaluations;
872 auto transcript_evaluations =
873 transcript->template receive_from_prover<std::array<FF, NUM_POLYNOMIALS>>("Sumcheck:evaluations");
874 for (auto [eval, transcript_eval] : zip_view(purported_evaluations.get_all(), transcript_evaluations)) {
875 eval = transcript_eval;
876 }
877
878 // Evaluate the Honk relation at the point (u_0, ..., u_{d-1}) using claimed evaluations of prover polynomials.
879 // In ZK Flavors, the evaluation is corrected by full_libra_purported_value
880 FF full_honk_purported_value = round.compute_full_relation_purported_value(
881 purported_evaluations, relation_parameters, gate_separators, alphas);
882
883 // For ZK Flavors: compute the evaluation of the Row Disabling Polynomial at the sumcheck challenge and of the
884 // libra univariate used to hide the contribution from the actual Honk relation
885 zk_correction_handler.apply_zk_corrections(
886 full_honk_purported_value, multivariate_challenge, padding_indicator_array);
887
889 verified = round.perform_final_verification(full_honk_purported_value) && verified;
890
891 // For ZK Flavors: the evaluations of Libra univariates are included in the Sumcheck Output
892 return SumcheckOutput<Flavor>{ .challenge = multivariate_challenge,
893 .claimed_evaluations = purported_evaluations,
894 .verified = verified,
895 .claimed_libra_evaluation = zk_correction_handler.get_libra_evaluation(),
896 .round_univariate_commitments = round.get_round_univariate_commitments(),
897 .round_univariate_evaluations = round.get_round_univariate_evaluations() };
898 };
899};
900
901template <typename FF, size_t N> std::array<FF, N> initialize_relation_separator(const FF& alpha)
902{
903 std::array<FF, N> alphas;
904 alphas[0] = alpha;
905 for (size_t i = 1; i < N; ++i) {
906 alphas[i] = alphas[i - 1] * alpha;
907 }
908 return alphas;
909}
910} // namespace bb
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:77
bb::field< bb::Bn254FrParams > FF
Definition field.cpp:22
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:219
A field element for each entity of the flavor. These entities represent the prover polynomials evalua...
A container for storing the partially evaluated multivariates produced by sumcheck.
A container for the prover polynomials.
static constexpr bool HasZK
typename Curve::ScalarField FF
static constexpr size_t NUM_SUBRELATIONS
static constexpr size_t NUM_ALL_ENTITIES
static constexpr size_t MAX_PARTIAL_RELATION_LENGTH
typename G1::affine_element Commitment
bb::CommitmentKey< Curve > CommitmentKey
NativeTranscript Transcript
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
The implementation of the sumcheck Prover for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:289
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
Definition sumcheck.hpp:310
typename Flavor::FF FF
Definition sumcheck.hpp:291
ProverPolynomials & full_polynomials
Definition sumcheck.hpp:319
const size_t multivariate_n
Definition sumcheck.hpp:315
bb::RelationParameters< FF > relation_parameters
Definition sumcheck.hpp:330
typename Flavor::Transcript Transcript
Definition sumcheck.hpp:298
std::vector< FF > accumulator_challenge
Definition sumcheck.hpp:338
std::vector< FF > instance_challenge
Definition sumcheck.hpp:339
void partially_evaluate(std::array< PolynomialT, N > &polynomials, const FF &round_challenge)
Evaluate at the round challenge and prepare class for next round. Specialization for array,...
Definition sumcheck.hpp:708
static constexpr bool isMultilinearBatchingFlavor
Definition sumcheck.hpp:302
typename Flavor::ProverPolynomials ProverPolynomials
Definition sumcheck.hpp:294
static constexpr size_t MAX_PARTIAL_RELATION_LENGTH
The total algebraic degree of the Sumcheck relation as a polynomial in Prover Polynomials .
Definition sumcheck.hpp:307
std::array< FF, Flavor::NUM_SUBRELATIONS - 1 > SubrelationSeparators
Definition sumcheck.hpp:299
const size_t multivariate_d
Definition sumcheck.hpp:317
ClaimedEvaluations extract_claimed_evaluations(PartiallyEvaluatedMultivariates &partially_evaluated_polynomials)
This method takes the book-keeping table containing partially evaluated prover polynomials and create...
Definition sumcheck.hpp:740
typename Flavor::AllValues ClaimedEvaluations
Definition sumcheck.hpp:296
typename bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > SumcheckRoundUnivariate
Definition sumcheck.hpp:312
std::vector< FF > multivariate_challenge
Definition sumcheck.hpp:335
SumcheckOutput< Flavor > prove(ZKData &zk_sumcheck_data) void partially_evaluate(auto &polynomials, const FF &round_challenge)
ZK-version of prove that runs Sumcheck with disabled rows and masking of Round Univariates....
Definition sumcheck.hpp:682
typename Flavor::PartiallyEvaluatedMultivariates PartiallyEvaluatedMultivariates
Definition sumcheck.hpp:295
SumcheckProver(size_t multivariate_n, ProverPolynomials &prover_polynomials, std::shared_ptr< Transcript > transcript, const FF &alpha, const std::vector< FF > &gate_challenges, const RelationParameters< FF > &relation_parameters, const size_t virtual_log_n)
Definition sumcheck.hpp:376
RowDisablingPolynomial< FF > row_disabling_polynomial
Definition sumcheck.hpp:342
typename Flavor::CommitmentKey CommitmentKey
Definition sumcheck.hpp:300
SumcheckProver(size_t multivariate_n, ProverPolynomials &prover_polynomials, std::shared_ptr< Transcript > transcript, const FF &relation_separator, const size_t virtual_log_n, const std::vector< FF > &accumulator_challenge, const std::vector< FF > &instance_challenge)
Definition sumcheck.hpp:356
std::vector< FF > gate_challenges
Definition sumcheck.hpp:328
SumcheckProverRound< Flavor > round
Definition sumcheck.hpp:323
PartiallyEvaluatedMultivariates partially_evaluated_polynomials
Container for partially evaluated Prover Polynomials at a current challenge. Upon computing challenge...
Definition sumcheck.hpp:353
std::shared_ptr< Transcript > transcript
Definition sumcheck.hpp:321
SumcheckOutput< Flavor > prove()
Non-ZK version: Compute round univariate, place it in transcript, compute challenge,...
Definition sumcheck.hpp:398
ZKSumcheckData< Flavor > ZKData
Definition sumcheck.hpp:297
SubrelationSeparators alphas
Definition sumcheck.hpp:326
Imlementation of the Sumcheck prover round.
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:786
typename std::vector< FF > ClaimedLibraEvaluations
Definition sumcheck.hpp:799
std::array< FF, Flavor::NUM_SUBRELATIONS - 1 > SubrelationSeparators
Definition sumcheck.hpp:801
typename Flavor::FF FF
Definition sumcheck.hpp:790
typename Flavor::Commitment Commitment
Definition sumcheck.hpp:802
SumcheckVerifierRound< Flavor > round
Definition sumcheck.hpp:816
SumcheckVerifier(std::shared_ptr< Transcript > transcript, const FF &alpha, size_t virtual_log_n, FF target_sum=0)
Definition sumcheck.hpp:825
std::shared_ptr< Transcript > transcript
Definition sumcheck.hpp:815
typename Flavor::AllValues ClaimedEvaluations
Container type for the evaluations of Prover Polynomials at the challenge point .
Definition sumcheck.hpp:796
SubrelationSeparators alphas
Definition sumcheck.hpp:823
typename Flavor::Transcript Transcript
Definition sumcheck.hpp:800
SumcheckOutput< Flavor > verify(const bb::RelationParameters< FF > &relation_parameters, const std::vector< FF > &gate_challenges, const std::vector< FF > &padding_indicator_array)
The Sumcheck verification method. First it extracts round univariate, checks sum (the sumcheck univar...
Definition sumcheck.hpp:844
Implementation of the Sumcheck Verifier Round.
std::vector< Commitment > get_round_univariate_commitments()
Get round univariate commitments (only used for Grumpkin flavors).
void process_round(const std::shared_ptr< Transcript > &transcript, std::vector< FF > &multivariate_challenge, bb::GateSeparatorPolynomial< FF > &gate_separators, const FF &padding_indicator, size_t round_idx)
Process a single sumcheck round: receive univariate from transcript, verify sum, generate challenge.
bool perform_final_verification(const FF &full_honk_purported_value)
Perform final verification: check that the computed target sum matches the full relation evaluation....
std::vector< std::array< FF, 3 > > get_round_univariate_evaluations()
Get round univariate evaluations (only used for Grumpkin flavors).
FF compute_full_relation_purported_value(const ClaimedEvaluations &purported_evaluations, const bb::RelationParameters< FF > &relation_parameters, const bb::GateSeparatorPolynomial< FF > &gate_separators, const SubrelationSeparators &alphas)
Compute the full relation purported value.
A univariate polynomial represented by its values on {0, 1,..., domain_end - 1}.
Fr & value_at(size_t i)
static Univariate zero()
std::array< Fr, LENGTH > evaluations
Fr evaluate(const Fr &u) const
Evaluate a univariate at a point u not known at compile time and assumed not to be in the domain (els...
#define vinfo(...)
Definition log.hpp:80
constexpr T get_msb(const T in)
Definition get_msb.hpp:47
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
CommitmentKey< Curve > ck
std::array< FF, N > initialize_relation_separator(const FF &alpha)
Definition sumcheck.hpp:901
void parallel_for(size_t num_iterations, const std::function< void(size_t)> &func)
Definition thread.cpp:111
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
Implementation of the methods for the -polynomials used in in Sumcheck.
void partially_evaluate(FF challenge)
Partially evaluate the -polynomial at the new challenge and update .
Container for parameters used by the grand product (permutation, lookup) Honk relations.
std::vector< std::array< FF, 3 > > round_evaluations
Definition sumcheck.hpp:63
void process_round_univariate(size_t round_idx, bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &round_univariate)
Definition sumcheck.hpp:77
typename Flavor::CommitmentKey CommitmentKey
Definition sumcheck.hpp:57
std::vector< Polynomial< FF > > round_univariates
Definition sumcheck.hpp:64
void finalize_last_round(size_t multivariate_d, const bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &round_univariate, const FF &last_challenge)
Definition sumcheck.hpp:101
std::vector< Polynomial< FF > > get_univariates()
Definition sumcheck.hpp:109
std::shared_ptr< Transcript > transcript
Definition sumcheck.hpp:60
typename Flavor::Transcript Transcript
Definition sumcheck.hpp:56
std::vector< std::array< FF, 3 > > get_evaluations()
Definition sumcheck.hpp:108
RoundUnivariateHandler(std::shared_ptr< Transcript > transcript)
Definition sumcheck.hpp:66
Handler for processing round univariates in sumcheck. Default implementation: send evaluations direct...
Definition sumcheck.hpp:24
std::vector< Polynomial< FF > > get_univariates()
Definition sumcheck.hpp:48
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
Definition sumcheck.hpp:28
typename Flavor::CommitmentKey CommitmentKey
Definition sumcheck.hpp:27
void process_round_univariate(size_t round_idx, bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &round_univariate)
Definition sumcheck.hpp:36
RoundUnivariateHandler(std::shared_ptr< Transcript > transcript)
Definition sumcheck.hpp:32
std::shared_ptr< Transcript > transcript
Definition sumcheck.hpp:30
std::vector< std::array< FF, 3 > > get_evaluations()
Definition sumcheck.hpp:47
typename Flavor::FF FF
Definition sumcheck.hpp:25
void finalize_last_round(size_t, const bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &, const FF &)
Definition sumcheck.hpp:42
typename Flavor::Transcript Transcript
Definition sumcheck.hpp:26
Polynomial for Sumcheck with disabled Rows.
static FF evaluate_at_challenge(std::vector< FF > multivariate_challenge, const size_t log_circuit_size)
Compute the evaluation of at the sumcheck challenge.
Contains the evaluations of multilinear polynomials at the challenge point . These are computed by S...
std::vector< FF > challenge
static FF eval(std::span< const FF > r_in, std::span< const FF > u)
VerifierZKCorrectionHandler(std::shared_ptr< Transcript > transcript)
Definition sumcheck.hpp:155
void initialize_target_sum(SumcheckRound &round)
Definition sumcheck.hpp:161
std::shared_ptr< Transcript > transcript
Definition sumcheck.hpp:148
void apply_zk_corrections(FF &full_honk_purported_value, std::vector< FF > &multivariate_challenge, const std::vector< FF > &padding_indicator_array)
Definition sumcheck.hpp:163
Handler for ZK-related verification adjustments in sumcheck. Default implementation: no ZK adjustment...
Definition sumcheck.hpp:116
void apply_zk_corrections(FF &, const std::vector< FF > &, const std::vector< FF > &)
Definition sumcheck.hpp:132
typename Flavor::Transcript Transcript
Definition sumcheck.hpp:118
void initialize_target_sum(SumcheckRound &)
Definition sumcheck.hpp:130
std::shared_ptr< Transcript > transcript
Definition sumcheck.hpp:121
VerifierZKCorrectionHandler(std::shared_ptr< Transcript > transcript)
Definition sumcheck.hpp:126
This structure is created to contain various polynomials and constants required by ZK Sumcheck.