Skip to content

Commit 634b3e9

Browse files
committed
Make secp256k1_scalar_b32 detect overflow in scalar_low
1 parent 9811672 commit 634b3e9

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

src/modules/recovery/tests_exhaustive_impl.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,20 @@ void test_exhaustive_recovery_sign(const secp256k1_context *ctx, const secp256k1
3838
CHECK(r == expected_r);
3939
CHECK((k * s) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER ||
4040
(k * (EXHAUSTIVE_TEST_ORDER - s)) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER);
41-
/* In computing the recid, there is an overflow condition that is disabled in
42-
* scalar_low_impl.h `secp256k1_scalar_set_b32` because almost every r.y value
43-
* will exceed the group order, and our signing code always holds out for r
44-
* values that don't overflow, so with a proper overflow check the tests would
45-
* loop indefinitely. */
41+
/* The recid's second bit is for conveying overflow (R.x value >= group order).
42+
* In the actual secp256k1 this is an astronomically unlikely event, but in the
43+
* small group used here, it will always be the case.
44+
* Note that this isn't actually useful; full recovery would need to convey
45+
* floor(R.x / group_order), but only one bit is used as that is sufficient
46+
* in the real group. */
47+
expected_recid = 2;
4648
r_dot_y_normalized = group[k].y;
4749
secp256k1_fe_normalize(&r_dot_y_normalized);
4850
/* Also the recovery id is flipped depending if we hit the low-s branch */
4951
if ((k * s) % EXHAUSTIVE_TEST_ORDER == (i + r * j) % EXHAUSTIVE_TEST_ORDER) {
50-
expected_recid = secp256k1_fe_is_odd(&r_dot_y_normalized) ? 1 : 0;
52+
expected_recid |= secp256k1_fe_is_odd(&r_dot_y_normalized);
5153
} else {
52-
expected_recid = secp256k1_fe_is_odd(&r_dot_y_normalized) ? 0 : 1;
54+
expected_recid |= !secp256k1_fe_is_odd(&r_dot_y_normalized);
5355
}
5456
CHECK(recid == expected_recid);
5557

src/scalar_low_impl.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,17 @@ static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int
4848
}
4949

5050
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) {
51-
const int base = 0x100 % EXHAUSTIVE_TEST_ORDER;
5251
int i;
52+
int over = 0;
5353
*r = 0;
5454
for (i = 0; i < 32; i++) {
55-
*r = ((*r * base) + b32[i]) % EXHAUSTIVE_TEST_ORDER;
55+
*r = (*r * 0x100) + b32[i];
56+
if (*r >= EXHAUSTIVE_TEST_ORDER) {
57+
over = 1;
58+
*r %= EXHAUSTIVE_TEST_ORDER;
59+
}
5660
}
57-
/* just deny overflow, it basically always happens */
58-
if (overflow) *overflow = 0;
61+
if (overflow) *overflow = over;
5962
}
6063

6164
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) {

0 commit comments

Comments
 (0)