Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
zk_sumcheck_data.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
8
13#include <array>
14#include <vector>
15
16namespace bb {
17
22template <typename Flavor> struct ZKSumcheckData {
23 using Curve = typename Flavor::Curve;
24 using FF = typename Curve::ScalarField;
25
26 static constexpr size_t SUBGROUP_SIZE = Curve::SUBGROUP_SIZE;
27
29
30 // The size of the LibraUnivariates.
32
33 static constexpr FF one_half = FF(1) / FF(2);
34
35 // Container for the evaluations of Libra Univariates that have to be proven.
36 using ClaimedLibraEvaluations = std::vector<FF>;
37
39
41 std::array<FF, SUBGROUP_SIZE> interpolation_domain;
42 // to compute product in lagrange basis
45
47 size_t log_circuit_size{ 0 };
53
55 // Default constructor
56 ZKSumcheckData() = default;
57
58 // Main constructor
59 ZKSumcheckData(const size_t multivariate_d,
61 const typename Flavor::CommitmentKey& commitment_key = typename Flavor::CommitmentKey())
62 : constant_term(FF::random_element())
63 , libra_concatenated_monomial_form(SUBGROUP_SIZE + 2) // includes masking
65 , log_circuit_size(multivariate_d)
67
68 {
70
72
73 // If proving_key is provided, commit to the concatenated and masked libra polynomial
74 if (commitment_key.initialized()) {
75 auto libra_commitment = commitment_key.commit(libra_concatenated_monomial_form);
76 transcript->send_to_verifier("Libra:concatenation_commitment", libra_commitment);
77 }
78 // Compute the total sum of the Libra polynomials
81
82 // Send the Libra total sum to the transcript
83 transcript->send_to_verifier("Libra:Sum", libra_total_sum);
84
85 // Receive the Libra challenge from the transcript
86 libra_challenge = transcript->template get_challenge<FF>("Libra:Challenge");
87
88 // Initialize the Libra running sum
90
91 // Prepare the Libra data for the first round of sumcheck
92
94 }
95
124 static std::vector<Polynomial<FF>> generate_libra_univariates(const size_t number_of_polynomials,
125 const size_t univariate_length)
126 {
127 std::vector<Polynomial<FF>> libra_full_polynomials(number_of_polynomials);
128
129 for (auto& libra_polynomial : libra_full_polynomials) {
130 libra_polynomial = Polynomial<FF>::random(univariate_length);
131 };
132 return libra_full_polynomials;
133 };
134
144 FF& scaling_factor,
145 const FF& constant_term)
146 {
147 FF total_sum = 0;
148 scaling_factor *= one_half;
149
150 for (auto& univariate : libra_univariates) {
151 total_sum += univariate.at(0) + univariate.evaluate(FF(1));
152 scaling_factor *= 2;
153 }
154 total_sum *= scaling_factor;
155
156 return total_sum + constant_term * (1 << libra_univariates.size());
157 }
158
173 const FF& libra_challenge,
175 {
176 libra_scaling_factor *= libra_challenge; // \rho * 2^{d-1}
177 for (auto& univariate : libra_univariates) {
178 univariate *= libra_scaling_factor;
179 };
180 // subtract the contribution of the first libra univariate from libra total sum
181 libra_running_sum += -libra_univariates[0].at(0) - libra_univariates[0].evaluate(FF(1));
183 }
184
191 {
194 if (bn_evaluation_domain.size > 0) {
195 bn_evaluation_domain.compute_lookup_table();
196 }
197 }
198
199 interpolation_domain[0] = FF{ 1 };
200 for (size_t idx = 1; idx < SUBGROUP_SIZE; idx++) {
202 }
203 }
204
210 {
211 std::array<FF, SUBGROUP_SIZE> coeffs_lagrange_subgroup;
212 coeffs_lagrange_subgroup[0] = constant_term;
213
214 for (size_t idx = 1; idx < SUBGROUP_SIZE; idx++) {
215 coeffs_lagrange_subgroup[idx] = FF{ 0 };
216 }
217
218 for (size_t poly_idx = 0; poly_idx < log_circuit_size; poly_idx++) {
219 for (size_t idx = 0; idx < LIBRA_UNIVARIATES_LENGTH; idx++) {
220 size_t idx_to_populate = 1 + poly_idx * LIBRA_UNIVARIATES_LENGTH + idx;
221 coeffs_lagrange_subgroup[idx_to_populate] = libra_univariates[poly_idx].at(idx);
222 }
223 }
224
225 libra_concatenated_lagrange_form = Polynomial<FF>(coeffs_lagrange_subgroup);
226
228
229 Polynomial<FF> libra_concatenated_monomial_form_unmasked(SUBGROUP_SIZE);
231 libra_concatenated_monomial_form_unmasked =
232 Polynomial<FF>(interpolation_domain, coeffs_lagrange_subgroup, SUBGROUP_SIZE);
233 } else {
234 std::vector<FF> coeffs_lagrange_subgroup_ifft(SUBGROUP_SIZE);
236 coeffs_lagrange_subgroup.data(), coeffs_lagrange_subgroup_ifft.data(), bn_evaluation_domain);
237 libra_concatenated_monomial_form_unmasked = Polynomial<FF>(coeffs_lagrange_subgroup_ifft);
238 }
239
240 for (size_t idx = 0; idx < SUBGROUP_SIZE; idx++) {
241 libra_concatenated_monomial_form.at(idx) = libra_concatenated_monomial_form_unmasked.at(idx);
242 }
243
244 for (size_t idx = 0; idx < masking_scalars.size(); idx++) {
245 libra_concatenated_monomial_form.at(idx) -= masking_scalars.value_at(idx);
246 libra_concatenated_monomial_form.at(SUBGROUP_SIZE + idx) += masking_scalars.value_at(idx);
247 }
248 }
249
275 void update_zk_sumcheck_data(const FF& round_challenge, const size_t round_idx)
276 {
277 static constexpr FF two_inv = FF(1) / FF(2);
278 // when round_idx = d - 1, the update is not needed
279 if (round_idx < this->log_circuit_size - 1) {
280 for (auto& univariate : this->libra_univariates) {
281 univariate *= two_inv;
282 };
283 // compute the evaluation \f$ \rho \cdot 2^{d-2-i} \çdot g_i(u_i) \f$
284 const FF libra_evaluation = this->libra_univariates[round_idx].evaluate(round_challenge);
285 const auto& next_libra_univariate = this->libra_univariates[round_idx + 1];
286 // update the running sum by adding g_i(u_i) and subtracting (g_i(0) + g_i(1))
287 this->libra_running_sum += -next_libra_univariate.at(0) - next_libra_univariate.evaluate(FF(1));
288 this->libra_running_sum *= two_inv;
289
290 this->libra_running_sum += libra_evaluation;
291 this->libra_scaling_factor *= two_inv;
292
293 this->libra_evaluations.emplace_back(libra_evaluation / this->libra_scaling_factor);
294 } else {
295 // compute the evaluation of the last Libra univariate at the challenge u_{d-1}
296 const FF libra_evaluation =
297 this->libra_univariates[round_idx].evaluate(round_challenge) / this->libra_scaling_factor;
298 // place the evalution into the vector of Libra evaluations
299 this->libra_evaluations.emplace_back(libra_evaluation);
300 for (auto univariate : this->libra_univariates) {
301 univariate *= FF(1) / this->libra_challenge;
302 }
303 };
304 }
305};
306
307} // namespace bb
CommitmentKey object over a pairing group 𝔾₁.
curve::BN254 Curve
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
Fr & at(size_t index)
Our mutable accessor, unlike operator[]. We abuse precedent a bit to differentiate at() and operator[...
A univariate polynomial represented by its values on {domain_start, domain_start + 1,...
Fr & value_at(size_t i)
static Univariate get_random()
static constexpr size_t SUBGROUP_SIZE
Definition grumpkin.hpp:67
static constexpr uint32_t LIBRA_UNIVARIATES_LENGTH
Definition grumpkin.hpp:79
static constexpr ScalarField subgroup_generator
Definition grumpkin.hpp:72
void ifft(Fr *coeffs, const EvaluationDomain< Fr > &domain)
Entry point for Barretenberg command-line interface.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
This structure is created to contain various polynomials and constants required by ZK Sumcheck.
ZKSumcheckData()=default
Polynomial< FF > libra_concatenated_monomial_form
static constexpr size_t LIBRA_UNIVARIATES_LENGTH
std::vector< Polynomial< FF > > libra_univariates
ClaimedLibraEvaluations libra_evaluations
static constexpr FF subgroup_generator
typename Curve::ScalarField FF
Polynomial< FF > libra_concatenated_lagrange_form
static std::vector< Polynomial< FF > > generate_libra_univariates(const size_t number_of_polynomials, const size_t univariate_length)
Given number of univariate polynomials and the number of their evaluations meant to be hidden,...
ZKSumcheckData(const size_t multivariate_d, std::shared_ptr< typename Flavor::Transcript > transcript=nullptr, const typename Flavor::CommitmentKey &commitment_key=typename Flavor::CommitmentKey())
std::vector< FF > ClaimedLibraEvaluations
static constexpr FF one_half
void update_zk_sumcheck_data(const FF &round_challenge, const size_t round_idx)
Upon receiving the challenge , the prover updates Libra data. If .
static FF compute_libra_total_sum(const std::vector< Polynomial< FF > > &libra_univariates, FF &scaling_factor, const FF &constant_term)
Compute the sum of the randomly sampled multivariate polynomial over the Boolean hypercube.
static void setup_auxiliary_data(auto &libra_univariates, FF &libra_scaling_factor, const FF &libra_challenge, FF &libra_running_sum)
Set up Libra book-keeping table that simplifies the computation of Libra Round Univariates.
EvaluationDomain< FF > bn_evaluation_domain
typename Flavor::Curve Curve
std::array< FF, SUBGROUP_SIZE > interpolation_domain
static constexpr size_t SUBGROUP_SIZE
void create_interpolation_domain()
Create a interpolation domain object and initialize the evaluation domain in the case of BN254 scalar...
ZKSumcheckData(const size_t multivariate_d, const size_t univariate_length)
For test purposes: Constructs a sumcheck instance from the polynomial , where is a random univariate...
void compute_concatenated_libra_polynomial()
Compute concatenated libra polynomial in lagrange basis, transform to monomial, add masking term Z_H(...