Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
eccvm_flavor.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Raju], commit: 2a49eb6 }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
32
33// NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members)
34
35namespace bb {
36
38 public:
42 using G1 = typename Curve::Group;
43 using FF = typename Curve::ScalarField;
44 using BF = typename Curve::BaseField;
46 using GroupElement = typename G1::element;
47 using Commitment = typename G1::affine_element;
51 using Codec = FrCodec;
55
56 // indicates when evaluating sumcheck, edges must be extended to be MAX_PARTIAL_RELATION_LENGTH
57 static constexpr bool USE_SHORT_MONOMIALS = false;
58
59 // Indicates that this flavor runs with ZK Sumcheck.
60 static constexpr bool HasZK = true;
61 // The number of rows reserved at the top of the execution trace for row-disabling / ZK masking.
62 static constexpr size_t TRACE_OFFSET = NUM_DISABLED_ROWS_IN_SUMCHECK;
63 // ECCVM proof size and its recursive verifier circuit are genuinely fixed, hence no padding is needed.
64 static constexpr bool USE_PADDING = false;
65 // Fixed size of the ECCVM circuits used in Chonk
66 // Important: these constants cannot be arbitrarily changes - please consult with a member of the Crypto team if
67 // they become too small.
68 static constexpr size_t ECCVM_FIXED_SIZE = 1UL << CONST_ECCVM_LOG_N;
69
70 static constexpr size_t NUM_WIRES = 85;
71
72 // The number of entities added for ZK (gemini_masking_poly)
73 static constexpr size_t NUM_MASKING_POLYNOMIALS = 1;
74
75 // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often
76 // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`.
77 // Note: this number does not include the individual sorted list polynomials.
78 // Includes gemini_masking_poly for ZK (NUM_ALL_ENTITIES = 117 + NUM_MASKING_POLYNOMIALS)
79 static constexpr size_t NUM_ALL_ENTITIES = 118;
80 // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying
81 // assignment of witnesses. We again choose a neutral name.
82 static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 4;
83 // The total number of witness entities not including shifts.
84 // Includes gemini_masking_poly for ZK (NUM_WITNESS_ENTITIES = 86 + NUM_MASKING_POLYNOMIALS)
85 static constexpr size_t NUM_WITNESS_ENTITIES = 87;
86 // The number of entities in ShiftedEntities.
87 static constexpr size_t NUM_SHIFTED_ENTITIES = 26;
88 // The number of entities in DerivedWitnessEntities that are not going to be shifted.
89 static constexpr size_t NUM_DERIVED_WITNESS_ENTITIES_NON_SHIFTED = 1;
90 // Indices into the Shplemini commitments vector that identify which "to-be-shifted" witness commitments in the
91 // unshifted block are duplicated in the shifted block, so their scalar muls can be merged.
92 //
93 // Shplemini's remove_repeated_commitments uses offset = HasZK ? 2 : 1. For ECCVM (HasZK=true), offset=2
94 // accounts for the Shplonk:Q commitment and the gemini_masking_poly that precede the Precomputed+Witness
95 // block in the commitments vector. The indices below are therefore relative to the start of
96 // {PrecomputedEntities + WitnessEntities} (i.e. they exclude MaskingEntities, which is covered by the offset).
97 //
98 // original_start: index of the first to-be-shifted entity within {Precomputed + Witness}
99 // = NUM_PRECOMPUTED + NUM_WIRE_NON_SHIFTED (= NUM_WITNESS - NUM_DERIVED_NON_SHIFTED - NUM_SHIFTED)
100 // duplicate_start: index where the shifted copies begin = NUM_PRECOMPUTED + NUM_WITNESS
101 static constexpr size_t NUM_WIRE_NON_SHIFTED =
107
108 // Pin entity counts and REPEATED_COMMITMENTS indices so that any layout change triggers a compile error.
109 // The to-be-shifted witnesses must form a contiguous block starting at NUM_WIRE_NON_SHIFTED within WitnessEntities.
110 static_assert(NUM_WIRE_NON_SHIFTED == 60, "WireNonShiftedEntities size changed — update REPEATED_COMMITMENTS");
111 static_assert(NUM_MASKING_POLYNOMIALS == 1, "MaskingEntities size changed — review REPEATED_COMMITMENTS offset");
112 static_assert(REPEATED_COMMITMENTS.first.original_start == 64,
113 "REPEATED_COMMITMENTS original_start changed — verify Shplemini offset convention");
114 static_assert(REPEATED_COMMITMENTS.first.duplicate_start == 91,
115 "REPEATED_COMMITMENTS duplicate_start changed — verify Shplemini offset convention");
116 static_assert(REPEATED_COMMITMENTS.first.count == 26, "REPEATED_COMMITMENTS count changed");
117
119 // define the tuple of Relations that comprise the Sumcheck relation
120 template <typename FF>
130
131 static constexpr size_t NUM_SUBRELATIONS = compute_number_of_subrelations<Relations>();
132 using SubrelationSeparators = std::array<FF, NUM_SUBRELATIONS - 1>;
133
134 static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length<Relations>();
135
136 // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta`
137 // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation
138 // length = 3.
139 // The degree has to be further increased by 1 because the relation is multiplied by the Row Disabling //
140 // Polynomial
142 static constexpr size_t NUM_RELATIONS = std::tuple_size<Relations>::value;
143
144 static constexpr size_t num_frs_comm = FrCodec::calc_num_fields<Commitment>();
145 static constexpr size_t num_frs_fq = FrCodec::calc_num_fields<FF>();
146
147 // Proof length formula
148 static constexpr size_t PROOF_LENGTH =
149 /* 1. NUM_WITNESS_ENTITIES commitments */ ((NUM_WITNESS_ENTITIES + NUM_MASKING_POLYNOMIALS) * num_frs_comm) +
150 /* 2. Libra concatenation commitment*/ (num_frs_comm) +
151 /* 3. Libra sum */ (num_frs_fq) +
152 /* 4. CONST_ECCVM_LOG_N sumcheck univariates commitments */
153 (CONST_ECCVM_LOG_N * num_frs_comm) +
154 /* 5. 2 * CONST_ECCVM_LOG_N sumcheck univariate evaluations */
155 (2 * CONST_ECCVM_LOG_N * num_frs_fq) +
156 /* 6. NUM_ALL_ENTITIES sumcheck evaluations*/ (NUM_ALL_ENTITIES * num_frs_fq) +
157 /* 7. Libra claimed evaluation */ (num_frs_fq) +
158 /* 8. Libra grand sum commitment */ (num_frs_comm) +
159 /* 9. Libra quotient commitment */ (num_frs_comm) +
160 /* 10. CONST_ECCVM_LOG_N - 1 Gemini Fold commitments */
161 ((CONST_ECCVM_LOG_N - 1) * num_frs_comm) +
162 /* 11. CONST_ECCVM_LOG_N Gemini a evaluations */
163 (CONST_ECCVM_LOG_N * num_frs_fq) +
164 /* 12. NUM_SMALL_IPA_EVALUATIONS libra evals */ (NUM_SMALL_IPA_EVALUATIONS * num_frs_fq) +
165 /* 13. Shplonk Q commitment */ (num_frs_comm) +
166 /* 14. Translator concatenated masking term commitment */ (num_frs_comm) +
167 /* 15 Translator op evaluation */ (num_frs_fq) +
168 /* 16 Translator Px evaluation */ (num_frs_fq) +
169 /* 17 Translator Py evaluation */ (num_frs_fq) +
170 /* 18 Translator z1 evaluation */ (num_frs_fq) +
171 /* 19 Translator z2 evaluation */ (num_frs_fq) +
172 /* 20 Translator concatenated masking term evaluation */ (num_frs_fq) +
173 /* 21 Translator grand sum commitment */ (num_frs_comm) +
174 /* 22 Translator quotient commitment */ (num_frs_comm) +
175 /* 23 Translator concatenation eval */ (num_frs_fq) +
176 /* 24 Translator grand sum shift eval */ (num_frs_fq) +
177 /* 25 Translator grand sum eval */ (num_frs_fq) +
178 /* 26 Translator quotient eval */ (num_frs_fq) +
179 /* 27 Shplonk Q commitment */ (num_frs_comm);
180
181 // The sub-protocol `compute_translation_opening_claims` outputs an opening claim for the batched univariate
182 // evaluation of `op`, `Px`, `Py`, `z1`, and `z2`, and an array of opening claims for the evaluations of the
183 // SmallSubgroupIPA witness polynomials.
184 static constexpr size_t NUM_TRANSLATION_OPENING_CLAIMS = NUM_SMALL_IPA_EVALUATIONS + 1;
185
186 // TODO(https://github.com/AztecProtocol/barretenberg/issues/989): refine access specifiers in flavors, this is
187 // public as it is also used in the recursive flavor but the two could possibly me unified eventually
192 template <typename DataType_> class PrecomputedEntities {
193 public:
194 bool operator==(const PrecomputedEntities& other) const = default;
195 using DataType = DataType_;
197 lagrange_first, // column 0
198 lagrange_second, // column 1 - hiding op row
199 lagrange_third, // column 2 - first real op row
200 lagrange_last); // column 3
201
202 DataType get_selectors() { return get_all(); };
203 };
204
209 template <typename DataType> struct DerivedWitnessEntities {
211 z_perm, // column 0
212 lookup_inverses); // column 1
213 };
214 template <typename DataType> class WireNonShiftedEntities {
215 public:
216 DEFINE_FLAVOR_MEMBERS(DataType,
217 transcript_add, // column 0
218 transcript_eq, // column 1
219 transcript_msm_transition, // column 2
220 transcript_Px, // column 3
221 transcript_Py, // column 4
222 transcript_z1, // column 5
223 transcript_z2, // column 6
224 transcript_z1zero, // column 7
225 transcript_z2zero, // column 8
226 transcript_op, // column 9
227 transcript_msm_x, // column 10
228 transcript_msm_y, // column 11
229 precompute_point_transition, // column 12
230 precompute_s1lo, // column 13
231 precompute_s2hi, // column 14
232 precompute_s2lo, // column 15
233 precompute_s3hi, // column 16
234 precompute_s3lo, // column 17
235 precompute_s4hi, // column 18
236 precompute_s4lo, // column 19
237 precompute_skew, // column 20
238 msm_size_of_msm, // column 21
239 msm_add2, // column 22
240 msm_add3, // column 23
241 msm_add4, // column 24
242 msm_x1, // column 25
243 msm_y1, // column 26
244 msm_x2, // column 27
245 msm_y2, // column 28
246 msm_x3, // column 29
247 msm_y3, // column 30
248 msm_x4, // column 31
249 msm_y4, // column 32
250 msm_collision_x1, // column 33
251 msm_collision_x2, // column 34
252 msm_collision_x3, // column 35
253 msm_collision_x4, // column 36
254 msm_lambda1, // column 37
255 msm_lambda2, // column 38
256 msm_lambda3, // column 39
257 msm_lambda4, // column 40
258 msm_slice1, // column 41
259 msm_slice2, // column 42
260 msm_slice3, // column 43
261 msm_slice4, // column 44
262 transcript_reset_accumulator, // column 45
263 lookup_read_counts_0, // column 46
264 lookup_read_counts_1, // column 47
265 transcript_base_infinity, // column 48
266 transcript_base_x_inverse, // column 49
267 transcript_base_y_inverse, // column 50
268 transcript_add_x_equal, // column 51
269 transcript_add_y_equal, // column 52
270 transcript_add_lambda, // column 53
271 transcript_msm_intermediate_x, // column 54
272 transcript_msm_intermediate_y, // column 55
273 transcript_msm_infinity, // column 56
274 transcript_msm_x_inverse, // column 57
275 transcript_msm_count_zero_at_transition, // column 58
276 transcript_msm_count_at_transition_inverse) // column 59
277 };
278
283 template <typename DataType> class MaskingEntities {
284 public:
285 DEFINE_FLAVOR_MEMBERS(DataType, gemini_masking_poly)
286 };
287
293 template <typename DataType> class WireToBeShiftedWithoutAccumulatorsEntities {
294 public:
295 DEFINE_FLAVOR_MEMBERS(DataType,
296 transcript_mul, // column 60
297 transcript_msm_count, // column 61
298 precompute_scalar_sum, // column 62
299 precompute_s1hi, // column 63
300 precompute_dx, // column 64
301 precompute_dy, // column 65
302 precompute_tx, // column 66
303 precompute_ty, // column 67
304 msm_transition, // column 68
305 msm_add, // column 69
306 msm_double, // column 70
307 msm_skew, // column 71
308 msm_accumulator_x, // column 72
309 msm_accumulator_y, // column 73
310 msm_count, // column 74
311 msm_round, // column 75
312 msm_add1, // column 76
313 msm_pc, // column 77
314 precompute_pc, // column 78
315 transcript_pc, // column 79
316 precompute_round, // column 80
317 precompute_select) // column 81
318 };
319
323 template <typename DataType> class WireToBeShiftedAccumulatorEntities {
324 public:
325 DEFINE_FLAVOR_MEMBERS(DataType,
326 transcript_accumulator_not_empty, // column 82
327 transcript_accumulator_x, // column 83
328 transcript_accumulator_y) // column 84
329 };
330
335 template <typename DataType>
336 class WitnessEntities : public WireNonShiftedEntities<DataType>,
338 public WireToBeShiftedAccumulatorEntities<DataType>,
339 public DerivedWitnessEntities<DataType> {
340 public:
351
352 // Used to amortize the commitment time when the ECCVM size is fixed
359 // The following getters group the wires by execution subtable (transcript / precompute / msm) plus the
360 // lookup read counts. ProverPolynomials uses these groups to physically allocate each subtable's columns to
361 // that subtable's actual row count, rather than zero-padding every column to the full (virtual) dyadic
362 // circuit size. The subtables have different lengths, so per-table sizing saves substantial prover memory.
364 {
365 return RefArray{ this->transcript_add,
366 this->transcript_eq,
367 this->transcript_msm_transition,
368 this->transcript_Px,
369 this->transcript_Py,
370 this->transcript_z1,
371 this->transcript_z2,
372 this->transcript_z1zero,
373 this->transcript_z2zero,
374 this->transcript_op,
375 this->transcript_msm_x,
376 this->transcript_msm_y,
377 this->transcript_reset_accumulator,
378 this->transcript_base_infinity,
379 this->transcript_base_x_inverse,
380 this->transcript_base_y_inverse,
381 this->transcript_add_x_equal,
382 this->transcript_add_y_equal,
383 this->transcript_add_lambda,
384 this->transcript_msm_intermediate_x,
385 this->transcript_msm_intermediate_y,
386 this->transcript_msm_infinity,
387 this->transcript_msm_x_inverse,
388 this->transcript_msm_count_zero_at_transition,
389 this->transcript_msm_count_at_transition_inverse };
390 }
392 {
393 return RefArray{ this->transcript_mul, this->transcript_msm_count, this->transcript_pc };
394 }
396 {
397 return RefArray{ this->precompute_point_transition,
398 this->precompute_s1lo,
399 this->precompute_s2hi,
400 this->precompute_s2lo,
401 this->precompute_s3hi,
402 this->precompute_s3lo,
403 this->precompute_s4hi,
404 this->precompute_s4lo,
405 this->precompute_skew };
406 }
408 {
409 return RefArray{ this->precompute_scalar_sum, this->precompute_s1hi, this->precompute_dx,
410 this->precompute_dy, this->precompute_tx, this->precompute_ty,
411 this->precompute_pc, this->precompute_round, this->precompute_select };
412 }
414 {
415 return RefArray{ this->msm_size_of_msm, this->msm_add2, this->msm_add3,
416 this->msm_add4, this->msm_x1, this->msm_y1,
417 this->msm_x2, this->msm_y2, this->msm_x3,
418 this->msm_y3, this->msm_x4, this->msm_y4,
419 this->msm_collision_x1, this->msm_collision_x2, this->msm_collision_x3,
420 this->msm_collision_x4, this->msm_lambda1, this->msm_lambda2,
421 this->msm_lambda3, this->msm_lambda4, this->msm_slice1,
422 this->msm_slice2, this->msm_slice3, this->msm_slice4 };
423 }
425 {
426 return RefArray{ this->msm_transition, this->msm_add, this->msm_double,
427 this->msm_skew, this->msm_accumulator_x, this->msm_accumulator_y,
428 this->msm_count, this->msm_round, this->msm_add1,
429 this->msm_pc };
430 }
431 auto get_lookup_read_counts() { return RefArray{ this->lookup_read_counts_0, this->lookup_read_counts_1 }; }
432 };
433
437 template <typename DataType> class ShiftedEntities {
438 public:
440 transcript_mul_shift, // column 0
441 transcript_msm_count_shift, // column 1
442 precompute_scalar_sum_shift, // column 2
443 precompute_s1hi_shift, // column 3
444 precompute_dx_shift, // column 4
445 precompute_dy_shift, // column 5
446 precompute_tx_shift, // column 6
447 precompute_ty_shift, // column 7
448 msm_transition_shift, // column 8
449 msm_add_shift, // column 9
450 msm_double_shift, // column 10
451 msm_skew_shift, // column 11
452 msm_accumulator_x_shift, // column 12
453 msm_accumulator_y_shift, // column 13
454 msm_count_shift, // column 14
455 msm_round_shift, // column 15
456 msm_add1_shift, // column 16
457 msm_pc_shift, // column 17
458 precompute_pc_shift, // column 18
459 transcript_pc_shift, // column 19
460 precompute_round_shift, // column 20
461 precompute_select_shift, // column 21
462 transcript_accumulator_not_empty_shift, // column 22
463 transcript_accumulator_x_shift, // column 23
464 transcript_accumulator_y_shift, // column 24
465 z_perm_shift); // column 25
466 };
467
468 template <typename DataType, typename PrecomputedAndWitnessEntitiesSuperset>
469 static auto get_to_be_shifted(PrecomputedAndWitnessEntitiesSuperset& entities)
470 {
471 // NOTE: must match order of ShiftedEntities above!
472 return RefArray{ entities.transcript_mul, // column 0
473 entities.transcript_msm_count, // column 1
474 entities.precompute_scalar_sum, // column 2
475 entities.precompute_s1hi, // column 3
476 entities.precompute_dx, // column 4
477 entities.precompute_dy, // column 5
478 entities.precompute_tx, // column 6
479 entities.precompute_ty, // column 7
480 entities.msm_transition, // column 8
481 entities.msm_add, // column 9
482 entities.msm_double, // column 10
483 entities.msm_skew, // column 11
484 entities.msm_accumulator_x, // column 12
485 entities.msm_accumulator_y, // column 13
486 entities.msm_count, // column 14
487 entities.msm_round, // column 15
488 entities.msm_add1, // column 16
489 entities.msm_pc, // column 17
490 entities.precompute_pc, // column 18
491 entities.transcript_pc, // column 19
492 entities.precompute_round, // column 20
493 entities.precompute_select, // column 21
494 entities.transcript_accumulator_not_empty, // column 22
495 entities.transcript_accumulator_x, // column 23
496 entities.transcript_accumulator_y, // column 24
497 entities.z_perm }; // column 25
498 }
499
510 template <typename DataType>
511 class AllEntities : public MaskingEntities<DataType>,
512 public PrecomputedEntities<DataType>,
513 public WitnessEntities<DataType>,
514 public ShiftedEntities<DataType> {
515 public:
526 auto get_to_be_shifted() { return ECCVMFlavor::get_to_be_shifted<DataType>(*this); }
527 auto get_to_be_shifted() const { return ECCVMFlavor::get_to_be_shifted<DataType>(*this); }
531 };
532
537 class AllValues : public AllEntities<FF> {
538 public:
540 using Base::Base;
541 };
542
547
552
556 class ProverPolynomials : public AllEntities<Polynomial> {
557 public:
558 // Define all operations as default, except copy construction/assignment
559 ProverPolynomials() = default;
562 ProverPolynomials(ProverPolynomials&& o) noexcept = default;
566 [[nodiscard]] size_t get_polynomial_size() const { return this->lagrange_first.size(); }
567
572 AllValues get_row(const size_t row_idx) const
573 {
574 AllValues result;
575 for (auto [result_field, polynomial] : zip_view(result.get_all(), this->get_all())) {
576 // .get() returns 0 past the polynomial's end_index; operator[] would be UB on the unallocated
577 // virtual tail, since columns are physically sized to their subtable (see the get_*_wires getters).
578 result_field = polynomial.get(row_idx);
579 }
580 return result;
581 }
582 // Set all shifted polynomials based on their to-be-shifted counterpart
584 {
585 for (auto [shifted, to_be_shifted] : zip_view(get_shifted(), get_to_be_shifted())) {
586 shifted = to_be_shifted.shifted();
587 }
588 }
589
590#ifdef FUZZING
591 ProverPolynomials(const CircuitBuilder& builder, bool disable_fixed_dyadic_trace_size = false)
592#else
691#endif
692 {
693 // compute rows for the three different sections of the ECCVM execution trace
694 // Note: the first operation (index 0) is always a hiding op with random Px, Py values
695 const auto transcript_rows =
696 ECCVMTranscriptBuilder::compute_rows(builder.op_queue->get_eccvm_ops(), builder.get_number_of_muls());
697 const std::vector<MSM> msms = builder.get_msms();
698 const auto point_table_rows =
700 const auto result = ECCVMMSMMBuilder::compute_rows(
701 msms, builder.get_number_of_muls(), builder.op_queue->get_num_msm_rows());
702 const auto& msm_rows = std::get<0>(result);
703 const auto& point_table_read_counts = std::get<1>(result);
704
705 const size_t num_rows =
706 std::max({ point_table_rows.size(), msm_rows.size(), transcript_rows.size() }) + TRACE_OFFSET;
707 vinfo("Num rows in the ECCVM: ", num_rows);
708 const auto log_num_rows = static_cast<size_t>(numeric::get_msb64(num_rows));
709 size_t dyadic_num_rows = 1UL << (log_num_rows + (1UL << log_num_rows == num_rows ? 0 : 1));
710 BB_ASSERT_LTE(dyadic_num_rows,
712 "The ECCVM circuit size has exceeded the fixed upper bound! Fixed size: " +
713 std::to_string(ECCVM_FIXED_SIZE) + " actual size: " + std::to_string(dyadic_num_rows));
714
715#ifdef FUZZING
716 // We don't want to spend all the time generating the full trace if we are just fuzzing eccvm.
717 if (disable_fixed_dyadic_trace_size) {
718 dyadic_num_rows = num_rows;
719 } else {
720 dyadic_num_rows = ECCVM_FIXED_SIZE;
721 }
722#else
723 dyadic_num_rows = ECCVM_FIXED_SIZE;
724#endif
725 // The first TRACE_OFFSET rows are disabled.
726 // Trace data starts at row TRACE_OFFSET. lagrange_last goes to dyadic end.
727 constexpr size_t trace_offset = TRACE_OFFSET;
728 const auto offset_size = [](const size_t size) { return TRACE_OFFSET + size; };
729 const size_t transcript_alloc_size = offset_size(transcript_rows.size());
730 const size_t point_table_alloc_size = offset_size(point_table_rows.size());
731 const size_t msm_alloc_size = offset_size(msm_rows.size());
732 const size_t read_counts_alloc_size = offset_size(point_table_read_counts[0].size() + 1);
733
734 // Active trace data occupies the single contiguous range [TRACE_OFFSET, num_rows) -- the union of the
735 // subtable ranges above, with no inactive rows in between -- so it is a tight row-skip prefix: every row
736 // beyond num_rows is relation-trivial. The sumcheck prover takes this directly as its static row-skip
737 // manifest (num_rows already includes the TRACE_OFFSET shift). See
738 // SumcheckProverRound::HAS_STATIC_ROW_SKIP_MANIFEST.
740
741 // 1. Wires backed by their active table range, with virtual zeros beyond that range.
742 for (auto& poly : get_transcript_wires()) {
743 poly = Polynomial(transcript_alloc_size, dyadic_num_rows);
744 poly.add_masking();
745 }
746 for (auto& poly : get_precompute_wires()) {
747 poly = Polynomial(point_table_alloc_size, dyadic_num_rows);
748 poly.add_masking();
749 }
750 for (auto& poly : get_msm_wires()) {
751 poly = Polynomial(msm_alloc_size, dyadic_num_rows);
752 poly.add_masking();
753 }
754 for (auto& poly : get_lookup_read_counts()) {
755 poly = Polynomial(read_counts_alloc_size, dyadic_num_rows);
756 poly.add_masking();
757 }
758
759 // 2. To-be-shifted wires retain one leading zero row for their shifted views.
760 for (auto& poly : get_shifted_transcript_wires()) {
761 poly = Polynomial::shiftable(transcript_alloc_size, dyadic_num_rows, /*masked=*/true);
762 }
763 for (auto& poly : get_shifted_precompute_wires()) {
764 poly = Polynomial::shiftable(point_table_alloc_size, dyadic_num_rows, /*masked=*/true);
765 }
766 for (auto& poly : get_shifted_msm_wires()) {
767 poly = Polynomial::shiftable(msm_alloc_size, dyadic_num_rows, /*masked=*/true);
768 }
770 poly = Polynomial::shiftable(transcript_alloc_size, dyadic_num_rows, /*masked=*/true);
771 }
772
773 // 3. z_perm: shiftable with masking (grand product starts after disabled region)
774 z_perm = Polynomial::shiftable(dyadic_num_rows, dyadic_num_rows, /*masked=*/true);
775
776 // 4. Catch-all: precomputed, lookup_inverses, gemini_masking_poly → full size
777 for (auto& poly : get_all()) {
778 if (poly.is_empty()) {
779 poly = Polynomial(dyadic_num_rows);
780 }
781 }
782 // lookup_inverses is a derived witness — mask it so the commitment hides its values
783 lookup_inverses.add_masking();
784
785 // Lagrange polys shifted by the disabled head region
786 lagrange_first.at(trace_offset) = 1;
787 lagrange_second.at(trace_offset + 1) = 1;
788 lagrange_third.at(trace_offset + 2) = 1;
789 lagrange_last.at(dyadic_num_rows - 1) = 1;
790 for (size_t i = 0; i < point_table_read_counts[0].size(); ++i) {
791 // Explanation of off-by-one offset:
792 // When computing the WNAF slice for a point at point counter value `pc` and a round index `round`, the
793 // row number that computes the slice can be derived. This row number is then mapped to the index of
794 // `lookup_read_counts`. We do this mapping in `ecc_msm_relation`. We are off-by-one because we add an
795 // empty row at the start of the WNAF columns that is not accounted for (index of lookup_read_counts
796 // maps to the row in our WNAF columns that computes a slice for a given value of pc and round)
797 lookup_read_counts_0.at(trace_offset + i + 1) = point_table_read_counts[0][i];
798 lookup_read_counts_1.at(trace_offset + i + 1) = point_table_read_counts[1][i];
799 }
800
801 // compute polynomials for transcript columns (offset by trace_offset for top masking)
802 parallel_for_range(transcript_rows.size(), [&](size_t start, size_t end) {
803 for (size_t i = start; i < end; i++) {
804 const size_t idx = trace_offset + i;
805 transcript_accumulator_not_empty.set_if_valid_index(idx, transcript_rows[i].accumulator_not_empty);
806 transcript_add.set_if_valid_index(idx, transcript_rows[i].q_add);
807 transcript_mul.set_if_valid_index(idx, transcript_rows[i].q_mul);
808 transcript_eq.set_if_valid_index(idx, transcript_rows[i].q_eq);
809 transcript_reset_accumulator.set_if_valid_index(idx, transcript_rows[i].q_reset_accumulator);
810 transcript_msm_transition.set_if_valid_index(idx, transcript_rows[i].msm_transition);
811 transcript_pc.set_if_valid_index(idx, transcript_rows[i].pc);
812 transcript_msm_count.set_if_valid_index(idx, transcript_rows[i].msm_count);
813 transcript_Px.set_if_valid_index(idx, transcript_rows[i].base_x);
814 transcript_Py.set_if_valid_index(idx, transcript_rows[i].base_y);
815 transcript_z1.set_if_valid_index(idx, transcript_rows[i].z1);
816 transcript_z2.set_if_valid_index(idx, transcript_rows[i].z2);
817 transcript_z1zero.set_if_valid_index(idx, transcript_rows[i].z1_zero);
818 transcript_z2zero.set_if_valid_index(idx, transcript_rows[i].z2_zero);
819 transcript_op.set_if_valid_index(idx, transcript_rows[i].opcode);
820 transcript_accumulator_x.set_if_valid_index(idx, transcript_rows[i].accumulator_x);
821 transcript_accumulator_y.set_if_valid_index(idx, transcript_rows[i].accumulator_y);
822 transcript_msm_x.set_if_valid_index(idx, transcript_rows[i].msm_output_x);
823 transcript_msm_y.set_if_valid_index(idx, transcript_rows[i].msm_output_y);
824 transcript_base_infinity.set_if_valid_index(idx, transcript_rows[i].base_infinity);
825 transcript_base_x_inverse.set_if_valid_index(idx, transcript_rows[i].base_x_inverse);
826 transcript_base_y_inverse.set_if_valid_index(idx, transcript_rows[i].base_y_inverse);
827 transcript_add_x_equal.set_if_valid_index(idx, transcript_rows[i].transcript_add_x_equal);
828 transcript_add_y_equal.set_if_valid_index(idx, transcript_rows[i].transcript_add_y_equal);
829 transcript_add_lambda.set_if_valid_index(idx, transcript_rows[i].transcript_add_lambda);
830 transcript_msm_intermediate_x.set_if_valid_index(idx,
831 transcript_rows[i].transcript_msm_intermediate_x);
832 transcript_msm_intermediate_y.set_if_valid_index(idx,
833 transcript_rows[i].transcript_msm_intermediate_y);
834 transcript_msm_infinity.set_if_valid_index(idx, transcript_rows[i].transcript_msm_infinity);
835 transcript_msm_x_inverse.set_if_valid_index(idx, transcript_rows[i].transcript_msm_x_inverse);
836 transcript_msm_count_zero_at_transition.set_if_valid_index(
837 idx, transcript_rows[i].msm_count_zero_at_transition);
838 transcript_msm_count_at_transition_inverse.set_if_valid_index(
839 idx, transcript_rows[i].msm_count_at_transition_inverse);
840 }
841 });
842
843 parallel_for_range(point_table_rows.size(), [&](size_t start, size_t end) {
844 for (size_t i = start; i < end; i++) {
845 const size_t idx = trace_offset + i;
846 // first row is always an empty row (to accommodate shifted polynomials which must have 0 as 1st
847 // coefficient). All other rows in the point_table_rows represent active wnaf gates (i.e.
848 // precompute_select = 1)
849 precompute_select.set_if_valid_index(idx, (i != 0) ? 1 : 0);
850 precompute_pc.set_if_valid_index(idx, point_table_rows[i].pc);
851 precompute_point_transition.set_if_valid_index(
852 idx, static_cast<uint64_t>(point_table_rows[i].point_transition));
853 precompute_round.set_if_valid_index(idx, point_table_rows[i].round);
854 precompute_scalar_sum.set_if_valid_index(idx, point_table_rows[i].scalar_sum);
855 precompute_s1hi.set_if_valid_index(idx, point_table_rows[i].s1);
856 precompute_s1lo.set_if_valid_index(idx, point_table_rows[i].s2);
857 precompute_s2hi.set_if_valid_index(idx, point_table_rows[i].s3);
858 precompute_s2lo.set_if_valid_index(idx, point_table_rows[i].s4);
859 precompute_s3hi.set_if_valid_index(idx, point_table_rows[i].s5);
860 precompute_s3lo.set_if_valid_index(idx, point_table_rows[i].s6);
861 precompute_s4hi.set_if_valid_index(idx, point_table_rows[i].s7);
862 precompute_s4lo.set_if_valid_index(idx, point_table_rows[i].s8);
863 // If skew is active (i.e. we need to subtract a base point from the msm result),
864 // write `7` into rows.precompute_skew. `7`, in binary representation, equals `-1` when converted
865 // into WNAF form
866 precompute_skew.set_if_valid_index(idx, point_table_rows[i].skew ? 7 : 0);
867 precompute_dx.set_if_valid_index(idx, point_table_rows[i].precompute_double.x);
868 precompute_dy.set_if_valid_index(idx, point_table_rows[i].precompute_double.y);
869 precompute_tx.set_if_valid_index(idx, point_table_rows[i].precompute_accumulator.x);
870 precompute_ty.set_if_valid_index(idx, point_table_rows[i].precompute_accumulator.y);
871 }
872 });
873
874 // compute polynomials for the msm columns (offset by trace_offset for top masking)
875 parallel_for_range(msm_rows.size(), [&](size_t start, size_t end) {
876 for (size_t i = start; i < end; i++) {
877 const size_t idx = trace_offset + i;
878 msm_transition.set_if_valid_index(idx, static_cast<int>(msm_rows[i].msm_transition));
879 msm_add.set_if_valid_index(idx, static_cast<int>(msm_rows[i].q_add));
880 msm_double.set_if_valid_index(idx, static_cast<int>(msm_rows[i].q_double));
881 msm_skew.set_if_valid_index(idx, static_cast<int>(msm_rows[i].q_skew));
882 msm_accumulator_x.set_if_valid_index(idx, msm_rows[i].accumulator_x);
883 msm_accumulator_y.set_if_valid_index(idx, msm_rows[i].accumulator_y);
884 msm_pc.set_if_valid_index(idx, msm_rows[i].pc);
885 msm_size_of_msm.set_if_valid_index(idx, msm_rows[i].msm_size);
886 msm_count.set_if_valid_index(idx, msm_rows[i].msm_count);
887 msm_round.set_if_valid_index(idx, msm_rows[i].msm_round);
888 msm_add1.set_if_valid_index(idx, static_cast<int>(msm_rows[i].add_state[0].add));
889 msm_add2.set_if_valid_index(idx, static_cast<int>(msm_rows[i].add_state[1].add));
890 msm_add3.set_if_valid_index(idx, static_cast<int>(msm_rows[i].add_state[2].add));
891 msm_add4.set_if_valid_index(idx, static_cast<int>(msm_rows[i].add_state[3].add));
892 msm_x1.set_if_valid_index(idx, msm_rows[i].add_state[0].point.x);
893 msm_y1.set_if_valid_index(idx, msm_rows[i].add_state[0].point.y);
894 msm_x2.set_if_valid_index(idx, msm_rows[i].add_state[1].point.x);
895 msm_y2.set_if_valid_index(idx, msm_rows[i].add_state[1].point.y);
896 msm_x3.set_if_valid_index(idx, msm_rows[i].add_state[2].point.x);
897 msm_y3.set_if_valid_index(idx, msm_rows[i].add_state[2].point.y);
898 msm_x4.set_if_valid_index(idx, msm_rows[i].add_state[3].point.x);
899 msm_y4.set_if_valid_index(idx, msm_rows[i].add_state[3].point.y);
900 msm_collision_x1.set_if_valid_index(idx, msm_rows[i].add_state[0].collision_inverse);
901 msm_collision_x2.set_if_valid_index(idx, msm_rows[i].add_state[1].collision_inverse);
902 msm_collision_x3.set_if_valid_index(idx, msm_rows[i].add_state[2].collision_inverse);
903 msm_collision_x4.set_if_valid_index(idx, msm_rows[i].add_state[3].collision_inverse);
904 msm_lambda1.set_if_valid_index(idx, msm_rows[i].add_state[0].lambda);
905 msm_lambda2.set_if_valid_index(idx, msm_rows[i].add_state[1].lambda);
906 msm_lambda3.set_if_valid_index(idx, msm_rows[i].add_state[2].lambda);
907 msm_lambda4.set_if_valid_index(idx, msm_rows[i].add_state[3].lambda);
908 msm_slice1.set_if_valid_index(idx, msm_rows[i].add_state[0].slice);
909 msm_slice2.set_if_valid_index(idx, msm_rows[i].add_state[1].slice);
910 msm_slice3.set_if_valid_index(idx, msm_rows[i].add_state[2].slice);
911 msm_slice4.set_if_valid_index(idx, msm_rows[i].add_state[3].slice);
912 }
913 });
914 this->set_shifted();
915 }
916 };
917
923
929 public:
930 size_t circuit_size = ECCVM_FIXED_SIZE; // The circuit size is fixed for the ECCVM.
931 size_t log_circuit_size = CONST_ECCVM_LOG_N;
932
933 // Used to amortize the commitment time if the `fixed size` > `real_size`.
934 size_t real_size = 0;
935
936 ProverPolynomials polynomials; // storage for all polynomials evaluated by the prover
938
939 // Constructor for fixed size ProvingKey
941 : real_size(builder.get_circuit_subgroup_size(builder.get_estimated_num_finalized_gates()))
942 , polynomials(builder)
943 {}
944 };
945
951
958 class CommitmentLabels : public AllEntities<std::string> {
959 private:
961
962 public:
964 : AllEntities<std::string>()
965 {
966 Base::transcript_add = "TRANSCRIPT_ADD";
967 Base::transcript_mul = "TRANSCRIPT_MUL";
968 Base::transcript_eq = "TRANSCRIPT_EQ";
969 Base::transcript_msm_transition = "TRANSCRIPT_MSM_TRANSITION";
970 Base::transcript_pc = "TRANSCRIPT_PC";
971 Base::transcript_msm_count = "TRANSCRIPT_MSM_COUNT";
972 Base::transcript_Px = "TRANSCRIPT_PX";
973 Base::transcript_Py = "TRANSCRIPT_PY";
974 Base::transcript_z1 = "TRANSCRIPT_Z1";
975 Base::transcript_z2 = "TRANSCRIPT_Z2";
976 Base::transcript_z1zero = "TRANSCRIPT_Z1ZERO";
977 Base::transcript_z2zero = "TRANSCRIPT_Z2ZERO";
978 Base::transcript_op = "TRANSCRIPT_OP";
979 Base::transcript_accumulator_x = "TRANSCRIPT_ACCUMULATOR_X";
980 Base::transcript_accumulator_y = "TRANSCRIPT_ACCUMULATOR_Y";
981 Base::transcript_msm_x = "TRANSCRIPT_MSM_X";
982 Base::transcript_msm_y = "TRANSCRIPT_MSM_Y";
983 Base::precompute_pc = "PRECOMPUTE_PC";
984 Base::precompute_point_transition = "PRECOMPUTE_POINT_TRANSITION";
985 Base::precompute_round = "PRECOMPUTE_ROUND";
986 Base::precompute_scalar_sum = "PRECOMPUTE_SCALAR_SUM";
987 Base::precompute_s1hi = "PRECOMPUTE_S1HI";
988 Base::precompute_s1lo = "PRECOMPUTE_S1LO";
989 Base::precompute_s2hi = "PRECOMPUTE_S2HI";
990 Base::precompute_s2lo = "PRECOMPUTE_S2LO";
991 Base::precompute_s3hi = "PRECOMPUTE_S3HI";
992 Base::precompute_s3lo = "PRECOMPUTE_S3LO";
993 Base::precompute_s4hi = "PRECOMPUTE_S4HI";
994 Base::precompute_s4lo = "PRECOMPUTE_S4LO";
995 Base::precompute_skew = "PRECOMPUTE_SKEW";
996 Base::precompute_dx = "PRECOMPUTE_DX";
997 Base::precompute_dy = "PRECOMPUTE_DY";
998 Base::precompute_tx = "PRECOMPUTE_TX";
999 Base::precompute_ty = "PRECOMPUTE_TY";
1000 Base::msm_transition = "MSM_TRANSITION";
1001 Base::msm_add = "MSM_ADD";
1002 Base::msm_double = "MSM_DOUBLE";
1003 Base::msm_skew = "MSM_SKEW";
1004 Base::msm_accumulator_x = "MSM_ACCUMULATOR_X";
1005 Base::msm_accumulator_y = "MSM_ACCUMULATOR_Y";
1006 Base::msm_pc = "MSM_PC";
1007 Base::msm_size_of_msm = "MSM_SIZE_OF_MSM";
1008 Base::msm_count = "MSM_COUNT";
1009 Base::msm_round = "MSM_ROUND";
1010 Base::msm_add1 = "MSM_ADD1";
1011 Base::msm_add2 = "MSM_ADD2";
1012 Base::msm_add3 = "MSM_ADD3";
1013 Base::msm_add4 = "MSM_ADD4";
1014 Base::msm_x1 = "MSM_X1";
1015 Base::msm_y1 = "MSM_Y1";
1016 Base::msm_x2 = "MSM_X2";
1017 Base::msm_y2 = "MSM_Y2";
1018 Base::msm_x3 = "MSM_X3";
1019 Base::msm_y3 = "MSM_Y3";
1020 Base::msm_x4 = "MSM_X4";
1021 Base::msm_y4 = "MSM_Y4";
1022 Base::msm_collision_x1 = "MSM_COLLISION_X1";
1023 Base::msm_collision_x2 = "MSM_COLLISION_X2";
1024 Base::msm_collision_x3 = "MSM_COLLISION_X3";
1025 Base::msm_collision_x4 = "MSM_COLLISION_X4";
1026 Base::msm_lambda1 = "MSM_LAMBDA1";
1027 Base::msm_lambda2 = "MSM_LAMBDA2";
1028 Base::msm_lambda3 = "MSM_LAMBDA3";
1029 Base::msm_lambda4 = "MSM_LAMBDA4";
1030 Base::msm_slice1 = "MSM_SLICE1";
1031 Base::msm_slice2 = "MSM_SLICE2";
1032 Base::msm_slice3 = "MSM_SLICE3";
1033 Base::msm_slice4 = "MSM_SLICE4";
1034 Base::transcript_accumulator_not_empty = "TRANSCRIPT_ACCUMULATOR_NOT_EMPTY";
1035 Base::transcript_reset_accumulator = "TRANSCRIPT_RESET_ACCUMULATOR";
1036 Base::precompute_select = "PRECOMPUTE_SELECT";
1037 Base::lookup_read_counts_0 = "LOOKUP_READ_COUNTS_0";
1038 Base::lookup_read_counts_1 = "LOOKUP_READ_COUNTS_1";
1039 Base::transcript_base_infinity = "TRANSCRIPT_BASE_INFINITY";
1040 Base::transcript_base_x_inverse = "TRANSCRIPT_BASE_X_INVERSE";
1041 Base::transcript_base_y_inverse = "TRANSCRIPT_BASE_Y_INVERSE";
1042 Base::transcript_add_x_equal = "TRANSCRIPT_ADD_X_EQUAL";
1043 Base::transcript_add_y_equal = "TRANSCRIPT_ADD_Y_EQUAL";
1044 Base::transcript_add_lambda = "TRANSCRIPT_ADD_LAMBDA";
1045 Base::transcript_msm_intermediate_x = "TRANSCRIPT_MSM_INTERMEDIATE_X";
1046 Base::transcript_msm_intermediate_y = "TRANSCRIPT_MSM_INTERMEDIATE_Y";
1047 Base::transcript_msm_infinity = "TRANSCRIPT_MSM_INFINITY";
1048 Base::transcript_msm_x_inverse = "TRANSCRIPT_MSM_X_INVERSE";
1049 Base::transcript_msm_count_zero_at_transition = "TRANSCRIPT_MSM_COUNT_ZERO_AT_TRANSITION";
1050 Base::transcript_msm_count_at_transition_inverse = "TRANSCRIPT_MSM_COUNT_AT_TRANSITION_INVERSE";
1051 Base::z_perm = "Z_PERM";
1052 Base::z_perm_shift = "Z_PERM_SHIFT";
1053 Base::lookup_inverses = "LOOKUP_INVERSES";
1054 // The ones beginning with "__" are only used for debugging
1055 Base::lagrange_first = "__LAGRANGE_FIRST";
1056 Base::lagrange_second = "__LAGRANGE_SECOND";
1057 Base::lagrange_third = "__LAGRANGE_THIRD";
1058 Base::lagrange_last = "__LAGRANGE_LAST";
1059 };
1060
1061 // Used in pippenger_unsafe to activate duplicate stripping.
1062 // Dups need to be > ~14 bits to be worth stripping.
1063 // Empirical tests showed these polys had high duplicate counts under these conditions
1064 static bool wire_has_high_duplicate_density(const std::string& label) noexcept
1065 {
1066 return label == "MSM_X1" || label == "MSM_X2" || label == "MSM_X3" || label == "MSM_X4" ||
1067 label == "MSM_Y1" || label == "MSM_Y2" || label == "MSM_Y3" || label == "MSM_Y4" ||
1068 label == "MSM_ROUND_MINUS_31_INV" || label == "PRECOMPUTE_DX" || label == "PRECOMPUTE_DY" ||
1069 label == "PRECOMPUTE_TX" || label == "PRECOMPUTE_TY" || label == "TRANSCRIPT_ACCUMULATOR_X" ||
1070 label == "TRANSCRIPT_ACCUMULATOR_Y" || label == "TRANSCRIPT_PX" || label == "TRANSCRIPT_PY";
1071 }
1072 };
1073
1074 template <typename Commitment, typename VerificationKey>
1075 class VerifierCommitments_ : public AllEntities<Commitment> {
1076 public:
1077 VerifierCommitments_(const std::shared_ptr<VerificationKey>& verification_key)
1078 {
1079 this->lagrange_first = verification_key->lagrange_first;
1080 this->lagrange_second = verification_key->lagrange_second;
1081 this->lagrange_third = verification_key->lagrange_third;
1082 this->lagrange_last = verification_key->lagrange_last;
1083 }
1084 };
1085
1087
1093 public:
1095 std::vector<Commitment> ipa_l_comms;
1096 std::vector<Commitment> ipa_r_comms;
1099
1100 IPATranscript() = default;
1101
1103 {
1104 // take current proof and put them into the struct
1105 size_t num_frs_read = 0;
1106 ipa_poly_degree = NativeTranscript::template deserialize_from_buffer<uint32_t>(NativeTranscript::proof_data,
1107 num_frs_read);
1108
1109 for (size_t i = 0; i < CONST_ECCVM_LOG_N; ++i) {
1110 ipa_l_comms.emplace_back(NativeTranscript::template deserialize_from_buffer<Commitment>(
1111 NativeTranscript::proof_data, num_frs_read));
1112 ipa_r_comms.emplace_back(NativeTranscript::template deserialize_from_buffer<Commitment>(
1113 NativeTranscript::proof_data, num_frs_read));
1114 }
1115 ipa_G_0_eval = NativeTranscript::template deserialize_from_buffer<Commitment>(NativeTranscript::proof_data,
1116 num_frs_read);
1117 ipa_a_0_eval =
1118 NativeTranscript::template deserialize_from_buffer<FF>(NativeTranscript::proof_data, num_frs_read);
1119 }
1120
1122 {
1123 size_t old_proof_length = NativeTranscript::proof_data.size();
1124 NativeTranscript::proof_data.clear();
1125
1126 NativeTranscript::serialize_to_buffer(ipa_poly_degree, NativeTranscript::proof_data);
1127 for (size_t i = 0; i < CONST_ECCVM_LOG_N; ++i) {
1128 NativeTranscript::serialize_to_buffer(ipa_l_comms[i], NativeTranscript::proof_data);
1129 NativeTranscript::serialize_to_buffer(ipa_r_comms[i], NativeTranscript::proof_data);
1130 }
1131
1132 serialize_to_buffer(ipa_G_0_eval, proof_data);
1133 serialize_to_buffer(ipa_a_0_eval, proof_data);
1134
1135 BB_ASSERT_EQ(NativeTranscript::proof_data.size(), old_proof_length);
1136 }
1137 };
1138
1139 template <typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
1140 static size_t row_skip_active_prefix_end(const ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials)
1141 {
1142 return polynomials.row_skip_active_prefix_end;
1143 }
1144};
1145} // namespace bb
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
#define BB_ASSERT_LTE(left, right,...)
Definition assert.hpp:158
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
CommitmentKey object over a pairing group 𝔾₁.
static std::vector< ScalarMul > get_flattened_scalar_muls(const std::vector< MSM > &msms)
A base class labelling all entities (for instance, all of the polynomials used by the prover during s...
DEFINE_COMPOUND_GET_ALL(MaskingEntities< DataType >, PrecomputedEntities< DataType >, WitnessEntities< DataType >, ShiftedEntities< DataType >) auto get_unshifted()
A field element for each entity of the flavor. These entities represent the prover polynomials evalua...
A container for commitment labels.
static bool wire_has_high_duplicate_density(const std::string &label) noexcept
Derived class that defines proof structure for ECCVM IPA proof, as well as supporting functions.
std::vector< Commitment > ipa_r_comms
std::vector< Commitment > ipa_l_comms
Container for ZK entities (gemini masking polynomial for ZK-PCS)
A base class labelling precomputed entities and (ordered) subsets of interest.
bool operator==(const PrecomputedEntities &other) const =default
DEFINE_FLAVOR_MEMBERS(DataType, lagrange_first, lagrange_second, lagrange_third, lagrange_last)
A container for the prover polynomials.
AllValues get_row(const size_t row_idx) const
Returns the evaluations of all prover polynomials at one point on the boolean hypercube,...
ProverPolynomials(const ProverPolynomials &o)=delete
ProverPolynomials(ProverPolynomials &&o) noexcept=default
ProverPolynomials(const CircuitBuilder &builder)
Compute the ECCVM flavor polynomial data required to generate an ECCVM Proof.
ProverPolynomials & operator=(const ProverPolynomials &)=delete
ProverPolynomials & operator=(ProverPolynomials &&o) noexcept=default
The proving key is responsible for storing the polynomials used by the prover.
ProverPolynomials polynomials
ProvingKey(const CircuitBuilder &builder)
Represents polynomials shifted by 1 or their evaluations, defined relative to WitnessEntities.
DEFINE_FLAVOR_MEMBERS(DataType, transcript_mul_shift, transcript_msm_count_shift, precompute_scalar_sum_shift, precompute_s1hi_shift, precompute_dx_shift, precompute_dy_shift, precompute_tx_shift, precompute_ty_shift, msm_transition_shift, msm_add_shift, msm_double_shift, msm_skew_shift, msm_accumulator_x_shift, msm_accumulator_y_shift, msm_count_shift, msm_round_shift, msm_add1_shift, msm_pc_shift, precompute_pc_shift, transcript_pc_shift, precompute_round_shift, precompute_select_shift, transcript_accumulator_not_empty_shift, transcript_accumulator_x_shift, transcript_accumulator_y_shift, z_perm_shift)
VerifierCommitments_(const std::shared_ptr< VerificationKey > &verification_key)
Container for transcript accumulator wires that need shifted views.
Container for all to-be-shifted witness polynomials excluding the accumulators used/constructed by th...
Container for all witness polynomials used/constructed by the prover.
DEFINE_COMPOUND_GET_ALL(WireNonShiftedEntities< DataType >, WireToBeShiftedWithoutAccumulatorsEntities< DataType >, WireToBeShiftedAccumulatorEntities< DataType >, DerivedWitnessEntities< DataType >) auto get_wires()
static constexpr size_t ECCVM_FIXED_SIZE
static constexpr bool HasZK
static constexpr size_t NUM_WIRE_NON_SHIFTED
typename Curve::ScalarField FF
static constexpr size_t NUM_MASKING_POLYNOMIALS
static constexpr size_t NUM_SUBRELATIONS
static constexpr size_t NUM_ALL_ENTITIES
static constexpr size_t MAX_PARTIAL_RELATION_LENGTH
static auto get_to_be_shifted(PrecomputedAndWitnessEntitiesSuperset &entities)
std::tuple< ECCVMTranscriptRelation< FF >, ECCVMPointTableRelation< FF >, ECCVMWnafRelation< FF >, ECCVMMSMRelation< FF >, ECCVMSetRelation< FF >, ECCVMLookupRelation< FF >, ECCVMBoolsRelation< FF > > Relations_
typename G1::affine_element Commitment
typename Curve::BaseField BF
bb::Polynomial< FF > Polynomial
static size_t row_skip_active_prefix_end(const ProverPolynomialsOrPartiallyEvaluatedMultivariates &polynomials)
typename G1::element GroupElement
std::tuple< ECCVMSetRelation< FF > > GrandProductRelations
typename Curve::Group G1
static constexpr bool USE_SHORT_MONOMIALS
static constexpr size_t PROOF_LENGTH
static constexpr size_t NUM_WITNESS_ENTITIES
static constexpr size_t NUM_TRANSLATION_OPENING_CLAIMS
static constexpr size_t NUM_SHIFTED_ENTITIES
static constexpr size_t NUM_PRECOMPUTED_ENTITIES
static constexpr size_t NUM_WIRES
static constexpr size_t BATCHED_RELATION_PARTIAL_LENGTH
static constexpr size_t num_frs_comm
static constexpr bool USE_PADDING
static constexpr size_t num_frs_fq
static constexpr RepeatedCommitmentsData REPEATED_COMMITMENTS
static constexpr size_t NUM_RELATIONS
Relations_< FF > Relations
bb::eccvm::MSM< CycleGroup > MSM
static constexpr size_t NUM_DERIVED_WITNESS_ENTITIES_NON_SHIFTED
std::array< FF, NUM_SUBRELATIONS - 1 > SubrelationSeparators
static constexpr size_t TRACE_OFFSET
Stores the fixed ECCVM VK commitments (to precomputed polynomials) that depend only on the circuit si...
static std::tuple< std::vector< MSMRow >, std::array< std::vector< size_t >, 2 > > compute_rows(const std::vector< MSM > &msms, const uint32_t total_number_of_muls, const size_t num_msm_rows)
Computes the row values for the Straus MSM columns of the ECCVM.
static std::vector< PointTablePrecomputationRow > compute_rows(const std::vector< bb::eccvm::ScalarMul< CycleGroup > > &ecc_muls)
static std::vector< TranscriptRow > compute_rows(const std::vector< ECCVMOperation > &vm_operations, const uint32_t total_number_of_muls)
Computes the ECCVM transcript rows.
Simple verification key class for fixed-size circuits (ECCVM, Translator, AVM).
Definition flavor.hpp:103
A container for storing the partially evaluated multivariates produced by sumcheck.
static Polynomial shiftable(size_t virtual_size, bool masked=false)
Utility to create a shiftable polynomial of given virtual size.
A template class for a reference array. Behaves as if std::array<T&, N> was possible.
Definition ref_array.hpp:22
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
typename grumpkin::g1 Group
Definition grumpkin.hpp:62
group class. Represents an elliptic curve group element. Group is parametrised by Fq and Fr
Definition group.hpp:38
#define vinfo(...)
Definition log.hpp:94
AluTraceBuilder builder
Definition alu.test.cpp:124
typename ECCVMFlavor::ProverPolynomials ProverPolynomials
Base class templates shared across Honk flavors.
#define DEFINE_FLAVOR_MEMBERS(DataType,...)
Define the body of a flavor class, included each member and a pointer view with which to iterate the ...
std::vector< ScalarMul< CycleGroup > > MSM
constexpr uint64_t get_msb64(const uint64_t in)
Definition get_msb.hpp:33
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
group< fq, fr, Bn254G1Params > g1
Definition g1.hpp:34
std::vector< fr > HonkProof
Definition proof.hpp:15
RefArray< T,(Ns+...)> constexpr concatenate(const RefArray< T, Ns > &... ref_arrays)
Concatenates multiple RefArray objects into a single RefArray.
void parallel_for_range(size_t num_points, const std::function< void(size_t, size_t)> &func, size_t no_multhreading_if_less_or_equal)
Split a loop into several loops running in parallel.
Definition thread.cpp:141
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
Container for all derived witness polynomials used/constructed by the prover.
DEFINE_FLAVOR_MEMBERS(DataType, z_perm, lookup_inverses)