Skip to content

Commit b106827

Browse files
author
notnotraju
committed
clarified more about set relation re: MSM
1 parent d7f4ec1 commit b106827

File tree

2 files changed

+46
-27
lines changed

2 files changed

+46
-27
lines changed

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

Lines changed: 41 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,9 @@ void ECCVMMSMRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulator
127127
*/
128128

129129
/**
130-
* @brief Constraining addition rounds
130+
* @brief Constraining addition rounds via a multiset-equality check
131131
*
132+
* @details
132133
* The boolean column q_add describes whether a round is an ADDITION round.
133134
* The values of q_add are Prover-defined. We need to ensure they set q_add correctly. We will do this via a
134135
* multiset-equality check (formerly called a "strict lookup"), which allows the various tables to "communicate".
@@ -194,29 +195,44 @@ void ECCVMMSMRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulator
194195
*
195196
* Suppose the Prover sets `q_addK = 0` when an honest Prover would set `q_addK == 1`. Then there would be some (pc,
196197
* round, wnaf_slice) that the Precomputed table add to its multiset that the prover did not add. The Prover can
197-
* _never_ "compensate" for this, as both `pc` and `round` are locally constrained to be monotonic; this means that
198-
* the Prover has "lost their chance" to add this element to the multiset and hence the multiset equality check will
199-
* fail.
198+
* _never_ "compensate" for this, as `pc` is locally constrained to be monotonic and `round` is constrained to be
199+
* periodic; this means that the Prover has "lost their chance" to add this element to the multiset and hence the
200+
* multiset equality check will fail.
200201
*
201202
* Conversely, if the Prover sets `q_addK = 1` when it should be set to 0, there are several options: either
202203
* we are at the end of a `round` (so e.g. `q_add4 ` _should_ be 0), or we are at a double row, or we are at a row
203204
* that should be all 0s. In the first two cases, as long as the Precomputed table is correctly constrained, again
204-
* we would be adding a tuple to the multiset that can never be hit by the Precomputed table due to `pc` and `round`
205-
* monotonicty. In the final case, the only way we don't break the multiset check is if `wnaf_slice == 0` for the
206-
* corresponding `q_addK` that is on. But then the lookup argument will fail, as there is no corresponding point
207-
* when `pc = 0`. (Here it is helpful to remember that `pc` stands for _point-counter_.) RAJU: check the LOOKUP
208-
* part. and the monotonicity part here.
205+
* we would be adding a tuple to the multiset that can never be hit by the Precomputed table due to `precompute_pc`
206+
* monotonicty and `precompute_round` periodicity(enforced in the precomputed columns.). In the final case, the only
207+
* way we don't break the multiset check is if `wnaf_slice == 0` for the corresponding `q_addK` that is on. But then
208+
* the lookup argument will fail, as there is no corresponding point when `pc = 0`. (Here it is helpful to remember
209+
* that `pc` stands for _point-counter_.) RAJU: check the LOOKUP part.
209210
*
210211
*
211-
* To ensure that all q_addK values are correctly set we apply consistency/continuity checks to
212-
* q_add1/q_add2/q_add3/q_add4:
212+
* We apply consistency/continuity checks to q_add1/q_add2/q_add3/q_add4:
213213
* 1. If q_add2 = 1, require q_add1 = 1
214214
* 2. If q_add3 = 1, require q_add2 = 1
215215
* 3. If q_add4 = 1, require q_add3 = 1
216216
* 4. If q_add1_shift = 1 AND round does not update between rows, require q_add4 = 1
217217
*
218218
*/
219219

