Skip to content

Commit 21c5b28

Browse files
committed
Split fe_set_b32 into reducing and normalizing variants
1 parent 727d50a commit 21c5b28

File tree

15 files changed

+78
-37
lines changed

15 files changed

+78
-37
lines changed

src/bench_internal.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ static void bench_setup(void* arg) {
6565

6666
secp256k1_scalar_set_b32(&data->scalar[0], init[0], NULL);
6767
secp256k1_scalar_set_b32(&data->scalar[1], init[1], NULL);
68-
secp256k1_fe_set_b32(&data->fe[0], init[0]);
69-
secp256k1_fe_set_b32(&data->fe[1], init[1]);
70-
secp256k1_fe_set_b32(&data->fe[2], init[2]);
71-
secp256k1_fe_set_b32(&data->fe[3], init[3]);
68+
secp256k1_fe_set_b32_mod(&data->fe[0], init[0]);
69+
secp256k1_fe_set_b32_mod(&data->fe[1], init[1]);
70+
secp256k1_fe_set_b32_mod(&data->fe[2], init[2]);
71+
secp256k1_fe_set_b32_mod(&data->fe[3], init[3]);
7272
CHECK(secp256k1_ge_set_xo_var(&data->ge[0], &data->fe[0], 0));
7373
CHECK(secp256k1_ge_set_xo_var(&data->ge[1], &data->fe[1], 1));
7474
secp256k1_gej_set_ge(&data->gej[0], &data->ge[0]);

src/ecdsa_impl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,8 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_scalar *sigr, const secp25
239239
}
240240
#else
241241
secp256k1_scalar_get_b32(c, sigr);
242-
secp256k1_fe_set_b32(&xr, c);
242+
/* we can ignore the fe_set_b32_limit return value, because we know the input is in range */
243+
(void)secp256k1_fe_set_b32_limit(&xr, c);
243244

244245
/** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n)
245246
* in xr. Naively, we would extract the x coordinate from pr (requiring a inversion modulo p),

src/eckey_impl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) {
1818
if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) {
1919
secp256k1_fe x;
20-
return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD);
20+
return secp256k1_fe_set_b32_limit(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD);
2121
} else if (size == 65 && (pub[0] == SECP256K1_TAG_PUBKEY_UNCOMPRESSED || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) {
2222
secp256k1_fe x, y;
23-
if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) {
23+
if (!secp256k1_fe_set_b32_limit(&x, pub+1) || !secp256k1_fe_set_b32_limit(&y, pub+33)) {
2424
return 0;
2525
}
2626
secp256k1_ge_set_xy(elem, &x, &y);

src/ecmult_gen_compute_table_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static void secp256k1_ecmult_gen_compute_table(secp256k1_ge_storage* table, cons
3131
secp256k1_fe nums_x;
3232
secp256k1_ge nums_ge;
3333
int r;
34-
r = secp256k1_fe_set_b32(&nums_x, nums_b32);
34+
r = secp256k1_fe_set_b32_limit(&nums_x, nums_b32);
3535
(void)r;
3636
VERIFY_CHECK(r);
3737
r = secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0);

src/ecmult_gen_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const
108108
memset(keydata, 0, sizeof(keydata));
109109
/* Accept unobservably small non-uniformity. */
110110
secp256k1_rfc6979_hmac_sha256_generate(&rng, nonce32, 32);
111-
overflow = !secp256k1_fe_set_b32(&s, nonce32);
111+
overflow = !secp256k1_fe_set_b32_limit(&s, nonce32);
112112
overflow |= secp256k1_fe_is_zero(&s);
113113
secp256k1_fe_cmov(&s, &secp256k1_fe_one, overflow);
114114
/* Randomize the projection to defend against multiplier sidechannels.

src/field.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,14 @@ static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b);
7575
/** Compare two field elements. Requires both inputs to be normalized */
7676
static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b);
7777

78-
/** Set a field element equal to 32-byte big endian value.
79-
* Returns 1 if no overflow occurred, and then the output is normalized.
80-
* Returns 0 if overflow occurred, and then the output is only weakly normalized. */
81-
static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a);
78+
/** Set a field element equal to 32-byte big endian value, reducing modulo the curve
79+
* order if need be. The output is weakly normalized. */
80+
static void secp256k1_fe_set_b32_mod(secp256k1_fe *r, const unsigned char *a);
81+
82+
/** Set a field element equal to 32-byte big endian value. If the input is >= the
83+
* curve order, r is set to an indeterminate value and 0 is returned. Otherwise,
84+
* 1 is returned and the output is normalized. */
85+
static int secp256k1_fe_set_b32_limit(secp256k1_fe *r, const unsigned char *a);
8286

8387
/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
8488
static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a);

src/field_10x26_impl.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,7 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) {
351351
return 0;
352352
}
353353

