Skip to content

Commit

Permalink
field: remove secp256k1_fe_equal_var
Browse files Browse the repository at this point in the history
`fe_equal_var` hits a fast path only when the inputs are unequal, which is
uncommon among its callers (public key parsing, ECDSA verify).
  • Loading branch information
siv2r committed Aug 15, 2023
1 parent 79abdf0 commit 315275f
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 50 deletions.
6 changes: 0 additions & 6 deletions src/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,6 @@ static int secp256k1_fe_is_odd(const secp256k1_fe *a);
*/
static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b);

/** Determine whether two field elements are equal, without constant-time guarantee.
*
* Identical in behavior to secp256k1_fe_equal, but not constant time in either a or b.
*/
static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b);

/** Compare the values represented by 2 field elements, without constant-time guarantee.
*
* On input, a and b must be valid normalized field elements.
Expand Down
15 changes: 1 addition & 14 deletions src/field_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,6 @@ SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe *a, const secp
return secp256k1_fe_normalizes_to_zero(&na);
}

SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b) {
secp256k1_fe na;
#ifdef VERIFY
secp256k1_fe_verify(a);
secp256k1_fe_verify(b);
VERIFY_CHECK(a->magnitude <= 1);
VERIFY_CHECK(b->magnitude <= 31);
#endif
secp256k1_fe_negate(&na, a, 1);
secp256k1_fe_add(&na, b);
return secp256k1_fe_normalizes_to_zero_var(&na);
}

static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k1_fe * SECP256K1_RESTRICT a) {
/** Given that p is congruent to 3 mod 4, we can compute the square root of
* a mod p as the (p+1)/4'th power of a.
Expand Down Expand Up @@ -151,7 +138,7 @@ static int secp256k1_fe_sqrt(secp256k1_fe * SECP256K1_RESTRICT r, const secp256k
if (!ret) {
secp256k1_fe_negate(&t1, &t1, 1);
secp256k1_fe_normalize_var(&t1);
VERIFY_CHECK(secp256k1_fe_equal_var(&t1, a));
VERIFY_CHECK(secp256k1_fe_equal(&t1, a));
}
#endif
return ret;
Expand Down
4 changes: 2 additions & 2 deletions src/group_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ static int secp256k1_gej_eq_x_var(const secp256k1_fe *x, const secp256k1_gej *a)
#endif

secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x);
return secp256k1_fe_equal_var(&r, &a->x);
return secp256k1_fe_equal(&r, &a->x);
}

static void secp256k1_gej_neg(secp256k1_gej *r, const secp256k1_gej *a) {
Expand Down Expand Up @@ -353,7 +353,7 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge *a) {
secp256k1_fe_sqr(&y2, &a->y);
secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x);
secp256k1_fe_add_int(&x3, SECP256K1_B);
return secp256k1_fe_equal_var(&y2, &x3);
return secp256k1_fe_equal(&y2, &x3);
}

static SECP256K1_INLINE void secp256k1_gej_double(secp256k1_gej *r, const secp256k1_gej *a) {
Expand Down
2 changes: 1 addition & 1 deletion src/modules/extrakeys/tests_exhaustive_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static void test_exhaustive_extrakeys(const secp256k1_context *ctx, const secp25

/* Compare the xonly_pubkey bytes against the precomputed group. */
secp256k1_fe_set_b32_mod(&fe, xonly_pubkey_bytes[i - 1]);
CHECK(secp256k1_fe_equal_var(&fe, &group[i].x));
CHECK(secp256k1_fe_equal(&fe, &group[i].x));

/* Check the parity against the precomputed group. */
fe = group[i].y;
Expand Down
2 changes: 1 addition & 1 deletion src/modules/schnorrsig/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ int secp256k1_schnorrsig_verify(const secp256k1_context* ctx, const unsigned cha

secp256k1_fe_normalize_var(&r.y);
return !secp256k1_fe_is_odd(&r.y) &&
secp256k1_fe_equal_var(&rx, &r.x);
secp256k1_fe_equal(&rx, &r.x);
}

#endif
36 changes: 18 additions & 18 deletions src/tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -2967,7 +2967,7 @@ static int check_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b) {
secp256k1_fe an = *a;
secp256k1_fe bn = *b;
secp256k1_fe_normalize_weak(&an);
return secp256k1_fe_equal_var(&an, &bn);
return secp256k1_fe_equal(&an, &bn);
}

