Skip to content

Commit d5aa2f0

Browse files
committed
Abstract out verify logic for fe_inv{,_var}
1 parent 3167646 commit d5aa2f0

File tree

4 files changed

+43
-51
lines changed

4 files changed

+43
-51
lines changed

src/field.h

+13-3
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ static const secp256k1_fe secp256k1_const_beta = SECP256K1_FE_CONST(
9595
# define secp256k1_fe_cmov secp256k1_fe_impl_cmov
9696
# define secp256k1_fe_to_storage secp256k1_fe_impl_to_storage
9797
# define secp256k1_fe_from_storage secp256k1_fe_impl_from_storage
98+
# define secp256k1_fe_inv secp256k1_fe_impl_inv
99+
# define secp256k1_fe_inv_var secp256k1_fe_impl_inv_var
98100
#endif /* !defined(VERIFY) */
99101

100102
/** Normalize a field element.
@@ -258,11 +260,19 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a);
258260
*/
259261
static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k1_fe * SECP256K1_RESTRICT a);
260262

261-
/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be
262-
* at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */
263+
/** Compute the modular inverse of a field element.
264+
*
265+
* On input, a must be a valid field element; r need not be initialized.
266+
* Performs {r = a**(p-2)} (which maps 0 to 0, and every other element to its
267+
* inverse).
268+
* On output, r will have magnitude (a.magnitude != 0) and be normalized.
269+
*/
263270
static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a);
264271

265-
/** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */
272+
/** Compute the modular inverse of a field element, without constant-time guarantee.
273+
*
274+
* Behaves identically to secp256k1_fe_inv, but is not constant-time in a.
275+
*/
266276
static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a);
267277