354-
static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) {
355-
int ret;
354+
static void secp256k1_fe_set_b32_mod(secp256k1_fe *r, const unsigned char *a) {
356355
r->n[0] = (uint32_t)a[31] | ((uint32_t)a[30] << 8) | ((uint32_t)a[29] << 16) | ((uint32_t)(a[28] & 0x3) << 24);
357356
r->n[1] = (uint32_t)((a[28] >> 2) & 0x3f) | ((uint32_t)a[27] << 6) | ((uint32_t)a[26] << 14) | ((uint32_t)(a[25] & 0xf) << 22);
358357
r->n[2] = (uint32_t)((a[25] >> 4) & 0xf) | ((uint32_t)a[24] << 4) | ((uint32_t)a[23] << 12) | ((uint32_t)(a[22] & 0x3f) << 20);
@@ -364,12 +363,29 @@ static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) {
364363
r->n[8] = (uint32_t)a[5] | ((uint32_t)a[4] << 8) | ((uint32_t)a[3] << 16) | ((uint32_t)(a[2] & 0x3) << 24);
365364
r->n[9] = (uint32_t)((a[2] >> 2) & 0x3f) | ((uint32_t)a[1] << 6) | ((uint32_t)a[0] << 14);
366365

367-
ret = !((r->n[9] == 0x3FFFFFUL) & ((r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL) & ((r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL));
368366
#ifdef VERIFY
369367
r->magnitude = 1;
370-
r->normalized = ret;
368+
r->normalized = 0;
371369
secp256k1_fe_verify(r);
372370
#endif
371+
}
372+
373+
static int secp256k1_fe_set_b32_limit(secp256k1_fe *r, const unsigned char *a) {
374+
int ret;
375+
376+
secp256k1_fe_set_b32_mod(r, a);
377+
ret = !((r->n[9] == 0x3FFFFFUL) & ((r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL) & ((r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL));
378+
379+
#ifdef VERIFY
380+
if (ret) {
381+
r->magnitude = 1;
382+
r->normalized = 1;
383+
secp256k1_fe_verify(r);
384+
} else {
385+
r->n[4] ^= 1; /* change value, hopefully triggering errors if the value is used. */
386+
}
387+
#endif
388+
373389
return ret;
374390
}
375391

src/field_5x52_impl.h

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,7 @@ static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b) {
303303
return 0;
304304
}
305305

306-
static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) {
307-
int ret;
306+
static void secp256k1_fe_set_b32_mod(secp256k1_fe *r, const unsigned char *a) {
308307
r->n[0] = (uint64_t)a[31]
309308
| ((uint64_t)a[30] << 8)
310309
| ((uint64_t)a[29] << 16)
@@ -339,12 +338,30 @@ static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a) {
339338
| ((uint64_t)a[2] << 24)
340339
| ((uint64_t)a[1] << 32)
341340
| ((uint64_t)a[0] << 40);
342-
ret = !((r->n[4] == 0x0FFFFFFFFFFFFULL) & ((r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL) & (r->n[0] >= 0xFFFFEFFFFFC2FULL));
341+
343342
#ifdef VERIFY
344343
r->magnitude = 1;
345-
r->normalized = ret;
344+
r->normalized = 0;
346345
secp256k1_fe_verify(r);
347346
#endif
347+
}
348+
349+
static int secp256k1_fe_set_b32_limit(secp256k1_fe *r, const unsigned char *a) {
350+
int ret;
351+
352+
secp256k1_fe_set_b32_mod(r, a);
353+
ret = !((r->n[4] == 0x0FFFFFFFFFFFFULL) & ((r->n[3] & r->n[2] & r->n[1]) == 0xFFFFFFFFFFFFFULL) & (r->n[0] >= 0xFFFFEFFFFFC2FULL));
354+
355+
#ifdef VERIFY
356+
if (ret) {
357+
r->magnitude = 1;
358+
r->normalized = 1;
359+
secp256k1_fe_verify(r);
360+
} else {
361+
r->n[2] ^= 1; /* change value, hopefully triggering errors if the value is used. */
362+
}
363+
#endif
364+
348365
return ret;
349366
}
350367

src/modules/extrakeys/main_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ int secp256k1_xonly_pubkey_parse(const secp256k1_context* ctx, secp256k1_xonly_p
2727
memset(pubkey, 0, sizeof(*pubkey));
2828
ARG_CHECK(input32 != NULL);
2929

30-
if (!secp256k1_fe_set_b32(&x, input32)) {
30+
if (!secp256k1_fe_set_b32_limit(&x, input32)) {
3131
return 0;
3232
}
3333
if (!secp256k1_ge_set_xo_var(&pk, &x, 0)) {

src/modules/extrakeys/tests_exhaustive_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ static void test_exhaustive_extrakeys(const secp256k1_context *ctx, const secp25
4747
CHECK(secp256k1_memcmp_var(xonly_pubkey_bytes[i - 1], buf, 32) == 0);
4848

4949
/* Compare the xonly_pubkey bytes against the precomputed group. */
50-
secp256k1_fe_set_b32(&fe, xonly_pubkey_bytes[i - 1]);
50+
secp256k1_fe_set_b32_mod(&fe, xonly_pubkey_bytes[i - 1]);
5151
CHECK(secp256k1_fe_equal_var(&fe, &group[i].x));
5252

5353
/* Check the parity against the precomputed group. */

0 commit comments

Comments
 (0)