Skip to content

Commit

Permalink
Add fe_half tests for worst-case inputs
Browse files Browse the repository at this point in the history
- Add field method _fe_get_bounds
  • Loading branch information
peterdettman committed Feb 1, 2022
1 parent 4eb8b93 commit d64bb5d
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/field.h
Expand Up @@ -135,4 +135,8 @@ static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag);
* The output is not guaranteed to be normalized, regardless of the input. */
static void secp256k1_fe_half(secp256k1_fe *r);

/** Sets each limb of 'r' to its upper bound at magnitude 'm'. The output will also have its
* magnitude set to 'm' and is normalized if (and only if) 'm' is zero. */
static void secp256k1_fe_get_bounds(secp256k1_fe *r, int m);

#endif /* SECP256K1_FIELD_H */
20 changes: 20 additions & 0 deletions src/field_10x26_impl.h
Expand Up @@ -49,6 +49,26 @@ static void secp256k1_fe_verify(const secp256k1_fe *a) {
}
#endif

static void secp256k1_fe_get_bounds(secp256k1_fe *r, int m) {
VERIFY_CHECK(m >= 0);
VERIFY_CHECK(m <= 2048);
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;
#ifdef VERIFY
r->magnitude = m;
r->normalized = (m == 0);
secp256k1_fe_verify(r);
#endif
}

static void secp256k1_fe_normalize(secp256k1_fe *r) {
uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
Expand Down
15 changes: 15 additions & 0 deletions src/field_5x52_impl.h
Expand Up @@ -58,6 +58,21 @@ static void secp256k1_fe_verify(const secp256k1_fe *a) {
}
#endif

static void secp256k1_fe_get_bounds(secp256k1_fe *r, int m) {
VERIFY_CHECK(m >= 0);
VERIFY_CHECK(m <= 2048);
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;
#ifdef VERIFY
r->magnitude = m;
r->normalized = (m == 0);
secp256k1_fe_verify(r);
#endif
}

static void secp256k1_fe_normalize(secp256k1_fe *r) {
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];

Expand Down
50 changes: 50 additions & 0 deletions src/tests.c
Expand Up @@ -2471,6 +2471,55 @@ int fe_identical(const secp256k1_fe *a, const secp256k1_fe *b) {
return ret;
}

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

/* Check magnitude 0 input */
secp256k1_fe_get_bounds(&t, 0);
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 */
secp256k1_fe_get_bounds(&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. */
secp256k1_fe_get_bounds(&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 @@ -6924,6 +6973,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 d64bb5d

Please sign in to comment.