Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
mock_witness_generator.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
8
16
17namespace bb {
23template <typename Curve> struct MockClaimGenerator {
24 public:
26 using Fr = typename Curve::ScalarField;
33
35
36 struct ClaimData {
38 std::vector<Commitment> commitments;
39 std::vector<Fr> evals;
40 };
41
44
46
49
50 // Containers for mock Sumcheck data
52 std::vector<Commitment> sumcheck_commitments;
54
62
74 MockClaimGenerator(const size_t poly_size,
75 const size_t num_polynomials,
76 const size_t num_to_be_shifted,
77 const std::vector<Fr>& mle_opening_point,
78 const CommitmentKey& commitment_key,
79 size_t num_interleaved = 0,
80 size_t num_to_be_interleaved = 0)
81
82 : ck(commitment_key) // Initialize the commitment key
83 , polynomial_batcher(poly_size)
84
85 {
86 size_t log_size = numeric::get_msb(poly_size);
87 // If the size of the opening point is bigger than the log of the poly size, we assume that the prover is
88 // extending all of its polynomials by zero outside of the hypercube of size 2^{log_size}.
89 bool has_virtual_rounds = (mle_opening_point.size() > log_size);
90
91 std::span<const Fr> challenge;
92
93 if (has_virtual_rounds) {
94 // The evaluation on the full domain can be obtain by scaling by extension-by-zero factor `ebz_factor`
95 // computed below.
96 challenge = std::span<const Fr>(mle_opening_point).subspan(0, log_size);
97 } else {
98 challenge = std::span<const Fr>(mle_opening_point);
99 }
100
101 BB_ASSERT_GTE(num_polynomials, num_to_be_shifted);
102 const size_t num_not_to_be_shifted = num_polynomials - num_to_be_shifted;
103
104 Fr ebz_factor = 1;
105
106 for (size_t idx = log_size; idx < mle_opening_point.size(); idx++) {
107 ebz_factor *= (Fr(1) - mle_opening_point[idx]);
108 }
109
110 // Construct claim data for polynomials that are NOT to be shifted
111 for (size_t idx = 0; idx < num_not_to_be_shifted; idx++) {
112 Polynomial poly = Polynomial::random(poly_size);
113 unshifted.commitments.push_back(ck.commit(poly));
114 unshifted.evals.push_back(poly.evaluate_mle(challenge) * ebz_factor);
115 unshifted.polys.push_back(std::move(poly));
116 }
117
118 // Construct claim data for polynomials that are to-be-shifted
119 for (size_t idx = 0; idx < num_to_be_shifted; idx++) {
120 Polynomial poly = Polynomial::random(poly_size, /*shiftable*/ 1);
121 Commitment commitment = ck.commit(poly);
122 to_be_shifted.commitments.push_back(commitment);
123 to_be_shifted.evals.push_back(poly.shifted().evaluate_mle(challenge) * ebz_factor);
124 to_be_shifted.polys.push_back(poly.share());
125 // Populate the unshifted counterpart in the unshifted claims
126 unshifted.commitments.push_back(commitment);
127 unshifted.evals.push_back(poly.evaluate_mle(challenge) * ebz_factor);
128 unshifted.polys.push_back(std::move(poly));
129 }
130
133
136 .shifted =
138 if (num_interleaved > 0) {
140 generate_interleaving_inputs(mle_opening_point, num_interleaved, num_to_be_interleaved, ck);
142 to_vector_of_ref_vectors(interleave_data.groups));
143
146 .evaluations = RefVector(interleave_data.evaluations) };
147 }
148 }
149
150 // Generate zero polynomials to test edge cases in PCS
151 MockClaimGenerator(const size_t n, const size_t num_zero_polynomials)
153 {
154 for (size_t idx = 0; idx < num_zero_polynomials; idx++) {
155 unshifted.polys.emplace_back(n);
156 unshifted.commitments.push_back(Commitment::infinity());
157 unshifted.evals.push_back(Fr(0));
158 }
159
161
164 }
165
166 // Generates mock claims by using the custom polynomials provided as input instead of random polynomials. Used for
167 // the high degree attack tests.
168 MockClaimGenerator(const size_t poly_size,
169 const std::vector<Polynomial> custom_unshifted,
170 const std::vector<Fr>& custom_unshifted_evals,
171 const CommitmentKey& commitment_key)
172
173 : ck(commitment_key)
174 , polynomial_batcher(poly_size)
175 {
176
177 // ---------- Unshifted ----------
178 for (size_t i = 0; i < custom_unshifted.size(); ++i) {
179 auto& p = custom_unshifted[i];
180 unshifted.commitments.push_back(ck.commit(p));
181 unshifted.evals.push_back(custom_unshifted_evals[i]);
182 unshifted.polys.push_back(std::move(p));
183 }
184
186
189 }
190
191 InterleaveData generate_interleaving_inputs(const std::vector<Fr>& u_challenge,
192 const size_t num_interleaved,
193 const size_t group_size,
194 const CommitmentKey& ck)
195 {
196
197 size_t N = 1 << u_challenge.size();
198 size_t MINI_CIRCUIT_N = N / group_size; // size of chunks
199
200 // Polynomials "chunks" that are interleaved in the PCS
202
203 // Concatenated polynomials
204 std::vector<Polynomial> interleaved_polynomials;
205
206 // Evaluations of interleaved polynomials
207 std::vector<Fr> c_evaluations;
208
209 // For each polynomial to be interleaved
210 for (size_t i = 0; i < num_interleaved; ++i) {
212 Polynomial interleaved_polynomial(N);
213 for (size_t j = 0; j < group_size; j++) {
214 Polynomial chunk_polynomial(N);
215 // Fill the chunk polynomial with random values and appropriately fill the space in
216 // interleaved_polynomial
217 for (size_t k = 0; k < MINI_CIRCUIT_N; k++) {
218 // Chunks should be shiftable
219 auto tmp = Fr(0);
220 if (k > 0) {
221 tmp = Fr::random_element();
222 }
223 chunk_polynomial.at(k) = tmp;
224 interleaved_polynomial.at(k * group_size + j) = tmp;
225 }
226 group.emplace_back(chunk_polynomial);
227 }
228 // Store chunks
229 groups.emplace_back(group);
230 // Store interleaved polynomial
231 interleaved_polynomials.emplace_back(interleaved_polynomial);
232 // Get evaluation
233 c_evaluations.emplace_back(interleaved_polynomial.evaluate_mle(u_challenge));
234 }
235
236 // Compute commitments of all polynomial chunks
237 std::vector<std::vector<Commitment>> groups_commitments;
238 for (size_t i = 0; i < num_interleaved; ++i) {
239 std::vector<Commitment> group_commitment;
240 for (size_t j = 0; j < group_size; j++) {
241 group_commitment.emplace_back(ck.commit(groups[i][j]));
242 }
243 groups_commitments.emplace_back(group_commitment);
244 }
245
246 return { groups, interleaved_polynomials, c_evaluations, groups_commitments };
247 }
248
249 template <typename Flavor>
250 void compute_sumcheck_opening_data(const size_t log_n,
251 const size_t sumcheck_univariate_length,
252 std::vector<Fr>& challenge,
253 const CommitmentKey& ck)
254 {
255 // Generate valid sumcheck polynomials of given length
256 auto mock_sumcheck_polynomials = ZKSumcheckData<Flavor>(log_n, sumcheck_univariate_length);
257
258 for (size_t idx = 0; idx < log_n; idx++) {
259 bb::Polynomial<Fr> round_univariate = mock_sumcheck_polynomials.libra_univariates[idx];
260
261 round_univariate.at(0) += mock_sumcheck_polynomials.libra_running_sum;
262
263 sumcheck_commitments.push_back(ck.commit(round_univariate));
264
265 sumcheck_evaluations.push_back({ round_univariate.at(0),
266 round_univariate.evaluate(Fr(1)),
267 round_univariate.evaluate(challenge[idx]) });
268
269 mock_sumcheck_polynomials.update_zk_sumcheck_data(challenge[idx], idx);
270 round_univariates.push_back(round_univariate);
271 }
272 }
273};
274
275} // namespace bb
#define BB_ASSERT_GTE(left, right,...)
Definition assert.hpp:122
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...
Definition gemini.hpp:126
void set_to_be_shifted_by_one(RefVector< Polynomial > polynomials)
Definition gemini.hpp:155
void set_interleaved(RefVector< Polynomial > results, std::vector< RefVector< Polynomial > > groups)
Definition gemini.hpp:157
void set_unshifted(RefVector< Polynomial > polynomials)
Definition gemini.hpp:154
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.
static Polynomial random(size_t size, size_t start_index=0)
Fr evaluate(const Fr &z, size_t target_size) const
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,...
Polynomial share() const
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 vector. Behaves as if std::vector<T&> was possible.
typename Group::affine_element AffineElement
Definition grumpkin.hpp:63
group class. Represents an elliptic curve group element. Group is parametrised by Fq and Fr
Definition group.hpp:36
constexpr T get_msb(const T in)
Definition get_msb.hpp:47
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::vector< RefVector< Commitment > > commitments_groups
Logic to support batching opening claims for unshifted and shifted polynomials in Shplemini.
std::optional< Batch > unshifted
std::optional< InterleavedBatch > interleaved
std::vector< std::vector< Polynomial > > groups
std::vector< std::vector< Commitment > > group_commitments
Constructs random polynomials, computes commitments and corresponding evaluations.
std::vector< bb::Polynomial< Fr > > round_univariates
std::vector< Fr > const_size_mle_opening_point
std::vector< Commitment > sumcheck_commitments
std::vector< std::array< Fr, 3 > > sumcheck_evaluations
typename Curve::AffineElement Commitment
InterleaveData generate_interleaving_inputs(const std::vector< Fr > &u_challenge, const size_t num_interleaved, const size_t group_size, const CommitmentKey &ck)
MockClaimGenerator(const size_t poly_size, const std::vector< Polynomial > custom_unshifted, const std::vector< Fr > &custom_unshifted_evals, const CommitmentKey &commitment_key)
MockClaimGenerator(const size_t poly_size, const size_t num_polynomials, const size_t num_to_be_shifted, const std::vector< Fr > &mle_opening_point, const CommitmentKey &commitment_key, size_t num_interleaved=0, size_t num_to_be_interleaved=0)
Construct claim data for a set of random polynomials with the specified type.
typename Curve::ScalarField Fr
MockClaimGenerator(const size_t n, const size_t num_zero_polynomials)
void compute_sumcheck_opening_data(const size_t log_n, const size_t sumcheck_univariate_length, std::vector< Fr > &challenge, const CommitmentKey &ck)
This structure is created to contain various polynomials and constants required by ZK Sumcheck.
static field random_element(numeric::RNG *engine=nullptr) noexcept