Skip to content

Commit a582c3f

Browse files
Detailed comments for secp256k1_scalar_split_lambda.
1 parent 57d4b0d commit a582c3f

File tree

1 file changed

+138
-10
lines changed

1 file changed

+138
-10
lines changed

src/scalar_impl.h

Lines changed: 138 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,19 +270,30 @@ static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar
270270
* lambda is {0x53,0x63,0xad,0x4c,0xc0,0x5c,0x30,0xe0,0xa5,0x26,0x1c,0x02,0x88,0x12,0x64,0x5a,
271271
* 0x12,0x2e,0x22,0xea,0x20,0x81,0x66,0x78,0xdf,0x02,0x96,0x7c,0x1b,0x23,0xbd,0x72}
272272
*
273-
* "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm
274-
* (algorithm 3.74) to find k1 and k2 given k, such that k1 + k2 * lambda == k mod n, and k1
275-
* and k2 have a small size.
276-
* It relies on constants a1, b1, a2, b2. These constants for the value of lambda above are:
273+
* Both lambda and beta are primitive cube roots of unity. That is lamba^3 == 1 mod n and
274+
* beta^3 == 1 mod p, where n is the curve order and p is the field order.
275+
*
276+
* Futhermore, because (X^3 - 1) = (X - 1)(X^2 + X + 1), the primitive cube roots of unity are
277+
* roots of X^2 + X + 1. Therefore lambda^2 + lamba == -1 mod n and beta^2 + beta == -1 mod p.
278+
* (The other primitive cube roots of unity are lambda^2 and beta^2 respectively.)
279+
*
280+
* Let l = -1/2 + i*sqrt(3)/2, the complex root of X^2 + X + 1. We can define a ring
281+
* homomorphism phi : Z[l] -> Z_n where phi(a + b*l) == a + b*lambda mod n. The kernel of phi
282+
* is a lattice over Z[l]. A reduced basis of this lattice is generated by the values a1 + b1*l
283+
* and a2 + b2*l where:
277284
*
278285
* - a1 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15}
279286
* - b1 = -{0xe4,0x43,0x7e,0xd6,0x01,0x0e,0x88,0x28,0x6f,0x54,0x7f,0xa9,0x0a,0xbf,0xe4,0xc3}
280287
* - a2 = {0x01,0x14,0xca,0x50,0xf7,0xa8,0xe2,0xf3,0xf6,0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8}
281288
* - b2 = {0x30,0x86,0xd2,0x21,0xa7,0xd4,0x6b,0xcd,0xe8,0x6c,0x90,0xe4,0x92,0x84,0xeb,0x15}
282289
*
283-
* The algorithm then computes c1 = round(b1 * k / n) and c2 = round(b2 * k / n), and gives
284-
* k1 = k - (c1*a1 + c2*a2) and k2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and
285-
* compute k1 as k - k2 * lambda, avoiding the need for constants a1 and a2.
290+
* "Guide to Elliptic Curve Cryptography" (Hankerson, Menezes, Vanstone) gives an algorithm
291+
* (algorithm 3.74) to find r1 and r2 given a, such that r1 + r2 * lambda == a mod n, and r1
292+
* and r2 have a small size.
293+
*
294+
* The algorithm computes c1 = round(b2 * a / n) and c2 = round((-b1) * a / n), and gives
295+
* r1 = a - (c1*a1 + c2*a2) and r2 = -(c1*b1 + c2*b2). Instead, we use modular arithmetic, and
296+
* compute r1 as a - r2 * lambda (mod n), avoiding the need for constants a1 and a2.
286297
*
287298
* g1, g2 are precomputed constants used to replace division with a rounded multiplication
288299
* when decomposing the scalar for an endomorphism-based point multiplication.
@@ -297,10 +308,127 @@ static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar
297308
* g1 = round((2^384)*b2/d)
298309
* g2 = round((2^384)*(-b1)/d)
299310
*
300-
* (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found
301-
* as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda').
311+
* (Note that 'd' is also equal to the curve order, n, here because [a1,b1] and [a2,b2]
312+
* can be found as outputs of the Extended Euclidean Algorithm on inputs 'n' and 'lambda').
313+
*
314+
* The function below splits a in r1 and r2, such that
315+
* - r1 + lambda * r2 == a (mod n)
316+
* - either 0 <= r1 <= (a1 + a2 + 1) / 2 or n - (a1 + a2 + 1)/2 <= r1 < n.
317+
* - either 0 <= r2 <= (-b1 + b2) / 2 or n - (-b1 + b2)/2 <= r2 < n.
318+
*
319+
* Proof.
320+
*
321+
* Let
322+
* - epsilon1 = |g1/2^384 - b2/d|
323+
* - epsilon2 = |g2/2^384 - (-b1)/d|
324+
* - c1 = round(a*g1/2^384)
325+
* - c2 = round(a*g2/2^384)
326+
*
327+
* Lemma 1: |c1 - a*b2/d| < 2^-1 + 2^-129
328+
*
329+
* |c1 - a*b2/d|
330+
* =
331+
* |c1 - a*g1/2^384 + a*g1/2^384 - a*b2/d|
332+
* <= {triangle inequality}
333+
* |c1 - a*g1/2^384| + |a*g1/2^384 - a*b2/d|
334+
* =
335+
* |c1 - a*g1/2^384| + a*|g1/2^384 - b2/d|
336+
* <= {property of rounding in c1 & definition of epsilon1
337+
* 2^-1 + a*epsilon1
338+
* < {a < 2^256 and epsilon1 < 2^-385}
339+
* 2^-1 + 2^256 * 2^-385
340+
* =
341+
* 2^-1 + 2^-129
342+
*
343+
* Lemma 2: |c2 - a*(-b1)/d| < 2^-1 + 2^-129
344+
*
345+
* |c2 - a*(-b1)/d|
346+
* =
347+
* |c2 - a*g2/2^384 + a*g2/2^384 - a*(-b1)/d|
348+
* <= {triangle inequality}
349+
* |c1 - a*g2/2^384| + |a*g2/2^384 - a*(-b1)/d|
350+
* =
351+
* |c1 - a*g2/2^384| + a*|g2/2^384 - (-b1)/d|
352+
* <= {property of rounding in c1 & definition of epsilon2
353+
* 2^-1 + a*epsilon2
354+
* < {a < 2^256 and epsilon2 < 2^-385}
355+
* 2^-1 + 2^256 * 2^-385
356+
* =
357+
* 2^-1 + 2^-129
358+
*
359+
* Let
360+
* - k1 = a - c1*a1 - c2*a2
361+
* - k2 = - c1*b1 - c2*b2
362+
*
363+
* Lemma 3: |k1| < (a1 + a2)(2^-1 + 2^-129) < (a1 + a2 + 3)/2
364+
*
365+
* |k1|
366+
* = {definition of k1}
367+
* |a - c1*a1 - c2*a2|
368+
* = {(a1*b2 - b1*a2)/n = 1}
369+
* |a*(a1*b2 - b1*a2)/n - c1*a1 - c2*a2|
370+
* =
371+
* |a1*(a*b2/n - c1) + a2*(a*(-b1)/n - c2)|
372+
* <= {triangle inequality}
373+
* a1*|a*b2/n - c1| + a2*|a*(-b1)/n - c2|
374+
* < {Lemma 1 and Lemma 2}
375+
* a1*(2^-1 + 2^-129) + a2*(2^-1 + 2^-129)
376+
* =
377+
* (a1 + a2)(2^-1 + 2^-129)
378+
* < {calculation}
379+
* (a1 + a2 + 3)/2
380+
*
381+
* Corollary 4: |k1| <= (a1 + a2 + 1)/2.
382+
* This follows from Lemma 3 and the fact that k1 and (a1 + a2 + 3)/2 are integers.
383+
*
384+
* Lemma 5: |k2| < (-b1 + b2)(2^-1 + 2^-129) < (-b1 + b2 + 2)/2
385+
*
386+
* |k2|
387+
* = {definition of k2}
388+
* |- c1*a1 - c2*a2|
389+
* = {a*(b1*b2 - b1*b2)/n = 0}
390+
* |a*(b1*b2 - b1*b2)/n - c1*b1 - c2*b2|
391+
* =
392+
* |b1*(a*b2/n - c1) + b2*(a*(-b1)/n - c2)|
393+
* <= {triangle inequality}
394+
* (-b1)*|a*b2/n - c1| + b2*|a*(-b1)/n - c2|
395+
* < {Lemma 1 and Lemma 2}
396+
* (-b1)*(2^-1 + 2^-129) + b2*(2^-1 + 2^-129)
397+
* =
398+
* (-b1 + b2)(2^-1 + 2^-129)
399+
* < {calculation}
400+
* (-b1 + b2 + 2)/2
401+
*
402+
* Corollary 4: |k2| <= (-b1 + b2)/2.
403+
* This follows from Lemma 5 and the fact that k2 and (-b1 + b2 + 2)/2 are integers.
404+
*
405+
* Let
406+
* - r2 = k2 mod n
407+
* - r1 = a - r2*lambda mod n.
408+
*
409+
* Notice that r1 is defined such that r1 + r2 * lambda == a (mod n).
410+
*
411+
* Lemma 6: r1 == k1 mod n.
412+
*
413+
* r1
414+
* == {definition of r1 and r2}
415+
* a - k2*lambda
416+
* == {definition of k2}
417+
* a - (- c1*b1 - c2*b2)*lambda
418+
* ==
419+
* a + c1*b1*lambda + c2*b2*lambda
420+
* == {a1 + b1*lambda == 0 mod n and a2 + b2*lambda == 0 mod n}
421+
* a - c1*a1 - c2*a2
422+
* == {definition of k1}
423+
* k1
424+
*
425+
* From Corollary 4, Corollary 5 and Lemma 6 we can conclude that
426+
*
427+
* - either r1 <= (a1 + a2 + 1) / 2 or n - (a1 + a2 + 1)/2 <= r1
428+
* - either r2 <= (-b1 + b2) / 2 or n - (-b1 + b2)/2 <= r2.
429+
*
430+
* Q.E.D.
302431
*
303-
* The function below splits a in r1 and r2, such that r1 + lambda * r2 == a (mod order).
304432
*/
305433

306434
static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) {

0 commit comments

Comments
 (0)