@@ -29,7 +29,7 @@ typedef struct {
2929 secp256k1_num_t order ;
3030#endif
3131#ifdef USE_ENDOMORPHISM
32- secp256k1_num_t a1b2 , b1 , a2 ;
32+ secp256k1_num_t a1b2 , b1 , a2 , g1 , g2 ;
3333#endif
3434} secp256k1_scalar_consts_t ;
3535
@@ -65,10 +65,38 @@ static void secp256k1_scalar_start(void) {
6565 0x14 ,0xca ,0x50 ,0xf7 ,0xa8 ,0xe2 ,0xf3 ,0xf6 ,
6666 0x57 ,0xc1 ,0x10 ,0x8d ,0x9d ,0x44 ,0xcf ,0xd8
6767 };
68-
68+ /**
69+ * g1, g2 are precomputed constants used to replace division with a rounded multiplication
70+ * when decomposing the scalar for an endomorphism-based point multiplication.
71+ *
72+ * The possibility of using precomputed estimates is mentioned in "Guide to Elliptic Curve
73+ * Cryptography" (Hankerson, Menezes, Vanstone) in section 3.5.
74+ *
75+ * The derivation is described in the paper "Efficient Software Implementation of Public-Key
76+ * Cryptography on Sensor Networks Using the MSP430X Microcontroller" (Gouvea, Oliveira, Lopez),
77+ * Section 4.3 (here we use a somewhat higher-precision estimate):
78+ * d = a1*b2 - b1*a2
79+ * g1 = round((2^272)*b2/d)
80+ * g2 = round((2^272)*b1/d)
81+ *
82+ * (Note that 'd' is also equal to the curve order here because [a1,b1] and [a2,b2] are found
83+ * as outputs of the Extended Euclidean Algorithm on inputs 'order' and 'lambda').
84+ */
85+ static const unsigned char secp256k1_scalar_consts_g1 [] = {
86+ 0x30 ,0x86 ,
87+ 0xd2 ,0x21 ,0xa7 ,0xd4 ,0x6b ,0xcd ,0xe8 ,0x6c ,
88+ 0x90 ,0xe4 ,0x92 ,0x84 ,0xeb ,0x15 ,0x3d ,0xab
89+ };
90+ static const unsigned char secp256k1_scalar_consts_g2 [] = {
91+ 0xe4 ,0x43 ,
92+ 0x7e ,0xd6 ,0x01 ,0x0e ,0x88 ,0x28 ,0x6f ,0x54 ,
93+ 0x7f ,0xa9 ,0x0a ,0xbf ,0xe4 ,0xc4 ,0x22 ,0x12
94+ };
6995 secp256k1_num_set_bin (& ret -> a1b2 , secp256k1_scalar_consts_a1b2 , sizeof (secp256k1_scalar_consts_a1b2 ));
7096 secp256k1_num_set_bin (& ret -> a2 , secp256k1_scalar_consts_a2 , sizeof (secp256k1_scalar_consts_a2 ));
7197 secp256k1_num_set_bin (& ret -> b1 , secp256k1_scalar_consts_b1 , sizeof (secp256k1_scalar_consts_b1 ));
98+ secp256k1_num_set_bin (& ret -> g1 , secp256k1_scalar_consts_g1 , sizeof (secp256k1_scalar_consts_g1 ));
99+ secp256k1_num_set_bin (& ret -> g2 , secp256k1_scalar_consts_g2 , sizeof (secp256k1_scalar_consts_g2 ));
72100#endif
73101
74102 /* Set the global pointer. */
@@ -273,26 +301,28 @@ static void secp256k1_scalar_split_lambda_var(secp256k1_scalar_t *r1, secp256k1_
273301 secp256k1_num_t rn1 , rn2 ;
274302
275303 const secp256k1_scalar_consts_t * c = secp256k1_scalar_consts ;
276- secp256k1_num_t bnc1 , bnc2 , bnt1 , bnt2 , bnn2 ;
277-
278- secp256k1_num_copy (& bnn2 , & c -> order );
279- secp256k1_num_shift (& bnn2 , 1 );
280-
281- secp256k1_num_mul (& bnc1 , & na , & c -> a1b2 );
282- secp256k1_num_add (& bnc1 , & bnc1 , & bnn2 );
283- secp256k1_num_div (& bnc1 , & bnc1 , & c -> order );
284-
285- secp256k1_num_mul (& bnc2 , & na , & c -> b1 );
286- secp256k1_num_add (& bnc2 , & bnc2 , & bnn2 );
287- secp256k1_num_div (& bnc2 , & bnc2 , & c -> order );
288-
289- secp256k1_num_mul (& bnt1 , & bnc1 , & c -> a1b2 );
290- secp256k1_num_mul (& bnt2 , & bnc2 , & c -> a2 );
291- secp256k1_num_add (& bnt1 , & bnt1 , & bnt2 );
292- secp256k1_num_sub (& rn1 , & na , & bnt1 );
293- secp256k1_num_mul (& bnt1 , & bnc1 , & c -> b1 );
294- secp256k1_num_mul (& bnt2 , & bnc2 , & c -> a1b2 );
295- secp256k1_num_sub (& rn2 , & bnt1 , & bnt2 );
304+ secp256k1_num_t d1 , d2 , t , one ;
305+ unsigned char cone [1 ] = {0x01 };
306+ secp256k1_num_set_bin (& one , cone , 1 );
307+
308+ secp256k1_num_mul (& d1 , & na , & c -> g1 );
309+ secp256k1_num_shift (& d1 , 271 );
310+ secp256k1_num_add (& d1 , & d1 , & one );
311+ secp256k1_num_shift (& d1 , 1 );
312+
313+ secp256k1_num_mul (& d2 , & na , & c -> g2 );
314+ secp256k1_num_shift (& d2 , 271 );
315+ secp256k1_num_add (& d2 , & d2 , & one );
316+ secp256k1_num_shift (& d2 , 1 );
317+
318+ secp256k1_num_mul (& t , & d1 , & c -> a1b2 );
319+ secp256k1_num_sub (& rn1 , & na , & t );
320+ secp256k1_num_mul (& t , & d2 , & c -> a2 );
321+ secp256k1_num_sub (& rn1 , & rn1 , & t );
322+
323+ secp256k1_num_mul (& rn2 , & d1 , & c -> b1 );
324+ secp256k1_num_mul (& t , & d2 , & c -> a1b2 );
325+ secp256k1_num_sub (& rn2 , & rn2 , & t );
296326
297327 secp256k1_num_get_bin (b , 32 , & rn1 );
298328 secp256k1_scalar_set_b32 (r1 , b , NULL );
0 commit comments