Skip to content

Commit bd1f64e

Browse files
committed
Add fe_half tests for worst-case inputs
1 parent b4963f1 commit bd1f64e

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/tests.c

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,37 @@ static void uncounting_illegal_callback_fn(const char* str, void* data) {
4747
(*p)--;
4848
}
4949

50+
void max_fe_for_magnitude(secp256k1_fe *r, int m) {
51+
secp256k1_fe_clear(r);
52+
53+
#if defined(SECP256K1_WIDEMUL_INT128)
54+
r->n[0] = 0xFFFFFFFFFFFFFULL * 2 * m;
55+
r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * m;
56+
r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * m;
57+
r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * m;
58+
r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * m;
59+
#elif defined(SECP256K1_WIDEMUL_INT64)
60+
r->n[0] = 0x3FFFFFFUL * 2 * m;
61+
r->n[1] = 0x3FFFFFFUL * 2 * m;
62+
r->n[2] = 0x3FFFFFFUL * 2 * m;
63+
r->n[3] = 0x3FFFFFFUL * 2 * m;
64+
r->n[4] = 0x3FFFFFFUL * 2 * m;
65+
r->n[5] = 0x3FFFFFFUL * 2 * m;
66+
r->n[6] = 0x3FFFFFFUL * 2 * m;
67+
r->n[7] = 0x3FFFFFFUL * 2 * m;
68+
r->n[8] = 0x3FFFFFFUL * 2 * m;
69+
r->n[9] = 0x03FFFFFUL * 2 * m;
70+
#else
71+
#error "Please select wide multiplication implementation"
72+
#endif
73+
74+
#ifdef VERIFY
75+
r->magnitude = m;
76+
r->normalized = (m == 0);
77+
secp256k1_fe_verify(r);
78+
#endif
79+
}
80+
5081
void random_field_element_test(secp256k1_fe *fe) {
5182
do {
5283
unsigned char b32[32];
@@ -2460,6 +2491,55 @@ int fe_secp256k1_memcmp_var(const secp256k1_fe *a, const secp256k1_fe *b) {
24602491
return secp256k1_memcmp_var(a, &t, sizeof(secp256k1_fe));
24612492
}
24622493

2494+
void run_field_half(void) {
2495+
secp256k1_fe t, u;
2496+
int m;
2497+
2498+
/* Check magnitude 0 input */
2499+
secp256k1_fe_clear(&t);
2500+
secp256k1_fe_half(&t);
2501+
#ifdef VERIFY
2502+
CHECK(t.magnitude == 1);
2503+
CHECK(t.normalized == 0);
2504+
#endif
2505+
CHECK(secp256k1_fe_normalizes_to_zero(&t));
2506+
2507+
/* Check non-zero magnitudes in the supported range */
2508+
for (m = 1; m < 32; m++) {
2509+
/* Check max-value input */
2510+
max_fe_for_magnitude(&t, m);
2511+
2512+
u = t;
2513+
secp256k1_fe_half(&u);
2514+
#ifdef VERIFY
2515+
CHECK(u.magnitude == (m >> 1) + 1);
2516+
CHECK(u.normalized == 0);
2517+
#endif
2518+
secp256k1_fe_normalize_weak(&u);
2519+
secp256k1_fe_add(&u, &u);
2520+
CHECK(check_fe_equal(&t, &u));
2521+
2522+
/* Check worst-case input: ensure the LSB is 1 so that P will be added,
2523+
* which will also cause all carries to be 1, since all limbs that can
2524+
* generate a carry are initially even and all limbs of P are odd in
2525+
* every existing field implementation. */
2526+
max_fe_for_magnitude(&t, m);
2527+
CHECK(t.n[0] > 0);
2528+
CHECK((t.n[0] & 1) == 0);
2529+
--t.n[0];
2530+
2531+
u = t;
2532+
secp256k1_fe_half(&u);
2533+
#ifdef VERIFY
2534+
CHECK(u.magnitude == (m >> 1) + 1);
2535+
CHECK(u.normalized == 0);
2536+
#endif
2537+
secp256k1_fe_normalize_weak(&u);
2538+
secp256k1_fe_add(&u, &u);
2539+
CHECK(check_fe_equal(&t, &u));
2540+
}
2541+
}
2542+
24632543
void run_field_misc(void) {
24642544
secp256k1_fe x;
24652545
secp256k1_fe y;
@@ -6809,6 +6889,7 @@ int main(int argc, char **argv) {
68096889
run_scalar_tests();
68106890

68116891
/* field tests */
6892+
run_field_half();
68126893
run_field_misc();
68136894
run_field_convert();
68146895
run_fe_mul();

0 commit comments

Comments
 (0)