11
11
12
12
#include "util.h"
13
13
14
- static void secp256k1_modinv32_signed30_verify (const secp256k1_modinv32_signed30 * a ) {
15
- /* a must be in the range [-2^256, 2^256). */
14
+ static void secp256k1_modinv32_signed30_verify (const secp256k1_modinv32_signed30 * a ) {
16
15
VERIFY_CHECK (a -> v [0 ] >> 30 == 0 );
17
16
VERIFY_CHECK (a -> v [1 ] >> 30 == 0 );
18
17
VERIFY_CHECK (a -> v [2 ] >> 30 == 0 );
@@ -21,7 +20,58 @@ static void secp256k1_modinv32_signed30_verify(const secp256k1_modinv32_signed30
21
20
VERIFY_CHECK (a -> v [5 ] >> 30 == 0 );
22
21
VERIFY_CHECK (a -> v [6 ] >> 30 == 0 );
23
22
VERIFY_CHECK (a -> v [7 ] >> 30 == 0 );
24
- VERIFY_CHECK (a -> v [8 ] >> 16 == 0 || a -> v [8 ] >> 16 == - (int32_t )1 );
23
+ VERIFY_CHECK (a -> v [8 ] >> 16 == 0 );
24
+ }
25
+
26
+ static void secp256k1_modinv32_normalize_30 (secp256k1_modinv32_signed30 * r , int32_t cond_negate , const secp256k1_modinv32_modinfo * modinfo ) {
27
+ const int32_t M30 = (int32_t )(UINT32_MAX >> 2 );
28
+ int32_t r0 = r -> v [0 ], r1 = r -> v [1 ], r2 = r -> v [2 ], r3 = r -> v [3 ], r4 = r -> v [4 ],
29
+ r5 = r -> v [5 ], r6 = r -> v [6 ], r7 = r -> v [7 ], r8 = r -> v [8 ];
30
+ int32_t c , cond_add ;
31
+
32
+ cond_add = r8 >> 31 ;
33
+
34
+ c = r0 + (modinfo -> modulus .v [0 ] & cond_add );
35
+ r0 = c & M30 ; c >>= 30 ;
36
+ c += r1 + (modinfo -> modulus .v [1 ] & cond_add );
37
+ r1 = c & M30 ; c >>= 30 ;
38
+ c += r2 + (modinfo -> modulus .v [2 ] & cond_add );
39
+ r2 = c & M30 ; c >>= 30 ;
40
+ c += r3 + (modinfo -> modulus .v [3 ] & cond_add );
41
+ r3 = c & M30 ; c >>= 30 ;
42
+ c += r4 + (modinfo -> modulus .v [4 ] & cond_add );
43
+ r4 = c & M30 ; c >>= 30 ;
44
+ c += r5 + (modinfo -> modulus .v [5 ] & cond_add );
45
+ r5 = c & M30 ; c >>= 30 ;
46
+ c += r6 + (modinfo -> modulus .v [6 ] & cond_add );
47
+ r6 = c & M30 ; c >>= 30 ;
48
+ c += r7 + (modinfo -> modulus .v [7 ] & cond_add );
49
+ r7 = c & M30 ; c >>= 30 ;
50
+ c += r8 + (modinfo -> modulus .v [8 ] & cond_add );
51
+ r8 = c ;
52
+
53
+ cond_add = (c >> 31 ) ^ cond_negate ;
54
+
55
+ c = (r0 ^ cond_negate ) - cond_negate + (modinfo -> modulus .v [0 ] & cond_add );
56
+ r -> v [0 ] = c & M30 ; c >>= 30 ;
57
+ c += (r1 ^ cond_negate ) - cond_negate + (modinfo -> modulus .v [1 ] & cond_add );
58
+ r -> v [1 ] = c & M30 ; c >>= 30 ;
59
+ c += (r2 ^ cond_negate ) - cond_negate + (modinfo -> modulus .v [2 ] & cond_add );
60
+ r -> v [2 ] = c & M30 ; c >>= 30 ;
61
+ c += (r3 ^ cond_negate ) - cond_negate + (modinfo -> modulus .v [3 ] & cond_add );
62
+ r -> v [3 ] = c & M30 ; c >>= 30 ;
63
+ c += (r4 ^ cond_negate ) - cond_negate + (modinfo -> modulus .v [4 ] & cond_add );
64
+ r -> v [4 ] = c & M30 ; c >>= 30 ;
65
+ c += (r5 ^ cond_negate ) - cond_negate + (modinfo -> modulus .v [5 ] & cond_add );
66
+ r -> v [5 ] = c & M30 ; c >>= 30 ;
67
+ c += (r6 ^ cond_negate ) - cond_negate + (modinfo -> modulus .v [6 ] & cond_add );
68
+ r -> v [6 ] = c & M30 ; c >>= 30 ;
69
+ c += (r7 ^ cond_negate ) - cond_negate + (modinfo -> modulus .v [7 ] & cond_add );
70
+ r -> v [7 ] = c & M30 ; c >>= 30 ;
71
+ c += (r8 ^ cond_negate ) - cond_negate + (modinfo -> modulus .v [8 ] & cond_add );
72
+ r -> v [8 ] = c ;
73
+
74
+ VERIFY_CHECK (c >> 16 == 0 );
25
75
}
26
76
27
77
static uint32_t secp256k1_modinv32_divsteps_30 (uint32_t eta , uint32_t f0 , uint32_t g0 , int32_t * t ) {
@@ -134,20 +184,37 @@ static uint32_t secp256k1_modinv32_divsteps_30_var(uint32_t eta, uint32_t f0, ui
134
184
135
185
static void secp256k1_modinv32_update_de_30 (secp256k1_modinv32_signed30 * d , secp256k1_modinv32_signed30 * e , const int32_t * t , const secp256k1_modinv32_modinfo * modinfo ) {
136
186
const int32_t M30 = (int32_t )(UINT32_MAX >> 2 );
137
- int32_t u = t [0 ], v = t [1 ], q = t [2 ], r = t [3 ], di , ei , md , me ;
187
+ const int32_t u = t [0 ], v = t [1 ], q = t [2 ], r = t [3 ];
188
+ int32_t di , ei , md , me , sd , se ;
138
189
int64_t cd , ce ;
139
190
int i ;
140
191
192
+ /*
193
+ * On input, d/e must be in the range (-2.P, P). For initially negative d (resp. e), we add
194
+ * u and/or v (resp. q and/or r) multiples of the modulus to the corresponding output (prior
195
+ * to division by 2^30). This has the same effect as if we added the modulus to the input(s).
196
+ */
197
+
198
+ sd = d -> v [8 ] >> 31 ;
199
+ se = e -> v [8 ] >> 31 ;
200
+
201
+ md = (u & sd ) + (v & se );
202
+ me = (q & sd ) + (r & se );
203
+
141
204
di = d -> v [0 ];
142
205
ei = e -> v [0 ];
143
206
144
207
cd = (int64_t )u * di + (int64_t )v * ei ;
145
208
ce = (int64_t )q * di + (int64_t )r * ei ;
146
209
147
- /* Calculate the multiples of P to add, to zero the 30 bottom bits. We choose md, me
148
- * from the centred range [-2^29, 2^29) to keep d, e within [-2^256, 2^256). */
149
- md = ((int32_t )(modinfo -> montmul4 * (uint32_t )cd )) >> 2 ;
150
- me = ((int32_t )(modinfo -> montmul4 * (uint32_t )ce )) >> 2 ;
210
+ /*
211
+ * Subtract from md/me an extra term in the range [0, 2^30) such that the low 30 bits of each
212
+ * sum of products will be 0. This allows clean division by 2^30. On output, d/e are thus in
213
+ * the range (-2.P, P), consistent with the input constraint.
214
+ */
215
+
216
+ md -= (modinfo -> modulus_inv30 * (int32_t )cd + md ) & M30 ;
217
+ me -= (modinfo -> modulus_inv30 * (int32_t )ce + me ) & M30 ;
151
218
152
219
if (modinfo -> modulus .v [0 ]) {
153
220
cd += (int64_t )modinfo -> modulus .v [0 ] * md ;
@@ -243,7 +310,7 @@ static void secp256k1_modinv32_update_fg_30_var(int len, secp256k1_modinv32_sign
243
310
g -> v [len - 1 ] = (int32_t )cg ;
244
311
}
245
312
246
- static void secp256k1_modinv32 (int * sign , secp256k1_modinv32_signed30 * x , const secp256k1_modinv32_modinfo * modinfo ) {
313
+ static void secp256k1_modinv32 (secp256k1_modinv32_signed30 * x , const secp256k1_modinv32_modinfo * modinfo ) {
247
314
/* Modular inversion based on the paper "Fast constant-time gcd computation and
248
315
* modular inversion" by Daniel J. Bernstein and Bo-Yin Yang. */
249
316
int32_t t [4 ];
@@ -272,11 +339,12 @@ static void secp256k1_modinv32(int* sign, secp256k1_modinv32_signed30* x, const
272
339
* values i.e. +/- 1, and d now contains +/- the modular inverse. */
273
340
VERIFY_CHECK ((g .v [0 ] | g .v [1 ] | g .v [2 ] | g .v [3 ] | g .v [4 ] | g .v [5 ] | g .v [6 ] | g .v [7 ] | g .v [8 ]) == 0 );
274
341
275
- * sign = (f .v [0 ] >> 1 ) & 1 ;
342
+ secp256k1_modinv32_normalize_30 (& d , f .v [8 ] >> 31 , modinfo );
343
+
276
344
* x = d ;
277
345
}
278
346
279
- static void secp256k1_modinv32_var (int * sign , secp256k1_modinv32_signed30 * x , const secp256k1_modinv32_modinfo * modinfo ) {
347
+ static void secp256k1_modinv32_var (secp256k1_modinv32_signed30 * x , const secp256k1_modinv32_modinfo * modinfo ) {
280
348
/* Modular inversion based on the paper "Fast constant-time gcd computation and
281
349
* modular inversion" by Daniel J. Bernstein and Bo-Yin Yang. */
282
350
int32_t t [4 ];
@@ -328,7 +396,8 @@ static void secp256k1_modinv32_var(int* sign, secp256k1_modinv32_signed30 *x, co
328
396
329
397
VERIFY_CHECK (i < 25 );
330
398
331
- * sign = (f .v [0 ] >> 1 ) & 1 ;
399
+ secp256k1_modinv32_normalize_30 (& d , f .v [len - 1 ] >> 31 , modinfo );
400
+
332
401
* x = d ;
333
402
}
334
403
0 commit comments