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>
214 size_t min_iterations_per_thread = 1 << 6;
253 size_t num_of_chunks = 1;
254 size_t chunk_thread_portion_size =
round_size / num_threads;
257 static_assert(Flavor::MAX_CHUNK_THREAD_PORTION_SIZE >= 2);
258 static_assert((Flavor::MAX_CHUNK_THREAD_PORTION_SIZE & (Flavor::MAX_CHUNK_THREAD_PORTION_SIZE - 1)) == 0);
263 chunk_thread_portion_size = std::min(
round_size / num_threads, Flavor::MAX_CHUNK_THREAD_PORTION_SIZE);
264 num_of_chunks =
round_size / (chunk_thread_portion_size * num_threads);
273 size_t chunk_size =
round_size / num_of_chunks;
283 for (
size_t chunk_idx = 0; chunk_idx < num_of_chunks; chunk_idx++) {
284 size_t start = (chunk_idx * chunk_size) + (thread_idx * chunk_thread_portion_size);
285 size_t end = (chunk_idx * chunk_size) + ((thread_idx + 1) * chunk_thread_portion_size);
286 for (
size_t edge_idx = start; edge_idx < end; edge_idx += 2) {
287 lazy_extended_edges.set_current_edge(edge_idx);
296 gate_separators[edge_idx]);
302 for (
auto& accumulators : thread_univariate_accumulators) {
330 for (
size_t i = 0; i <
blocks->size(); ++i) {
332 if (count + (block.
size / 2) > starting_index) {
337 count += (block.
size / 2);
368 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
370 ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials)
375 const size_t min_iterations_per_thread = 1 << 10;
381 if constexpr (can_skip_rows) {
385 auto range = chunk.range(effective_round_size);
389 size_t current_block_size = 0;
390 size_t start = *range.begin();
391 size_t end = start + range.size();
393 for (
size_t edge_idx = start; edge_idx < end; edge_idx += 2) {
395 current_block_size += 2;
397 if (current_block_size > 0) {
399 .
starting_edge_idx = edge_idx - current_block_size, .size = current_block_size });
400 current_block_size = 0;
404 if (current_block_size > 0) {
406 .size = current_block_size });
408 all_thread_blocks[thread_idx] = thread_blocks;
411 for (
const auto& thread_blocks : all_thread_blocks) {
412 for (
const auto block : thread_blocks) {
413 result.push_back(block);
443 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
445 ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials,
464 size_t block_iterations = block.size / 2;
467 auto iteration_range = chunk.
range(block_iterations);
469 for (
size_t i : iteration_range) {
470 size_t edge_idx = block.starting_edge_idx + (i * 2);
484 scaling_factor = gate_separators[edge_idx];
495 for (
auto& accumulators : thread_univariate_accumulators) {
500 const auto round_univariate =
504 return round_univariate;
513 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
515 ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials,
519 const size_t round_idx,
532 for (
size_t edge_idx = start_edge_idx; edge_idx <
round_size; edge_idx += 2) {
535 univariate_accumulator, extended_edges, relation_parameters, gate_separators[edge_idx]);
537 result = batch_over_relations<SumcheckRoundUnivariate>(univariate_accumulator, alphas, gate_separators);
541 row_disabling_factor.template extend_to<SumcheckRoundUnivariate::LENGTH>();
542 result *= row_disabling_factor_extended;
547 template <
typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
549 ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials,
561 const size_t virtual_contribution_edge_idx = 0;
565 auto extended_edges = [&]() {
568 lazy_extended_edges.set_current_edge(virtual_contribution_edge_idx);
569 return lazy_extended_edges;
572 extend_edges(extended_edges, polynomials, virtual_contribution_edge_idx);
573 return extended_edges;
578 const FF gate_separator_tail{ 1 };
580 univariate_accumulator, extended_edges, relation_parameters, gate_separator_tail);
582 return batch_over_relations<SumcheckRoundUnivariate>(univariate_accumulator, alphas, gate_separator);
600 template <
typename ExtendedUnivariate,
typename ContainerOverSubrelations>
607 auto result = ExtendedUnivariate(0);
628 template <
typename ExtendedUnivariate,
typename TupleOfTuplesOfUnivariates>
630 ExtendedUnivariate& result,
635 ExtendedUnivariate extended_random_polynomial =
636 random_polynomial.template extend_to<ExtendedUnivariate::LENGTH>();
638 constexpr_for<0, std::tuple_size_v<TupleOfTuplesOfUnivariates>, 1>([&]<
size_t relation_idx>() {
641 [&]<
size_t subrelation_idx>() {
643 auto extended = element.template extend_to<ExtendedUnivariate::LENGTH>();
646 constexpr bool is_subrelation_linearly_independent =
647 bb::subrelation_is_linearly_independent<Relation, subrelation_idx>();
652 if constexpr (!is_subrelation_linearly_independent) {
684 libra_round_univariate.
value_at(idx) =
688 return libra_round_univariate;
690 return libra_round_univariate.template extend_to<SumcheckRoundUnivariate::LENGTH>();
696 const auto& extended_edges,
698 const FF& scaling_factor)
732 const auto& extended_edges,
734 const FF& scaling_factor)
736 constexpr_for<0, NUM_RELATIONS, 1>([&]<
size_t relation_idx>() {
747 if (!Relation::skip(extended_edges)) {
804 bool sumcheck_round_failed(
false);
806 if (indicator.get_value() ==
FF{ 1 }.get_value()) {
807 sumcheck_round_failed = (
target_total_sum.get_value() != total_sum.get_value());
834 Utils::template accumulate_relation_evaluations_without_skipping<>(purported_evaluations,
848 std::vector<FF>& multivariate_challenge,
850 const FF& padding_indicator,
854 std::string round_univariate_label =
"Sumcheck:univariate_" +
std::to_string(round_idx);
855 auto round_univariate =
856 transcript->template receive_from_prover<bb::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(
857 round_univariate_label);
858 FF round_challenge = transcript->template get_challenge<FF>(
"Sumcheck:u_" +
std::to_string(round_idx));
859 multivariate_challenge.emplace_back(round_challenge);
862 check_sum(round_univariate, padding_indicator);
874 bool verified =
false;
876 verified = (full_honk_purported_value.get_value() ==
target_total_sum.get_value());
938 Utils::template accumulate_relation_evaluations_without_skipping<>(purported_evaluations,
950 std::vector<FF>& multivariate_challenge,
956 const std::string round_univariate_comm_label =
"Sumcheck:univariate_comm_" +
std::to_string(round_idx);
957 const std::string univariate_eval_label_0 =
"Sumcheck:univariate_" +
std::to_string(round_idx) +
"_eval_0";
958 const std::string univariate_eval_label_1 =
"Sumcheck:univariate_" +
std::to_string(round_idx) +
"_eval_1";
961 round_univariate_commitments.push_back(
962 transcript->template receive_from_prover<Commitment>(round_univariate_comm_label));
964 round_univariate_evaluations.push_back(
965 { transcript->template receive_from_prover<FF>(univariate_eval_label_0),
966 transcript->template receive_from_prover<FF>(univariate_eval_label_1),
969 const FF round_challenge = transcript->template get_challenge<FF>(
"Sumcheck:u_" +
std::to_string(round_idx));
970 multivariate_challenge.emplace_back(round_challenge);
985 FF first_sumcheck_round_evaluations_sum =
986 round_univariate_evaluations[0][0] + round_univariate_evaluations[0][1];
988 bool verified =
false;
990 first_sumcheck_round_evaluations_sum.self_reduce();
993 verified = (first_sumcheck_round_evaluations_sum.get_value() ==
target_total_sum.get_value());
998 full_honk_purported_value.self_reduce();
1007 for (
size_t round_idx = 1; round_idx < round_univariate_evaluations.size(); round_idx++) {
1008 round_univariate_evaluations[round_idx - 1][2] =
1009 round_univariate_evaluations[round_idx][0] + round_univariate_evaluations[round_idx][1];
1013 round_univariate_evaluations[round_univariate_evaluations.size() - 1][2] = full_honk_purported_value;
#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 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
NativeTranscript Transcript
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
static constexpr size_t NUM_RELATIONS
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
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 for structures that contain data parameterized by the fundamental polynomials of...
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_pow2(size_t num_iterations, size_t min_iterations_per_thread)
calculates number of threads to create based on minimum iterations per thread, guaranteed power of 2
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