Example: Fixed-base scalar multiplication
Last updated
Last updated
We assume our scalar is in the range for smaller than half the elliptic curve group order having the form for some integer . (Allowing a general scalar requires some additional work which we omit here for simplicity of presentation.) When s is in this range, we can write , where , and . Thus, we think of our input as consisting of input quads and one input bit .
Our program consists of rounds where in round , we add either , where is a precomputed power of our actual generator. We initialize our sum as . An optimization we use to reduce program width, is that we only explicitly represent "intermediate sums" of our scalar, and not the actual input quads (the intermediate sums are more convenient than the quads in checking the correct scalar was used). We define the intermediate sums as follows: , and for . Induction shows we get .
Another optimization we use is that by squaring the difference of two intermediate sums, we cancel the effect of the sign of the input quad, which is useful since the coordinate of the point we want to select only depends on the magnitude of the difference. (And needing to explicitly represent this magnitude would again increase the width of the final program.)
We describe a width 4 program that given row values , checks that .
The first step is to use a variant of the lookup method from the previous section to choose the coordinates of the correct point out to add in a given round.
Let's focus on a specific round and denote . Let's also denote by the point we wish to add in this round according to the input; thus is one of the points in the set. We can recover via the following relationship:
We can represent the precomputed constants by selectors:
We can also represent this via two precomputed selectors
Finally, we also check that the differences of intermediate sums fall within the prescribed range via the equation
We've seen how to select the correct point to add in a given round, let's now see how to actually add it.
Expressed as an identity we can evaluate via a gate, we have
x-coordinate check
y-coordinate check
By storing as a distinct wire value, we can extract the y-coordinate, , using a cubic polynomial identity
We can recover by computing , where is a constant that describes the short weierstrass curve in question (for our BN254 embedded curve, )
As we are adding in each round powers of disjoint magnitude of our generator, we can use an incomplete affine addition formula that doesn't handle repeated coordinate. To add point with point , to obtain output , the formula is:
What is left to do is to add the "offset" t. We do this by initializing the "starting point" as either or , according to whether the value of is or .We also check that is in this range using the corresponding degree two constraint.
We summarize the ideas above and describe the program. We will have n+1 rows each containing values labeled . The 2-bit NAF addition gate will be active on the first n rows.In the first row the initialization gate will also be active.