4#include "barretenberg/polynomials/polynomial.hpp"
5#include "barretenberg/transcript/transcript.hpp"
61 std::vector<OpeningPair<Curve>> opening_pairs;
62 std::vector<barretenberg::Polynomial<typename Curve::ScalarField>> witnesses;
73template <
class Fr>
inline std::vector<Fr>
powers_of_rho(
const Fr rho,
const size_t num_powers)
75 std::vector<Fr> rhos = {
Fr(1), rho };
76 rhos.reserve(num_powers);
77 for (
size_t j = 2; j < num_powers; j++) {
78 rhos.emplace_back(rhos[j - 1] * rho);
90template <
class Fr>
inline std::vector<Fr>
squares_of_r(
const Fr r,
const size_t num_squares)
92 std::vector<Fr> squares = { r };
93 squares.reserve(num_squares);
94 for (
size_t j = 1; j < num_squares; j++) {
95 squares.emplace_back(squares[j - 1].sqr());
101 using Fr =
typename Curve::ScalarField;
110 std::vector<Polynomial>&& gemini_polynomials,
111 const Fr& r_challenge);
115 using Fr =
typename Curve::ScalarField;
116 using GroupElement =
typename Curve::Element;
117 using Commitment =
typename Curve::AffineElement;
133 const Fr batched_evaluation,
134 GroupElement& batched_f,
135 GroupElement& batched_g,
138 const size_t num_variables = mle_opening_point.size();
141 std::vector<Commitment> commitments;
142 commitments.reserve(num_variables - 1);
143 for (
size_t i = 0; i < num_variables - 1; ++i) {
145 transcript->template receive_from_prover<Commitment>(
"Gemini:FOLD_" + std::to_string(i + 1));
146 commitments.emplace_back(commitment);
150 const Fr r = transcript->get_challenge(
"Gemini:r");
151 std::vector<Fr> r_squares =
squares_of_r(r, num_variables);
154 std::vector<Fr> evaluations;
155 evaluations.reserve(num_variables);
156 for (
size_t i = 0; i < num_variables; ++i) {
157 auto eval = transcript->template receive_from_prover<Fr>(
"Gemini:a_" + std::to_string(i));
158 evaluations.emplace_back(eval);
162 auto a_0_pos = compute_eval_pos(batched_evaluation, mle_opening_point, r_squares, evaluations);
166 auto [c0_r_pos, c0_r_neg] = compute_simulated_commitments(batched_f, batched_g, r);
168 std::vector<OpeningClaim<Curve>> fold_polynomial_opening_claims;
169 fold_polynomial_opening_claims.reserve(num_variables + 1);
172 fold_polynomial_opening_claims.emplace_back(
OpeningClaim<Curve>{ { r, a_0_pos }, c0_r_pos });
174 fold_polynomial_opening_claims.emplace_back(
OpeningClaim<Curve>{ { -r, evaluations[0] }, c0_r_neg });
175 for (
size_t l = 0; l < num_variables - 1; ++l) {
177 fold_polynomial_opening_claims.emplace_back(
181 return fold_polynomial_opening_claims;
194 static Fr compute_eval_pos(
const Fr batched_mle_eval,
195 std::span<const Fr> mle_vars,
196 std::span<const Fr> r_squares,
197 std::span<const Fr> fold_polynomial_evals)
199 const size_t num_variables = mle_vars.size();
201 const auto& evals = fold_polynomial_evals;
204 Fr eval_pos = batched_mle_eval;
205 for (
size_t l = num_variables; l != 0; --l) {
206 const Fr r = r_squares[l - 1];
207 const Fr eval_neg = evals[l - 1];
208 const Fr u = mle_vars[l - 1];
216 eval_pos = ((r * eval_pos * 2) - eval_neg * (r * (
Fr(1) - u) - u)) / (r * (
Fr(1) - u) + u);
230 static std::pair<GroupElement, GroupElement> compute_simulated_commitments(GroupElement& batched_f,
231 GroupElement& batched_g,
235 GroupElement C0_r_pos;
237 GroupElement C0_r_neg;
238 Fr r_inv = r.invert();
243 if constexpr (Curve::is_stdlib_type) {
244 std::vector<GroupElement> commitments = { batched_f, batched_g };
245 auto builder = r.get_context();
246 auto one =
Fr(builder, 1);
250 C0_r_pos = GroupElement::batch_mul(commitments, { one, r_inv });
251 C0_r_neg = GroupElement::batch_mul(commitments, { one, -r_inv });
253 C0_r_pos = batched_f;
254 C0_r_neg = batched_f;
255 if (!batched_g.is_point_at_infinity()) {
256 batched_g = batched_g * r_inv;
257 C0_r_pos += batched_g;
258 C0_r_neg -= batched_g;
262 return { C0_r_pos, C0_r_neg };
Definition: polynomial.hpp:12
Unverified claim (C,r,v) for some witness polynomial p(X) such that.
Definition: claim.hpp:43
Definition: gemini.hpp:100
static ProverOutput< Curve > compute_fold_polynomial_evaluations(std::span< const Fr > mle_opening_point, std::vector< Polynomial > &&gemini_polynomials, const Fr &r_challenge)
Computes/aggragates d+1 Fold polynomials and their opening pairs (challenge, evaluation)
Definition: gemini.cpp:146
static std::vector< Polynomial > compute_gemini_polynomials(std::span< const Fr > mle_opening_point, Polynomial &&batched_unshifted, Polynomial &&batched_to_be_shifted)
Computes d-1 fold polynomials Fold_i, i = 1, ..., d-1.
Definition: gemini.cpp:57
Definition: gemini.hpp:114
static std::vector< OpeningClaim< Curve > > reduce_verification(std::span< const Fr > mle_opening_point, const Fr batched_evaluation, GroupElement &batched_f, GroupElement &batched_g, auto &transcript)
Returns univariate opening claims for the Fold polynomials to be checked later.
Definition: gemini.hpp:132
Protocol for opening several multi-linear polynomials at the same point.
Definition: gemini.cpp:45
std::vector< Fr > powers_of_rho(const Fr rho, const size_t num_powers)
Compute powers of challenge ρ
Definition: gemini.hpp:73
std::vector< Fr > squares_of_r(const Fr r, const size_t num_squares)
Compute squares of folding challenge r.
Definition: gemini.hpp:90
Prover output (evalutation pair, witness) that can be passed on to Shplonk batch opening.
Definition: gemini.hpp:60