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: Complete, auditors: [Khashayar], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8
13#include <array>
14#include <tuple>
15#include <vector>
16
17namespace bb {
18
23template <typename Flavor> struct ZKSumcheckData {
24 using Curve = typename Flavor::Curve;
25 using FF = typename Curve::ScalarField;
26
27 static constexpr size_t SUBGROUP_SIZE = Curve::SUBGROUP_SIZE;
28
30
31 // The size of the LibraUnivariates.
33
34 static constexpr FF one_half = FF(1) / FF(2);
35
36 // Container for the evaluations of Libra Univariates that have to be proven.
37 using ClaimedLibraEvaluations = std::vector<FF>;
38
40
42 std::array<FF, SUBGROUP_SIZE> interpolation_domain;
43 // to compute product in lagrange basis
46
48 size_t log_circuit_size{ 0 };
54
56 // Default constructor
57 ZKSumcheckData() = default;
58
59 // Main constructor
60 ZKSumcheckData(const size_t multivariate_d,
62 const typename Flavor::CommitmentKey& commitment_key = typename Flavor::CommitmentKey())
63 : constant_term(FF::random_element())
64 , libra_concatenated_monomial_form(SUBGROUP_SIZE + 2) // includes masking
66 , log_circuit_size(multivariate_d)
68
69 {
71
73
74 // If prover_instance is provided, commit to the concatenated and masked libra polynomial
75 if (commitment_key.initialized()) {
76 auto libra_commitment = commitment_key.commit(libra_concatenated_monomial_form);
77 transcript->send_to_verifier("Libra:concatenation_commitment", libra_commitment);
78 }
79 // 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
123 static std::vector<Polynomial<FF>> generate_libra_univariates(const size_t number_of_polynomials,
124 const size_t univariate_length)
125 {
126 std::vector<Polynomial<FF>> libra_full_polynomials(number_of_polynomials);
127
128 for (auto& libra_polynomial : libra_full_polynomials) {
129 libra_polynomial = Polynomial<FF>::random(univariate_length);
130 };
131 return libra_full_polynomials;
132 };
133
143 const FF& constant_term)
144 {
145 FF total_sum = 0;
146 FF scaling_factor = one_half;
147
148 for (auto& univariate : libra_univariates) {
149 total_sum += univariate.at(0) + univariate.evaluate(FF(1));
150 scaling_factor *= 2;
151 }
152 total_sum *= scaling_factor;
153
154 return { total_sum + constant_term * (1UL << libra_univariates.size()), scaling_factor };
155 }
156
171 const FF& libra_challenge,
173 {
174 libra_scaling_factor *= libra_challenge; // \rho * 2^{d-1}
175 for (auto& univariate : libra_univariates) {
176 univariate *= libra_scaling_factor;
177 };
178 // subtract the contribution of the first libra univariate from libra total sum
179 libra_running_sum += -libra_univariates[0].at(0) - libra_univariates[0].evaluate(FF(1));
181 }
182
189 {
192 if (bn_evaluation_domain.size > 0) {
193 bn_evaluation_domain.compute_lookup_table();
194 }
195 }
196
197 interpolation_domain[0] = FF{ 1 };
198 for (size_t idx = 1; idx < SUBGROUP_SIZE; idx++) {
200 }
201 }
202
208 {
209 std::array<FF, SUBGROUP_SIZE> coeffs_lagrange_subgroup;
210 coeffs_lagrange_subgroup[0] = constant_term;
211
212 for (size_t idx = 1; idx < SUBGROUP_SIZE; idx++) {
213 coeffs_lagrange_subgroup[idx] = FF{ 0 };
214 }
215
216 for (size_t poly_idx = 0; poly_idx < log_circuit_size; poly_idx++) {
217 for (size_t idx = 0; idx < LIBRA_UNIVARIATES_LENGTH; idx++) {
218 size_t idx_to_populate = 1 + poly_idx * LIBRA_UNIVARIATES_LENGTH + idx;
219 coeffs_lagrange_subgroup[idx_to_populate] = libra_univariates[poly_idx].at(idx);
220 }
221 }
222
223 libra_concatenated_lagrange_form = Polynomial<FF>(coeffs_lagrange_subgroup);
224
226
227 Polynomial<FF> libra_concatenated_monomial_form_unmasked(SUBGROUP_SIZE);
229 libra_concatenated_monomial_form_unmasked =
230 Polynomial<FF>(interpolation_domain, coeffs_lagrange_subgroup, SUBGROUP_SIZE);
231 } else {
232 std::vector<FF> coeffs_lagrange_subgroup_ifft(SUBGROUP_SIZE);
234 coeffs_lagrange_subgroup.data(), coeffs_lagrange_subgroup_ifft.data(), bn_evaluation_domain);
235 libra_concatenated_monomial_form_unmasked = Polynomial<FF>(coeffs_lagrange_subgroup_ifft);
236 }
237
238 for (size_t idx = 0; idx < SUBGROUP_SIZE; idx++) {
239 libra_concatenated_monomial_form.at(idx) = libra_concatenated_monomial_form_unmasked.at(idx);
240 }
241
242 for (size_t idx = 0; idx < masking_scalars.size(); idx++) {
243 libra_concatenated_monomial_form.at(idx) -= masking_scalars.value_at(idx);
244 libra_concatenated_monomial_form.at(SUBGROUP_SIZE + idx) += masking_scalars.value_at(idx);
245 }
246 }
247
271 void update_zk_sumcheck_data(const FF& round_challenge, const size_t round_idx)
272 {
273 static constexpr FF two_inv = FF(1) / FF(2);
274 // when round_idx = d - 1, the update is not needed
275 if (round_idx < this->log_circuit_size - 1) {
276 for (auto& univariate : this->libra_univariates) {
277 univariate *= two_inv;
278 };
279 // compute the evaluation \f$ \rho \cdot 2^{d-2-i} \çdot g_i(u_i) \f$
280 const FF libra_evaluation = this->libra_univariates[round_idx].evaluate(round_challenge);
281 const auto& next_libra_univariate = this->libra_univariates[round_idx + 1];
282 // update the running sum by adding g_i(u_i) and subtracting (g_i(0) + g_i(1))
283 this->libra_running_sum += -next_libra_univariate.at(0) - next_libra_univariate.evaluate(FF(1));
284 this->libra_running_sum *= two_inv;
285
286 this->libra_running_sum += libra_evaluation;
287 this->libra_scaling_factor *= two_inv;
288
289 this->libra_evaluations.emplace_back(libra_evaluation / this->libra_scaling_factor);
290 } else {
291 // compute the evaluation of the last Libra univariate at the challenge u_{d-1}
292 const FF libra_evaluation =
293 this->libra_univariates[round_idx].evaluate(round_challenge) / this->libra_scaling_factor;
294 // place the evalution into the vector of Libra evaluations
295 this->libra_evaluations.emplace_back(libra_evaluation);
296 };
297 }
298};
299
300} // namespace bb
CommitmentKey object over a pairing group 𝔾₁.
curve::Grumpkin Curve
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
static Polynomial random(size_t size, size_t start_index=0)
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 {0, 1,..., domain_end - 1}.
Fr & value_at(size_t i)
static Univariate get_random()
static constexpr size_t SUBGROUP_SIZE
Definition grumpkin.hpp:72
static constexpr uint32_t LIBRA_UNIVARIATES_LENGTH
Definition grumpkin.hpp:84
static constexpr ScalarField subgroup_generator
Definition grumpkin.hpp:77
void ifft(Fr *coeffs, Fr *target, const EvaluationDomain< Fr > &domain)
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
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 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
static std::pair< FF, FF > compute_libra_total_sum(const std::vector< Polynomial< FF > > &libra_univariates, const FF &constant_term)
Compute the sum of the randomly sampled multivariate polynomial over the Boolean hypercube.
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(...