Skip to content

Commit

Permalink
Add fe_half tests for worst-case inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
peterdettman committed Dec 23, 2021
1 parent b4963f1 commit bd1f64e
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions src/tests.c
Expand Up @@ -47,6 +47,37 @@ static void uncounting_illegal_callback_fn(const char* str, void* data) {
(*p)--;
}

void max_fe_for_magnitude(secp256k1_fe *r, int m) {
secp256k1_fe_clear(r);

#if defined(SECP256K1_WIDEMUL_INT128)
r->n[0] = 0xFFFFFFFFFFFFFULL * 2 * m;
r->n[1] = 0xFFFFFFFFFFFFFULL * 2 * m;
r->n[2] = 0xFFFFFFFFFFFFFULL * 2 * m;
r->n[3] = 0xFFFFFFFFFFFFFULL * 2 * m;
r->n[4] = 0x0FFFFFFFFFFFFULL * 2 * m;
#elif defined(SECP256K1_WIDEMUL_INT64)
r->n[0] = 0x3FFFFFFUL * 2 * m;
r->n[1] = 0x3FFFFFFUL * 2 * m;
r->n[2] = 0x3FFFFFFUL * 2 * m;
r->n[3] = 0x3FFFFFFUL * 2 * m;
r->n[4] = 0x3FFFFFFUL * 2 * m;
r->n[5] = 0x3FFFFFFUL * 2 * m;
r->n[6] = 0x3FFFFFFUL * 2 * m;
r->n[7] = 0x3FFFFFFUL * 2 * m;
r->n[8] = 0x3FFFFFFUL * 2 * m;
r->n[9] = 0x03FFFFFUL * 2 * m;
#else
#error "Please select wide multiplication implementation"
#endif

#ifdef VERIFY
r->magnitude = m;
r->normalized = (m == 0);
secp256k1_fe_verify(r);
#endif
}

void random_field_element_test(secp256k1_fe *fe) {
do {
unsigned char b32[32];
Expand Down Expand Up @@ -2460,6 +2491,55 @@ int fe_secp256k1_memcmp_var(const secp256k1_fe *a, const secp256k1_fe *b) {
return secp256k1_memcmp_var(a, &t, sizeof(secp256k1_fe));
}

void run_field_half(void) {
secp256k1_fe t, u;
int m;

/* Check magnitude 0 input */
secp256k1_fe_clear(&t);
secp256k1_fe_half(&t);
#ifdef VERIFY
CHECK(t.magnitude == 1);
CHECK(t.normalized == 0);
#endif
CHECK(secp256k1_fe_normalizes_to_zero(&t));

/* Check non-zero magnitudes in the supported range */
for (m = 1; m < 32; m++) {
/* Check max-value input */
max_fe_for_magnitude(&t, m);

u = t;
secp256k1_fe_half(&u);
#ifdef VERIFY
CHECK(u.magnitude == (m >> 1) + 1);
CHECK(u.normalized == 0);
#endif
secp256k1_fe_normalize_weak(&u);
secp256k1_fe_add(&u, &u);
CHECK(check_fe_equal(&t, &u));

/* Check worst-case input: ensure the LSB is 1 so that P will be added,
* which will also cause all carries to be 1, since all limbs that can
* generate a carry are initially even and all limbs of P are odd in
* every existing field implementation. */
max_fe_for_magnitude(&t, m);
CHECK(t.n[0] > 0);
CHECK((t.n[0] & 1) == 0);
--t.n[0];

u = t;
secp256k1_fe_half(&u);
#ifdef VERIFY
CHECK(u.magnitude == (m >> 1) + 1);
CHECK(u.normalized == 0);
#endif
secp256k1_fe_normalize_weak(&u);
secp256k1_fe_add(&u, &u);
CHECK(check_fe_equal(&t, &u));
}
}

void run_field_misc(void) {
secp256k1_fe x;
secp256k1_fe y;
Expand Down Expand Up @@ -6809,6 +6889,7 @@ int main(int argc, char **argv) {
run_scalar_tests();

/* field tests */
run_field_half();
run_field_misc();
run_field_convert();
run_fe_mul();
Expand Down

0 comments on commit bd1f64e

Please sign in to comment.