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
14#include <array>
15#include <tuple>
16#include <vector>
17
18namespace bb {
19
24template <typename Flavor> struct ZKSumcheckData {
25 using Curve = typename Flavor::Curve;
26 using FF = typename Curve::ScalarField;
28
29 static constexpr size_t SUBGROUP_SIZE = Curve::SUBGROUP_SIZE;
30
32
33 // The size of the LibraUnivariates.
35
36 static constexpr FF one_half = FF(1) / FF(2);
37
38 // Container for the evaluations of Libra Univariates that have to be proven.
39 using ClaimedLibraEvaluations = std::vector<FF>;
40
42
44 std::array<FF, SUBGROUP_SIZE> interpolation_domain;
45 // to compute product in lagrange basis
49
51 size_t log_circuit_size{ 0 };
57
59 // Default constructor
60 ZKSumcheckData() = default;
61
62 // Main constructor
63 ZKSumcheckData(const size_t multivariate_d,
65 const typename Flavor::CommitmentKey& commitment_key = typename Flavor::CommitmentKey())
66 : constant_term(FF::random_element())
67 , libra_concatenated_monomial_form(SUBGROUP_SIZE + WITNESS_MASKING_TERM_LENGTH)
69 , log_circuit_size(multivariate_d)
71
72 {
73 // transcript defaults to nullptr but is dereferenced unconditionally below.
74 BB_ASSERT(transcript != nullptr, "ZKSumcheckData: transcript must not be null");
75
77
79
80 // If prover_instance is provided, commit to the concatenated and masked libra polynomial
81 if (commitment_key.initialized()) {
83 transcript->send_to_verifier("Libra:concatenation_commitment", libra_concatenation_commitment);
84 }
85 // Compute the total sum of the Libra polynomials
87
88 // Send the Libra total sum to the transcript
89 transcript->send_to_verifier("Libra:Sum", libra_total_sum);
90
91 // Receive the Libra challenge from the transcript
92 libra_challenge = transcript->template get_challenge<FF>("Libra:Challenge");
93
94 // Initialize the Libra running sum
96
97 // Prepare the Libra data for the first round of sumcheck
98
100 }
101
129 static std::vector<Polynomial<FF>> generate_libra_univariates(const size_t number_of_polynomials,
130 const size_t univariate_length)
131 {
132 std::vector<Polynomial<FF>> libra_full_polynomials(number_of_polynomials);
133
134 for (auto& libra_polynomial : libra_full_polynomials) {
135 libra_polynomial = Polynomial<FF>::random(univariate_length);
136 };
137 return libra_full_polynomials;
138 };
139
155 const FF& constant_term)
156 {
157 FF total_sum = 0;
158 FF scaling_factor = one_half;
159
160 for (auto& univariate : libra_univariates) {
161 total_sum += univariate.at(0) + univariate.evaluate(FF(1));
162 scaling_factor *= 2;
163 }
164 total_sum *= scaling_factor;
165
166 return { total_sum + constant_term * (1UL << libra_univariates.size()), scaling_factor };
167 }
168
185 const FF& libra_challenge,
187 {
188 libra_scaling_factor *= libra_challenge; // \rho * 2^{d-1}
189 for (auto& univariate : libra_univariates) {
190 univariate *= libra_scaling_factor;
191 };
192 // subtract the contribution of the first libra univariate from libra total sum
193 libra_running_sum += -libra_univariates[0].at(0) - libra_univariates[0].evaluate(FF(1));
195 }
196
203 {
206 if (bn_evaluation_domain.size > 0) {
207 bn_evaluation_domain.compute_lookup_table();
208 }
209 }
210
211 interpolation_domain[0] = FF{ 1 };
212 for (size_t idx = 1; idx < SUBGROUP_SIZE; idx++) {
214 }
215 }
216
222 {
225 "Concatenated Libra polynomial does not fit in the SmallSubgroupIPA subgroup");
226 std::array<FF, SUBGROUP_SIZE> coeffs_lagrange_subgroup;
227 coeffs_lagrange_subgroup[0] = constant_term;
228
229 for (size_t idx = 1; idx < SUBGROUP_SIZE; idx++) {
230 coeffs_lagrange_subgroup[idx] = FF{ 0 };
231 }
232
233 for (size_t poly_idx = 0; poly_idx < log_circuit_size; poly_idx++) {
234 for (size_t idx = 0; idx < LIBRA_UNIVARIATES_LENGTH; idx++) {
235 size_t idx_to_populate = 1 + poly_idx * LIBRA_UNIVARIATES_LENGTH + idx;
236 coeffs_lagrange_subgroup[idx_to_populate] = libra_univariates[poly_idx].at(idx);
237 }
238 }
239
240 libra_concatenated_lagrange_form = Polynomial<FF>(coeffs_lagrange_subgroup);
241
243
244 Polynomial<FF> libra_concatenated_monomial_form_unmasked(SUBGROUP_SIZE);
246 libra_concatenated_monomial_form_unmasked =
247 Polynomial<FF>(interpolation_domain, coeffs_lagrange_subgroup, SUBGROUP_SIZE);
248 } else {
249 std::vector<FF> coeffs_lagrange_subgroup_ifft(SUBGROUP_SIZE);
251 coeffs_lagrange_subgroup.data(), coeffs_lagrange_subgroup_ifft.data(), bn_evaluation_domain);
252 libra_concatenated_monomial_form_unmasked = Polynomial<FF>(coeffs_lagrange_subgroup_ifft);
253 }
254
255 for (size_t idx = 0; idx < SUBGROUP_SIZE; idx++) {
256 libra_concatenated_monomial_form.at(idx) = libra_concatenated_monomial_form_unmasked.at(idx);
257 }
258
259 for (size_t idx = 0; idx < masking_scalars.size(); idx++) {
260 libra_concatenated_monomial_form.at(idx) -= masking_scalars.value_at(idx);
261 libra_concatenated_monomial_form.at(SUBGROUP_SIZE + idx) += masking_scalars.value_at(idx);
262 }
263 }
264
288 void update_zk_sumcheck_data(const FF& round_challenge, const size_t round_idx)
289 {
290 static constexpr FF two_inv = FF(1) / FF(2);
291 BB_ASSERT(round_idx < this->libra_univariates.size(), "update_zk_sumcheck_data: round_idx out of range");
292 // when round_idx = d - 1, the update is not needed
293 if (round_idx < this->log_circuit_size - 1) {
294 for (auto& univariate : this->libra_univariates) {
295 univariate *= two_inv;
296 };
297 // compute the evaluation \f$ \rho \cdot 2^{d-2-i} \çdot g_i(u_i) \f$
298 const FF libra_evaluation = this->libra_univariates[round_idx].evaluate(round_challenge);
299 BB_ASSERT(round_idx + 1 < this->libra_univariates.size(),
300 "update_zk_sumcheck_data: round_idx + 1 out of range");
301 const auto& next_libra_univariate = this->libra_univariates[round_idx + 1];
302 // update the running sum by adding g_i(u_i) and subtracting (g_i(0) + g_i(1))
303 this->libra_running_sum += -next_libra_univariate.at(0) - next_libra_univariate.evaluate(FF(1));
304 this->libra_running_sum *= two_inv;
305
306 this->libra_running_sum += libra_evaluation;
307 this->libra_scaling_factor *= two_inv;
308
309 this->libra_evaluations.emplace_back(libra_evaluation / this->libra_scaling_factor);
310 } else {
311 // compute the evaluation of the last Libra univariate at the challenge u_{d-1}
312 const FF libra_evaluation =
313 this->libra_univariates[round_idx].evaluate(round_challenge) / this->libra_scaling_factor;
314 // place the evalution into the vector of Libra evaluations
315 this->libra_evaluations.emplace_back(libra_evaluation);
316 };
317 }
318};
319
320} // namespace bb
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
#define BB_ASSERT_LT(left, right,...)
Definition assert.hpp:143
CommitmentKey object over a pairing group 𝔾₁.
curve::Grumpkin Curve
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:74
static constexpr uint32_t LIBRA_UNIVARIATES_LENGTH
Definition grumpkin.hpp:87
typename Group::affine_element AffineElement
Definition grumpkin.hpp:64
static constexpr ScalarField subgroup_generator
Definition grumpkin.hpp:79
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
Commitment libra_concatenation_commitment
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 ,...
typename Curve::AffineElement Commitment
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(...