21template <
typename Flavor>
53 typename Flavor::template ProverUnivariates<2>,
102 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
112 size_t max_end_index = 0;
115 if constexpr (
requires { multivariates.get_witness(); }) {
116 for (
auto& witness_poly : multivariates.get_witness()) {
117 max_end_index =
std::max(max_end_index, witness_poly.end_index());
125 return std::min(
round_size, max_end_index + (max_end_index % 2));
157 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
159 const ProverPolynomialsOrPartiallyEvaluatedMultivariates& multivariates,
160 const size_t edge_idx)
162 for (
auto [extended_edge, multivariate] :
zip_view(extended_edges.get_all(), multivariates.get_all())) {
166 if (multivariate.end_index() < edge_idx) {
168 extended_edge = zero_univariate;
171 .
template extend_to<MAX_PARTIAL_RELATION_LENGTH>();
181 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
202 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
213 BB_ASSERT(effective_round_size % 2 == 0,
"effective_round_size must be even");
218 size_t min_iterations_per_thread = 1 << 6;
235 constexpr size_t rows_per_thread = 2;
236 static_assert((rows_per_thread >= 2) && (rows_per_thread % 2 == 0),
237 "rows_per_thread must be at least 2 and even, because edges are processed in pairs");
238 size_t chunk_size = rows_per_thread * num_threads;
239 size_t num_chunks = (effective_round_size / chunk_size) +
240 (effective_round_size % chunk_size > 0 ? 1 : 0);
250 for (
size_t chunk_idx = 0; chunk_idx < num_chunks; chunk_idx++) {
251 size_t start = (chunk_idx * chunk_size) + (thread_idx * rows_per_thread);
252 size_t end = std::min(start + rows_per_thread, effective_round_size);
253 for (
size_t edge_idx = start; edge_idx < end; edge_idx += 2) {
254 lazy_extended_edges.set_current_edge(edge_idx);
263 gate_separators[edge_idx]);
269 for (
auto& accumulators : thread_univariate_accumulators) {
297 for (
size_t i = 0; i <
blocks->size(); ++i) {
299 if (count + (block.
size / 2) > starting_index) {
304 count += (block.
size / 2);
335 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
337 ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials)
345 if constexpr (can_skip_rows) {
347 const size_t num_edge_pairs = effective_round_size / 2;
355 auto range = chunk.
range(num_edge_pairs);
362 size_t current_block_start = 0;
363 size_t current_block_size = 0;
365 for (
size_t pair_idx : range) {
366 size_t edge_idx = pair_idx * 2;
369 if (current_block_size == 0) {
370 current_block_start = edge_idx;
372 current_block_size += 2;
375 if (current_block_size > 0) {
377 .size = current_block_size });
378 current_block_size = 0;
383 if (current_block_size > 0) {
385 .size = current_block_size });
391 for (
const auto& thread_blocks : all_thread_blocks) {
392 for (
const auto block : thread_blocks) {
393 result.push_back(block);
423 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
425 ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials,
444 size_t block_iterations = block.size / 2;
447 auto iteration_range = chunk.
range(block_iterations);
449 for (
size_t i : iteration_range) {
450 size_t edge_idx = block.starting_edge_idx + (i * 2);
464 scaling_factor = gate_separators[edge_idx];
475 for (
auto& accumulators : thread_univariate_accumulators) {
480 const auto round_univariate =
484 return round_univariate;
493 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
495 ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials,
499 const size_t round_idx,
512 for (
size_t edge_idx = start_edge_idx; edge_idx <
round_size; edge_idx += 2) {
515 univariate_accumulator, extended_edges, relation_parameters, gate_separators[edge_idx]);
517 result = batch_over_relations<SumcheckRoundUnivariate>(univariate_accumulator, alphas, gate_separators);
521 row_disabling_factor.template extend_to<SumcheckRoundUnivariate::LENGTH>();
522 result *= row_disabling_factor_extended;
527 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
529 ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials,
541 const size_t virtual_contribution_edge_idx = 0;
545 auto extended_edges = [&]() {
548 lazy_extended_edges.set_current_edge(virtual_contribution_edge_idx);
549 return lazy_extended_edges;
552 extend_edges(extended_edges, polynomials, virtual_contribution_edge_idx);
553 return extended_edges;
558 const FF gate_separator_tail{ 1 };
560 univariate_accumulator, extended_edges, relation_parameters, gate_separator_tail);
562 return batch_over_relations<SumcheckRoundUnivariate>(univariate_accumulator, alphas, gate_separator);
580 template <
typename ExtendedUnivariate,
typename ContainerOverSubrelations>
587 auto result = ExtendedUnivariate(0);
608 template <
typename ExtendedUnivariate,
typename TupleOfTuplesOfUnivariates>
610 ExtendedUnivariate& result,
615 ExtendedUnivariate extended_random_polynomial =
616 random_polynomial.template extend_to<ExtendedUnivariate::LENGTH>();
618 constexpr_for<0, std::tuple_size_v<TupleOfTuplesOfUnivariates>, 1>([&]<
size_t relation_idx>() {
621 [&]<
size_t subrelation_idx>() {
623 auto extended = element.template extend_to<ExtendedUnivariate::LENGTH>();
626 constexpr bool is_subrelation_linearly_independent =
627 bb::subrelation_is_linearly_independent<Relation, subrelation_idx>();
632 if constexpr (!is_subrelation_linearly_independent) {
664 libra_round_univariate.
value_at(idx) =
668 return libra_round_univariate;
670 return libra_round_univariate.template extend_to<SumcheckRoundUnivariate::LENGTH>();
676 const auto& extended_edges,
678 const FF& scaling_factor)
712 const auto& extended_edges,
714 const FF& scaling_factor)
716 constexpr_for<0, NUM_RELATIONS, 1>([&]<
size_t relation_idx>() {
727 if (!Relation::skip(extended_edges)) {
787 eval.set_origin_tag(bound_tag);
793 bool sumcheck_round_failed(
false);
795 if (indicator.get_value() ==
FF{ 1 }.get_value()) {
796 sumcheck_round_failed = (
target_total_sum.get_value() != total_sum.get_value());
823 Utils::template accumulate_relation_evaluations_without_skipping<>(purported_evaluations,
837 std::vector<FF>& multivariate_challenge,
839 const FF& padding_indicator,
843 std::string round_univariate_label =
"Sumcheck:univariate_" +
std::to_string(round_idx);
844 auto round_univariate =
845 transcript->template receive_from_prover<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(
846 round_univariate_label);
847 FF round_challenge = transcript->template get_challenge<FF>(
"Sumcheck:u_" +
std::to_string(round_idx));
848 multivariate_challenge.emplace_back(round_challenge);
851 check_sum(round_univariate, padding_indicator);
863 bool verified =
false;
865 verified = (full_honk_purported_value.get_value() ==
target_total_sum.get_value());
927 Utils::template accumulate_relation_evaluations_without_skipping<>(purported_evaluations,
939 std::vector<FF>& multivariate_challenge,
945 const std::string round_univariate_comm_label =
"Sumcheck:univariate_comm_" +
std::to_string(round_idx);
946 const std::string univariate_eval_label_0 =
"Sumcheck:univariate_" +
std::to_string(round_idx) +
"_eval_0";
947 const std::string univariate_eval_label_1 =
"Sumcheck:univariate_" +
std::to_string(round_idx) +
"_eval_1";
950 round_univariate_commitments.push_back(
951 transcript->template receive_from_prover<Commitment>(round_univariate_comm_label));
953 round_univariate_evaluations.push_back(
954 { transcript->template receive_from_prover<FF>(univariate_eval_label_0),
955 transcript->template receive_from_prover<FF>(univariate_eval_label_1),
958 const FF round_challenge = transcript->template get_challenge<FF>(
"Sumcheck:u_" +
std::to_string(round_idx));
959 multivariate_challenge.emplace_back(round_challenge);
974 FF first_sumcheck_round_evaluations_sum =
975 round_univariate_evaluations[0][0] + round_univariate_evaluations[0][1];
977 bool verified =
false;
979 first_sumcheck_round_evaluations_sum.self_reduce();
982 verified = (first_sumcheck_round_evaluations_sum.get_value() ==
target_total_sum.get_value());
987 full_honk_purported_value.self_reduce();
996 for (
size_t round_idx = 1; round_idx < round_univariate_evaluations.size(); round_idx++) {
997 round_univariate_evaluations[round_idx - 1][2] =
998 round_univariate_evaluations[round_idx][0] + round_univariate_evaluations[round_idx][1];
1002 round_univariate_evaluations[round_univariate_evaluations.size() - 1][2] = full_honk_purported_value;
#define BB_ASSERT(expression,...)
#define BB_BENCH_NAME(name)
A base class labelling all entities (for instance, all of the polynomials used by the prover during s...
A field element for each entity of the flavor. These entities represent the prover polynomials evalua...
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
static bool skip_entire_row(const ProverPolynomialsOrPartiallyEvaluatedMultivariates &polynomials, const EdgeType edge_idx)
When evaluating the sumcheck protocol - can we skip evaluation of all relations for a given row?...
static constexpr bool USE_SHORT_MONOMIALS
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
static constexpr size_t NUM_RELATIONS
BaseTranscript< Codec, HashFunction > Transcript
Relations_< FF > Relations
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
static void scale_univariates(auto &tuple, const SubrelationSeparators &subrelation_separators)
Scale Univariates, each representing a subrelation, by different challenges.
static void zero_elements(auto &tuple)
Set each element in a tuple of arrays to zero.
static void zero_univariates(auto &tuple)
Set all coefficients of Univariates to zero.
static constexpr void add_nested_tuples(Tuple &tuple_1, const Tuple &tuple_2)
Componentwise addition of nested tuples (tuples of tuples)
static FF scale_and_batch_elements(auto &tuple, const SubrelationSeparators &subrelation_separators)
Scale elements, representing evaluations of subrelations, by separate challenges then sum them.
Imlementation of the Sumcheck prover round.
decltype(create_sumcheck_tuple_of_tuples_of_univariates< Relations >()) SumcheckTupleOfTuplesOfUnivariates
static constexpr size_t LIBRA_UNIVARIATES_LENGTH
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
The total algebraic degree of the Sumcheck relation as a polynomial in Prover Polynomials incremen...
std::conditional_t< Flavor::USE_SHORT_MONOMIALS, typename Flavor::template ProverUnivariates< 2 >, typename Flavor::ExtendedEdges > ExtendedEdges
static constexpr size_t MAX_PARTIAL_RELATION_LENGTH
The total algebraic degree of the Sumcheck relation as a polynomial in Prover Polynomials .
static void extend_and_batch_univariates(const TupleOfTuplesOfUnivariates &tuple, ExtendedUnivariate &result, const bb::GateSeparatorPolynomial< FF > &gate_separators)
Extend Univariates then sum them multiplying by the current -contributions.
static ExtendedUnivariate batch_over_relations(ContainerOverSubrelations &univariate_accumulators, const SubrelationSeparators &challenge, const bb::GateSeparatorPolynomial< FF > &gate_separators)
Given a tuple of tuples of extended per-relation contributions, and a challenge ,...
SumcheckRoundUnivariate compute_virtual_contribution(ProverPolynomialsOrPartiallyEvaluatedMultivariates &polynomials, const bb::RelationParameters< FF > &relation_parameters, const GateSeparatorPolynomial< FF > &gate_separator, const SubrelationSeparators &alphas)
size_t compute_effective_round_size(const ProverPolynomialsOrPartiallyEvaluatedMultivariates &multivariates) const
Compute the effective round size when !HasZK by finding the maximum end_index() across witness polyno...
SumcheckRoundUnivariate compute_univariate_with_row_skipping(ProverPolynomialsOrPartiallyEvaluatedMultivariates &polynomials, const bb::RelationParameters< FF > &relation_parameters, const bb::GateSeparatorPolynomial< FF > &gate_separators, const SubrelationSeparators alphas)
Return the evaluations of the univariate round polynomials at . Most likely, is around ....
SumcheckProverRound(size_t initial_round_size)
SumcheckRoundUnivariate compute_disabled_contribution(ProverPolynomialsOrPartiallyEvaluatedMultivariates &polynomials, const bb::RelationParameters< FF > &relation_parameters, const bb::GateSeparatorPolynomial< FF > &gate_separators, const SubrelationSeparators &alphas, const size_t round_idx, const RowDisablingPolynomial< FF > row_disabling_polynomial)
For ZK Flavors: A method disabling the last 4 rows of the ProverPolynomials.
SumcheckRoundUnivariate compute_univariate_avm(ProverPolynomialsOrPartiallyEvaluatedMultivariates &polynomials, const bb::RelationParameters< FF > &relation_parameters, const bb::GateSeparatorPolynomial< FF > &gate_separators, const SubrelationSeparators &alphas)
A version of compute_univariate that is better optimized for the AVM.
SumcheckTupleOfTuplesOfUnivariates univariate_accumulators
SumcheckRoundUnivariate compute_univariate(ProverPolynomialsOrPartiallyEvaluatedMultivariates &polynomials, const bb::RelationParameters< FF > &relation_parameters, const bb::GateSeparatorPolynomial< FF > &gate_separators, const SubrelationSeparators &alphas)
Return the evaluations of the univariate round polynomials. Toggles between chunked computation (desi...
void extend_edges(ExtendedEdges &extended_edges, const ProverPolynomialsOrPartiallyEvaluatedMultivariates &multivariates, const size_t edge_idx)
To compute the round univariate in Round , the prover first computes the values of Honk polynomials ...
std::array< FF, Flavor::NUM_SUBRELATIONS - 1 > SubrelationSeparators
void accumulate_relation_univariates(SumcheckTupleOfTuplesOfUnivariates &univariate_accumulators, const auto &extended_edges, const bb::RelationParameters< FF > &relation_parameters, const FF &scaling_factor)
In Round , for a given point , calculate the contribution of each sub-relation to .
static SumcheckRoundUnivariate compute_libra_univariate(const ZKData &zk_sumcheck_data, size_t round_idx)
Compute Libra round univariate expressed given by the formula.
static constexpr size_t NUM_RELATIONS
Number of batched sub-relations in specified by Flavor.
std::vector< BlockOfContiguousRows > compute_contiguous_round_size(ProverPolynomialsOrPartiallyEvaluatedMultivariates &polynomials)
Compute the number of unskippable rows we must iterate over.
typename Flavor::Relations Relations
size_t round_size
In Round , equals .
void accumulate_relation_univariates_public(SumcheckTupleOfTuplesOfUnivariates &univariate_accumulators, const auto &extended_edges, const bb::RelationParameters< FF > &relation_parameters, const FF &scaling_factor)
TupleOfArraysOfValues relation_evaluations
std::vector< std::array< FF, 3 > > round_univariate_evaluations
typename Flavor::Commitment Commitment
typename std::vector< FF > ClaimedLibraEvaluations
std::vector< Commitment > round_univariate_commitments
typename Flavor::Relations Relations
void process_round(const std::shared_ptr< Transcript > &transcript, std::vector< FF > &multivariate_challenge, bb::GateSeparatorPolynomial< FF > &gate_separators, const FF &, size_t round_idx)
Process a single sumcheck round for Grumpkin: receive commitment and evaluations, defer per-round ver...
decltype(create_tuple_of_arrays_of_values< typename Flavor::Relations >()) TupleOfArraysOfValues
bool perform_final_verification(const FF &full_honk_purported_value)
Perform final verification for Grumpkin: check first round sum, populate Shplemini data,...
std::array< FF, Flavor::NUM_SUBRELATIONS - 1 > SubrelationSeparators
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.
std::vector< std::array< FF, 3 > > get_round_univariate_evaluations()
Get round univariate evaluations for Shplemini.
std::vector< Commitment > get_round_univariate_commitments()
Get round univariate commitments for Shplemini.
typename Flavor::Transcript Transcript
SumcheckVerifierRound(FF target_total_sum=0)
typename Flavor::AllValues ClaimedEvaluations
Implementation of the Sumcheck Verifier Round.
std::vector< Commitment > get_round_univariate_commitments()
Get round univariate commitments (only used for Grumpkin flavors).
typename Flavor::Relations Relations
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.
SumcheckVerifierRound(FF target_total_sum=0)
bool perform_final_verification(const FF &full_honk_purported_value)
Perform final verification: check that the computed target sum matches the full relation evaluation....
decltype(create_tuple_of_arrays_of_values< typename Flavor::Relations >()) TupleOfArraysOfValues
void check_sum(bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &univariate, const FF &indicator)
Check that the round target sum is correct.
void compute_next_target_sum(bb::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &univariate, FF &round_challenge, const FF &indicator)
Compute the next target sum.
std::array< FF, Flavor::NUM_SUBRELATIONS - 1 > SubrelationSeparators
std::vector< std::array< FF, 3 > > get_round_univariate_evaluations()
Get round univariate evaluations (only used for Grumpkin flavors).
typename Flavor::Transcript Transcript
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.
typename std::vector< FF > ClaimedLibraEvaluations
typename Flavor::AllValues ClaimedEvaluations
typename Flavor::Commitment Commitment
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
TupleOfArraysOfValues relation_evaluations
static constexpr size_t NUM_RELATIONS
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...
Check if the flavor has a static skip method to determine if accumulation of all relations can be ski...
The templates defined herein facilitate sharing the relation arithmetic between the prover and the ve...
Base class templates shared across Honk flavors.
constexpr size_t FF_COPY_COST
Entry point for Barretenberg command-line interface.
constexpr void constexpr_for(F &&f)
Implements a loop using a compile-time iterator. Requires c++20. Implementation (and description) fro...
size_t calculate_num_threads(size_t num_iterations, size_t min_iterations_per_thread)
calculates number of threads to create based on minimum iterations per thread
void parallel_for_heuristic(size_t num_points, const std::function< void(size_t, size_t, size_t)> &func, size_t heuristic_cost)
Split a loop into several loops running in parallel based on operations in 1 iteration.
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)
Implementation of the methods for the -polynomials used in in Sumcheck.
FF current_element() const
Computes the component at index current_element_idx in betas.
void partially_evaluate(FF challenge)
Partially evaluate the -polynomial at the new challenge and update .
FF partial_evaluation_result
The value obtained by partially evaluating one variable in the power polynomial at each round....
Container for parameters used by the grand product (permutation, lookup) Honk relations.
Polynomial for Sumcheck with disabled Rows.
Helper struct that describes a block of non-zero unskippable rows.
Helper struct that will, given a vector of BlockOfContiguousRows, return the edge indices that corres...
RowIterator(const std::vector< BlockOfContiguousRows > &_blocks, size_t starting_index=0)
size_t current_block_index
size_t current_block_count
const std::vector< BlockOfContiguousRows > * blocks
auto range(size_t size, size_t offset=0) const
This structure is created to contain various polynomials and constants required by ZK Sumcheck.
std::vector< Polynomial< FF > > libra_univariates