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
33
34// NOLINTBEGIN(cppcoreguidelines-avoid-const-or-ref-data-members)
35
36namespace bb {
37
39 public:
43 using G1 = typename Curve::Group;
44 using FF = typename Curve::ScalarField;
45 using BF = typename Curve::BaseField;
47 using GroupElement = typename G1::element;
48 using Commitment = typename G1::affine_element;
52 using Codec = FrCodec;
56
57 // indicates when evaluating sumcheck, edges must be extended to be MAX_PARTIAL_RELATION_LENGTH
58 static constexpr bool USE_SHORT_MONOMIALS = false;
59
60 // Indicates that this flavor runs with ZK Sumcheck.
61 static constexpr bool HasZK = true;
62 // The number of rows reserved at the top of the execution trace for row-disabling / ZK masking.
63 static constexpr size_t TRACE_OFFSET = NUM_DISABLED_ROWS_IN_SUMCHECK;
64 // ECCVM proof size and its recursive verifier circuit are genuinely fixed, hence no padding is needed.
65 static constexpr bool USE_PADDING = false;
66 // Fixed size of the ECCVM circuits used in Chonk
67 // Important: these constants cannot be arbitrarily changes - please consult with a member of the Crypto team if
68 // they become too small.
69 static constexpr size_t ECCVM_FIXED_SIZE = 1UL << CONST_ECCVM_LOG_N;
70
71 static constexpr size_t NUM_WIRES = 86;
72
73 // The number of entities added for ZK (gemini_masking_poly)
74 static constexpr size_t NUM_MASKING_POLYNOMIALS = 1;
75
76 // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often
77 // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`.
78 // Note: this number does not include the individual sorted list polynomials.
79 // Includes gemini_masking_poly for ZK (NUM_ALL_ENTITIES = 118 + NUM_MASKING_POLYNOMIALS)
80 static constexpr size_t NUM_ALL_ENTITIES = 119;
81 // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying
82 // assignment of witnesses. We again choose a neutral name.
83 static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 4;
84 // The total number of witness entities not including shifts.
85 // Includes gemini_masking_poly for ZK (NUM_WITNESS_ENTITIES = 87 + NUM_MASKING_POLYNOMIALS)
86 static constexpr size_t NUM_WITNESS_ENTITIES = 88;
88 // define the tuple of Relations that comprise the Sumcheck relation
89 template <typename FF>
100
101 static constexpr size_t NUM_SUBRELATIONS = compute_number_of_subrelations<Relations>();
102 using SubrelationSeparators = std::array<FF, NUM_SUBRELATIONS - 1>;
103
104 // ECCVM has many high-degree subrelations, so per-relation thread dispatch pays off; it opts into parallel
105 // relation batching (see ParallelizesRelationBatching).
106 static constexpr bool PARALLELIZE_RELATION_BATCHING = true;
107
108 static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length<Relations>();
109
110 // BATCHED_RELATION_PARTIAL_LENGTH = algebraic degree of sumcheck relation *after* multiplying by the `pow_zeta`
111 // random polynomial e.g. For \sum(x) [A(x) * B(x) + C(x)] * PowZeta(X), relation length = 2 and random relation
112 // length = 3.
113 // The degree has to be further increased by 1 because the relation is multiplied by the Row Disabling //
114 // Polynomial
116 static constexpr size_t NUM_RELATIONS = std::tuple_size<Relations>::value;
117
118 // Masking budget of the committed sumcheck: per round, the verifier's view exposes 3 Libra-sensitive functionals
119 // of the round univariate U_i — its evaluation at 0, the chained target T_{i+1} = U_i(u_i), and the non-hiding
120 // commitment [U_i] — and the pair-sum bookkeeping U_i(0) + U_i(1) = T_i consumes one Libra coefficient, so the
121 // Libra masking univariates must have length 3 + 1 = 4. The BN254 ZK flavors pin their (non-committed) budget
122 // with an analogous static_assert. See sumcheck/docs/committed_sumcheck_zk.md.
123 static_assert(Curve::LIBRA_UNIVARIATES_LENGTH == 4,
124 "Committed sumcheck requires LIBRA_UNIVARIATES_LENGTH == #revealed evaluations (3) + 1");
125 static_assert(Curve::LIBRA_UNIVARIATES_LENGTH * CONST_ECCVM_LOG_N + 1 < Curve::SUBGROUP_SIZE,
126 "Concatenated Libra polynomial must fit in the SmallSubgroupIPA subgroup");
127
128 static constexpr size_t num_frs_comm = FrCodec::calc_num_fields<Commitment>();
129 static constexpr size_t num_frs_fq = FrCodec::calc_num_fields<FF>();
130
131 static constexpr size_t TRIPLE_IPA_PROOF_LENGTH =
132 /* TripleIPA cross sums (cross_F_shift, cross_F_P, cross_shift_P) */ (3 * num_frs_fq) +
133 /* TripleIPA L and R round commitments */ (2 * CONST_ECCVM_LOG_N * num_frs_comm) +
134 /* TripleIPA G_0 commitment */ (num_frs_comm) +
135 /* TripleIPA a_0 evaluation */ (num_frs_fq);
136
137 // Proof length formula
138 static constexpr size_t PROOF_LENGTH =
139 /* 1. NUM_WITNESS_ENTITIES commitments */ ((NUM_WITNESS_ENTITIES + NUM_MASKING_POLYNOMIALS) * num_frs_comm) +
140 /* 2. Libra concatenation commitment*/ (num_frs_comm) +
141 /* 3. Libra sum */ (num_frs_fq) +
142 /* 4. CONST_ECCVM_LOG_N sumcheck univariates commitments */
143 (CONST_ECCVM_LOG_N * num_frs_comm) +
144 /* 5. 2 * CONST_ECCVM_LOG_N sumcheck univariate evaluations */
145 (2 * CONST_ECCVM_LOG_N * num_frs_fq) +
146 /* 6. NUM_ALL_ENTITIES sumcheck evaluations*/ (NUM_ALL_ENTITIES * num_frs_fq) +
147 /* 7. Libra claimed evaluation */ (num_frs_fq) +
148 /* 8. Libra grand sum commitment */ (num_frs_comm) +
149 /* 9. Libra quotient commitment */ (num_frs_comm) +
150 /* 10. NUM_SMALL_IPA_TRANSCRIPT_EVALS libra evals */
152 /* 11. Translator concatenated masking term commitment */ (num_frs_comm) +
153 /* 12. Translator op evaluation */ (num_frs_fq) +
154 /* 13. Translator Px evaluation */ (num_frs_fq) +
155 /* 14. Translator Py evaluation */ (num_frs_fq) +
156 /* 15. Translator z1 evaluation */ (num_frs_fq) +
157 /* 16. Translator z2 evaluation */ (num_frs_fq) +
158 /* 17. Translator concatenated masking term evaluation */ (num_frs_fq) +
159 /* 18. Translator grand sum commitment */ (num_frs_comm) +
160 /* 19. Translator quotient commitment */ (num_frs_comm) +
161 /* 20. Translator concatenation eval */ (num_frs_fq) +
162 /* 21. Translator grand sum shift eval */ (num_frs_fq) +
163 /* 22. Translator grand sum eval */ (num_frs_fq) +
164 /* 23. Translator quotient eval */ (num_frs_fq) +
165 /* 24. TripleIPA pow-tensor masking commitment */ (num_frs_comm) +
166 /* 25. TripleIPA pow-tensor masking evaluation */ (num_frs_fq) +
167 /* 26. Shplonk Q commitment (single TripleIPA Shplonk reduction) */ (num_frs_comm);
168
169 // The translation opening-claim step outputs an opening claim for the batched univariate
170 // evaluation of `op`, `Px`, `Py`, `z1`, and `z2`, and an array of opening claims for the evaluations of the
171 // SmallSubgroupIPA witness polynomials.
173
174 // TODO(https://github.com/AztecProtocol/barretenberg/issues/989): refine access specifiers in flavors, this is
175 // public as it is also used in the recursive flavor but the two could possibly me unified eventually
180 template <typename DataType_> class PrecomputedEntities {
181 public:
182 bool operator==(const PrecomputedEntities& other) const = default;
183 using DataType = DataType_;
185 lagrange_first, // column 0
186 lagrange_second, // column 1 - hiding op row
187 lagrange_third, // column 2 - first real op row
188 lagrange_last); // column 3
189
190 DataType get_selectors() { return get_all(); };
191 };
192
197 template <typename DataType> struct DerivedWitnessEntities {
199 z_perm, // column 0
200 lookup_inverses); // column 1
201 };
202 template <typename DataType> class WireNonShiftedEntities {
203 public:
204 DEFINE_FLAVOR_MEMBERS(DataType,
205 transcript_add, // column 0
206 transcript_eq, // column 1
207 transcript_msm_transition, // column 2
208 transcript_Px, // column 3
209 transcript_Py, // column 4
210 transcript_z1, // column 5
211 transcript_z2, // column 6
212 transcript_z1zero, // column 7
213 transcript_z2zero, // column 8
214 transcript_op, // column 9
215 transcript_msm_x, // column 10
216 transcript_msm_y, // column 11
217 precompute_point_transition, // column 12
218 precompute_s1lo, // column 13
219 precompute_s2hi, // column 14
220 precompute_s2lo, // column 15
221 precompute_s3hi, // column 16
222 precompute_s3lo, // column 17
223 precompute_s4hi, // column 18
224 precompute_s4lo, // column 19
225 precompute_skew, // column 20
226 msm_size_of_msm, // column 21
227 msm_add2, // column 22
228 msm_add3, // column 23
229 msm_add4, // column 24
230 msm_x1, // column 25
231 msm_y1, // column 26
232 msm_x2, // column 27
233 msm_y2, // column 28
234 msm_x3, // column 29
235 msm_y3, // column 30
236 msm_x4, // column 31
237 msm_y4, // column 32
238 msm_collision_x1, // column 33
239 msm_collision_x2, // column 34
240 msm_collision_x3, // column 35
241 msm_collision_x4, // column 36
242 msm_lambda1, // column 37
243 msm_lambda2, // column 38
244 msm_lambda3, // column 39
245 msm_lambda4, // column 40
246 msm_slice1, // column 41
247 msm_slice2, // column 42
248 msm_slice3, // column 43
249 msm_slice4, // column 44
250 transcript_reset_accumulator, // column 45
251 lookup_read_counts_0, // column 46
252 lookup_read_counts_1, // column 47
253 transcript_base_infinity, // column 48
254 transcript_base_x_inverse, // column 49
255 transcript_base_y_inverse, // column 50
256 transcript_add_x_equal, // column 51
257 transcript_add_y_equal, // column 52
258 transcript_add_lambda, // column 53
259 transcript_msm_intermediate_x, // column 54
260 transcript_msm_intermediate_y, // column 55
261 transcript_msm_infinity, // column 56
262 transcript_msm_x_inverse, // column 57
263 transcript_msm_count_zero_at_transition, // column 58
264 transcript_msm_count_at_transition_inverse, // column 59
265 msm_round_minus_31_inv) // column 60
266 };
267
272 template <typename DataType> class MaskingEntities {
273 public:
274 DEFINE_FLAVOR_MEMBERS(DataType, gemini_masking_poly)
275 };
276
282 template <typename DataType> class WireToBeShiftedWithoutAccumulatorsEntities {
283 public:
284 DEFINE_FLAVOR_MEMBERS(DataType,
285 transcript_mul, // column 60
286 transcript_msm_count, // column 61
287 precompute_scalar_sum, // column 62
288 precompute_s1hi, // column 63
289 precompute_dx, // column 64
290 precompute_dy, // column 65
291 precompute_tx, // column 66
292 precompute_ty, // column 67
293 msm_transition, // column 68
294 msm_add, // column 69
295 msm_double, // column 70
296 msm_skew, // column 71
297 msm_accumulator_x, // column 72
298 msm_accumulator_y, // column 73
299 msm_count, // column 74
300 msm_round, // column 75
301 msm_add1, // column 76
302 msm_pc, // column 77
303 precompute_pc, // column 78
304 transcript_pc, // column 79
305 precompute_round, // column 80
306 precompute_select) // column 81
307 };
308
312 template <typename DataType> class WireToBeShiftedAccumulatorEntities {
313 public:
314 DEFINE_FLAVOR_MEMBERS(DataType,
315 transcript_accumulator_not_empty, // column 82
316 transcript_accumulator_x, // column 83
317 transcript_accumulator_y) // column 84
318 };
319
324 template <typename DataType>
325 class WitnessEntities : public WireNonShiftedEntities<DataType>,
327 public WireToBeShiftedAccumulatorEntities<DataType>,
328 public DerivedWitnessEntities<DataType> {
329 public:
340
341 // Used to amortize the commitment time when the ECCVM size is fixed
348 // The following getters group the wires by execution subtable (transcript / precompute / msm) plus the
349 // lookup read counts. ProverPolynomials uses these groups to physically allocate each subtable's columns to
350 // that subtable's actual row count, rather than zero-padding every column to the full (virtual) dyadic
351 // circuit size. The subtables have different lengths, so per-table sizing saves substantial prover memory.
353 {
354 return RefArray{ this->transcript_add,
355 this->transcript_eq,
356 this->transcript_msm_transition,
357 this->transcript_Px,
358 this->transcript_Py,
359 this->transcript_z1,
360 this->transcript_z2,
361 this->transcript_z1zero,
362 this->transcript_z2zero,
363 this->transcript_op,
364 this->transcript_msm_x,
365 this->transcript_msm_y,
366 this->transcript_reset_accumulator,
367 this->transcript_base_infinity,
368 this->transcript_base_x_inverse,
369 this->transcript_base_y_inverse,
370 this->transcript_add_x_equal,
371 this->transcript_add_y_equal,
372 this->transcript_add_lambda,
373 this->transcript_msm_intermediate_x,
374 this->transcript_msm_intermediate_y,
375 this->transcript_msm_infinity,
376 this->transcript_msm_x_inverse,
377 this->transcript_msm_count_zero_at_transition,
378 this->transcript_msm_count_at_transition_inverse };
379 }
381 {
382 return RefArray{ this->transcript_mul, this->transcript_msm_count, this->transcript_pc };
383 }
385 {
386 return RefArray{ this->precompute_point_transition,
387 this->precompute_s1lo,
388 this->precompute_s2hi,
389 this->precompute_s2lo,
390 this->precompute_s3hi,
391 this->precompute_s3lo,
392 this->precompute_s4hi,
393 this->precompute_s4lo,
394 this->precompute_skew };
395 }
397 {
398 return RefArray{ this->precompute_scalar_sum, this->precompute_s1hi, this->precompute_dx,
399 this->precompute_dy, this->precompute_tx, this->precompute_ty,
400 this->precompute_pc, this->precompute_round, this->precompute_select };
401 }
403 {
404 return RefArray{ this->msm_size_of_msm,
405 this->msm_add2,
406 this->msm_add3,
407 this->msm_add4,
408 this->msm_x1,
409 this->msm_y1,
410 this->msm_x2,
411 this->msm_y2,
412 this->msm_x3,
413 this->msm_y3,
414 this->msm_x4,
415 this->msm_y4,
416 this->msm_collision_x1,
417 this->msm_collision_x2,
418 this->msm_collision_x3,
419 this->msm_collision_x4,
420 this->msm_lambda1,
421 this->msm_lambda2,
422 this->msm_lambda3,
423 this->msm_lambda4,
424 this->msm_slice1,
425 this->msm_slice2,
426 this->msm_slice3,
427 this->msm_slice4,
428 this->msm_round_minus_31_inv };
429 }
431 {
432 return RefArray{ this->msm_transition, this->msm_add, this->msm_double,
433 this->msm_skew, this->msm_accumulator_x, this->msm_accumulator_y,
434 this->msm_count, this->msm_round, this->msm_add1,
435 this->msm_pc };
436 }
437 auto get_lookup_read_counts() { return RefArray{ this->lookup_read_counts_0, this->lookup_read_counts_1 }; }
438 };
439
443 template <typename DataType> class ShiftedEntities {
444 public:
446 transcript_mul_shift, // column 0
447 transcript_msm_count_shift, // column 1
448 precompute_scalar_sum_shift, // column 2
449 precompute_s1hi_shift, // column 3
450 precompute_dx_shift, // column 4
451 precompute_dy_shift, // column 5
452 precompute_tx_shift, // column 6
453 precompute_ty_shift, // column 7
454 msm_transition_shift, // column 8
455 msm_add_shift, // column 9
456 msm_double_shift, // column 10
457 msm_skew_shift, // column 11
458 msm_accumulator_x_shift, // column 12
459 msm_accumulator_y_shift, // column 13
460 msm_count_shift, // column 14
461 msm_round_shift, // column 15
462 msm_add1_shift, // column 16
463 msm_pc_shift, // column 17
464 precompute_pc_shift, // column 18
465 transcript_pc_shift, // column 19
466 precompute_round_shift, // column 20
467 precompute_select_shift, // column 21
468 transcript_accumulator_not_empty_shift, // column 22
469 transcript_accumulator_x_shift, // column 23
470 transcript_accumulator_y_shift, // column 24
471 z_perm_shift); // column 25
472 };
473
474 template <typename DataType, typename PrecomputedAndWitnessEntitiesSuperset>
475 static auto get_to_be_shifted(PrecomputedAndWitnessEntitiesSuperset& entities)
476 {
477 // NOTE: must match order of ShiftedEntities above!
478 return RefArray{ entities.transcript_mul, // column 0
479 entities.transcript_msm_count, // column 1
480 entities.precompute_scalar_sum, // column 2
481 entities.precompute_s1hi, // column 3
482 entities.precompute_dx, // column 4
483 entities.precompute_dy, // column 5
484 entities.precompute_tx, // column 6
485 entities.precompute_ty, // column 7
486 entities.msm_transition, // column 8
487 entities.msm_add, // column 9
488 entities.msm_double, // column 10
489 entities.msm_skew, // column 11
490 entities.msm_accumulator_x, // column 12
491 entities.msm_accumulator_y, // column 13
492 entities.msm_count, // column 14
493 entities.msm_round, // column 15
494 entities.msm_add1, // column 16
495 entities.msm_pc, // column 17
496 entities.precompute_pc, // column 18
497 entities.transcript_pc, // column 19
498 entities.precompute_round, // column 20
499 entities.precompute_select, // column 21
500 entities.transcript_accumulator_not_empty, // column 22
501 entities.transcript_accumulator_x, // column 23
502 entities.transcript_accumulator_y, // column 24
503 entities.z_perm }; // column 25
504 }
505
516 template <typename DataType>
517 class AllEntities : public MaskingEntities<DataType>,
518 public PrecomputedEntities<DataType>,
519 public WitnessEntities<DataType>,
520 public ShiftedEntities<DataType> {
521 public:
532 auto get_to_be_shifted() { return ECCVMFlavor::get_to_be_shifted<DataType>(*this); }
533 auto get_to_be_shifted() const { return ECCVMFlavor::get_to_be_shifted<DataType>(*this); }
537 };
538
543 class AllValues : public AllEntities<FF> {
544 public:
546 using Base::Base;
547 };
548
553
558
562 class ProverPolynomials : public AllEntities<Polynomial> {
563 public:
564 // Define all operations as default, except copy construction/assignment
565 ProverPolynomials() = default;
568 ProverPolynomials(ProverPolynomials&& o) noexcept = default;
572 [[nodiscard]] size_t get_polynomial_size() const { return this->lagrange_first.size(); }
573
578 AllValues get_row(const size_t row_idx) const
579 {
581 for (auto [result_field, polynomial] : zip_view(result.get_all(), this->get_all())) {
582 // .get() returns 0 past the polynomial's end_index; operator[] would be UB on the unallocated
583 // virtual tail, since columns are physically sized to their subtable (see the get_*_wires getters).
584 result_field = polynomial.get(row_idx);
585 }
586 return result;
587 }
588 // Set all shifted polynomials based on their to-be-shifted counterpart
590 {
591 for (auto [shifted, to_be_shifted] : zip_view(get_shifted(), get_to_be_shifted())) {
592 shifted = to_be_shifted.shifted();
593 }
594 }
595
596#ifdef FUZZING
597 ProverPolynomials(const CircuitBuilder& builder, bool disable_fixed_dyadic_trace_size = false)
598#else
697#endif
698 {
699 // compute rows for the three different sections of the ECCVM execution trace
700 // Note: the first operation (index 0) is always a hiding op with random Px, Py values
701 const auto transcript_rows =
702 ECCVMTranscriptBuilder::compute_rows(builder.op_queue->get_eccvm_ops(), builder.get_number_of_muls());
703 const std::vector<MSM> msms = builder.get_msms();
704 const auto point_table_rows =
707 msms, builder.get_number_of_muls(), builder.op_queue->get_num_msm_rows());
708 const auto& msm_rows = std::get<0>(result);
709 const auto& point_table_read_counts = std::get<1>(result);
710
711 const size_t num_rows =
712 std::max({ point_table_rows.size(), msm_rows.size(), transcript_rows.size() }) + TRACE_OFFSET;
713 vinfo("Num rows in the ECCVM: ", num_rows);
714 const auto log_num_rows = static_cast<size_t>(numeric::get_msb64(num_rows));
715 size_t dyadic_num_rows = 1UL << (log_num_rows + (1UL << log_num_rows == num_rows ? 0 : 1));
716 BB_ASSERT_LTE(dyadic_num_rows,
718 "The ECCVM circuit size has exceeded the fixed upper bound! Fixed size: " +
719 std::to_string(ECCVM_FIXED_SIZE) + " actual size: " + std::to_string(dyadic_num_rows));
720
721#ifdef FUZZING
722 // We don't want to spend all the time generating the full trace if we are just fuzzing eccvm.
723 if (disable_fixed_dyadic_trace_size) {
724 dyadic_num_rows = num_rows;
725 } else {
726 dyadic_num_rows = ECCVM_FIXED_SIZE;
727 }
728#else
729 dyadic_num_rows = ECCVM_FIXED_SIZE;
730#endif
731 // The first TRACE_OFFSET rows are disabled.
732 // Trace data starts at row TRACE_OFFSET. lagrange_last goes to dyadic end.
733 constexpr size_t trace_offset = TRACE_OFFSET;
734 const auto offset_size = [](const size_t size) { return TRACE_OFFSET + size; };
735 const size_t transcript_alloc_size = offset_size(transcript_rows.size());
736 const size_t point_table_alloc_size = offset_size(point_table_rows.size());
737 const size_t msm_alloc_size = offset_size(msm_rows.size());
738 const size_t read_counts_alloc_size = offset_size(point_table_read_counts[0].size() + 1);
739
740 // Active trace data occupies the single contiguous range [TRACE_OFFSET, num_rows) -- the union of the
741 // subtable ranges above, with no inactive rows in between -- so it is a tight row-skip prefix: every row
742 // beyond num_rows is relation-trivial. The sumcheck prover takes this directly as its static row-skip
743 // manifest (num_rows already includes the TRACE_OFFSET shift). See
744 // SumcheckProverRound::HAS_STATIC_ROW_SKIP_MANIFEST.
746
747 // 1. Wires backed by their active table range, with virtual zeros beyond that range.
748 for (auto& poly : get_transcript_wires()) {
749 poly = Polynomial(transcript_alloc_size, dyadic_num_rows);
750 poly.add_masking();
751 }
752 for (auto& poly : get_precompute_wires()) {
753 poly = Polynomial(point_table_alloc_size, dyadic_num_rows);
754 poly.add_masking();
755 }
756 for (auto& poly : get_msm_wires()) {
757 poly = Polynomial(msm_alloc_size, dyadic_num_rows);
758 poly.add_masking();
759 }
760 for (auto& poly : get_lookup_read_counts()) {
761 poly = Polynomial(read_counts_alloc_size, dyadic_num_rows);
762 poly.add_masking();
763 }
764
765 // 2. To-be-shifted wires retain one leading zero row for their shifted views.
766 for (auto& poly : get_shifted_transcript_wires()) {
767 poly = Polynomial::shiftable(transcript_alloc_size, dyadic_num_rows, /*masked=*/true);
768 }
769 for (auto& poly : get_shifted_precompute_wires()) {
770 poly = Polynomial::shiftable(point_table_alloc_size, dyadic_num_rows, /*masked=*/true);
771 }
772 for (auto& poly : get_shifted_msm_wires()) {
773 poly = Polynomial::shiftable(msm_alloc_size, dyadic_num_rows, /*masked=*/true);
774 }
776 poly = Polynomial::shiftable(transcript_alloc_size, dyadic_num_rows, /*masked=*/true);
777 }
778
779 // 3. z_perm: shiftable with masking (grand product starts after disabled region)
780 z_perm = Polynomial::shiftable(dyadic_num_rows, dyadic_num_rows, /*masked=*/true);
781
782 // 4. Catch-all: precomputed, lookup_inverses, gemini_masking_poly → full size
783 for (auto& poly : get_all()) {
784 if (poly.is_empty()) {
785 poly = Polynomial(dyadic_num_rows);
786 }
787 }
788 // lookup_inverses is a derived witness — mask it so the commitment hides its values
789 lookup_inverses.add_masking();
790
791 // Lagrange polys shifted by the disabled head region
792 lagrange_first.at(trace_offset) = 1;
793 lagrange_second.at(trace_offset + 1) = 1;
794 lagrange_third.at(trace_offset + 2) = 1;
795 lagrange_last.at(dyadic_num_rows - 1) = 1;
796
797 static const auto MSM_ROUND_MINUS_31_INV_BY_ROUND = []() {
799 for (size_t round = 0; round < table.size(); ++round) {
800 // IMPORTANT: when round == LAST_ADDITION_ROUND, the entry is exactly 0 because
801 // (round - LAST_ADDITION_ROUND)^-1 is undefined. Every other slot stores the canonical inverse.
802 table[round] = (round == LAST_ADDITION_ROUND)
803 ? FF(0)
804 : (FF(static_cast<uint32_t>(round)) - FF(LAST_ADDITION_ROUND)).invert();
805 }
806 return table;
807 }();
808
809 for (size_t i = 0; i < point_table_read_counts[0].size(); ++i) {
810 // Explanation of off-by-one offset:
811 // When computing the WNAF slice for a point at point counter value `pc` and a round index `round`, the
812 // row number that computes the slice can be derived. This row number is then mapped to the index of
813 // `lookup_read_counts`. We do this mapping in `ecc_msm_relation`. We are off-by-one because we add an
814 // empty row at the start of the WNAF columns that is not accounted for (index of lookup_read_counts
815 // maps to the row in our WNAF columns that computes a slice for a given value of pc and round)
816 lookup_read_counts_0.at(trace_offset + i + 1) = point_table_read_counts[0][i];
817 lookup_read_counts_1.at(trace_offset + i + 1) = point_table_read_counts[1][i];
818 }
819
820 // compute polynomials for transcript columns (offset by trace_offset for top masking)
821 parallel_for_range(transcript_rows.size(), [&](size_t start, size_t end) {
822 for (size_t i = start; i < end; i++) {
823 const size_t idx = trace_offset + i;
824 transcript_accumulator_not_empty.set_if_valid_index(idx, transcript_rows[i].accumulator_not_empty);
825 transcript_add.set_if_valid_index(idx, transcript_rows[i].q_add);
826 transcript_mul.set_if_valid_index(idx, transcript_rows[i].q_mul);
827 transcript_eq.set_if_valid_index(idx, transcript_rows[i].q_eq);
828 transcript_reset_accumulator.set_if_valid_index(idx, transcript_rows[i].q_reset_accumulator);
829 transcript_msm_transition.set_if_valid_index(idx, transcript_rows[i].msm_transition);
830 transcript_pc.set_if_valid_index(idx, transcript_rows[i].pc);
831 transcript_msm_count.set_if_valid_index(idx, transcript_rows[i].msm_count);
832 transcript_Px.set_if_valid_index(idx, transcript_rows[i].base_x);
833 transcript_Py.set_if_valid_index(idx, transcript_rows[i].base_y);
834 transcript_z1.set_if_valid_index(idx, transcript_rows[i].z1);
835 transcript_z2.set_if_valid_index(idx, transcript_rows[i].z2);
836 transcript_z1zero.set_if_valid_index(idx, transcript_rows[i].z1_zero);
837 transcript_z2zero.set_if_valid_index(idx, transcript_rows[i].z2_zero);
838 transcript_op.set_if_valid_index(idx, transcript_rows[i].opcode);
839 transcript_accumulator_x.set_if_valid_index(idx, transcript_rows[i].accumulator_x);
840 transcript_accumulator_y.set_if_valid_index(idx, transcript_rows[i].accumulator_y);
841 transcript_msm_x.set_if_valid_index(idx, transcript_rows[i].msm_output_x);
842 transcript_msm_y.set_if_valid_index(idx, transcript_rows[i].msm_output_y);
843 transcript_base_infinity.set_if_valid_index(idx, transcript_rows[i].base_infinity);
844 transcript_base_x_inverse.set_if_valid_index(idx, transcript_rows[i].base_x_inverse);
845 transcript_base_y_inverse.set_if_valid_index(idx, transcript_rows[i].base_y_inverse);
846 transcript_add_x_equal.set_if_valid_index(idx, transcript_rows[i].transcript_add_x_equal);
847 transcript_add_y_equal.set_if_valid_index(idx, transcript_rows[i].transcript_add_y_equal);
848 transcript_add_lambda.set_if_valid_index(idx, transcript_rows[i].transcript_add_lambda);
849 transcript_msm_intermediate_x.set_if_valid_index(idx,
850 transcript_rows[i].transcript_msm_intermediate_x);
851 transcript_msm_intermediate_y.set_if_valid_index(idx,
852 transcript_rows[i].transcript_msm_intermediate_y);
853 transcript_msm_infinity.set_if_valid_index(idx, transcript_rows[i].transcript_msm_infinity);
854 transcript_msm_x_inverse.set_if_valid_index(idx, transcript_rows[i].transcript_msm_x_inverse);
855 transcript_msm_count_zero_at_transition.set_if_valid_index(
856 idx, transcript_rows[i].msm_count_zero_at_transition);
857 transcript_msm_count_at_transition_inverse.set_if_valid_index(
858 idx, transcript_rows[i].msm_count_at_transition_inverse);
859 }
860 });
861
862 parallel_for_range(point_table_rows.size(), [&](size_t start, size_t end) {
863 for (size_t i = start; i < end; i++) {
864 const size_t idx = trace_offset + i;
865 // first row is always an empty row (to accommodate shifted polynomials which must have 0 as 1st
866 // coefficient). All other rows in the point_table_rows represent active wnaf gates (i.e.
867 // precompute_select = 1)
868 precompute_select.set_if_valid_index(idx, (i != 0) ? 1 : 0);
869 precompute_pc.set_if_valid_index(idx, point_table_rows[i].pc);
870 precompute_point_transition.set_if_valid_index(
871 idx, static_cast<uint64_t>(point_table_rows[i].point_transition));
872 precompute_round.set_if_valid_index(idx, point_table_rows[i].round);
873 precompute_scalar_sum.set_if_valid_index(idx, point_table_rows[i].scalar_sum);
874 precompute_s1hi.set_if_valid_index(idx, point_table_rows[i].s1);
875 precompute_s1lo.set_if_valid_index(idx, point_table_rows[i].s2);
876 precompute_s2hi.set_if_valid_index(idx, point_table_rows[i].s3);
877 precompute_s2lo.set_if_valid_index(idx, point_table_rows[i].s4);
878 precompute_s3hi.set_if_valid_index(idx, point_table_rows[i].s5);
879 precompute_s3lo.set_if_valid_index(idx, point_table_rows[i].s6);
880 precompute_s4hi.set_if_valid_index(idx, point_table_rows[i].s7);
881 precompute_s4lo.set_if_valid_index(idx, point_table_rows[i].s8);
882 // If skew is active (i.e. we need to subtract a base point from the msm result),
883 // write `7` into rows.precompute_skew. `7`, in binary representation, equals `-1` when converted
884 // into WNAF form
885 precompute_skew.set_if_valid_index(idx, point_table_rows[i].skew ? 7 : 0);
886 precompute_dx.set_if_valid_index(idx, point_table_rows[i].precompute_double.x);
887 precompute_dy.set_if_valid_index(idx, point_table_rows[i].precompute_double.y);
888 precompute_tx.set_if_valid_index(idx, point_table_rows[i].precompute_accumulator.x);
889 precompute_ty.set_if_valid_index(idx, point_table_rows[i].precompute_accumulator.y);
890 }
891 });
892
893 // compute polynomials for the msm columns (offset by trace_offset for top masking)
894 parallel_for_range(msm_rows.size(), [&](size_t start, size_t end) {
895 for (size_t i = start; i < end; i++) {
896 const size_t idx = trace_offset + i;
897 msm_transition.set_if_valid_index(idx, static_cast<int>(msm_rows[i].msm_transition));
898 msm_add.set_if_valid_index(idx, static_cast<int>(msm_rows[i].q_add));
899 msm_double.set_if_valid_index(idx, static_cast<int>(msm_rows[i].q_double));
900 msm_skew.set_if_valid_index(idx, static_cast<int>(msm_rows[i].q_skew));
901 msm_accumulator_x.set_if_valid_index(idx, msm_rows[i].accumulator_x);
902 msm_accumulator_y.set_if_valid_index(idx, msm_rows[i].accumulator_y);
903 msm_pc.set_if_valid_index(idx, msm_rows[i].pc);
904 msm_size_of_msm.set_if_valid_index(idx, msm_rows[i].msm_size);
905 msm_count.set_if_valid_index(idx, msm_rows[i].msm_count);
906 msm_round.set_if_valid_index(idx, msm_rows[i].msm_round);
907 // IMPORTANT: when msm_round == 31, this witness is exactly 0 because (31 - 31)^-1 does not exist.
908 // On every other active MSM row it is the precomputed inverse (msm_round - 31)^-1.
909 msm_round_minus_31_inv.set_if_valid_index(idx,
910 MSM_ROUND_MINUS_31_INV_BY_ROUND[msm_rows[i].msm_round]);
911 msm_add1.set_if_valid_index(idx, static_cast<int>(msm_rows[i].add_state[0].add));
912 msm_add2.set_if_valid_index(idx, static_cast<int>(msm_rows[i].add_state[1].add));
913 msm_add3.set_if_valid_index(idx, static_cast<int>(msm_rows[i].add_state[2].add));
914 msm_add4.set_if_valid_index(idx, static_cast<int>(msm_rows[i].add_state[3].add));
915 msm_x1.set_if_valid_index(idx, msm_rows[i].add_state[0].point.x);
916 msm_y1.set_if_valid_index(idx, msm_rows[i].add_state[0].point.y);
917 msm_x2.set_if_valid_index(idx, msm_rows[i].add_state[1].point.x);
918 msm_y2.set_if_valid_index(idx, msm_rows[i].add_state[1].point.y);
919 msm_x3.set_if_valid_index(idx, msm_rows[i].add_state[2].point.x);
920 msm_y3.set_if_valid_index(idx, msm_rows[i].add_state[2].point.y);
921 msm_x4.set_if_valid_index(idx, msm_rows[i].add_state[3].point.x);
922 msm_y4.set_if_valid_index(idx, msm_rows[i].add_state[3].point.y);
923 msm_collision_x1.set_if_valid_index(idx, msm_rows[i].add_state[0].collision_inverse);
924 msm_collision_x2.set_if_valid_index(idx, msm_rows[i].add_state[1].collision_inverse);
925 msm_collision_x3.set_if_valid_index(idx, msm_rows[i].add_state[2].collision_inverse);
926 msm_collision_x4.set_if_valid_index(idx, msm_rows[i].add_state[3].collision_inverse);
927 msm_lambda1.set_if_valid_index(idx, msm_rows[i].add_state[0].lambda);
928 msm_lambda2.set_if_valid_index(idx, msm_rows[i].add_state[1].lambda);
929 msm_lambda3.set_if_valid_index(idx, msm_rows[i].add_state[2].lambda);
930 msm_lambda4.set_if_valid_index(idx, msm_rows[i].add_state[3].lambda);
931 msm_slice1.set_if_valid_index(idx, msm_rows[i].add_state[0].slice);
932 msm_slice2.set_if_valid_index(idx, msm_rows[i].add_state[1].slice);
933 msm_slice3.set_if_valid_index(idx, msm_rows[i].add_state[2].slice);
934 msm_slice4.set_if_valid_index(idx, msm_rows[i].add_state[3].slice);
935 }
936 });
937 this->set_shifted();
938 }
939 };
940
946
952 public:
953 size_t circuit_size = ECCVM_FIXED_SIZE; // The circuit size is fixed for the ECCVM.
954 size_t log_circuit_size = CONST_ECCVM_LOG_N;
955
956 // Used to amortize the commitment time if the `fixed size` > `real_size`.
957 size_t real_size = 0;
958
959 ProverPolynomials polynomials; // storage for all polynomials evaluated by the prover
961
962 // Constructor for fixed size ProvingKey
964 : real_size(builder.get_circuit_subgroup_size(builder.get_estimated_num_finalized_gates()))
965 , polynomials(builder)
966 {}
967 };
968
974
981 class CommitmentLabels : public AllEntities<std::string> {
982 private:
984
985 public:
987 : AllEntities<std::string>()
988 {
989 Base::transcript_add = "TRANSCRIPT_ADD";
990 Base::transcript_mul = "TRANSCRIPT_MUL";
991 Base::transcript_eq = "TRANSCRIPT_EQ";
992 Base::transcript_msm_transition = "TRANSCRIPT_MSM_TRANSITION";
993 Base::transcript_pc = "TRANSCRIPT_PC";
994 Base::transcript_msm_count = "TRANSCRIPT_MSM_COUNT";
995 Base::transcript_Px = "TRANSCRIPT_PX";
996 Base::transcript_Py = "TRANSCRIPT_PY";
997 Base::transcript_z1 = "TRANSCRIPT_Z1";
998 Base::transcript_z2 = "TRANSCRIPT_Z2";
999 Base::transcript_z1zero = "TRANSCRIPT_Z1ZERO";
1000 Base::transcript_z2zero = "TRANSCRIPT_Z2ZERO";
1001 Base::transcript_op = "TRANSCRIPT_OP";
1002 Base::transcript_accumulator_x = "TRANSCRIPT_ACCUMULATOR_X";
1003 Base::transcript_accumulator_y = "TRANSCRIPT_ACCUMULATOR_Y";
1004 Base::transcript_msm_x = "TRANSCRIPT_MSM_X";
1005 Base::transcript_msm_y = "TRANSCRIPT_MSM_Y";
1006 Base::precompute_pc = "PRECOMPUTE_PC";
1007 Base::precompute_point_transition = "PRECOMPUTE_POINT_TRANSITION";
1008 Base::precompute_round = "PRECOMPUTE_ROUND";
1009 Base::precompute_scalar_sum = "PRECOMPUTE_SCALAR_SUM";
1010 Base::precompute_s1hi = "PRECOMPUTE_S1HI";
1011 Base::precompute_s1lo = "PRECOMPUTE_S1LO";
1012 Base::precompute_s2hi = "PRECOMPUTE_S2HI";
1013 Base::precompute_s2lo = "PRECOMPUTE_S2LO";
1014 Base::precompute_s3hi = "PRECOMPUTE_S3HI";
1015 Base::precompute_s3lo = "PRECOMPUTE_S3LO";
1016 Base::precompute_s4hi = "PRECOMPUTE_S4HI";
1017 Base::precompute_s4lo = "PRECOMPUTE_S4LO";
1018 Base::precompute_skew = "PRECOMPUTE_SKEW";
1019 Base::precompute_dx = "PRECOMPUTE_DX";
1020 Base::precompute_dy = "PRECOMPUTE_DY";
1021 Base::precompute_tx = "PRECOMPUTE_TX";
1022 Base::precompute_ty = "PRECOMPUTE_TY";
1023 Base::msm_transition = "MSM_TRANSITION";
1024 Base::msm_add = "MSM_ADD";
1025 Base::msm_double = "MSM_DOUBLE";
1026 Base::msm_skew = "MSM_SKEW";
1027 Base::msm_accumulator_x = "MSM_ACCUMULATOR_X";
1028 Base::msm_accumulator_y = "MSM_ACCUMULATOR_Y";
1029 Base::msm_pc = "MSM_PC";
1030 Base::msm_size_of_msm = "MSM_SIZE_OF_MSM";
1031 Base::msm_count = "MSM_COUNT";
1032 Base::msm_round = "MSM_ROUND";
1033 Base::msm_add1 = "MSM_ADD1";
1034 Base::msm_add2 = "MSM_ADD2";
1035 Base::msm_add3 = "MSM_ADD3";
1036 Base::msm_add4 = "MSM_ADD4";
1037 Base::msm_x1 = "MSM_X1";
1038 Base::msm_y1 = "MSM_Y1";
1039 Base::msm_x2 = "MSM_X2";
1040 Base::msm_y2 = "MSM_Y2";
1041 Base::msm_x3 = "MSM_X3";
1042 Base::msm_y3 = "MSM_Y3";
1043 Base::msm_x4 = "MSM_X4";
1044 Base::msm_y4 = "MSM_Y4";
1045 Base::msm_collision_x1 = "MSM_COLLISION_X1";
1046 Base::msm_collision_x2 = "MSM_COLLISION_X2";
1047 Base::msm_collision_x3 = "MSM_COLLISION_X3";
1048 Base::msm_collision_x4 = "MSM_COLLISION_X4";
1049 Base::msm_lambda1 = "MSM_LAMBDA1";
1050 Base::msm_lambda2 = "MSM_LAMBDA2";
1051 Base::msm_lambda3 = "MSM_LAMBDA3";
1052 Base::msm_lambda4 = "MSM_LAMBDA4";
1053 Base::msm_slice1 = "MSM_SLICE1";
1054 Base::msm_slice2 = "MSM_SLICE2";
1055 Base::msm_slice3 = "MSM_SLICE3";
1056 Base::msm_slice4 = "MSM_SLICE4";
1057 Base::transcript_accumulator_not_empty = "TRANSCRIPT_ACCUMULATOR_NOT_EMPTY";
1058 Base::transcript_reset_accumulator = "TRANSCRIPT_RESET_ACCUMULATOR";
1059 Base::precompute_select = "PRECOMPUTE_SELECT";
1060 Base::lookup_read_counts_0 = "LOOKUP_READ_COUNTS_0";
1061 Base::lookup_read_counts_1 = "LOOKUP_READ_COUNTS_1";
1062 Base::transcript_base_infinity = "TRANSCRIPT_BASE_INFINITY";
1063 Base::transcript_base_x_inverse = "TRANSCRIPT_BASE_X_INVERSE";
1064 Base::transcript_base_y_inverse = "TRANSCRIPT_BASE_Y_INVERSE";
1065 Base::transcript_add_x_equal = "TRANSCRIPT_ADD_X_EQUAL";
1066 Base::transcript_add_y_equal = "TRANSCRIPT_ADD_Y_EQUAL";
1067 Base::transcript_add_lambda = "TRANSCRIPT_ADD_LAMBDA";
1068 Base::transcript_msm_intermediate_x = "TRANSCRIPT_MSM_INTERMEDIATE_X";
1069 Base::transcript_msm_intermediate_y = "TRANSCRIPT_MSM_INTERMEDIATE_Y";
1070 Base::transcript_msm_infinity = "TRANSCRIPT_MSM_INFINITY";
1071 Base::transcript_msm_x_inverse = "TRANSCRIPT_MSM_X_INVERSE";
1072 Base::transcript_msm_count_zero_at_transition = "TRANSCRIPT_MSM_COUNT_ZERO_AT_TRANSITION";
1073 Base::transcript_msm_count_at_transition_inverse = "TRANSCRIPT_MSM_COUNT_AT_TRANSITION_INVERSE";
1074 Base::msm_round_minus_31_inv = "MSM_ROUND_MINUS_31_INV";
1075 Base::z_perm = "Z_PERM";
1076 Base::z_perm_shift = "Z_PERM_SHIFT";
1077 Base::lookup_inverses = "LOOKUP_INVERSES";
1078 // The ones beginning with "__" are only used for debugging
1079 Base::lagrange_first = "__LAGRANGE_FIRST";
1080 Base::lagrange_second = "__LAGRANGE_SECOND";
1081 Base::lagrange_third = "__LAGRANGE_THIRD";
1082 Base::lagrange_last = "__LAGRANGE_LAST";
1083 };
1084
1085 // Used in pippenger_unsafe to activate duplicate stripping.
1086 // Dups need to be > ~14 bits to be worth stripping.
1087 // Empirical tests showed these polys had high duplicate counts under these conditions
1088 static bool wire_has_high_duplicate_density(const std::string& label) noexcept
1089 {
1090 return label == "MSM_X1" || label == "MSM_X2" || label == "MSM_X3" || label == "MSM_X4" ||
1091 label == "MSM_Y1" || label == "MSM_Y2" || label == "MSM_Y3" || label == "MSM_Y4" ||
1092 label == "MSM_ROUND_MINUS_31_INV" || label == "PRECOMPUTE_DX" || label == "PRECOMPUTE_DY" ||
1093 label == "PRECOMPUTE_TX" || label == "PRECOMPUTE_TY" || label == "TRANSCRIPT_ACCUMULATOR_X" ||
1094 label == "TRANSCRIPT_ACCUMULATOR_Y" || label == "TRANSCRIPT_PX" || label == "TRANSCRIPT_PY";
1095 }
1096 };
1097
1098 template <typename Commitment, typename VerificationKey>
1099 class VerifierCommitments_ : public AllEntities<Commitment> {
1100 public:
1101 VerifierCommitments_(const std::shared_ptr<VerificationKey>& verification_key)
1102 {
1103 this->lagrange_first = verification_key->lagrange_first;
1104 this->lagrange_second = verification_key->lagrange_second;
1105 this->lagrange_third = verification_key->lagrange_third;
1106 this->lagrange_last = verification_key->lagrange_last;
1107 }
1108 };
1109
1111
1117 public:
1119 std::vector<Commitment> ipa_l_comms;
1120 std::vector<Commitment> ipa_r_comms;
1123
1124 IPATranscript() = default;
1125
1127 {
1128 // take current proof and put them into the struct
1129 size_t num_frs_read = 0;
1130 ipa_poly_degree = NativeTranscript::template deserialize_from_buffer<uint32_t>(NativeTranscript::proof_data,
1131 num_frs_read);
1132
1133 for (size_t i = 0; i < CONST_ECCVM_LOG_N; ++i) {
1134 ipa_l_comms.emplace_back(NativeTranscript::template deserialize_from_buffer<Commitment>(
1135 NativeTranscript::proof_data, num_frs_read));
1136 ipa_r_comms.emplace_back(NativeTranscript::template deserialize_from_buffer<Commitment>(
1137 NativeTranscript::proof_data, num_frs_read));
1138 }
1139 ipa_G_0_eval = NativeTranscript::template deserialize_from_buffer<Commitment>(NativeTranscript::proof_data,
1140 num_frs_read);
1141 ipa_a_0_eval =
1142 NativeTranscript::template deserialize_from_buffer<FF>(NativeTranscript::proof_data, num_frs_read);
1143 }
1144
1146 {
1147 size_t old_proof_length = NativeTranscript::proof_data.size();
1148 NativeTranscript::proof_data.clear();
1149
1150 NativeTranscript::serialize_to_buffer(ipa_poly_degree, NativeTranscript::proof_data);
1151 for (size_t i = 0; i < CONST_ECCVM_LOG_N; ++i) {
1152 NativeTranscript::serialize_to_buffer(ipa_l_comms[i], NativeTranscript::proof_data);
1153 NativeTranscript::serialize_to_buffer(ipa_r_comms[i], NativeTranscript::proof_data);
1154 }
1155
1156 serialize_to_buffer(ipa_G_0_eval, proof_data);
1157 serialize_to_buffer(ipa_a_0_eval, proof_data);
1158
1159 BB_ASSERT_EQ(NativeTranscript::proof_data.size(), old_proof_length);
1160 }
1161 };
1162
1163 template <typename ProverPolynomialsOrPartiallyEvaluatedMultivariates>
1164 static size_t row_skip_active_prefix_end(const ProverPolynomialsOrPartiallyEvaluatedMultivariates& polynomials)
1165 {
1166 return polynomials.row_skip_active_prefix_end;
1167 }
1168};
1169} // 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
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)
typename G1::affine_element Commitment
typename Curve::BaseField BF
static constexpr bool PARALLELIZE_RELATION_BATCHING
bb::Polynomial< FF > Polynomial
std::tuple< ECCVMTranscriptRelation< FF >, ECCVMPointTableRelation< FF >, ECCVMWnafRelation< FF >, ECCVMMSMRelation< FF >, ECCVMSetRelation< FF >, ECCVMLookupRelation< FF >, ECCVMBoolsRelation< FF >, ECCVMShiftableInitRelation< FF > > Relations_
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 TRIPLE_IPA_PROOF_LENGTH
static constexpr size_t NUM_WITNESS_ENTITIES
static constexpr size_t NUM_TRANSLATION_OPENING_CLAIMS
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 size_t NUM_RELATIONS
Relations_< FF > Relations
bb::eccvm::MSM< CycleGroup > MSM
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:104
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:23
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.
static constexpr size_t SUBGROUP_SIZE
Definition grumpkin.hpp:74
static constexpr uint32_t LIBRA_UNIVARIATES_LENGTH
Definition grumpkin.hpp:87
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
std::string label
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
constexpr size_t NUM_SMALL_IPA_TRANSCRIPT_EVALS
std::vector< fr > HonkProof
Definition proof.hpp:15
constexpr size_t LAST_ADDITION_ROUND
RefArray< T,(Ns+...)> constexpr concatenate(const RefArray< T, Ns > &... ref_arrays)
Concatenates multiple RefArray objects into a single RefArray.
constexpr size_t NUM_SMALL_IPA_OPENING_CLAIMS
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:142
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)
BB_VF_LOAD_LIMBS * this
VectorField result