Never got around to it :)
The idea is to allow larger limbs than 68 bits, e.g. 110 bits, so that you don't have to reduce back to 68 bit limbs after each addition...but only have to reduce when reaching the larger limb limit (the limit is set so that the native field modulus doesn't interfere with the constraints here, see bigfield class in Aztec code for details) (Edited)
1. Compute witnesses $q$ and $r$ such that $ab -qp -r = 0$.
2. Apply range constraints on the limbs of $q, r$ such that they are all $<2^b$.
3. Apply multiplication gates and addition gates to evaluate the following intermediate products mod $2^t$ (note that other intermediate products that arise in $ab-qp$ are zero mod $2^t$):
how to constrain the validation of q and r? If I give a q' (= q - 2) and giving r' (= (2p + r) mod 2^{t}), it could also pass the following validation. (Edited)
1. Compute witnesses $q$ and $r$ such that $ab -qp -r = 0$.
2. Apply range constraints on the limbs of $q, r$ such that they are all $<2^b$.
3. Apply multiplication gates and addition gates to evaluate the following intermediate products mod $2^t$ (note that other intermediate products that arise in $ab-qp$ are zero mod $2^t$):
if 2p + r is larger than 2^t, then the property that ab - q'*p - r' = 0 (mod n) will not hold. (Edited)
the formula for that number is ceil(log2 # elements in the sum) I believe (which would make 3 the correct number in that last one). This is due to the possible carry bits for each element in the sum. The authors would do well to be more explicit and help the reader if they wish to avoid confusion and transmit their ideas to others. (Edited)
Aztec emulated field and group operations
Disclaimer: This documentation was written on September, 2021. It is intended to give readers a high-level understanding. The codebase is the canonical source of truth, and over time this document might fall behind the implementation details of the code.
Emulated Field
We want to evaluate a modular multiplication of elements a, b, using constraints over ( are prime). In particular we allow for the case where . We will choose integer such that . And also leverage operations mod together with the CRT.
In more detail: We will check that as positive integers The way we do this at a high level is
check that the equation holds both mod and mod
check that each side of the equation is smaller than .
The first, using CRT, implies the equation hold mod . Then the second implies the equation hold over the integers since both sides are smaller than . This in turn implies mod , which means is the correct multiplication result in .
Notation summary:
p = non-native field modulus
n = native circuit modulus
= extra CRT modulus
= mod
are the 4 limbs of a.
b = maximum size of a limb (e.g. b = 2^68 in the code)
- number of bits of (having seprate parameters will be helpful for "lazy reductions" e.g. for long addition chains, see Aztec bigfield class for details).
Unless specified, all arithmetic is modulo n.
When we say 'compute' a variable we mean also insert constraints to enforce that value.
Multiplication algorithm:
Assume for simplicity that below.
Compute witnesses and such that .
Apply range constraints on the limbs of such that they are all .
Apply multiplication gates and addition gates to evaluate the following intermediate products mod (note that other intermediate products that arise in are zero mod ):
- bits
-bits
- bits .
- bits
Let's call these 4 (size ~2b) limbs . We can create them using 10 mult-add gates (the terms can be added to the multiplication cause is fixed)
Note that the range of each follows from the range checks on the limbs of .
Compute and .
Both and should be in the range [0, 3b] (plus some overflow bits). Moreover, the first bits of should be zero because we have subtracted from them the low 2b-bits of the remainder term using . Same holds for the first bits of .
Compute such that
Validate is in the range [0, b].
Compute such that .
Validate is in the range [0,b] plus some overflow bits.
Finally, to use the CRT, check also that . Since is the native modulus this can be done very efficiently.
Range constrain so that . The reason this range constraint is needed is that the CRT allows us to verify the desired equality as integers only when both side of the equation are smaller than . Note that for this to be possible we need in partciular that is large enough so that .
acknowledgements: Thanks to Onur Kilic & Xin for pointing out necessity of step 10