Here, we explain a fairly simple mathematical idea that underpins our multiplication technique. We fix a number nmul of MUL constraints; we recall the constraint arraysp, q, lo and hi. Each of these arrays is of length nmul and contains 64-bit words.
For each x∈{0,…,nmul−1}, p[x] and q[x] are in {0,…,264−1}. We're interested in p[x]⋅q[x]. Recall that we work throughout with binary fields. This means that we can't use typical prime-field ideas (like breaking our numbers into limbs so small that their products don't overflow the characteristic, using range checks, and so on).
The Exponentiation Identity
The idea is to use the basic identity (gp[x])q[x]=gp[x]⋅q[x]. This is true in all rings, but we have to be careful about reduction in the exponent.
We recall that the multiplicative group of units F2128∗ is cyclic; we fix a generator g∈F2128∗. Thus, the multiplicative order of g in F2128 is 2128−1.
For each x∈{0,…,nmul−1}, the array elements p[x], q[x], lo[x] and hi[x] are all elements of {0,…,264−1}. Our goal is to check whether
p[x]⋅q[x]=?264⋅hi[x]+lo[x]
holds as integers. By the basic properties of rings, we know that
gr=gs
holds if and only if r≡s(modord(g)); in our case, we conclude that
If p[x]⋅q[x]=?264⋅hi[x]+lo[x] holds as integers, then it definitely also holds modulo 2128−1. The converse is not quite true, as we now explain. Since
p[x]⋅q[x]≤(264−1)2=2128−2⋅264+1<2128−1,
p[x]⋅q[x] can't wrap around modulo 2128−1. On the other hand, since
264⋅hi[x]+lo[x]≤264⋅(264−1)+264−1=2128−1,
264⋅hi[x]+lo[x] can wrap around only in the case of a direct equality 264⋅hi[x]+lo[x]=2128−1. This equality happens if and only if lo[x] and hi[x] are both 264−1; and indeed, by choosing at least one of p[x] and q[x] to be zero, the prover could get a case in which p[x]⋅q[x]=?264⋅hi[x]+lo[x] holds modulo 2128−1 but not over the integers.
In this latter case, p[x]⋅q[x] is even, while 264⋅hi[x]+lo[x] is odd. To eliminate it, it thus suffices to ensure to boot that
p[x]⋅q[x]≡264⋅hi[x]+lo[x](mod2).
This latter equality is easy to check, since it only depends on the least-significant bits of p, q and lo. One simple way to do this is to use AND constraints. It's enough to add 3 new witness words, say p′, q′, and lo′, and to constrain that
sll(p′,63)&sll(q′,63)=?sll(lo′,63),
as well as that p=p′, q=q′, and lo=lo′. The total cost for this is 3 new witness components and 4 new AND constraints (we note that MUL is already much costlier than AND, on a per-constraint basis).
Putting it Together
Assuming that the above issue has been separately resolved, we see that the MUL constraint
p[x]⋅q[x]=?264⋅hi[x]+lo[x]
holds over the integers if and only if
(gp[x])q[x]=?(g264)hi[x]⋅glo[x]
holds in F2128. We spend the rest of this site section explaining how to check the exponent condition above.