mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
Weak normalization for secp256k1_fe_equal
This commit is contained in:
parent
0295f0a33d
commit
d7174edf5f
6 changed files with 28 additions and 52 deletions
|
@ -63,8 +63,8 @@ static int secp256k1_fe_is_zero(const secp256k1_fe_t *a);
|
|||
/** Check the "oddness" of a field element. Requires the input to be normalized. */
|
||||
static int secp256k1_fe_is_odd(const secp256k1_fe_t *a);
|
||||
|
||||
/** Compare two field elements. Requires both inputs to be normalized */
|
||||
static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
|
||||
/** Compare two field elements. Requires magnitude-1 inputs. */
|
||||
static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
|
||||
|
||||
/** Compare two field elements. Requires both inputs to be normalized */
|
||||
static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
|
||||
|
|
|
@ -224,18 +224,6 @@ SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) {
|
|||
}
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
|
||||
#ifdef VERIFY
|
||||
VERIFY_CHECK(a->normalized);
|
||||
VERIFY_CHECK(b->normalized);
|
||||
secp256k1_fe_verify(a);
|
||||
secp256k1_fe_verify(b);
|
||||
#endif
|
||||
const uint32_t *t = a->n, *u = b->n;
|
||||
return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4])
|
||||
| (t[5]^u[5]) | (t[6]^u[6]) | (t[7]^u[7]) | (t[8]^u[8]) | (t[9]^u[9])) == 0;
|
||||
}
|
||||
|
||||
static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
|
||||
#ifdef VERIFY
|
||||
VERIFY_CHECK(a->normalized);
|
||||
|
|
|
@ -205,17 +205,6 @@ SECP256K1_INLINE static void secp256k1_fe_clear(secp256k1_fe_t *a) {
|
|||
}
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
|
||||
#ifdef VERIFY
|
||||
VERIFY_CHECK(a->normalized);
|
||||
VERIFY_CHECK(b->normalized);
|
||||
secp256k1_fe_verify(a);
|
||||
secp256k1_fe_verify(b);
|
||||
#endif
|
||||
const uint64_t *t = a->n, *u = b->n;
|
||||
return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4])) == 0;
|
||||
}
|
||||
|
||||
static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
|
||||
#ifdef VERIFY
|
||||
VERIFY_CHECK(a->normalized);
|
||||
|
|
|
@ -64,6 +64,14 @@ static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) {
|
|||
return secp256k1_fe_set_b32(r, tmp);
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static int secp256k1_fe_equal_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
|
||||
secp256k1_fe_t na;
|
||||
secp256k1_fe_negate(&na, a, 1);
|
||||
secp256k1_fe_add(&na, b);
|
||||
secp256k1_fe_normalize_var(&na);
|
||||
return secp256k1_fe_is_zero(&na);
|
||||
}
|
||||
|
||||
static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
|
||||
|
||||
/** The binary representation of (p + 1)/4 has 3 blocks of 1s, with lengths in
|
||||
|
|
|
@ -161,9 +161,9 @@ static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t
|
|||
VERIFY_CHECK(!a->infinity);
|
||||
secp256k1_fe_t r; secp256k1_fe_sqr(&r, &a->z); secp256k1_fe_mul(&r, &r, x);
|
||||
secp256k1_fe_t r2 = a->x;
|
||||
secp256k1_fe_normalize_var(&r);
|
||||
secp256k1_fe_normalize_var(&r2);
|
||||
return secp256k1_fe_equal(&r, &r2);
|
||||
secp256k1_fe_normalize_weak(&r);
|
||||
secp256k1_fe_normalize_weak(&r2);
|
||||
return secp256k1_fe_equal_var(&r, &r2);
|
||||
}
|
||||
|
||||
static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
|
||||
|
@ -193,9 +193,8 @@ static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) {
|
|||
secp256k1_fe_t z6; secp256k1_fe_sqr(&z6, &z2); secp256k1_fe_mul(&z6, &z6, &z2);
|
||||
secp256k1_fe_mul_int(&z6, 7);
|
||||
secp256k1_fe_add(&x3, &z6);
|
||||
secp256k1_fe_normalize_var(&y2);
|
||||
secp256k1_fe_normalize_var(&x3);
|
||||
return secp256k1_fe_equal(&y2, &x3);
|
||||
secp256k1_fe_normalize_weak(&x3);
|
||||
return secp256k1_fe_equal_var(&y2, &x3);
|
||||
}
|
||||
|
||||
static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) {
|
||||
|
@ -206,9 +205,8 @@ static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) {
|
|||
secp256k1_fe_t x3; secp256k1_fe_sqr(&x3, &a->x); secp256k1_fe_mul(&x3, &x3, &a->x);
|
||||
secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7);
|
||||
secp256k1_fe_add(&x3, &c);
|
||||
secp256k1_fe_normalize_var(&y2);
|
||||
secp256k1_fe_normalize_var(&x3);
|
||||
return secp256k1_fe_equal(&y2, &x3);
|
||||
secp256k1_fe_normalize_weak(&x3);
|
||||
return secp256k1_fe_equal_var(&y2, &x3);
|
||||
}
|
||||
|
||||
static void secp256k1_gej_double_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
|
||||
|
@ -259,12 +257,8 @@ static void secp256k1_gej_add_var(secp256k1_gej_t *r, const secp256k1_gej_t *a,
|
|||
secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12);
|
||||
secp256k1_fe_t s1; secp256k1_fe_mul(&s1, &a->y, &z22); secp256k1_fe_mul(&s1, &s1, &b->z);
|
||||
secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
|
||||
secp256k1_fe_normalize_var(&u1);
|
||||
secp256k1_fe_normalize_var(&u2);
|
||||
if (secp256k1_fe_equal(&u1, &u2)) {
|
||||
secp256k1_fe_normalize_var(&s1);
|
||||
secp256k1_fe_normalize_var(&s2);
|
||||
if (secp256k1_fe_equal(&s1, &s2)) {
|
||||
if (secp256k1_fe_equal_var(&u1, &u2)) {
|
||||
if (secp256k1_fe_equal_var(&s1, &s2)) {
|
||||
secp256k1_gej_double_var(r, a);
|
||||
} else {
|
||||
r->infinity = 1;
|
||||
|
@ -298,15 +292,12 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *
|
|||
}
|
||||
r->infinity = 0;
|
||||
secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z);
|
||||
secp256k1_fe_t u1 = a->x;
|
||||
secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize_weak(&u1);
|
||||
secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12);
|
||||
secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_var(&s1);
|
||||
secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_weak(&s1);
|
||||
secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
|
||||
secp256k1_fe_normalize_var(&u1);
|
||||
secp256k1_fe_normalize_var(&u2);
|
||||
if (secp256k1_fe_equal(&u1, &u2)) {
|
||||
secp256k1_fe_normalize_var(&s2);
|
||||
if (secp256k1_fe_equal(&s1, &s2)) {
|
||||
if (secp256k1_fe_equal_var(&u1, &u2)) {
|
||||
if (secp256k1_fe_equal_var(&s1, &s2)) {
|
||||
secp256k1_gej_double_var(r, a);
|
||||
} else {
|
||||
r->infinity = 1;
|
||||
|
|
10
src/tests.c
10
src/tests.c
|
@ -494,9 +494,9 @@ void random_fe_non_square(secp256k1_fe_t *ns) {
|
|||
}
|
||||
|
||||
int check_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
|
||||
secp256k1_fe_t an = *a; secp256k1_fe_normalize(&an);
|
||||
secp256k1_fe_t an = *a; secp256k1_fe_normalize_weak(&an);
|
||||
secp256k1_fe_t bn = *b; secp256k1_fe_normalize_var(&bn);
|
||||
return secp256k1_fe_equal(&an, &bn);
|
||||
return secp256k1_fe_equal_var(&an, &bn);
|
||||
}
|
||||
|
||||
int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) {
|
||||
|
@ -523,16 +523,16 @@ void run_field_misc(void) {
|
|||
random_fe_non_zero(&y);
|
||||
/* Test the fe equality and comparison operations. */
|
||||
CHECK(secp256k1_fe_cmp_var(&x, &x) == 0);
|
||||
CHECK(secp256k1_fe_equal(&x, &x));
|
||||
CHECK(secp256k1_fe_equal_var(&x, &x));
|
||||
z = x;
|
||||
secp256k1_fe_add(&z,&y);
|
||||
secp256k1_fe_normalize(&z);
|
||||
/* Test the conditional move. */
|
||||
secp256k1_fe_cmov(&z, &x, 0);
|
||||
CHECK(secp256k1_fe_equal(&x, &z) == 0);
|
||||
CHECK(secp256k1_fe_equal_var(&x, &z) == 0);
|
||||
CHECK(secp256k1_fe_cmp_var(&x, &z) != 0);
|
||||
secp256k1_fe_cmov(&y, &x, 1);
|
||||
CHECK(secp256k1_fe_equal(&x, &y));
|
||||
CHECK(secp256k1_fe_equal_var(&x, &y));
|
||||
/* Test that mul_int, mul, and add agree. */
|
||||
secp256k1_fe_add(&y, &x);
|
||||
secp256k1_fe_add(&y, &x);
|
||||
|
|
Loading…
Reference in a new issue