@@ -145,33 +145,35 @@ typedef struct {
145
145
int64_t u , v , q , r ;
146
146
} secp256k1_modinv64_trans2x2 ;
147
147
148
- /* Compute the transition matrix and eta for 62 divsteps.
148
+ /* Compute the transition matrix and eta for 59 divsteps (where zeta=-(delta+1/2)).
149
+ * Note that the transformation matrix is scaled by 2^62 and not 2^59.
149
150
*
150
- * Input: eta : initial eta
151
- * f0: bottom limb of initial f
152
- * g0: bottom limb of initial g
151
+ * Input: zeta : initial zeta
152
+ * f0: bottom limb of initial f
153
+ * g0: bottom limb of initial g
153
154
* Output: t: transition matrix
154
- * Return: final eta
155
+ * Return: final zeta
155
156
*
156
157
* Implements the divsteps_n_matrix function from the explanation.
157
158
*/
158
- static int64_t secp256k1_modinv64_divsteps_62 (int64_t eta , uint64_t f0 , uint64_t g0 , secp256k1_modinv64_trans2x2 * t ) {
159
+ static int64_t secp256k1_modinv64_divsteps_59 (int64_t zeta , uint64_t f0 , uint64_t g0 , secp256k1_modinv64_trans2x2 * t ) {
159
160
/* u,v,q,r are the elements of the transformation matrix being built up,
160
- * starting with the identity matrix. Semantically they are signed integers
161
+ * starting with the identity matrix times 8 (because the caller expects
162
+ * a result scaled by 2^62). Semantically they are signed integers
161
163
* in range [-2^62,2^62], but here represented as unsigned mod 2^64. This
162
164
* permits left shifting (which is UB for negative numbers). The range
163
165
* being inside [-2^63,2^63) means that casting to signed works correctly.
164
166
*/
165
- uint64_t u = 1 , v = 0 , q = 0 , r = 1 ;
167
+ uint64_t u = 8 , v = 0 , q = 0 , r = 8 ;
166
168
uint64_t c1 , c2 , f = f0 , g = g0 , x , y , z ;
167
169
int i ;
168
170
169
- for (i = 0 ; i < 62 ; ++ i ) {
171
+ for (i = 3 ; i < 62 ; ++ i ) {
170
172
VERIFY_CHECK ((f & 1 ) == 1 ); /* f must always be odd */
171
173
VERIFY_CHECK ((u * f0 + v * g0 ) == f << i );
172
174
VERIFY_CHECK ((q * f0 + r * g0 ) == g << i );
173
- /* Compute conditional masks for (eta < 0) and for (g & 1). */
174
- c1 = eta >> 63 ;
175
+ /* Compute conditional masks for (zeta < 0) and for (g & 1). */
176
+ c1 = zeta >> 63 ;
175
177
c2 = - (g & 1 );
176
178
/* Compute x,y,z, conditionally negated versions of f,u,v. */
177
179
x = (f ^ c1 ) - c1 ;
@@ -181,10 +183,10 @@ static int64_t secp256k1_modinv64_divsteps_62(int64_t eta, uint64_t f0, uint64_t
181
183
g += x & c2 ;
182
184
q += y & c2 ;
183
185
r += z & c2 ;
184
- /* In what follows, c1 is a condition mask for (eta < 0) and (g & 1). */
186
+ /* In what follows, c1 is a condition mask for (zeta < 0) and (g & 1). */
185
187
c1 &= c2 ;
186
- /* Conditionally negate eta, and unconditionally subtract 1. */
187
- eta = (eta ^ c1 ) - ( c1 + 1 ) ;
188
+ /* Conditionally change zeta into -zeta-2 or zeta- 1. */
189
+ zeta = (zeta ^ c1 ) - 1 ;
188
190
/* Conditionally add g,q,r to f,u,v. */
189
191
f += g & c1 ;
190
192
u += q & c1 ;
@@ -193,8 +195,8 @@ static int64_t secp256k1_modinv64_divsteps_62(int64_t eta, uint64_t f0, uint64_t
193
195
g >>= 1 ;
194
196
u <<= 1 ;
195
197
v <<= 1 ;
196
- /* Bounds on eta that follow from the bounds on iteration count (max 12*62 divsteps). */
197
- VERIFY_CHECK (eta >= -745 && eta <= 745 );
198
+ /* Bounds on zeta that follow from the bounds on iteration count (max 10*59 divsteps). */
199
+ VERIFY_CHECK (zeta >= -591 && zeta <= 591 );
198
200
}
199
201
/* Return data in t and return value. */
200
202
t -> u = (int64_t )u ;
@@ -204,12 +206,14 @@ static int64_t secp256k1_modinv64_divsteps_62(int64_t eta, uint64_t f0, uint64_t
204
206
/* The determinant of t must be a power of two. This guarantees that multiplication with t
205
207
* does not change the gcd of f and g, apart from adding a power-of-2 factor to it (which
206
208
* will be divided out again). As each divstep's individual matrix has determinant 2, the
207
- * aggregate of 62 of them will have determinant 2^62. */
208
- VERIFY_CHECK ((int128_t )t -> u * t -> r - (int128_t )t -> v * t -> q == ((int128_t )1 ) << 62 );
209
- return eta ;
209
+ * aggregate of 59 of them will have determinant 2^59. Multiplying with the initial
210
+ * 8*identity (which has determinant 2^6) means the overall outputs has determinant
211
+ * 2^65. */
212
+ VERIFY_CHECK ((int128_t )t -> u * t -> r - (int128_t )t -> v * t -> q == ((int128_t )1 ) << 65 );
213
+ return zeta ;
210
214
}
211
215
212
- /* Compute the transition matrix and eta for 62 divsteps (variable time).
216
+ /* Compute the transition matrix and eta for 62 divsteps (variable time, eta=-delta ).
213
217
*
214
218
* Input: eta: initial eta
215
219
* f0: bottom limb of initial f
@@ -290,7 +294,7 @@ static int64_t secp256k1_modinv64_divsteps_62_var(int64_t eta, uint64_t f0, uint
290
294
return eta ;
291
295
}
292
296
293
- /* Compute (t/2^62) * [d, e] mod modulus, where t is a transition matrix for 62 divsteps .
297
+ /* Compute (t/2^62) * [d, e] mod modulus, where t is a transition matrix scaled by 2^62 .
294
298
*
295
299
* On input and output, d and e are in range (-2*modulus,modulus). All output limbs will be in range
296
300
* (-2^62,2^62).
@@ -376,7 +380,7 @@ static void secp256k1_modinv64_update_de_62(secp256k1_modinv64_signed62 *d, secp
376
380
#endif
377
381
}
378
382
379
- /* Compute (t/2^62) * [f, g], where t is a transition matrix for 62 divsteps .
383
+ /* Compute (t/2^62) * [f, g], where t is a transition matrix scaled by 2^62 .
380
384
*
381
385
* This implements the update_fg function from the explanation.
382
386
*/
@@ -455,19 +459,19 @@ static void secp256k1_modinv64_update_fg_62_var(int len, secp256k1_modinv64_sign
455
459
456
460
/* Compute the inverse of x modulo modinfo->modulus, and replace x with it (constant time in x). */
457
461
static void secp256k1_modinv64 (secp256k1_modinv64_signed62 * x , const secp256k1_modinv64_modinfo * modinfo ) {
458
- /* Start with d=0, e=1, f=modulus, g=x, eta =-1. */
462
+ /* Start with d=0, e=1, f=modulus, g=x, zeta =-1. */
459
463
secp256k1_modinv64_signed62 d = {{0 , 0 , 0 , 0 , 0 }};
460
464
secp256k1_modinv64_signed62 e = {{1 , 0 , 0 , 0 , 0 }};
461
465
secp256k1_modinv64_signed62 f = modinfo -> modulus ;
462
466
secp256k1_modinv64_signed62 g = * x ;
463
467
int i ;
464
- int64_t eta = -1 ;
468
+ int64_t zeta = -1 ; /* zeta = -(delta+1/2); delta starts at 1/2. */
465
469
466
- /* Do 12 iterations of 62 divsteps each = 744 divsteps. 724 suffices for 256-bit inputs. */
467
- for (i = 0 ; i < 12 ; ++ i ) {
468
- /* Compute transition matrix and new eta after 62 divsteps. */
470
+ /* Do 10 iterations of 59 divsteps each = 590 divsteps. This suffices for 256-bit inputs. */
471
+ for (i = 0 ; i < 10 ; ++ i ) {
472
+ /* Compute transition matrix and new zeta after 59 divsteps. */
469
473
secp256k1_modinv64_trans2x2 t ;
470
- eta = secp256k1_modinv64_divsteps_62 ( eta , f .v [0 ], g .v [0 ], & t );
474
+ zeta = secp256k1_modinv64_divsteps_59 ( zeta , f .v [0 ], g .v [0 ], & t );
471
475
/* Update d,e using that transition matrix. */
472
476
secp256k1_modinv64_update_de_62 (& d , & e , & t , modinfo );
473
477
/* Update f,g using that transition matrix. */
@@ -517,7 +521,7 @@ static void secp256k1_modinv64_var(secp256k1_modinv64_signed62 *x, const secp256
517
521
int i = 0 ;
518
522
#endif
519
523
int j , len = 5 ;
520
- int64_t eta = -1 ;
524
+ int64_t eta = -1 ; /* eta = -delta; delta is initially 1 */
521
525
int64_t cond , fn , gn ;
522
526
523
527
/* Do iterations of 62 divsteps each until g=0. */
0 commit comments