@@ -54,7 +54,7 @@ void ECCVMWnafRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulato
5454 auto q_transition = View (in.precompute_point_transition );
5555 auto round = View (in.precompute_round );
5656 auto round_shift = View (in.precompute_round_shift );
57- auto pc = View (in.precompute_pc );
57+ auto pc = View (in.precompute_pc ); // note that this is a _point-counter_.
5858 auto pc_shift = View (in.precompute_pc_shift );
5959 // precompute_select is a boolean column. We only evaluate the ecc_wnaf_relation and the ecc_point_table_relation if
6060 // `precompute_select=1`
@@ -156,15 +156,29 @@ void ECCVMWnafRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulato
156156 std::get<8 >(accumulator) += precompute_select * check_sum * scaled_transition_is_zero;
157157
158158 /* *
159- * @brief Round transition logic.
159+ * @brief Transition logic with `round` and `q_transition` .
160160 * Goal: `round` is an integer in [0, ... 7] that tracks how many slices we have processed for a given scalar.
161- * i.e. number of 4-bit WNAF slices processed = round * 4.
162- * We apply the following constraints:
163- * If q_transition = 0, round increments by 1 between rows.
164- * If q_transition = 1, round value at current row = 7
165- * If q_transition = 1, round value at next row = 0
166- * Question: is this sufficient? We don't actually range constrain `round` (expensive if we don't need to!).
167- * Let us analyze...
161+ * i.e., the number of 4-bit WNAF slices processed = round * 4.
162+ * We must ensure that `q_transition` is well-formed and that `round` is correctly constrained. For the former, we
163+ * force the following:
164+ * 1. When `q_transition == 1`, then `scalar_sum_shift == 0`, `round_shift == 0`, `round == 7`, and `pc_shift
165+ * == pc - 1`.
166+ * 2. When `q_transition == 0`, then `round_shift - round == 1` and `pc_shift == pc`
167+ * Note that we don't actually range-constrain `round` (expensive if we don't need to!). We claim this logic is
168+ * nonetheless sufficient to correctly constrain `round`, because of the multiset checks. There are two multiset
169+ * equality checks that we perform that implicate the wNAF relation (note that point-counter is the `pc`):
170+ * 1. (point-counter, msm_round, wnaf_slice)
171+ * 2. (point-counter, P.x, P.y, scalar-multiplier)
172+ * Both are used communicate with the MSM relation. (The second also implicitly facilitates communication with the
173+ * PointTable relation.)
174+ *
175+ * Here is the logic. We must ensure that `round` can never be set to a value > 7. If this were possible at row `i`,
176+ * then `q_transition == 0` for all subsequent rows by the incrementing logic. The implicit MSM round (accounted for
177+ in
178+ * (1)) is between `4 * round` and `4 * round + 3` (in fact `4 * round + 4` iff we are at a skew). As the `round`
179+ must increment,
180+ * this means that the `msm_round` will be larger than 32, which RAJU: make sure this is all kosher.
181+
168182 * 1. When `q_transition = 1`, we use a set membership check to map the tuple of (pc, scalar_sum) into a set.
169183 * We compare this set with an equivalent set generated from the transcript columns. The sets must match.
170184 * 2. The only case where, at row `i`, a Prover can set `round` to value > 7 is if `q_transition = 0` for all j > i.
@@ -220,7 +234,7 @@ void ECCVMWnafRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulato
220234 std::get<18 >(accumulator) += precompute_select_zero * round;
221235 std::get<19 >(accumulator) += precompute_select_zero * pc;
222236
223- // TODO (@zac-williamson #2226)
237+ // Optimize (@zac-williamson #2226)
224238 // if precompute_select = 0, validate pc, round, slice values are all zero
225239 // If we do this we can reduce the degree of the set equivalence relations
226240 // (currently when checking pc/round/wnaf tuples from WNAF columns match those from MSM columns,
0 commit comments