barretenberg
Loading...
Searching...
No Matches
sumcheck.hpp
1#pragma once
2#include "barretenberg/proof_system/library/grand_product_delta.hpp"
3#include "barretenberg/sumcheck/instance/prover_instance.hpp"
4#include "barretenberg/sumcheck/sumcheck_output.hpp"
5#include "barretenberg/transcript/transcript.hpp"
6#include "sumcheck_round.hpp"
7
8namespace proof_system::honk::sumcheck {
9
10template <typename Flavor> class SumcheckProver {
11
12 public:
13 using FF = typename Flavor::FF;
14 using ProverPolynomials = typename Flavor::ProverPolynomials;
15 using PartiallyEvaluatedMultivariates = typename Flavor::PartiallyEvaluatedMultivariates;
16 using ClaimedEvaluations = typename Flavor::AllValues;
17 using Transcript = typename Flavor::Transcript;
19
20 std::shared_ptr<Transcript> transcript;
21
22 const size_t multivariate_n;
23 const size_t multivariate_d;
25
57 PartiallyEvaluatedMultivariates partially_evaluated_polynomials;
58
59 // prover instantiates sumcheck with circuit size and a prover transcript
60 SumcheckProver(size_t multivariate_n, const std::shared_ptr<Transcript>& transcript)
61 : transcript(transcript)
62 , multivariate_n(multivariate_n)
63 , multivariate_d(numeric::get_msb(multivariate_n))
64 , round(multivariate_n)
65 , partially_evaluated_polynomials(multivariate_n){};
66
73 SumcheckOutput<Flavor> prove(ProverPolynomials& full_polynomials,
74 const proof_system::RelationParameters<FF>& relation_parameters,
75 FF alpha) // pass by value, not by reference
76 {
77 FF zeta = transcript->get_challenge("Sumcheck:zeta");
78
79 barretenberg::PowUnivariate<FF> pow_univariate(zeta);
80
81 std::vector<FF> multivariate_challenge;
82 multivariate_challenge.reserve(multivariate_d);
83
84 // First round
85 // This populates partially_evaluated_polynomials.
86 auto round_univariate = round.compute_univariate(full_polynomials, relation_parameters, pow_univariate, alpha);
87 transcript->send_to_verifier("Sumcheck:univariate_0", round_univariate);
88 FF round_challenge = transcript->get_challenge("Sumcheck:u_0");
89 multivariate_challenge.emplace_back(round_challenge);
90 partially_evaluate(full_polynomials, multivariate_n, round_challenge);
91 pow_univariate.partially_evaluate(round_challenge);
92 round.round_size =
93 round.round_size >> 1; // TODO(#224)(Cody): Maybe partially_evaluate should do this and release memory?
94
95 // All but final round
96 // We operate on partially_evaluated_polynomials in place.
97 for (size_t round_idx = 1; round_idx < multivariate_d; round_idx++) {
98 // Write the round univariate to the transcript
99 round_univariate =
100 round.compute_univariate(partially_evaluated_polynomials, relation_parameters, pow_univariate, alpha);
101 transcript->send_to_verifier("Sumcheck:univariate_" + std::to_string(round_idx), round_univariate);
102 FF round_challenge = transcript->get_challenge("Sumcheck:u_" + std::to_string(round_idx));
103 multivariate_challenge.emplace_back(round_challenge);
104 partially_evaluate(partially_evaluated_polynomials, round.round_size, round_challenge);
105 pow_univariate.partially_evaluate(round_challenge);
106 round.round_size = round.round_size >> 1;
107 }
108
109 // Final round: Extract multivariate evaluations from partially_evaluated_polynomials and add to transcript
110 ClaimedEvaluations multivariate_evaluations;
111 for (auto [eval, poly] :
112 zip_view(multivariate_evaluations.get_all(), partially_evaluated_polynomials.get_all())) {
113 eval = (poly)[0];
114 }
115 transcript->send_to_verifier("Sumcheck:evaluations", multivariate_evaluations);
116
117 return { multivariate_challenge, multivariate_evaluations };
118 };
119
124 SumcheckOutput<Flavor> prove(std::shared_ptr<Instance> instance)
125 {
126 return prove(instance->prover_polynomials, instance->relation_parameters, instance->alpha);
127 };
128
144 void partially_evaluate(auto& polynomials, size_t round_size, FF round_challenge)
145 {
146 auto pep_view = partially_evaluated_polynomials.get_all();
147 auto poly_view = polynomials.get_all();
148 // after the first round, operate in place on partially_evaluated_polynomials
149 parallel_for(poly_view.size(), [&](size_t j) {
150 for (size_t i = 0; i < round_size; i += 2) {
151 pep_view[j][i >> 1] = poly_view[j][i] + round_challenge * (poly_view[j][i + 1] - poly_view[j][i]);
152 }
153 });
154 };
159 template <typename PolynomialT, std::size_t N>
160 void partially_evaluate(std::array<PolynomialT, N>& polynomials, size_t round_size, FF round_challenge)
161 {
162 auto pep_view = partially_evaluated_polynomials.get_all();
163 // after the first round, operate in place on partially_evaluated_polynomials
164 parallel_for(polynomials.size(), [&](size_t j) {
165 for (size_t i = 0; i < round_size; i += 2) {
166 pep_view[j][i >> 1] = polynomials[j][i] + round_challenge * (polynomials[j][i + 1] - polynomials[j][i]);
167 }
168 });
169 };
170};
171
172template <typename Flavor> class SumcheckVerifier {
173
174 public:
176 using FF = typename Flavor::FF;
177 using ClaimedEvaluations = typename Flavor::AllValues;
178 using Transcript = typename Flavor::Transcript;
179
180 static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH = Flavor::BATCHED_RELATION_PARTIAL_LENGTH;
181 static constexpr size_t NUM_POLYNOMIALS = Flavor::NUM_ALL_ENTITIES;
182
183 const size_t multivariate_d;
185
186 // verifier instantiates sumcheck with circuit size
187 explicit SumcheckVerifier(size_t multivariate_n)
188 : multivariate_d(numeric::get_msb(multivariate_n))
189 , round(){};
190
201 FF alpha,
202 const std::shared_ptr<Transcript>& transcript)
203 {
204 bool verified(true);
205
206 FF zeta = transcript->get_challenge("Sumcheck:zeta");
207
208 barretenberg::PowUnivariate<FF> pow_univariate(zeta);
209 // All but final round.
210 // target_total_sum is initialized to zero then mutated in place.
211
212 if (multivariate_d == 0) {
213 throw_or_abort("Number of variables in multivariate is 0.");
214 }
215
216 std::vector<FF> multivariate_challenge;
217 multivariate_challenge.reserve(multivariate_d);
218
219 for (size_t round_idx = 0; round_idx < multivariate_d; round_idx++) {
220 // Obtain the round univariate from the transcript
221 std::string round_univariate_label = "Sumcheck:univariate_" + std::to_string(round_idx);
222 auto round_univariate =
223 transcript->template receive_from_prover<barretenberg::Univariate<FF, BATCHED_RELATION_PARTIAL_LENGTH>>(
224 round_univariate_label);
225
226 bool checked = round.check_sum(round_univariate);
227 verified = verified && checked;
228 FF round_challenge = transcript->get_challenge("Sumcheck:u_" + std::to_string(round_idx));
229 multivariate_challenge.emplace_back(round_challenge);
230
231 round.compute_next_target_sum(round_univariate, round_challenge);
232 pow_univariate.partially_evaluate(round_challenge);
233 }
234
235 // Final round
236 ClaimedEvaluations purported_evaluations;
237 auto transcript_evaluations =
238 transcript->template receive_from_prover<std::array<FF, NUM_POLYNOMIALS>>("Sumcheck:evaluations");
239 for (auto [eval, transcript_eval] : zip_view(purported_evaluations.get_all(), transcript_evaluations)) {
240 eval = transcript_eval;
241 }
242
243 FF full_honk_relation_purported_value = round.compute_full_honk_relation_purported_value(
244 purported_evaluations, relation_parameters, pow_univariate, alpha);
245
246 bool checked = false;
247 if constexpr (IsRecursiveFlavor<Flavor>) {
248 checked = (full_honk_relation_purported_value == round.target_total_sum).get_value();
249 } else {
250 checked = (full_honk_relation_purported_value == round.target_total_sum);
251 }
252 verified = verified && checked;
253
254 return SumcheckOutput<Flavor>{ multivariate_challenge, purported_evaluations, verified };
255 };
256};
257} // namespace proof_system::honk::sumcheck
Definition: utils.hpp:7
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
Definition: transcript.hpp:62
An Instance is normally constructed from a finalized circuit and it's role is to compute all the poly...
Definition: prover_instance.hpp:20
A field element for each entity of the flavor. These entities represent the prover polynomials evalua...
Definition: goblin_translator.hpp:947
A container for storing the partially evaluated multivariates produced by sumcheck.
Definition: goblin_translator.hpp:993
A container for the prover polynomials handles.
Definition: goblin_translator.hpp:955
Definition: sumcheck_round.hpp:53
barretenberg::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > compute_univariate(ProverPolynomialsOrPartiallyEvaluatedMultivariates &polynomials, const proof_system::RelationParameters< FF > &relation_parameters, const barretenberg::PowUnivariate< FF > &pow_univariate, const FF alpha)
Return the evaluations of the univariate restriction (S_l(X_l) in the thesis) at num_multivariates-ma...
Definition: sumcheck_round.hpp:103
PartiallyEvaluatedMultivariates partially_evaluated_polynomials
(partially_evaluated_polynomials) Suppose the Honk polynomials (multilinear in d variables) are calle...
Definition: sumcheck.hpp:57
void partially_evaluate(auto &polynomials, size_t round_size, FF round_challenge)
Evaluate at the round challenge and prepare class for next round. Illustration of layout in example o...
Definition: sumcheck.hpp:144
void partially_evaluate(std::array< PolynomialT, N > &polynomials, size_t round_size, FF round_challenge)
Evaluate at the round challenge and prepare class for next round. Specialization for array,...
Definition: sumcheck.hpp:160
SumcheckOutput< Flavor > prove(ProverPolynomials &full_polynomials, const proof_system::RelationParameters< FF > &relation_parameters, FF alpha)
Compute univariate restriction place in transcript, generate challenge, partially evaluate,...
Definition: sumcheck.hpp:73
SumcheckOutput< Flavor > prove(std::shared_ptr< Instance > instance)
Compute univariate restriction place in transcript, generate challenge, partially evaluate,...
Definition: sumcheck.hpp:124
Definition: sumcheck_round.hpp:258
FF compute_full_honk_relation_purported_value(ClaimedEvaluations purported_evaluations, const proof_system::RelationParameters< FF > &relation_parameters, const barretenberg::PowUnivariate< FF > &pow_univariate, const FF alpha)
General purpose method for applying a tuple of arrays (of FFs)
Definition: sumcheck_round.hpp:324
FF compute_next_target_sum(barretenberg::Univariate< FF, BATCHED_RELATION_PARTIAL_LENGTH > &univariate, FF &round_challenge)
After checking that the univariate is good for this round, compute the next target sum.
Definition: sumcheck_round.hpp:307
SumcheckOutput< Flavor > verify(const proof_system::RelationParameters< FF > &relation_parameters, FF alpha, const std::shared_ptr< Transcript > &transcript)
Extract round univariate, check sum, generate challenge, compute next target sum.....
Definition: sumcheck.hpp:200
Definition: zip_view.hpp:159
Definition: flavor.hpp:300
Definition: field2_declarations.hpp:6
Definition: pow.hpp:93
void partially_evaluate(FF challenge)
Parially evaluate the polynomial in the new challenge, by updating the constant c_{l} -> c_{l+1}....
Definition: pow.hpp:121
Container for parameters used by the grand product (permutation, lookup) Honk relations.
Definition: relation_parameters.hpp:12
Contains the multi-linear evaluations of the polynomials at the challenge point 'u'....
Definition: sumcheck_output.hpp:13