static void run_field_convert(void) {
Expand All @@ -2990,9 +2990,9 @@ static void run_field_convert(void) {
secp256k1_fe_storage fes2;
/* Check conversions to fe. */
CHECK(secp256k1_fe_set_b32_limit(&fe2, b32));
CHECK(secp256k1_fe_equal_var(&fe, &fe2));
CHECK(secp256k1_fe_equal(&fe, &fe2));
secp256k1_fe_from_storage(&fe2, &fes);
CHECK(secp256k1_fe_equal_var(&fe, &fe2));
CHECK(secp256k1_fe_equal(&fe, &fe2));
/* Check conversion from fe. */
secp256k1_fe_get_b32(b322, &fe);
CHECK(secp256k1_memcmp_var(b322, b32, 32) == 0);
Expand Down Expand Up @@ -3149,7 +3149,7 @@ static void run_field_misc(void) {
CHECK(check_fe_equal(&q, &z));
/* Test the fe equality and comparison operations. */
CHECK(secp256k1_fe_cmp_var(&x, &x) == 0);
CHECK(secp256k1_fe_equal_var(&x, &x));
CHECK(secp256k1_fe_equal(&x, &x));
z = x;
secp256k1_fe_add(&z,&y);
/* Test fe conditional move; z is not normalized here. */
Expand All @@ -3174,7 +3174,7 @@ static void run_field_misc(void) {
q = z;
secp256k1_fe_normalize_var(&x);
secp256k1_fe_normalize_var(&z);
CHECK(!secp256k1_fe_equal_var(&x, &z));
CHECK(!secp256k1_fe_equal(&x, &z));
secp256k1_fe_normalize_var(&q);
secp256k1_fe_cmov(&q, &z, (i&1));
#ifdef VERIFY
Expand Down Expand Up @@ -3679,8 +3679,8 @@ static void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) {
if (a->infinity) {
return;
}
CHECK(secp256k1_fe_equal_var(&a->x, &b->x));
CHECK(secp256k1_fe_equal_var(&a->y, &b->y));
CHECK(secp256k1_fe_equal(&a->x, &b->x));
CHECK(secp256k1_fe_equal(&a->y, &b->y));
}

/* This compares jacobian points including their Z, not just their geometric meaning. */
Expand Down Expand Up @@ -3718,8 +3718,8 @@ static void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) {
u2 = b->x;
secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z);
s2 = b->y;
CHECK(secp256k1_fe_equal_var(&u1, &u2));
CHECK(secp256k1_fe_equal_var(&s1, &s2));
CHECK(secp256k1_fe_equal(&u1, &u2));
CHECK(secp256k1_fe_equal(&s1, &s2));
}

static void test_ge(void) {
Expand Down Expand Up @@ -3787,7 +3787,7 @@ static void test_ge(void) {
/* Check Z ratio. */
if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&refj)) {
secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z);
CHECK(secp256k1_fe_equal_var(&zrz, &refj.z));
CHECK(secp256k1_fe_equal(&zrz, &refj.z));
}
secp256k1_ge_set_gej_var(&ref, &refj);

