Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
gemini.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
51namespace bb {
52
67namespace gemini {
76template <class Fr> inline std::vector<Fr> powers_of_rho(const Fr& rho, const size_t num_powers)
77{
78 std::vector<Fr> rhos = { Fr(1), rho };
79 rhos.reserve(num_powers);
80 for (size_t j = 2; j < num_powers; j++) {
81 rhos.emplace_back(rhos[j - 1] * rho);
82 }
83 return rhos;
84};
85
93template <class Fr> inline std::vector<Fr> powers_of_evaluation_challenge(const Fr& r, const size_t num_squares)
94{
95 std::vector<Fr> squares = { r };
96 squares.reserve(num_squares);
97 for (size_t j = 1; j < num_squares; j++) {
98 squares.emplace_back(squares[j - 1].sqr());
99 }
100 return squares;
101};
102} // namespace gemini
103
104template <typename Curve> class GeminiProver_ {
105 using Fr = typename Curve::ScalarField;
109
110 public:
126
127 size_t full_batched_size = 0; // size of the full batched polynomial (generally the circuit size)
128 size_t actual_data_size_ = 0; // max end_index across all polynomials (actual data extent)
129
130 Polynomial batched_unshifted; // linear combination of unshifted polynomials
131 Polynomial batched_to_be_shifted_by_one; // linear combination of to-be-shifted polynomials
132
133 public:
134 RefVector<Polynomial> unshifted; // set of unshifted polynomials
135 RefVector<Polynomial> to_be_shifted_by_one; // set of polynomials to be left shifted by 1
136
137 PolynomialBatcher(const size_t full_batched_size, const size_t actual_data_size = 0)
139 , actual_data_size_(actual_data_size == 0 ? full_batched_size : actual_data_size)
142 {}
143
144 bool has_unshifted() const { return unshifted.size() > 0; }
145 bool has_to_be_shifted_by_one() const { return to_be_shifted_by_one.size() > 0; }
146
147 // Set references to the polynomials to be batched
148 void set_unshifted(RefVector<Polynomial> polynomials) { unshifted = polynomials; }
150
159 Polynomial compute_batched(const Fr& challenge)
160 {
161 Fr running_scalar(1);
162 BB_BENCH_NAME("compute_batched");
163 // lambda for batching polynomials; updates the running scalar in place
164 auto batch = [&](Polynomial& batched, const RefVector<Polynomial>& polynomials_to_batch) {
165 for (auto& poly : polynomials_to_batch) {
166 batched.add_scaled(poly, running_scalar);
167 running_scalar *= challenge;
168 }
169 };
170
171 Polynomial full_batched(full_batched_size);
172
173 // compute the linear combination F of the unshifted polynomials
174 if (has_unshifted()) {
176 full_batched += batched_unshifted; // A₀ += F
177 }
178
179 // compute the linear combination G of the to-be-shifted polynomials
182 full_batched += batched_to_be_shifted_by_one.shifted(); // A₀ += G/X
183 }
184
185 return full_batched;
186 }
187
195 {
196 // Initialize A₀₊ with only the actual data extent; virtual zeroes cover the rest
198
199 if (has_unshifted()) {
200 A_0_pos += batched_unshifted; // A₀₊ += F
201 }
202
203 Polynomial A_0_neg = A_0_pos;
204
206 Fr r_inv = r_challenge.invert(); // r⁻¹
207 batched_to_be_shifted_by_one *= r_inv; // G = G/r
208
209 A_0_pos += batched_to_be_shifted_by_one; // A₀₊ += G/r
210 A_0_neg -= batched_to_be_shifted_by_one; // A₀₋ -= G/r
211 }
212
213 return { A_0_pos, A_0_neg };
214 };
215 };
216
217 static std::vector<Polynomial> compute_fold_polynomials(const size_t log_n,
218 std::span<const Fr> multilinear_challenge,
219 const Polynomial& A_0,
220 const bool& has_zk = false);
221
223 Polynomial&& A_0_pos,
224 Polynomial&& A_0_neg,
225 std::vector<Polynomial>&& fold_polynomials,
226 const Fr& r_challenge);
227
228 template <typename Transcript>
229 static std::vector<Claim> prove(size_t circuit_size,
230 PolynomialBatcher& polynomial_batcher,
231 std::span<Fr> multilinear_challenge,
232 const CommitmentKey<Curve>& commitment_key,
233 const std::shared_ptr<Transcript>& transcript,
234 bool has_zk = false);
235
236}; // namespace bb
237
241template <typename Curve> class GeminiVerifier_ {
242 using Fr = typename Curve::ScalarField;
244
245 public:
254 static std::vector<Commitment> get_fold_commitments(const size_t virtual_log_n, auto& transcript)
255 {
256 std::vector<Commitment> fold_commitments;
257 fold_commitments.reserve(virtual_log_n - 1);
258 for (size_t i = 1; i < virtual_log_n; ++i) {
259 const Commitment commitment =
260 transcript->template receive_from_prover<Commitment>("Gemini:FOLD_" + std::to_string(i));
261 fold_commitments.emplace_back(commitment);
262 }
263 return fold_commitments;
264 }
265
275 static std::vector<Fr> get_gemini_evaluations(const size_t virtual_log_n, auto& transcript)
276 {
277 std::vector<Fr> gemini_evaluations;
278 gemini_evaluations.reserve(virtual_log_n);
279
280 for (size_t i = 1; i <= virtual_log_n; ++i) {
281 const Fr evaluation = transcript->template receive_from_prover<Fr>("Gemini:a_" + std::to_string(i));
282 gemini_evaluations.emplace_back(evaluation);
283 }
284 return gemini_evaluations;
285 }
286
319 static std::vector<Fr> compute_fold_pos_evaluations(std::span<const Fr> padding_indicator_array,
320 const Fr& batched_evaluation,
321 std::span<const Fr> evaluation_point, // size = virtual_log_n
322 std::span<const Fr> challenge_powers, // size = virtual_log_n
323 std::span<const Fr> fold_neg_evals) // size = virtual_log_n
324 {
325 const size_t virtual_log_n = evaluation_point.size();
326
327 std::vector<Fr> evals(fold_neg_evals.begin(), fold_neg_evals.end());
328
329 Fr eval_pos_prev = batched_evaluation;
330
331 std::vector<Fr> fold_pos_evaluations;
332 fold_pos_evaluations.reserve(virtual_log_n);
333
334 // Solve the sequence of linear equations
335 for (size_t l = virtual_log_n; l != 0; --l) {
336 // Get r²⁽ˡ⁻¹⁾
337 const Fr& challenge_power = challenge_powers[l - 1];
338 // Get uₗ₋₁
339 const Fr& u = evaluation_point[l - 1];
340 // Get A₍ₗ₋₁₎(−r²⁽ˡ⁻¹⁾)
341 const Fr& eval_neg = evals[l - 1];
342 // Compute the numerator
343 Fr eval_pos = ((challenge_power * eval_pos_prev * 2) - eval_neg * (challenge_power * (Fr(1) - u) - u));
344 // Divide by the denominator
345 eval_pos *= (challenge_power * (Fr(1) - u) + u).invert();
346
347 // If current index is bigger than log_n, we propagate `batched_evaluation` to the next
348 // round. Otherwise, current `eval_pos` A₍ₗ₋₁₎(r²⁽ˡ⁻¹⁾) becomes `eval_pos_prev` in the round l-2.
349 eval_pos_prev =
350 padding_indicator_array[l - 1] * eval_pos + (Fr{ 1 } - padding_indicator_array[l - 1]) * eval_pos_prev;
351 // If current index is bigger than log_n, we emplace 0, which is later multiplied against
352 // Commitment::one().
353 fold_pos_evaluations.emplace_back(padding_indicator_array[l - 1] * eval_pos_prev);
354 }
355
356 std::reverse(fold_pos_evaluations.begin(), fold_pos_evaluations.end());
357
358 return fold_pos_evaluations;
359 }
360};
361
362} // namespace bb
#define BB_BENCH_NAME(name)
Definition bb_bench.hpp:225
CommitmentKey object over a pairing group 𝔾₁.
Class responsible for computation of the batched multilinear polynomials required by the Gemini proto...
Definition gemini.hpp:125
void set_to_be_shifted_by_one(RefVector< Polynomial > polynomials)
Definition gemini.hpp:149
PolynomialBatcher(const size_t full_batched_size, const size_t actual_data_size=0)
Definition gemini.hpp:137
void set_unshifted(RefVector< Polynomial > polynomials)
Definition gemini.hpp:148
Polynomial compute_batched(const Fr &challenge)
Compute batched polynomial A₀ = F + G/X as the linear combination of all polynomials to be opened,...
Definition gemini.hpp:159
RefVector< Polynomial > to_be_shifted_by_one
Definition gemini.hpp:135
std::pair< Polynomial, Polynomial > compute_partially_evaluated_batch_polynomials(const Fr &r_challenge)
Compute partially evaluated batched polynomials A₀(X, r) = A₀₊ = F + G/r, A₀(X, -r) = A₀₋ = F - G/r.
Definition gemini.hpp:194
RefVector< Polynomial > unshifted
Definition gemini.hpp:134
static std::vector< Claim > prove(size_t circuit_size, PolynomialBatcher &polynomial_batcher, std::span< Fr > multilinear_challenge, const CommitmentKey< Curve > &commitment_key, const std::shared_ptr< Transcript > &transcript, bool has_zk=false)
static std::vector< Claim > construct_univariate_opening_claims(const size_t log_n, Polynomial &&A_0_pos, Polynomial &&A_0_neg, std::vector< Polynomial > &&fold_polynomials, const Fr &r_challenge)
Computes/aggragates d+1 univariate polynomial opening claims of the form {polynomial,...
typename Curve::ScalarField Fr
Definition gemini.hpp:105
typename Curve::AffineElement Commitment
Definition gemini.hpp:106
static std::vector< Polynomial > compute_fold_polynomials(const size_t log_n, std::span< const Fr > multilinear_challenge, const Polynomial &A_0, const bool &has_zk=false)
Computes d-1 fold polynomials Fold_i, i = 1, ..., d-1.
Gemini Verifier utility methods used by ShpleminiVerifier.
Definition gemini.hpp:241
typename Curve::ScalarField Fr
Definition gemini.hpp:242
static std::vector< Fr > compute_fold_pos_evaluations(std::span< const Fr > padding_indicator_array, const Fr &batched_evaluation, std::span< const Fr > evaluation_point, std::span< const Fr > challenge_powers, std::span< const Fr > fold_neg_evals)
Compute .
Definition gemini.hpp:319
static std::vector< Commitment > get_fold_commitments(const size_t virtual_log_n, auto &transcript)
Receive the fold commitments from the prover. This method is used by Shplemini where padding may be e...
Definition gemini.hpp:254
static std::vector< Fr > get_gemini_evaluations(const size_t virtual_log_n, auto &transcript)
Receive the fold evaluations from the prover. This method is used by Shplemini where padding may be e...
Definition gemini.hpp:275
typename Curve::AffineElement Commitment
Definition gemini.hpp:243
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
Polynomial shifted() const
Returns a Polynomial the left-shift of self.
void add_scaled(PolynomialSpan< const Fr > other, const Fr &scaling_factor)
adds the polynomial q(X) 'other', multiplied by a scaling factor.
Polynomial p and an opening pair (r,v) such that p(r) = v.
Definition claim.hpp:36
A template class for a reference vector. Behaves as if std::vector<T&> was possible.
typename Group::affine_element AffineElement
Definition grumpkin.hpp:65
std::vector< Fr > powers_of_evaluation_challenge(const Fr &r, const size_t num_squares)
Compute squares of folding challenge r.
Definition gemini.hpp:93
std::vector< Fr > powers_of_rho(const Fr &rho, const size_t num_powers)
Compute powers of challenge ρ
Definition gemini.hpp:76
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
Curve::ScalarField Fr