Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
shplemini_concatenated.test.cpp
Go to the documentation of this file.
1
14#include "../gemini/gemini.hpp"
15#include "../kzg/kzg.hpp"
16#include "../pcs_test_utils.hpp"
20#include "shplemini.hpp"
21
22#include <gtest/gtest.h>
23
24namespace bb {
25
26class ShpleminiConcatenatedTest : public CommitmentTest<curve::BN254> {
27 public:
34
35 static constexpr size_t mini_log_n = 8; // log of minicircuit size
36 static constexpr size_t MINI = 1UL << mini_log_n; // minicircuit size (256)
37 static constexpr size_t CONCATENATION_GROUP_SIZE = 16; // number of wires per group
38 static constexpr size_t log_n = mini_log_n + 4; // log of concatenated size (8 + 4 = 12)
39 static constexpr size_t n = 1UL << log_n; // concatenated size (4096)
40 static constexpr size_t k = 4; // log₂(CONCATENATION_GROUP_SIZE) = extra challenges for concatenation
41
46 {
48 for (size_t j = 0; j < CONCATENATION_GROUP_SIZE; ++j) {
49 polys[j] = Polynomial(MINI - 1, n, 1);
50 for (size_t idx = 1; idx < MINI; ++idx) {
51 polys[j].at(idx) = Fr::random_element();
52 }
53 }
54 return polys;
55 }
56
61 {
62 Polynomial concatenated(n - 1, n, 1);
63 for (size_t j = 0; j < CONCATENATION_GROUP_SIZE; ++j) {
64 for (size_t idx = 1; idx < MINI; ++idx) {
65 concatenated.at(j * MINI + idx) = polys[j][idx];
66 }
67 }
68 return concatenated;
69 }
70
75 Fr compute_batched_evaluation(const std::vector<Fr>& challenge,
76 const std::array<Fr, CONCATENATION_GROUP_SIZE>& individual_evals)
77 {
78 Fr padding = Fr::one();
79 for (size_t i = 0; i < k; ++i) {
80 padding *= (Fr::one() - challenge[log_n - k + i]);
81 }
82
83 Fr result = Fr::zero();
84 for (size_t j = 0; j < CONCATENATION_GROUP_SIZE; ++j) {
85 Fr lagrange_j = Fr::one();
86 for (size_t bit = 0; bit < k; ++bit) {
87 bool bit_set = (j >> bit) & 1;
88 lagrange_j *= bit_set ? challenge[log_n - k + bit] : (Fr::one() - challenge[log_n - k + bit]);
89 }
90 result += lagrange_j * individual_evals[j];
91 }
92 return result * padding.invert();
93 }
94
100 const Polynomial& concat_poly,
101 const std::vector<Fr>& challenge)
102 {
105
106 for (size_t j = 0; j < CONCATENATION_GROUP_SIZE; ++j) {
107 wire_evals[j] = wires[j].evaluate_mle(challenge);
108 wire_shift_evals[j] = wires[j].shifted().evaluate_mle(challenge);
109 }
110
111 Fr batched_unshifted = compute_batched_evaluation(challenge, wire_evals);
112 Fr batched_shifted = compute_batched_evaluation(challenge, wire_shift_evals);
113
114 EXPECT_EQ(batched_unshifted, concat_poly.evaluate_mle(challenge));
115 EXPECT_EQ(batched_shifted, concat_poly.shifted().evaluate_mle(challenge));
116
117 return { batched_unshifted, batched_shifted };
118 }
119
123 template <size_t N>
125 std::array<Commitment, N>& commitments,
126 std::array<Fr, N>& unshifted_evals,
127 std::array<Fr, N>& shifted_evals,
128 std::vector<Fr>& challenge)
129 {
130 CK ck(n);
131
132 // --- Prover ---
133 auto prover_transcript = NativeTranscript::test_prover_init_empty();
134
135 using PolynomialBatcher = GeminiProver_<Curve>::PolynomialBatcher;
136 PolynomialBatcher polynomial_batcher(n);
137
138 std::vector<Polynomial> polys_vec(concat_polys.begin(), concat_polys.end());
139 polynomial_batcher.set_unshifted(RefVector<Polynomial>(polys_vec));
140 polynomial_batcher.set_to_be_shifted_by_one(RefVector<Polynomial>(polys_vec));
141
142 auto prover_opening_claim =
143 ShpleminiProver_<Curve>::prove(n, polynomial_batcher, challenge, ck, prover_transcript);
144 KZG<Curve>::compute_opening_proof(ck, prover_opening_claim, prover_transcript);
145
146 // --- Verifier ---
147 auto verifier_transcript = NativeTranscript::test_verifier_init_empty(prover_transcript);
148
149 using ClaimBatcher = ClaimBatcher_<Curve>;
150 using ClaimBatch = ClaimBatcher::Batch;
151
152 ClaimBatcher claim_batcher{
153 .unshifted = ClaimBatch{ RefArray<Commitment, N>(commitments), RefArray<Fr, N>(unshifted_evals) },
154 .shifted = ClaimBatch{ RefArray<Commitment, N>(commitments), RefArray<Fr, N>(shifted_evals) }
155 };
156
157 std::vector<Fr> padding_indicator(challenge.size(), Fr{ 1 });
158
160 padding_indicator, claim_batcher, challenge, Commitment::one(), verifier_transcript);
161
163 std::move(shplemini_output.batch_opening_claim), verifier_transcript);
164
165 return pairing_points.check();
166 }
167};
168
170{
171 auto wires = create_minicircuit_polynomials();
172 std::array<Polynomial, 1> concat_polys = { concatenate_polynomials(wires) };
173
174 CK ck(n);
175 std::array<Commitment, 1> commitments = { ck.commit(concat_polys[0]) };
176
177 std::vector<Fr> challenge(log_n);
178 for (auto& u : challenge) {
179 u = Fr::random_element();
180 }
181
182 auto [unshifted, shifted] = evaluate_concatenation_group(wires, concat_polys[0], challenge);
183 std::array<Fr, 1> unshifted_evals = { unshifted };
184 std::array<Fr, 1> shifted_evals = { shifted };
185
186 EXPECT_TRUE(prove_and_verify(concat_polys, commitments, unshifted_evals, shifted_evals, challenge));
187}
188
190{
191 constexpr size_t NUM_GROUPS = 5;
192
193 CK ck(n);
194
198
199 for (size_t g = 0; g < NUM_GROUPS; ++g) {
200 all_groups[g] = create_minicircuit_polynomials();
201 concat_polys[g] = concatenate_polynomials(all_groups[g]);
202 commitments[g] = ck.commit(concat_polys[g]);
203 }
204
205 std::vector<Fr> challenge(log_n);
206 for (auto& u : challenge) {
207 u = Fr::random_element();
208 }
209
210 std::array<Fr, NUM_GROUPS> unshifted_evals;
211 std::array<Fr, NUM_GROUPS> shifted_evals;
212
213 for (size_t g = 0; g < NUM_GROUPS; ++g) {
214 auto [u, s] = evaluate_concatenation_group(all_groups[g], concat_polys[g], challenge);
215 unshifted_evals[g] = u;
216 shifted_evals[g] = s;
217 }
218
219 EXPECT_TRUE(prove_and_verify(concat_polys, commitments, unshifted_evals, shifted_evals, challenge));
220}
221
222} // namespace bb
static std::shared_ptr< BaseTranscript > test_prover_init_empty()
For testing: initializes transcript with some arbitrary data so that a challenge can be generated aft...
static std::shared_ptr< BaseTranscript > test_verifier_init_empty(const std::shared_ptr< BaseTranscript > &transcript)
For testing: initializes transcript based on proof data then receives junk data produced by BaseTrans...
CommitmentKey object over a pairing group 𝔾₁.
Class responsible for computation of the batched multilinear polynomials required by the Gemini proto...
Definition gemini.hpp:125
static PairingPointsType reduce_verify_batch_opening_claim(BatchOpeningClaim< Curve > &&batch_opening_claim, const std::shared_ptr< Transcript > &transcript, const size_t expected_final_msm_size=0)
Computes the input points for the pairing check needed to verify a KZG opening claim obtained from a ...
Definition kzg.hpp:126
static void compute_opening_proof(const CK &ck, const ProverOpeningClaim< Curve > &opening_claim, const std::shared_ptr< Transcript > &prover_trancript)
Computes the KZG commitment to an opening proof polynomial at a single evaluation point.
Definition kzg.hpp:42
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.
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[...
A template class for a reference array. Behaves as if std::array<T&, N> was possible.
Definition ref_array.hpp:22
A template class for a reference vector. Behaves as if std::vector<T&> was possible.
bool prove_and_verify(std::array< Polynomial, N > &concat_polys, std::array< Commitment, N > &commitments, std::array< Fr, N > &unshifted_evals, std::array< Fr, N > &shifted_evals, std::vector< Fr > &challenge)
Run Shplemini prove-and-verify for N concatenated polynomials (unshifted + shifted).
std::array< Polynomial, CONCATENATION_GROUP_SIZE > create_minicircuit_polynomials()
Create 16 minicircuit-sized random polynomials with values in [1, MINI)
Fr compute_batched_evaluation(const std::vector< Fr > &challenge, const std::array< Fr, CONCATENATION_GROUP_SIZE > &individual_evals)
Compute batched evaluation = [1/L₀(u_top)] * Σⱼ Lⱼ(u_top) * eval_j.
std::pair< Fr, Fr > evaluate_concatenation_group(const std::array< Polynomial, CONCATENATION_GROUP_SIZE > &wires, const Polynomial &concat_poly, const std::vector< Fr > &challenge)
Compute batched evaluations (unshifted + shifted) for a group of wires at a challenge point,...
Polynomial concatenate_polynomials(const std::array< Polynomial, CONCATENATION_GROUP_SIZE > &polys)
Concatenate 16 minicircuit polynomials: concat[j*MINI + idx] = wire[j][idx].
static OpeningClaim prove(size_t circuit_size, PolynomialBatcher &polynomial_batcher, std::span< FF > multilinear_challenge, const CommitmentKey< Curve > &commitment_key, const std::shared_ptr< Transcript > &transcript, const std::array< Polynomial, NUM_SMALL_IPA_EVALUATIONS > &libra_polynomials={}, const std::vector< Polynomial > &sumcheck_round_univariates={}, const std::vector< std::array< FF, 3 > > &sumcheck_round_evaluations={})
Definition shplemini.hpp:36
static ShpleminiVerifierOutput compute_batch_opening_claim(std::span< const Fr > padding_indicator_array, ClaimBatcher &claim_batcher, const std::vector< Fr > &multivariate_challenge, const Commitment &g1_identity, const std::shared_ptr< Transcript > &transcript, const RepeatedCommitmentsData &repeated_commitments={}, const std::array< Commitment, NUM_LIBRA_COMMITMENTS > &libra_commitments={}, const Fr &libra_univariate_evaluation=Fr{ 0 }, const std::vector< Commitment > &sumcheck_round_commitments={}, const std::vector< std::array< Fr, 3 > > &sumcheck_round_evaluations={})
This method receives commitments to all prover polynomials, their claimed evaluations,...
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
typename Group::affine_element AffineElement
Definition bn254.hpp:22
bb::fr ScalarField
Definition bn254.hpp:18
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:155
CommitmentKey< Curve > ck
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Logic to support batching opening claims for unshifted and shifted polynomials in Shplemini.
std::optional< Batch > unshifted
static constexpr field one()
constexpr field invert() const noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()