Expand All @@ -3796,7 +3796,7 @@ static void test_ge(void) {
ge_equals_gej(&ref, &resj);
if (!secp256k1_gej_is_infinity(&gej[i1]) && !secp256k1_gej_is_infinity(&resj)) {
secp256k1_fe zrz; secp256k1_fe_mul(&zrz, &zr, &gej[i1].z);
CHECK(secp256k1_fe_equal_var(&zrz, &resj.z));
CHECK(secp256k1_fe_equal(&zrz, &resj.z));
}

/* Test gej + ge (var, with additional Z factor). */
Expand Down Expand Up @@ -3825,7 +3825,7 @@ static void test_ge(void) {
ge_equals_gej(&ref, &resj);
/* Check Z ratio. */
secp256k1_fe_mul(&zr2, &zr2, &gej[i1].z);
CHECK(secp256k1_fe_equal_var(&zr2, &resj.z));
CHECK(secp256k1_fe_equal(&zr2, &resj.z));
/* Normal doubling. */
secp256k1_gej_double_var(&resj, &gej[i2], NULL);
ge_equals_gej(&ref, &resj);
Expand Down Expand Up @@ -3908,7 +3908,7 @@ static void test_ge(void) {
ret_set_xo = secp256k1_ge_set_xo_var(&q, &r, 0);
CHECK(ret_on_curve == ret_frac_on_curve);
CHECK(ret_on_curve == ret_set_xo);
if (ret_set_xo) CHECK(secp256k1_fe_equal_var(&r, &q.x));
if (ret_set_xo) CHECK(secp256k1_fe_equal(&r, &q.x));
}

/* Test batch gej -> ge conversion with many infinities. */
Expand Down Expand Up @@ -4148,8 +4148,8 @@ static void test_group_decompress(const secp256k1_fe* x) {
CHECK(!ge_odd.infinity);

/* Check that the x coordinates check out. */
CHECK(secp256k1_fe_equal_var(&ge_even.x, x));
CHECK(secp256k1_fe_equal_var(&ge_odd.x, x));
CHECK(secp256k1_fe_equal(&ge_even.x, x));
CHECK(secp256k1_fe_equal(&ge_odd.x, x));

/* Check odd/even Y in ge_odd, ge_even. */
CHECK(secp256k1_fe_is_odd(&ge_odd.y));
Expand Down Expand Up @@ -4207,12 +4207,12 @@ static void test_pre_g_table(const secp256k1_ge_storage * pre_g, size_t n) {
CHECK(!secp256k1_fe_normalizes_to_zero_var(&dqx) || !secp256k1_fe_normalizes_to_zero_var(&dqy));

/* Check that -q is not equal to p */
CHECK(!secp256k1_fe_equal_var(&dpx, &dqx) || !secp256k1_fe_equal_var(&dpy, &dqy));
CHECK(!secp256k1_fe_equal(&dpx, &dqx) || !secp256k1_fe_equal(&dpy, &dqy));

/* Check that p, -q and gg are colinear */
secp256k1_fe_mul(&dpx, &dpx, &dqy);
secp256k1_fe_mul(&dpy, &dpy, &dqx);
CHECK(secp256k1_fe_equal_var(&dpx, &dpy));
CHECK(secp256k1_fe_equal(&dpx, &dpy));

p = q;
}
Expand Down Expand Up @@ -4431,7 +4431,7 @@ static void run_point_times_order(void) {
secp256k1_fe_sqr(&x, &x);
}
secp256k1_fe_normalize_var(&x);
CHECK(secp256k1_fe_equal_var(&x, &xr));
CHECK(secp256k1_fe_equal(&x, &xr));
}

static void ecmult_const_random_mult(void) {
Expand Down
16 changes: 8 additions & 8 deletions src/tests_exhaustive.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ static void ge_equals_ge(const secp256k1_ge *a, const secp256k1_ge *b) {
if (a->infinity) {
return;
}
CHECK(secp256k1_fe_equal_var(&a->x, &b->x));
CHECK(secp256k1_fe_equal_var(&a->y, &b->y));
CHECK(secp256k1_fe_equal(&a->x, &b->x));
CHECK(secp256k1_fe_equal(&a->y, &b->y));
}

static void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) {
Expand All @@ -55,8 +55,8 @@ static void ge_equals_gej(const secp256k1_ge *a, const secp256k1_gej *b) {
u2 = b->x;
secp256k1_fe_mul(&s1, &a->y, &z2s); secp256k1_fe_mul(&s1, &s1, &b->z);
s2 = b->y;
CHECK(secp256k1_fe_equal_var(&u1, &u2));
CHECK(secp256k1_fe_equal_var(&s1, &s2));
CHECK(secp256k1_fe_equal(&u1, &u2));
CHECK(secp256k1_fe_equal(&s1, &s2));
}

static void random_fe(secp256k1_fe *x) {
Expand Down Expand Up @@ -219,14 +219,14 @@ static void test_exhaustive_ecmult(const secp256k1_ge *group, const secp256k1_ge
/* Test secp256k1_ecmult_const_xonly with all curve X coordinates, and xd=NULL. */
ret = secp256k1_ecmult_const_xonly(&tmpf, &group[i].x, NULL, &ng, 0);
CHECK(ret);
CHECK(secp256k1_fe_equal_var(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
CHECK(secp256k1_fe_equal(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));

/* Test secp256k1_ecmult_const_xonly with all curve X coordinates, with random xd. */
random_fe_non_zero(&xd);
secp256k1_fe_mul(&xn, &xd, &group[i].x);
ret = secp256k1_ecmult_const_xonly(&tmpf, &xn, &xd, &ng, 0);
CHECK(ret);
CHECK(secp256k1_fe_equal_var(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
CHECK(secp256k1_fe_equal(&tmpf, &group[(i * j) % EXHAUSTIVE_TEST_ORDER].x));
}
}
}
Expand Down Expand Up @@ -475,8 +475,8 @@ int main(int argc, char** argv) {

CHECK(group[i].infinity == 0);
CHECK(generated.infinity == 0);
CHECK(secp256k1_fe_equal_var(&generated.x, &group[i].x));
CHECK(secp256k1_fe_equal_var(&generated.y, &group[i].y));
CHECK(secp256k1_fe_equal(&generated.x, &group[i].x));
CHECK(secp256k1_fe_equal(&generated.y, &group[i].y));
}
}

Expand Down

0 comments on commit 315275f

Please sign in to comment.