Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecc_transcript_short_relation.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Planned, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8
12
13namespace bb {
14
15template <typename FF_> class ECCVMTranscriptShortRelationImpl : public ECCVMTranscriptRelationImpl<FF_> {
16 public:
17 using FF = FF_;
19
20 // This relation covers the first 27 transcript subrelations (indices 0..26). The final 5 subrelations
21 // (OFFSET_GENERATOR_X/Y, MSM_INFINITY_*) are gated entirely by `msm_transition` and live in the separate
22 // ECCVMTranscriptMsmTransitionShortRelation, which the prover skips on the (overwhelming majority of) rows where
23 // msm_transition == 0. The base enum was ordered to place those 5 contiguously at the end so this split preserves
24 // the global subrelation order (and hence the alpha batching) expected by the verifier.
25 //
26 // Tightened per-subrelation partial lengths. LAMBDA_RELATION / ACCUMULATOR_X/Y_UPDATE / ACCUMULATOR_EMPTY_UPDATE
27 // stay at length 8 so they can share promoted Accumulator-typed intermediates (result_is_lhs/rhs/inf,
28 // opcode_is_zero). Other subrelations only share length-2 short views with the core block and can shrink to
29 // their true degree+1.
30 static constexpr size_t NUM_MAIN_SUBRELATIONS = Base::OFFSET_GENERATOR_X; // 27 (everything before the split)
31 static constexpr std::array<size_t, NUM_MAIN_SUBRELATIONS> SUBRELATION_PARTIAL_LENGTHS{
32 3, // Z1_ZERO_CHECK (deg 2)
33 3, // Z2_ZERO_CHECK (deg 2)
34 2, // OPCODE_WELL_FORMED (deg 1)
35 5, // PC_UPDATE (deg 4)
36 7, // MSM_COUNT_ZERO_AT_TRANSITION (deg 6)
37 4, // MSM_TRANSITION (deg 3)
38 3, // MSM_COUNT_ZERO_WHEN_NOT_MUL (deg 2)
39 6, // MSM_COUNT_INCREMENT_ACROSS_ROWS (deg 5)
40 3, // OPCODE_EXCLUSION (deg 2)
41 6, // EQ_X_DIFF (deg 5)
42 6, // EQ_Y_DIFF (deg 5)
43 3, // BOUNDARY_ACCUMULATOR_EMPTY (deg 2)
44 3, // BOUNDARY_MSM_COUNT_AND_PC (deg 2)
45 7, // ON_CURVE_CHECK (deg 6)
46 8, // LAMBDA_RELATION (deg 7)
47 8, // ACCUMULATOR_X_UPDATE (deg 7)
48 8, // ACCUMULATOR_Y_UPDATE (deg 7)
49 8, // ACCUMULATOR_EMPTY_UPDATE (keep at 8 to share opcode_is_zero / result_is_infinity_short)
50 6, // ADD_X_EQUAL_CHECK (deg 5)
51 6, // ADD_Y_EQUAL_CHECK (deg 5)
52 3, // HIDING_ROW_EQ (deg 2)
53 3, // HIDING_ROW_RESET (deg 2)
54 3, // INFINITY_BASE_PX (deg 2)
55 3, // INFINITY_BASE_PY (deg 2)
56 3, // INFINITY_ACC_X (deg 2)
57 3, // INFINITY_ACC_Y (deg 2)
58 3, // ACCUMULATOR_NOT_EMPTY_INIT (deg 2)
59 };
61
62 // Skip rows on which every one of the 27 main subrelations contributes the identically-zero polynomial.
63 //
64 // Predicate: skip iff the sum of these wires is_zero(): transcript_op, transcript_msm_transition,
65 // transcript_msm_count, transcript_accumulator_not_empty, transcript_accumulator_x, transcript_accumulator_y,
66 // lagrange_first, lagrange_second, lagrange_third, lagrange_last. On a non-randomised row each summand is a
67 // boolean, region, or coordinate wire that is genuinely 0 on the honest trailing-padding rows, so the sum is 0 iff
68 // each is individually 0. The four lagranges live on disjoint single rows, so they never cancel each other. On the
69 // row-disabled rows the wires are randomised, so the sum is nonzero w.h.p. and those rows are never skipped (same
70 // reasoning as the existing ECCVM skips).
71 //
72 // EVERY boundary lagrange that gates a subrelation is included: lagrange_first gates ACCUMULATOR_NOT_EMPTY_INIT;
73 // lagrange_second gates HIDING_ROW_EQ and HIDING_ROW_RESET and the is_not_hiding_row factor in the eq and on-curve
74 // checks; lagrange_third gates BOUNDARY_ACCUMULATOR_EMPTY and BOUNDARY_MSM_COUNT_AND_PC; lagrange_last gates the pc
75 // term of BOUNDARY_MSM_COUNT_AND_PC. Omitting lagrange_third was the bug in a prior naive port: it wrongly skipped
76 // the first real-op row (row 2).
77 //
78 // Per-subrelation soundness when the predicate fires. On such a row op == 0, which via OPCODE_WELL_FORMED forces
79 // all four opcode selectors q_add, q_mul, q_eq, q_reset to 0; also msm_transition == 0, msm_count == 0,
80 // accumulator_not_empty == 0 (so is_accumulator_empty == 1), accumulator_x == accumulator_y == 0, and all four
81 // lagranges == 0.
82 // - Selector- and region-gated subrelations (PC_UPDATE, MSM_COUNT_ZERO_AT_TRANSITION, MSM_TRANSITION,
83 // MSM_COUNT_ZERO_WHEN_NOT_MUL, MSM_COUNT_INCREMENT_ACROSS_ROWS, OPCODE_EXCLUSION, the two eq-diff checks,
84 // ON_CURVE_CHECK, LAMBDA_RELATION, the two add-equal checks): every term carries a factor among q_add, q_mul,
85 // q_eq, q_reset, msm_transition, any_add_is_active (q_add plus msm_transition), msm_count, or is_not_first_row,
86 // all 0 here. OPCODE_WELL_FORMED equals (8 q_add plus 4 q_mul plus 2 q_eq plus q_reset) minus op, which is 0.
87 // - Boundary-lagrange-gated subrelations (BOUNDARY_ACCUMULATOR_EMPTY, BOUNDARY_MSM_COUNT_AND_PC, HIDING_ROW_EQ,
88 // HIDING_ROW_RESET, ACCUMULATOR_NOT_EMPTY_INIT): the gating lagrange is 0.
89 // - INFINITY_ACC_X and INFINITY_ACC_Y equal is_accumulator_empty times an accumulator coordinate, which is 0
90 // since the coordinate is 0. INFINITY_BASE_PX, INFINITY_BASE_PY and the two z-zero checks vanish because honest
91 // padding sets base_x, base_y, z1, z2 all to 0.
92 // - The persistent-accumulator subrelations ACCUMULATOR_X_UPDATE, ACCUMULATOR_Y_UPDATE and
93 // ACCUMULATOR_EMPTY_UPDATE reduce, once all selectors and any_add_is_active and the propagate flag are 0, to
94 // out_coord times opcode_is_zero and opcode_is_zero times (1 minus is_accumulator_empty_shift), with
95 // opcode_is_zero == 1. These read the SHIFTED accumulator wires (transcript_accumulator_x_shift,
96 // transcript_accumulator_y_shift, transcript_accumulator_not_empty_shift). Soundness here rests on the
97 // trailing-padding geometry in ECCVMFlavor::ProverPolynomials: transcript content occupies a contiguous prefix
98 // ending at the finalize row, after which all transcript wires are virtual zeros up to lagrange_last. A skipped
99 // row lies strictly inside that trailing zero block: the finalize row is never skipped because its accumulator
100 // coordinates and not_empty flag appear in the predicate, and the last real-op row precedes the finalize row
101 // and has op nonzero. Hence a skipped row's successor is also a zero or empty row, so every shifted accumulator
102 // wire is 0 there and these subrelations vanish.
103 //
104 // Correctness is checked end-to-end by ECCVMTests.ShortMonomialProverVerifies: a wrongly-skipped live row would
105 // desynchronise the prover's sumcheck round polynomials from the verifier's recomputation.
106 template <typename AllEntities> inline static bool skip(const AllEntities& in)
107 {
108 return (in.transcript_op + in.transcript_msm_transition + in.transcript_msm_count +
109 in.transcript_accumulator_not_empty + in.transcript_accumulator_x + in.transcript_accumulator_y +
110 in.lagrange_first + in.lagrange_second + in.lagrange_third + in.lagrange_last)
111 .is_zero();
112 }
113
114 template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
115 static void accumulate(ContainerOverSubrelations& accumulator,
116 const AllEntities& in,
117 const Parameters& params,
118 const FF& scaling_factor);
119};
120
122
123} // namespace bb
ECCVMTranscriptRelationImpl evaluates the correctness of the ECCVM transcript columns.
static void accumulate(ContainerOverSubrelations &accumulator, const AllEntities &in, const Parameters &params, const FF &scaling_factor)
static constexpr std::array< size_t, NUM_MAIN_SUBRELATIONS > SUBRELATION_PARTIAL_LENGTHS
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
Entry point for Barretenberg command-line interface.
Definition api.hpp:5