@@ -165,7 +165,13 @@ void ECCVMWnafRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulato
165165 auto sum_delta = scalar_sum * FF (1ULL << 16 ) + row_slice;
166166 const auto check_sum = scalar_sum_shift - sum_delta;
167167 std::get<8 >(accumulator) += precompute_select * check_sum * scaled_transition_is_zero;
168-
168+ // We must constrain `precompute_select` to be of the correct shape: 0 1 1 ... 1 0 ...0. In other words, after the
169+ // first row, it is monotonically non-decreasing. In other words, a malicious prover cannot inject the value '0' in
170+ // the middle.
171+ const auto scaled_lagrange_first_minus_one =
172+ scaled_lagrange_first - scaling_factor; // (if not at the first row, is -1, else 0) * scaling_factor
173+ const auto precompute_select_check = precompute_select_shift * (precompute_select - 1 );
174+ std::get<22 >(accumulator) += scaled_lagrange_first_minus_one * precompute_select_check;
169175 /* *
170176 * @brief Transition logic with `round` and `q_transition`.
171177 * Goal: `round` is an integer in [0, ... 7] that tracks how many slices we have processed for a given scalar.
@@ -250,7 +256,8 @@ void ECCVMWnafRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulato
250256 std::get<13 >(accumulator) += precompute_select * (precompute_skew * (precompute_skew - 7 )) * scaling_factor;
251257
252258 // Set slices (a.k.a. compressed digits), pc, and round all to zero when `precompute_select == 0`.
253- // (this is for one of the multiset equality checks.)
259+ // (this is for one of the multiset equality checks.) Defensively, we also set precompute_point_transition to 0 when
260+ // precompute_select == 0.
254261 const auto precompute_select_zero = (-precompute_select + 1 ) * scaling_factor;
255262 std::get<14 >(accumulator) += precompute_select_zero * (w0 + 15 );
256263 std::get<15 >(accumulator) += precompute_select_zero * (w1 + 15 );
@@ -259,14 +266,6 @@ void ECCVMWnafRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulato
259266
260267 std::get<18 >(accumulator) += precompute_select_zero * round;
261268 std::get<19 >(accumulator) += precompute_select_zero * pc;
262-
263- // Note(@zac-williamson #2226)
264- // if precompute_select = 0, validate pc, round, slice values are all zero
265- // If we do this we can reduce the degree of the set equivalence relations
266- // (currently when checking pc/round/wnaf tuples from WNAF columns match those from MSM columns,
267- // we conditionally include tuples depending on if precompute_select = 1 (for WNAF columns) or if q_add1/2/3/4 = 1
268- // (for MSM columns).
269- // If we KNOW that the wnaf tuple values are 0 when precompute_select = 0, we can remove the conditional checks in
270- // the set equivalence relation
269+ std::get<21 >(accumulator) += precompute_select_zero * q_transition;
271270}
272271} // namespace bb
0 commit comments