We assume our scalar s is in the range {1,..,M} for M smaller than half the elliptic curve group order having the form 2⋅4n−1 for some integer n . (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 s=t+∑i=0n−1bi⋅4i , where bi∈{−3,−1,1,3}, and t∈{4n,4n+1}. Thus, we think of our input as consisting of n input quads {bi} and one input bit t.
Our program consists of n rounds where in round i, we add either −3[gi],−1[gi],1[gi],3[gi], where gi=4n−i[g]is a precomputed power of our actual generator. We initialize our sum as t[g]. 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 swas used). We define the intermediate sums as follows: a0=t/4n,a1=t/4n−1+bn−1 , and for i∈{2,…,n}ai=4⋅ai−1+bn−i . Induction shows we get an=s.
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 x 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.)
2-bit NAF addition gate
We describe a width 4 program that given row values (x1,y1,xα,ai−1),(x2,y2,xα,2,ai), checks that (x2,y2)=(x1,y1)+(ai−4ai−1)[gi] .
Selecting the correct point to add
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 i∈[n] and denote gi=(xβ,yβ),3[gi]=(xγ,yγ). Let's also denote by (xα,yα) the point we wish to add in this round according to the input; thus (xα,yα)is one of the points in the set{(xβ,yβ),(xβ,−yβ),(xγ,yγ),(xγ,−yγ)}. We can recover xα via the following relationship:
We can recover yα2 by computing xα3+bcurve, where bcurveis a constant that describes the short weierstrass curve in question (for our BN254 embedded curve, bcurve=−17)
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.
Adding the selected point
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 x coordinate. To add point (x1,y1)with point (xα,yα), to obtain output (x2,y2), the formula is:
What is left to do is to add the "offset" t. We do this by initializing the "starting point" (x0,y0) as either (4n)[g] or (4n+1)[g], according to whether the value of a0 is 1 or 1+1/4n .We also check that a0 is in this range using the corresponding degree two constraint.
The Final Program
We summarize the ideas above and describe the program. We will have n+1 rows each containing values labeled xi,yi,xα,a. 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.