220+
/**
221+
* @brief Constrain msm_size and output of MSM computation via multiset equality
222+
*
223+
* @details
224+
* As explained in the section on constraining the addition wire values, to make everything work we also need to
225+
* constrain `msm_size`, something directly computed in the Transcript columns. We also need to "send" the final
226+
* output value of an MSM from the MSM table to the transcript table so it can continue its processing. (Send here
227+
* is a euphemism for constrain.) We do this via a multiset equality check of the form:
228+
* (pc, P.x, P.y, msm-size)
229+
* From the perspective of the MSM table, we add such a tuple only at an `msm_transition`. The terms P.x and P.y
230+
* refer to the output values of the MSM just computed by the MSM table. `msm_size` is the size of the _just
231+
* completed_ MSM.
232+
*
233+
*
234+
*/
235+
220236
/**
221237
* @brief Addition relation
222238
*
@@ -407,10 +423,6 @@ void ECCVMMSMRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulator
407423
std::get<8>(accumulator) += (x3_delta * collision_inverse3 - add_third_point) * scaling_factor;
408424
std::get<9>(accumulator) += (x4_delta * collision_inverse4 - add_fourth_point) * scaling_factor;
409425

410-
// Validate that if q_add = 1 or q_skew = 1, add1 also is 1
411-
// Optimize(@zac-williamson): could just get rid of add1 as a column, as it is a linear combination, see issue #2222
412-
std::get<32>(accumulator) += (add1 - q_add - q_skew) * scaling_factor;
413-
414426
// When add_i = 0, force slice_i to ALSO be 0
415427
std::get<13>(accumulator) += (-add1 + 1) * slice1 * scaling_factor;
416428
std::get<14>(accumulator) += (-add2 + 1) * slice2 * scaling_factor;
@@ -422,6 +434,10 @@ void ECCVMMSMRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulator
422434
// note that as we can expect our table to be zero padded, we _do not_ insist that q_add + q_double + q_skew == 1.
423435
std::get<17>(accumulator) += (q_add * q_double + q_add * q_skew + q_double * q_skew) * scaling_factor;
424436

437+
// Validate that if q_add = 1 or q_skew = 1, add1 also is 1
438+
// Optimize(@zac-williamson): could just get rid of add1 as a column, as it is a linear combination, see issue #2222
439+
std::get<32>(accumulator) += (add1 - q_add - q_skew) * scaling_factor;
440+
425441
// ROUND TRANSITION LOGIC
426442
// `round_transition` describes whether we are transitioning between "rounds" of the MSM according to the Straus
427443
// algorithm. In particular, the `round` corresponds to the wNAF digit we are currently processing.
@@ -438,19 +454,22 @@ void ECCVMMSMRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulator
438454
const auto round_transition = round_delta * (-msm_transition_shift + 1);
439455
std::get<18>(accumulator) += round_transition * (round_delta - 1) * scaling_factor;
440456

441-
// If `round_transition == 1`, then `round_delta == 1` and `msm_transition_shift == 0`. Therefore, the
442-
// next row in the VM is either a double (if `round != 31`) or skew (if `round == 31`). In either case, the point is
443-
// that we have finished processing a wNAF digit place and need to either perform the doublings to move on to the
444-
// next place _or_ we are at the last place and need to perform the skew computation to finish. These are
457+
// If `round_transition == 1`, then `round_delta == 1` and `msm_transition_shift == 0`. Therefore, we wish to
458+
// constrain next row in the VM to either be a double (if `round != 31`) or skew (if `round == 31`). In either case,
459+
// the point is that we have finished processing a wNAF digit place and need to either perform the doublings to move
460+
// on to the next place _or_ we are at the last place and need to perform the skew computation to finish. These are
445461
// equationally represented as:
446462
// round_transition * skew_shift * (round - 31) = 0 (if round tx and skew, then round == 31);
447463
// round_transition * (skew_shift + double_shift - 1) = 0 (if round tx, then skew XOR double = 1).
464+
// (-round_delta + 1) * q_double_shift = 1 (if q_double_shift == 1, then round_transition = 1)
448465
// together, these have the following implications: if round tx and round != 31, then double_shift = 1.
449-
// conversely, if round tx and double_shift == 0, then `skew_shift == 1` (which then forces `round == 31`).
450-
466+
// conversely, if round tx and double_shift == 0, then `q_skew_shift == 1` (which then forces `round == 31`).
467+
// similarly, if q_double_shift == 1, then round_transition == 0,
468+
// the fact that a round_transition occurs at the first time skew_shift == 1 follows from the fact that skew == 1
469+
// implies round == 32 and the above three relations, together with the _definition_ of round_transition.
451470
std::get<19>(accumulator) += round_transition * q_skew_shift * (round - 31) * scaling_factor;
452471
std::get<20>(accumulator) += round_transition * (q_skew_shift + q_double_shift - 1) * scaling_factor;
453-
472+
std::get<35>(accumulator) += (-round_delta + 1) * q_double_shift * scaling_factor;
454473
// if the next is neither double nor skew, and we are not at an msm_transition, then round_delta = 0 and the next
455474
// "row" of our VM is processing the same wNAF digit place.
456475
std::get<21>(accumulator) += round_transition * (-q_double_shift + 1) * (-q_skew_shift + 1) * scaling_factor;

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace bb {
2828
* Second term: tuple of (pc, P.x, P.y, scalar-multiplier), used in ECCVMWnafRelation and
2929
* ECCVMPointTableRelation.
3030
* Input source: ECCVMPointTableRelation
31-
* Output source: ECCVMMSMRelation
31+
* Output source: ECCVMTranscriptRelation
3232
*
3333
* Third term: tuple of (pc, P.x, P.y, msm-size) from ECCVMMSMRelation.
3434
* Input source: ECCVMMSMRelation
@@ -215,10 +215,10 @@ Accumulator ECCVMSetRelationImpl<FF>::compute_grand_product_numerator(const AllE
215215
* multi-scalar multiplication of size `msm-size`, starting at `pc`.
216216
*
217217
* If msm_transition_shift = 1, this indicates the current row is the last row of a multiscalar
218-
* multiplication evaluation. The output of the MSM will be present on `(msm_accumulator_x_shift,
219-
* msm_accumulator_y_shift)`. The values of `msm_accumulator_x_shift, msm_accumulator_y_shift, msm_pc,
220-
* msm_size_of_msm` must match up with equivalent values `transcript_msm_output_x, transcript_msm_output_y,
221-
* transcript_pc, transcript_msm_count` present in the Transcript columns
218+
* multiplication evaluation. The output of the MSM will be present on `(msm_accumulator_x_shift,
219+
* msm_accumulator_y_shift)`. The values of `msm_accumulator_x_shift, msm_accumulator_y_shift, msm_pc,
220+
* msm_size_of_msm` must match up with equivalent values `transcript_msm_output_x, transcript_msm_output_y,
221+
* transcript_pc, transcript_msm_count` present in the Transcript columns
222222
*/
223223
{
224224
const auto& lagrange_first = View(in.lagrange_first);

0 commit comments

Comments
 (0)