Skip to content

Commit c8d22e2

Browse files
notnotrajunotnotraju
authored andcommitted
feat: enforce accumulator_not_empty = 0 at ECCVM lagrange_first row (#22461)
## Summary Add `lagrange_first * transcript_accumulator_not_empty = 0` subrelation to `ECCVMTranscriptRelation`. This is a prerequisite for #22334 (masking at top of ECCVM circuit). The audit in #22442 identified that when `lagrange_first` moves to row k (away from the PCS-enforced zero row), `transcript_accumulator_not_empty` is the only shiftable column where a malicious prover can potentially set a non-zero value at the `lagrange_first` row without any existing relation catching it. Setting it to 1 disables `INFINITY_ACC_X/Y`, allowing arbitrary accumulator coordinates to be injected. ## Changes - New subrelation `ACCUMULATOR_NOT_EMPTY_INIT` in `ecc_transcript_relation.hpp` (degree 2) - Gate count updates (+174 gates from the new subrelation): - `ECCVM_RECURSIVE_VERIFIER_GATE_COUNT`: 224336 → 224510 - `CHONK_RECURSION_GATES`: 1491593 → 1491767 ## Test plan - [x] `eccvm_tests` — all 44 tests pass - [x] `stdlib_eccvm_verifier_tests` — `SingleRecursiveVerification` passes with updated gate count - [x] `dsl_tests` — `GateCountChonkRecursion` passes with updated gate count Co-authored-by: notnotraju <raju@aztec-labs.com>
1 parent 25982ed commit c8d22e2

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

barretenberg/cpp/src/barretenberg/dsl/acir_format/gate_count_constants.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ constexpr std::tuple<size_t, size_t> HONK_RECURSION_CONSTANTS(
113113
// ========================================
114114

115115
// Gate count for Chonk recursive verification (Ultra with RollupIO)
116-
inline constexpr size_t CHONK_RECURSION_GATES = 1491593;
116+
inline constexpr size_t CHONK_RECURSION_GATES = 1491767;
117117

118118
// ========================================
119119
// Hypernova Recursion Constants
@@ -147,7 +147,7 @@ inline constexpr size_t HIDING_KERNEL_ULTRA_OPS = 127;
147147
// ========================================
148148

149149
// Gate count for ECCVM recursive verifier (Ultra-arithmetized)
150-
inline constexpr size_t ECCVM_RECURSIVE_VERIFIER_GATE_COUNT = 224336;
150+
inline constexpr size_t ECCVM_RECURSIVE_VERIFIER_GATE_COUNT = 224510;
151151

152152
// ========================================
153153
// Goblin AVM Recursive Verifier Constants

barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_transcript_relation.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,13 @@ template <typename FF_> class ECCVMTranscriptRelationImpl {
9999
INFINITY_ACC_X = 29,
100100
// Infinity flag consistency: acc_y = 0 when accumulator empty
101101
INFINITY_ACC_Y = 30,
102+
// Boundary: accumulator_not_empty must be 0 at lagrange_first row
103+
ACCUMULATOR_NOT_EMPTY_INIT = 31,
102104
NUM_SUBRELATIONS,
103105
};
104106

105-
static constexpr std::array<size_t, 31> SUBRELATION_PARTIAL_LENGTHS{
106-
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
107+
static constexpr std::array<size_t, 32> SUBRELATION_PARTIAL_LENGTHS{
108+
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
107109
};
108110
static_assert(NUM_SUBRELATIONS == SUBRELATION_PARTIAL_LENGTHS.size());
109111

barretenberg/cpp/src/barretenberg/relations/ecc_vm/ecc_transcript_relation_impl.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,5 +566,14 @@ void ECCVMTranscriptRelationImpl<FF>::accumulate(ContainerOverSubrelations& accu
566566
is_accumulator_empty * transcript_accumulator_x * scaling_factor; // degree 2
567567
std::get<INFINITY_ACC_Y>(accumulator) +=
568568
is_accumulator_empty * transcript_accumulator_y * scaling_factor; // degree 2
569+
570+
/**
571+
* @brief Enforce accumulator_not_empty = 0 at the lagrange_first row.
572+
* Without this, a malicious prover can set accumulator_not_empty = 1 at the lagrange_first row,
573+
* which disables INFINITY_ACC_X/Y above, allowing arbitrary accumulator coordinates to be injected
574+
* without any relation catching it.
575+
*/
576+
std::get<ACCUMULATOR_NOT_EMPTY_INIT>(accumulator) +=
577+
lagrange_first * View(in.transcript_accumulator_not_empty) * scaling_factor; // degree 2
569578
}
570579
} // namespace bb

0 commit comments

Comments
 (0)