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 26 transcript subrelations (indices 0..25). 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; // 26 (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 };
60
61 // Skip rows on which every one of the 26 main subrelations contributes the identically-zero polynomial.
62 //
63 // Predicate: skip iff the sum of these wires is_zero(): transcript_op, transcript_msm_transition,
64 // transcript_msm_count, transcript_accumulator_not_empty, transcript_accumulator_x, transcript_accumulator_y,
65 // lagrange_first, lagrange_second, lagrange_third, lagrange_last. On a non-randomised row each summand is a
66 // boolean, region, or coordinate wire that is genuinely 0 on the honest trailing-padding rows, so the sum is 0 iff
67 // each is individually 0. The four lagranges live on disjoint single rows, so they never cancel each other. On the
68 // row-disabled rows the wires are randomised, so the sum is nonzero w.h.p. and those rows are never skipped (same
69 // reasoning as the existing ECCVM skips).
70 //
71 // EVERY boundary lagrange that gates or disables a subrelation is included: lagrange_first gates is_not_first_row;
72 // lagrange_second gates HIDING_ROW_EQ and HIDING_ROW_RESET and the is_not_hiding_row factor in the eq and on-curve
73 // checks; lagrange_third gates BOUNDARY_ACCUMULATOR_EMPTY and BOUNDARY_MSM_COUNT_AND_PC; lagrange_last gates the pc
74 // term of BOUNDARY_MSM_COUNT_AND_PC. Omitting lagrange_third was the bug in a prior naive port: it wrongly skipped
75 // the first real-op row (row 2).
76 //
77 // Per-subrelation soundness when the predicate fires. On such a row op == 0, which via OPCODE_WELL_FORMED forces
78 // all four opcode selectors q_add, q_mul, q_eq, q_reset to 0; also msm_transition == 0, msm_count == 0,
79 // accumulator_not_empty == 0 (so is_accumulator_empty == 1), accumulator_x == accumulator_y == 0, and all four
80 // lagranges == 0.
81 // - Selector- and region-gated subrelations (PC_UPDATE, MSM_COUNT_ZERO_AT_TRANSITION, MSM_TRANSITION,
82 // MSM_COUNT_ZERO_WHEN_NOT_MUL, MSM_COUNT_INCREMENT_ACROSS_ROWS, OPCODE_EXCLUSION, the two eq-diff checks,
83 // ON_CURVE_CHECK, LAMBDA_RELATION, the two add-equal checks): every term carries a factor among q_add, q_mul,
84 // q_eq, q_reset, msm_transition, any_add_is_active (q_add plus msm_transition), msm_count, or is_not_first_row,
85 // 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.
86 // - Boundary-lagrange-gated subrelations (BOUNDARY_ACCUMULATOR_EMPTY, BOUNDARY_MSM_COUNT_AND_PC, HIDING_ROW_EQ,
87 // HIDING_ROW_RESET): the gating lagrange is 0.
88 // - INFINITY_ACC_X and INFINITY_ACC_Y equal is_accumulator_empty times an accumulator coordinate, which is 0
89 // since the coordinate is 0. INFINITY_BASE_PX, INFINITY_BASE_PY and the two z-zero checks vanish because honest
90 // padding sets base_x, base_y, z1, z2 all to 0.
91 // - The persistent-accumulator subrelations ACCUMULATOR_X_UPDATE, ACCUMULATOR_Y_UPDATE and
92 // ACCUMULATOR_EMPTY_UPDATE reduce, once all selectors and any_add_is_active and the propagate flag are 0, to
93 // out_coord times opcode_is_zero and opcode_is_zero times (1 minus is_accumulator_empty_shift), with
94 // opcode_is_zero == 1. These read the SHIFTED accumulator wires (transcript_accumulator_x_shift,
95 // transcript_accumulator_y_shift, transcript_accumulator_not_empty_shift). Soundness here rests on the
96 // trailing-padding geometry in ECCVMFlavor::ProverPolynomials: transcript content occupies a contiguous prefix
97 // ending at the finalize row, after which all transcript wires are virtual zeros up to lagrange_last. A skipped
98 // row lies strictly inside that trailing zero block: the finalize row is never skipped because its accumulator
99 // coordinates and not_empty flag appear in the predicate, and the last real-op row precedes the finalize row
100 // and has op nonzero. Hence a skipped row's successor is also a zero or empty row, so every shifted accumulator
101 // wire is 0 there and these subrelations vanish.
102 //
103 // Correctness is checked end-to-end by ECCVMTests.ShortMonomialProverVerifies: a wrongly-skipped live row would
104 // desynchronise the prover's sumcheck round polynomials from the verifier's recomputation.
105 template <typename AllEntities> inline static bool skip(const AllEntities& in)
106 {
107 return (in.transcript_op + in.transcript_msm_transition + in.transcript_msm_count +
108 in.transcript_accumulator_not_empty + in.transcript_accumulator_x + in.transcript_accumulator_y +
109 in.lagrange_first + in.lagrange_second + in.lagrange_third + in.lagrange_last)
110 .is_zero();
111 }
112
113 template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
114 static void accumulate(ContainerOverSubrelations& accumulator,
115 const AllEntities& in,
116 const Parameters& params,
117 const FF& scaling_factor);
118};
119
121
122} // 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