268278
/** Convert a field element to secp256k1_fe_storage.

src/field_10x26_impl.h

+4-24
Original file line numberDiff line numberDiff line change
@@ -1197,23 +1197,13 @@ static void secp256k1_fe_from_signed30(secp256k1_fe *r, const secp256k1_modinv32
11971197
r->n[7] = (a6 >> 2 ) & M26;
11981198
r->n[8] = (a6 >> 28 | a7 << 2) & M26;
11991199
r->n[9] = (a7 >> 24 | a8 << 6);
1200-
1201-
#ifdef VERIFY
1202-
r->magnitude = 1;
1203-
r->normalized = 1;
1204-
secp256k1_fe_verify(r);
1205-
#endif
12061200
}
12071201

12081202
static void secp256k1_fe_to_signed30(secp256k1_modinv32_signed30 *r, const secp256k1_fe *a) {
12091203
const uint32_t M30 = UINT32_MAX >> 2;
12101204
const uint64_t a0 = a->n[0], a1 = a->n[1], a2 = a->n[2], a3 = a->n[3], a4 = a->n[4],
12111205
a5 = a->n[5], a6 = a->n[6], a7 = a->n[7], a8 = a->n[8], a9 = a->n[9];
12121206

1213-
#ifdef VERIFY
1214-
VERIFY_CHECK(a->normalized);
1215-
#endif
1216-
12171207
r->v[0] = (a0 | a1 << 26) & M30;
12181208
r->v[1] = (a1 >> 4 | a2 << 22) & M30;
12191209
r->v[2] = (a2 >> 8 | a3 << 18) & M30;
@@ -1231,34 +1221,24 @@ static const secp256k1_modinv32_modinfo secp256k1_const_modinfo_fe = {
12311221
0x2DDACACFL
12321222
};
12331223

1234-
static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) {
1235-
secp256k1_fe tmp;
1224+
static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x) {
1225+
secp256k1_fe tmp = *x;
12361226
secp256k1_modinv32_signed30 s;
12371227

1238-
tmp = *x;
12391228
secp256k1_fe_normalize(&tmp);
12401229
secp256k1_fe_to_signed30(&s, &tmp);
12411230
secp256k1_modinv32(&s, &secp256k1_const_modinfo_fe);
12421231
secp256k1_fe_from_signed30(r, &s);
1243-
1244-
#ifdef VERIFY
1245-
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
1246-
#endif
12471232
}
12481233

1249-
static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
1250-
secp256k1_fe tmp;
1234+
static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
1235+
secp256k1_fe tmp = *x;
12511236
secp256k1_modinv32_signed30 s;
12521237

1253-
tmp = *x;
12541238
secp256k1_fe_normalize_var(&tmp);
12551239
secp256k1_fe_to_signed30(&s, &tmp);
12561240
secp256k1_modinv32_var(&s, &secp256k1_const_modinfo_fe);
12571241
secp256k1_fe_from_signed30(r, &s);
1258-
1259-
#ifdef VERIFY
1260-
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
1261-
#endif
12621242
}
12631243

12641244
static int secp256k1_fe_is_square_var(const secp256k1_fe *x) {

src/field_5x52_impl.h

+4-24
Original file line numberDiff line numberDiff line change
@@ -492,22 +492,12 @@ static void secp256k1_fe_from_signed62(secp256k1_fe *r, const secp256k1_modinv64
492492
r->n[2] = (a1 >> 42 | a2 << 20) & M52;
493493
r->n[3] = (a2 >> 32 | a3 << 30) & M52;
494494
r->n[4] = (a3 >> 22 | a4 << 40);
495-
496-
#ifdef VERIFY
497-
r->magnitude = 1;
498-
r->normalized = 1;
499-
secp256k1_fe_verify(r);
500-
#endif
501495
}
502496

503497
static void secp256k1_fe_to_signed62(secp256k1_modinv64_signed62 *r, const secp256k1_fe *a) {
504498
const uint64_t M62 = UINT64_MAX >> 2;
505499
const uint64_t a0 = a->n[0], a1 = a->n[1], a2 = a->n[2], a3 = a->n[3], a4 = a->n[4];
506500

507-
#ifdef VERIFY
508-
VERIFY_CHECK(a->normalized);
509-
#endif
510-
511501
r->v[0] = (a0 | a1 << 52) & M62;
512502
r->v[1] = (a1 >> 10 | a2 << 42) & M62;
513503
r->v[2] = (a2 >> 20 | a3 << 32) & M62;
@@ -520,34 +510,24 @@ static const secp256k1_modinv64_modinfo secp256k1_const_modinfo_fe = {
520510
0x27C7F6E22DDACACFLL
521511
};
522512

523-
static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) {
524-
secp256k1_fe tmp;
513+
static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x) {
514+
secp256k1_fe tmp = *x;
525515
secp256k1_modinv64_signed62 s;
526516

527-
tmp = *x;
528517
secp256k1_fe_normalize(&tmp);
529518
secp256k1_fe_to_signed62(&s, &tmp);
530519
secp256k1_modinv64(&s, &secp256k1_const_modinfo_fe);
531520
secp256k1_fe_from_signed62(r, &s);
532-
533-
#ifdef VERIFY
534-
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
535-
#endif
536521
}
537522

538-
static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
539-
secp256k1_fe tmp;
523+
static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
524+
secp256k1_fe tmp = *x;
540525
secp256k1_modinv64_signed62 s;
541526

542-
tmp = *x;
543527
secp256k1_fe_normalize_var(&tmp);
544528
secp256k1_fe_to_signed62(&s, &tmp);
545529
secp256k1_modinv64_var(&s, &secp256k1_const_modinfo_fe);
546530
secp256k1_fe_from_signed62(r, &s);
547-
548-
#ifdef VERIFY
549-
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
550-
#endif
551531
}
552532

553533
static int secp256k1_fe_is_square_var(const secp256k1_fe *x) {

src/field_impl.h

+22
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,28 @@ SECP256K1_INLINE static void secp256k1_fe_from_storage(secp256k1_fe *r, const se
351351
r->normalized = 1;
352352
secp256k1_fe_verify(r);
353353
}
354+
355+
static void secp256k1_fe_impl_inv(secp256k1_fe *r, const secp256k1_fe *x);
356+
SECP256K1_INLINE static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *x) {
357+
int input_is_zero = secp256k1_fe_normalizes_to_zero(x);
358+
secp256k1_fe_verify(x);
359+
secp256k1_fe_impl_inv(r, x);
360+
r->magnitude = x->magnitude > 0;
361+
r->normalized = 1;
362+
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == input_is_zero);
363+
secp256k1_fe_verify(r);
364+
}
365+
366+
static void secp256k1_fe_impl_inv_var(secp256k1_fe *r, const secp256k1_fe *x);
367+
SECP256K1_INLINE static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
368+
int input_is_zero = secp256k1_fe_normalizes_to_zero(x);
369+
secp256k1_fe_verify(x);
370+
secp256k1_fe_impl_inv_var(r, x);
371+
r->magnitude = x->magnitude > 0;
372+
r->normalized = 1;
373+
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == input_is_zero);
374+
secp256k1_fe_verify(r);
375+
}
354376
#endif /* defined(VERIFY) */
355377

356378
#endif /* SECP256K1_FIELD_IMPL_H */

0 commit comments

Comments
 (0)