38 BB_ASSERT(this->transcript !=
nullptr,
"RoundUnivariateHandler: transcript must not be null");
78 BB_ASSERT(this->transcript !=
nullptr,
"RoundUnivariateHandler: transcript must not be null");
83 eval_domain.push_back(
FF(idx));
95 auto round_commitment =
ck.commit(round_poly_monomial);
96 transcript->send_to_verifier(
"Sumcheck:univariate_comm_" + idx, round_commitment);
97 round_commitments.push_back(round_commitment);
100 round_univariates.push_back(
std::move(round_poly_monomial));
103 transcript->send_to_verifier(
"Sumcheck:univariate_" + idx +
"_eval_0", round_univariate.
value_at(0));
104 transcript->send_to_verifier(
"Sumcheck:univariate_" + idx +
"_eval_1", round_univariate.
value_at(1));
107 round_evaluations.push_back({ round_univariate.
value_at(0), round_univariate.
value_at(1),
FF(0) });
109 round_evaluations[round_idx - 1][2] = round_univariate.
value_at(0) + round_univariate.
value_at(1);
115 const FF& last_challenge)
117 round_evaluations[multivariate_d - 1][2] = round_univariate.
evaluate(last_challenge);
172 libra_total_sum =
transcript->template receive_from_prover<FF>(
"Libra:Sum");
186 const auto challenge_tag = multivariate_challenge.back().get_origin_tag();
377 "SumcheckProver: multivariate_n must be a power of two");
381 "Incorrect number of computed multilinear batching challenges.");
384 "Sumcheck Prover: Multilinear batching flavor has only dependent relations, no gate "
385 "challenges should be provided.");
401 vinfo(
"starting sumcheck rounds...");
413 auto round_univariate =
417 transcript->send_to_verifier(
"Sumcheck:univariate_0", round_univariate);
418 FF round_challenge =
transcript->template get_challenge<FF>(
"Sumcheck:u_0");
424 round.advance_round();
427 for (
size_t round_idx = 1; round_idx <
multivariate_d; round_idx++) {
431 auto round_univariate =
440 round.advance_round();
450 Flavor::extend_eq_polynomials_for_virtual_round(
455 const auto virtual_round_univariate =
round.compute_virtual_contribution(
464 for (
auto& poly : partially_evaluated_polynomials.get_all()) {
466 if (poly.size() > 0) {
467 if (poly.size() == 1) {
468 poly.at(0) *= (
FF(1) - round_challenge);
469 }
else if (poly.size() == 2) {
471 poly.at(0) = poly.at(0) * (
FF(1) - round_challenge) + poly.at(1) * round_challenge;
474 BB_ASSERT_EQ(
true,
false,
"Polynomial size is not 1 or 2");
482 transcript->send_to_verifier(
"Sumcheck:evaluations", multivariate_evaluations.get_all());
484 vinfo(
"finished sumcheck");
486 .claimed_evaluations = multivariate_evaluations };
500 vinfo(
"starting sumcheck rounds...");
507 size_t round_idx = 0;
513 auto round_univariate =
517 auto hiding_univariate =
round.compute_libra_univariate(zk_sumcheck_data, round_idx);
518 round_univariate += hiding_univariate;
522 round_univariate +=
round.compute_offset_area_contribution(
526 handler.process_round_univariate(round_idx, round_univariate);
528 const FF round_challenge =
transcript->template get_challenge<FF>(
"Sumcheck:u_0");
536 zk_sumcheck_data.update_zk_sumcheck_data(round_challenge, round_idx);
538 gate_separators.partially_evaluate(round_challenge);
539 round.advance_round();
540 if constexpr (UseRowDisablingPolynomial<Flavor>) {
541 round.excluded_head_size = 2;
543 for (
size_t round_idx = 1; round_idx <
multivariate_d; round_idx++) {
552 hiding_univariate =
round.compute_libra_univariate(zk_sumcheck_data, round_idx);
554 round_univariate += hiding_univariate;
556 if constexpr (UseRowDisablingPolynomial<Flavor>) {
557 round_univariate +=
round.compute_offset_area_contribution(partially_evaluated_polynomials,
564 handler.process_round_univariate(round_idx, round_univariate);
566 const FF round_challenge =
573 if constexpr (IsTranslatorFlavor<Flavor>) {
574 if (round_idx == Flavor::LOG_MINI_CIRCUIT_SIZE - 1) {
577 transcript->send_to_verifier(
"Sumcheck:minicircuit_evaluations",
578 Flavor::get_minicircuit_evaluations(partially_evaluated_polynomials));
583 zk_sumcheck_data.update_zk_sumcheck_data(round_challenge, round_idx);
586 gate_separators.partially_evaluate(round_challenge);
587 round.advance_round();
602 partially_evaluated_polynomials,
604 virtual_gate_separator,
608 hiding_univariate =
round.compute_libra_univariate(zk_sumcheck_data, idx);
609 round_univariate += hiding_univariate;
611 handler.process_round_univariate(idx, round_univariate);
616 zk_sumcheck_data.update_zk_sumcheck_data(round_challenge, idx);
618 virtual_gate_separator.partially_evaluate(round_challenge);
625 if constexpr (IsTranslatorFlavor<Flavor>) {
626 transcript->send_to_verifier(
"Sumcheck:evaluations",
627 Flavor::get_full_circuit_evaluations(multivariate_evaluations));
629 transcript->send_to_verifier(
"Sumcheck:evaluations", multivariate_evaluations.get_all());
634 for (
const auto& libra_eval : zk_sumcheck_data.libra_evaluations) {
641 vinfo(
"finished sumcheck");
643 .claimed_evaluations = multivariate_evaluations,
645 .round_univariate_commitments = handler.get_commitments(),
646 .round_univariates = handler.get_univariates(),
647 .round_univariate_evaluations = handler.get_evaluations() };
662 const FF& round_challenge)
664 auto source_view = source_polynomials.get_all();
665 auto dest_view = dest_polynomials.get_all();
667 BB_BENCH_TRACY_NAME(
"Sumcheck::partially_evaluate");
668 const auto& poly = source_view[j];
669 auto& dest = dest_view[j];
670 const size_t limit = poly.end_index();
673 const size_t num_outputs = (limit / 2) + (limit % 2);
674 fold_stride2(poly, dest, 0, num_outputs, round_challenge);
675 dest.shrink_end_index(num_outputs);
679 if constexpr (
requires {
680 source_polynomials.row_skip_active_prefix_end;
681 dest_polynomials.row_skip_active_prefix_end;
683 dest_polynomials.row_skip_active_prefix_end = (source_polynomials.row_skip_active_prefix_end / 2) +
684 (source_polynomials.row_skip_active_prefix_end % 2);
695 const FF& round_challenge)
699 return partially_evaluated_polynomials;
724 for (
auto [eval, poly] :
725 zip_view(multivariate_evaluations.get_all(), partially_evaluated_polynomials.get_all())) {
728 return multivariate_evaluations;
737 template <
typename PartialEvals,
typename Alphas>
740 PartialEvals& partially_evaluated_polynomials,
749 return round.compute_virtual_contribution(
758 for (
auto& poly : pe.get_all()) {
759 if (poly.end_index() > 0) {
760 poly.at(0) *= (
FF(1) - round_challenge);
860 const std::vector<FF>& gate_challenges)
865 "Incorrect number of computed multilinear batching challenges.");
875 std::vector<FF> multivariate_challenge;
883 bool verified =
true;
889 for (
size_t round_idx = 0; round_idx <
virtual_log_n; round_idx++) {
890 round.process_round(
transcript, multivariate_challenge, gate_separators, round_idx);
891 verified = verified && !
round.round_failed;
894 if (round_idx == Flavor::LOG_MINI_CIRCUIT_SIZE - 1) {
897 Flavor::set_minicircuit_evaluations(
898 purported_evaluations,
900 "Sumcheck:minicircuit_evaluations"));
910 transcript->template receive_from_prover<std::array<FF, Flavor::NUM_FULL_CIRCUIT_EVALUATIONS>>(
911 "Sumcheck:evaluations"));
912 Flavor::complete_full_circuit_evaluations(
913 purported_evaluations, *get_full_circuit_evaluations,
std::span<const FF>(multivariate_challenge));
917 transcript->template receive_from_prover<std::array<FF, NUM_POLYNOMIALS>>(
"Sumcheck:evaluations"));
918 for (
auto [eval, transcript_eval] :
zip_view(purported_evaluations.get_all(), *transcript_evaluations)) {
919 eval = transcript_eval;
926 const auto challenge_tag = multivariate_challenge.back().get_origin_tag();
927 for (
auto& eval : purported_evaluations.get_all()) {
928 eval.set_origin_tag(challenge_tag);
934 FF full_honk_purported_value =
round.compute_full_relation_purported_value(
935 purported_evaluations, relation_parameters, gate_separators,
alphas, multivariate_challenge);
941 bool final_check =
round.perform_final_verification(full_honk_purported_value);
942 verified = final_check && verified;
946 .claimed_evaluations =
std::move(purported_evaluations),
947 .verified = verified,
949 .round_univariate_commitments =
round.get_round_univariate_commitments(),
950 .round_univariate_evaluations =
round.get_round_univariate_evaluations() };
958 for (
size_t i = 1; i <
N; ++i) {
959 alphas[i] = alphas[i - 1] * alpha;
#define BB_ASSERT(expression,...)
#define BB_ASSERT_GTE(left, right,...)
#define BB_ASSERT_EQ(actual, expected,...)
#define BB_BENCH_NAME(name)
A field element for each entity of the flavor. These entities represent the prover polynomials evalua...
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
PartiallyEvaluatedMultivariatesBase< AllEntities< Polynomial >, ProverPolynomials, Polynomial > PartiallyEvaluatedMultivariates
A container for storing the partially evaluated multivariates produced by sumcheck.
bb::CommitmentKey< Curve > CommitmentKey
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
BaseTranscript< Codec, HashFunction > Transcript
The implementation of the sumcheck Prover for statements of the form for multilinear polynomials .
SumcheckOutput< Flavor > static prove(ZKData &zk_sumcheck_data) void partially_evaluate(auto &source_polynomials, PartiallyEvaluatedMultivariates &dest_polynomials, const FF &round_challenge)
ZK-version of prove that runs Sumcheck with disabled rows and masking of Round Univariates....
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
ProverPolynomials & full_polynomials
const size_t multivariate_n
bb::RelationParameters< FF > relation_parameters
typename Flavor::Transcript Transcript
SumcheckOutput< Flavor > prove()
Non-ZK version: Compute round univariate, place it in transcript, compute challenge,...
PartiallyEvaluatedMultivariates partially_evaluate_first_round(ProverPolynomials &full_polynomials, const FF &round_challenge)
Initialize partially evaluated polynomials and perform first round of partial evaluation.
static constexpr bool isMultilinearBatchingFlavor
typename Flavor::ProverPolynomials ProverPolynomials
static constexpr size_t MAX_PARTIAL_RELATION_LENGTH
The total algebraic degree of the Sumcheck relation as a polynomial in Prover Polynomials .
std::array< FF, Flavor::NUM_SUBRELATIONS - 1 > SubrelationSeparators
const size_t multivariate_d
static void partially_evaluate_in_place(PartiallyEvaluatedMultivariates &polynomials, const FF &round_challenge)
Evaluate at the round challenge in-place.
ClaimedEvaluations extract_claimed_evaluations(PartiallyEvaluatedMultivariates &partially_evaluated_polynomials)
This method takes the book-keeping table containing partially evaluated prover polynomials and create...
typename Flavor::AllValues ClaimedEvaluations
typename bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > SumcheckRoundUnivariate
static void fold_for_zero_extension(PartiallyEvaluatedMultivariates &pe, const FF &round_challenge)
Fold partially-evaluated polynomials for zero-extension: PE[0] *= (1 - u_k).
std::vector< FF > multivariate_challenge
static bb::Univariate< FF, Flavor::BATCHED_RELATION_PARTIAL_LENGTH > compute_virtual_round_univariate(SumcheckProverRound< Flavor > &round, PartialEvals &partially_evaluated_polynomials, const RelationParameters< FF > &relation_parameters, GateSeparatorPolynomial< FF > &gate_separator, const Alphas &alphas, RowDisablingPolynomial< FF > &row_disabling_polynomial)
Compute the virtual round univariate with the row-disabling polynomial factor applied.
typename Flavor::PartiallyEvaluatedMultivariates PartiallyEvaluatedMultivariates
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)
RowDisablingPolynomial< FF > row_disabling_polynomial
typename Flavor::CommitmentKey CommitmentKey
std::vector< FF > gate_challenges
SumcheckProverRound< Flavor > round
std::shared_ptr< Transcript > transcript
ZKSumcheckData< Flavor > ZKData
SubrelationSeparators alphas
Imlementation of the Sumcheck prover round.
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
typename std::vector< FF > ClaimedLibraEvaluations
std::array< FF, Flavor::NUM_SUBRELATIONS - 1 > SubrelationSeparators
typename Flavor::Commitment Commitment
SumcheckOutput< Flavor > verify(const bb::RelationParameters< FF > &relation_parameters, const std::vector< FF > &gate_challenges)
The Sumcheck verification method. First it extracts round univariate, checks sum (the sumcheck univar...
static constexpr bool isMultilinearBatchingFlavor
SumcheckVerifierRound< Flavor > round
SumcheckVerifier(std::shared_ptr< Transcript > transcript, const FF &alpha, size_t virtual_log_n, FF target_sum=0)
static constexpr size_t NUM_POLYNOMIALS
The number of Prover Polynomials specified by the Flavor.
std::shared_ptr< Transcript > transcript
typename Flavor::AllValues ClaimedEvaluations
Container type for the evaluations of Prover Polynomials at the challenge point .
SubrelationSeparators alphas
typename Flavor::Transcript Transcript
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
Maximum partial algebraic degree of the relation , i.e. MAX_PARTIAL_RELATION_LENGTH + 1.
Implementation of the Sumcheck Verifier Round.
A univariate polynomial represented by its values on {0, 1,..., domain_end - 1}.
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...
constexpr T get_msb(const T in)
Entry point for Barretenberg command-line interface.
CommitmentKey< Curve > ck
std::array< FF, N > initialize_relation_separator(const FF &alpha)
void parallel_for(size_t num_iterations, const std::function< void(size_t)> &func)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
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.
size_t num_multilinear_batching_challenges
std::vector< FF > eval_domain
std::vector< std::array< FF, 3 > > round_evaluations
void process_round_univariate(size_t round_idx, bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &round_univariate)
typename Flavor::CommitmentKey CommitmentKey
std::vector< Polynomial< FF > > round_univariates
typename Flavor::Commitment Commitment
std::vector< Commitment > round_commitments
void finalize_last_round(size_t multivariate_d, const bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &round_univariate, const FF &last_challenge)
std::vector< Polynomial< FF > > get_univariates()
std::shared_ptr< Transcript > transcript
typename Flavor::Transcript Transcript
std::vector< Commitment > get_commitments()
std::vector< std::array< FF, 3 > > get_evaluations()
RoundUnivariateHandler(std::shared_ptr< Transcript > transcript)
Handler for processing round univariates in sumcheck. Default implementation: send evaluations direct...
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
typename Flavor::Transcript Transcript
void finalize_last_round(size_t, const bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &, const FF &)
void process_round_univariate(size_t round_idx, bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &round_univariate)
std::shared_ptr< Transcript > transcript
typename Flavor::CommitmentKey CommitmentKey
std::vector< Polynomial< FF > > get_univariates()
RoundUnivariateHandler(std::shared_ptr< Transcript > transcript)
std::vector< typename Flavor::Commitment > get_commitments()
std::vector< std::array< FF, 3 > > get_evaluations()
Polynomial for Sumcheck with disabled Rows.
Contains the evaluations of multilinear polynomials at the challenge point . These are computed by S...
std::vector< FF > challenge
void apply_zk_corrections(FF &full_honk_purported_value, std::vector< FF > &multivariate_challenge)
VerifierZKCorrectionHandler(std::shared_ptr< Transcript > transcript)
FF get_libra_evaluation() const
void initialize_target_sum(SumcheckRound &round)
typename Flavor::Transcript Transcript
std::shared_ptr< Transcript > transcript
Handler for ZK-related verification adjustments in sumcheck. Default implementation: no ZK adjustment...
void apply_zk_corrections(FF &, const std::vector< FF > &)
typename Flavor::Transcript Transcript
void initialize_target_sum(SumcheckRound &)
FF get_libra_evaluation() const
std::shared_ptr< Transcript > transcript
VerifierZKCorrectionHandler(std::shared_ptr< Transcript > transcript)
This structure is created to contain various polynomials and constants required by ZK Sumcheck.