48template <
typename Curve>
49template <
typename Transcript>
55 const std::shared_ptr<Transcript>& transcript,
59 const size_t virtual_log_n = multilinear_challenge.size();
61 const size_t n = 1 << log_n;
65 Polynomial random_polynomial = Polynomial::random(n);
66 transcript->send_to_verifier(
"Gemini:masking_poly_comm", commitment_key.
commit(random_polynomial));
69 transcript->send_to_verifier(
"Gemini:masking_poly_eval",
70 random_polynomial.
evaluate_mle(multilinear_challenge.subspan(0, log_n)));
76 const Fr rho = transcript->template get_challenge<Fr>(
"rho");
78 Fr running_scalar = has_zk ? rho : 1;
86 for (
size_t l = 0; l < virtual_log_n - 1; l++) {
89 transcript->send_to_verifier(label, commitment_key.
commit(fold_polynomials[l]));
91 const Fr r_challenge = transcript->template get_challenge<Fr>(
"Gemini:r");
93 const bool gemini_challenge_in_small_subgroup = (has_zk) && (r_challenge.pow(
Curve::SUBGROUP_SIZE) ==
Fr(1));
98 if (gemini_challenge_in_small_subgroup) {
99 throw_or_abort(
"Gemini evaluation challenge is in the SmallSubgroup.");
108 for (
size_t l = 1; l <= virtual_log_n; l++) {
110 transcript->send_to_verifier(label, claims[l].opening_pair.evaluation);
120 Fr P_pos_eval = P_pos.evaluate(r_pow);
121 Fr P_neg_eval = P_neg.evaluate(r_pow);
122 claims.emplace_back(
Claim{
std::move(P_pos), { r_pow, P_pos_eval } });
123 transcript->send_to_verifier(
"Gemini:P_pos", P_pos_eval);
124 claims.emplace_back(
Claim{
std::move(P_neg), { r_pow, P_neg_eval } });
125 transcript->send_to_verifier(
"Gemini:P_neg", P_neg_eval);
138template <
typename Curve>
144 const size_t virtual_log_n = multilinear_challenge.size();
146 constexpr size_t efficient_operations_per_thread = 64;
151 fold_polynomials.reserve(virtual_log_n - 1);
152 for (
size_t l = 0; l < log_n - 1; ++l) {
154 const size_t n_l = 1 << (log_n - l - 1);
157 fold_polynomials.emplace_back(
Polynomial(n_l));
163 auto A_l = A_0.
data();
164 for (
size_t l = 0; l < log_n - 1; ++l) {
166 const size_t n_l = 1 << (log_n - l - 1);
170 size_t num_used_threads = std::min(n_l / efficient_operations_per_thread, num_threads);
171 num_used_threads = num_used_threads ? num_used_threads : 1;
172 size_t chunk_size = n_l / num_used_threads;
173 size_t last_chunk_size = (n_l % chunk_size) ? (n_l % num_used_threads) : chunk_size;
176 const Fr u_l = multilinear_challenge[l];
179 auto A_l_fold = fold_polynomials[l].data();
182 size_t current_chunk_size = (i == (num_used_threads - 1)) ? last_chunk_size : chunk_size;
189 A_l_fold[j] = A_l[j << 1] + u_l * (A_l[(j << 1) + 1] - A_l[j << 1]);
200 const auto& last = fold_polynomials.back();
201 const Fr u_last = multilinear_challenge[log_n - 1];
202 const Fr final_eval = last.at(0) + u_last * (last.at(1) - last.at(0));
206 const_fold.at(0) = final_eval *
Fr(
static_cast<int>(!has_zk));
207 fold_polynomials.emplace_back(const_fold);
211 for (
size_t k = log_n; k < virtual_log_n - 1; ++k) {
212 tail *= (
Fr(1) - multilinear_challenge[k]);
214 next_const.
at(0) = final_eval * tail *
Fr(
static_cast<int>(!has_zk));
215 fold_polynomials.emplace_back(next_const);
218 return fold_polynomials;
242template <
typename Curve>
248 const Fr& r_challenge)
253 Fr a_0_pos = A_0_pos.evaluate(r_challenge);
254 claims.emplace_back(
Claim{
std::move(A_0_pos), { r_challenge, a_0_pos } });
256 Fr a_0_neg = A_0_neg.evaluate(-r_challenge);
257 claims.emplace_back(
Claim{
std::move(A_0_neg), { -r_challenge, a_0_neg } });
264 const bool gemini_fold =
true;
267 for (
size_t l = 0; l < log_n - 1; ++l) {
268 Fr evaluation = fold_polynomials[l].evaluate(-r_squares[l + 1]);
269 claims.emplace_back(
Claim{
std::move(fold_polynomials[l]), { -r_squares[l + 1], evaluation }, gemini_fold });
CommitmentKey object over a pairing group 𝔾₁.
Commitment commit(PolynomialSpan< const Fr > polynomial) const
Uses the ProverSRS to create a commitment to p(X)
Class responsible for computation of the batched multilinear polynomials required by the Gemini proto...
std::pair< Polynomial, Polynomial > compute_partially_evaluated_interleaved_polynomial(const Fr &r_challenge)
Compute the partially evaluated polynomials P₊(X, r) and P₋(X, -r)
void set_random_polynomial(Polynomial &&random)
Polynomial compute_batched(const Fr &challenge, Fr &running_scalar)
Compute batched polynomial A₀ = F + G/X as the linear combination of all polynomials to be opened.
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.
bool has_interleaved() const
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
static std::vector< Claim > prove(const Fr 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< 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.
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
Fr evaluate_mle(std::span< const Fr > evaluation_points, bool shift=false) const
evaluate multi-linear extension p(X_0,…,X_{n-1}) = \sum_i a_i*L_i(X_0,…,X_{n-1}) at u = (u_0,...
Fr & at(size_t index)
Our mutable accessor, unlike operator[]. We abuse precedent a bit to differentiate at() and operator[...
Polynomial p and an opening pair (r,v) such that p(r) = v.
static constexpr size_t SUBGROUP_SIZE
std::vector< Fr > powers_of_evaluation_challenge(const Fr r, const size_t num_squares)
Compute squares of folding challenge r.
constexpr T get_msb(const T in)
Entry point for Barretenberg command-line interface.
size_t get_num_cpus_pow2()
void parallel_for(size_t num_iterations, const std::function< void(size_t)> &func)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
void throw_or_abort(std::string const &err)