mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-27 11:43:26 -03:00
Variable time normalize
This commit is contained in:
parent
ad86bdf1f2
commit
39bd94d86d
12 changed files with 160 additions and 48 deletions
|
@ -38,7 +38,7 @@ static void secp256k1_ecdsa_start(void) {
|
|||
|
||||
secp256k1_fe_set_b32(&ret->order_as_fe, order);
|
||||
secp256k1_fe_negate(&ret->p_minus_order, &ret->order_as_fe, 1);
|
||||
secp256k1_fe_normalize(&ret->p_minus_order);
|
||||
secp256k1_fe_normalize_var(&ret->p_minus_order);
|
||||
|
||||
/* Set the global pointer. */
|
||||
secp256k1_ecdsa_consts = ret;
|
||||
|
@ -122,7 +122,7 @@ static int secp256k1_ecdsa_sig_recompute(secp256k1_scalar_t *r2, const secp256k1
|
|||
secp256k1_gej_t pr; secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1);
|
||||
if (!secp256k1_gej_is_infinity(&pr)) {
|
||||
secp256k1_fe_t xr; secp256k1_gej_get_x_var(&xr, &pr);
|
||||
secp256k1_fe_normalize(&xr);
|
||||
secp256k1_fe_normalize_var(&xr);
|
||||
unsigned char xrb[32]; secp256k1_fe_get_b32(xrb, &xr);
|
||||
secp256k1_scalar_set_b32(r2, xrb, NULL);
|
||||
ret = 1;
|
||||
|
@ -144,7 +144,7 @@ static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256
|
|||
secp256k1_fe_add(&fx, &secp256k1_ecdsa_consts->order_as_fe);
|
||||
}
|
||||
secp256k1_ge_t x;
|
||||
if (!secp256k1_ge_set_xo(&x, &fx, recid & 1))
|
||||
if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1))
|
||||
return 0;
|
||||
secp256k1_gej_t xj;
|
||||
secp256k1_gej_set_ge(&xj, &x);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size) {
|
||||
if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) {
|
||||
secp256k1_fe_t x;
|
||||
return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo(elem, &x, pub[0] == 0x03);
|
||||
return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == 0x03);
|
||||
} else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) {
|
||||
secp256k1_fe_t x, y;
|
||||
if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) {
|
||||
|
@ -26,7 +26,7 @@ static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned cha
|
|||
secp256k1_ge_set_xy(elem, &x, &y);
|
||||
if ((pub[0] == 0x06 || pub[0] == 0x07) && secp256k1_fe_is_odd(&y) != (pub[0] == 0x07))
|
||||
return 0;
|
||||
return secp256k1_ge_is_valid(elem);
|
||||
return secp256k1_ge_is_valid_var(elem);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char
|
|||
if (secp256k1_ge_is_infinity(elem)) {
|
||||
return 0;
|
||||
}
|
||||
secp256k1_fe_normalize(&elem->x);
|
||||
secp256k1_fe_normalize(&elem->y);
|
||||
secp256k1_fe_normalize_var(&elem->x);
|
||||
secp256k1_fe_normalize_var(&elem->y);
|
||||
secp256k1_fe_get_b32(&pub[1], &elem->x);
|
||||
if (compressed) {
|
||||
*size = 33;
|
||||
|
|
|
@ -47,7 +47,7 @@ static void secp256k1_ecmult_gen_start(void) {
|
|||
secp256k1_fe_t nums_x;
|
||||
VERIFY_CHECK(secp256k1_fe_set_b32(&nums_x, nums_b32));
|
||||
secp256k1_ge_t nums_ge;
|
||||
VERIFY_CHECK(secp256k1_ge_set_xo(&nums_ge, &nums_x, 0));
|
||||
VERIFY_CHECK(secp256k1_ge_set_xo_var(&nums_ge, &nums_x, 0));
|
||||
secp256k1_gej_set_ge(&nums_gej, &nums_ge);
|
||||
/* Add G to make the bits in x uniformly distributed. */
|
||||
secp256k1_gej_add_ge_var(&nums_gej, &nums_gej, g);
|
||||
|
@ -73,7 +73,7 @@ static void secp256k1_ecmult_gen_start(void) {
|
|||
secp256k1_gej_double_var(&numsbase, &numsbase);
|
||||
if (j == 62) {
|
||||
/* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
|
||||
secp256k1_gej_neg(&numsbase, &numsbase);
|
||||
secp256k1_gej_neg_var(&numsbase, &numsbase);
|
||||
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,8 +67,8 @@ static void secp256k1_ecmult_table_precomp_ge_var(secp256k1_ge_t *pre, const sec
|
|||
(neg)((r), &(pre)[(-(n)-1)/2]); \
|
||||
} while(0)
|
||||
|
||||
#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg)
|
||||
#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg)
|
||||
#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg_var)
|
||||
#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg_var)
|
||||
|
||||
typedef struct {
|
||||
/* For accelerating the computation of a*P + b*G: */
|
||||
|
|
|
@ -50,6 +50,9 @@ static void secp256k1_fe_stop(void);
|
|||
/** Normalize a field element. */
|
||||
static void secp256k1_fe_normalize(secp256k1_fe_t *r);
|
||||
|
||||
/** Normalize a field element, without constant-time guarantee. */
|
||||
static void secp256k1_fe_normalize_var(secp256k1_fe_t *r);
|
||||
|
||||
/** Set a field element equal to a small integer. Resulting field element is normalized. */
|
||||
static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a);
|
||||
|
||||
|
@ -93,7 +96,7 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a);
|
|||
/** Sets a field element to be the (modular) square root (if any exist) of another. Requires the
|
||||
* input's magnitude to be at most 8. The output magnitude is 1 (but not guaranteed to be
|
||||
* normalized). Return value indicates whether a square root was found. */
|
||||
static int secp256k1_fe_sqrt(secp256k1_fe_t *r, const secp256k1_fe_t *a);
|
||||
static int secp256k1_fe_sqrt_var(secp256k1_fe_t *r, const secp256k1_fe_t *a);
|
||||
|
||||
/** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be
|
||||
* at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */
|
||||
|
|
|
@ -103,6 +103,62 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void secp256k1_fe_normalize_var(secp256k1_fe_t *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];
|
||||
|
||||
/* Reduce t9 at the start so there will be at most a single carry from the first pass */
|
||||
uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
|
||||
uint32_t m;
|
||||
|
||||
/* The first pass ensures the magnitude is 1, ... */
|
||||
t0 += x * 0x3D1UL; t1 += (x << 6);
|
||||
t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
|
||||
t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
|
||||
t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL; m = t2;
|
||||
t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL; m &= t3;
|
||||
t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL; m &= t4;
|
||||
t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL; m &= t5;
|
||||
t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL; m &= t6;
|
||||
t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL; m &= t7;
|
||||
t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL; m &= t8;
|
||||
|
||||
/* ... except for a possible carry at bit 22 of t9 (i.e. bit 256 of the field element) */
|
||||
VERIFY_CHECK(t9 >> 23 == 0);
|
||||
|
||||
/* At most a single final reduction is needed; check if the value is >= the field characteristic */
|
||||
x = (t9 >> 22) | ((t9 == 0x03FFFFFUL) & (m == 0x3FFFFFFUL)
|
||||
& ((t1 + 0x40UL + ((t0 + 0x3D1UL) >> 26)) > 0x3FFFFFFUL));
|
||||
|
||||
if (x) {
|
||||
t0 += 0x3D1UL; t1 += (x << 6);
|
||||
t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
|
||||
t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
|
||||
t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
|
||||
t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
|
||||
t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
|
||||
t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
|
||||
t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
|
||||
t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
|
||||
t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
|
||||
|
||||
/* If t9 didn't carry to bit 22 already, then it should have after any final reduction */
|
||||
VERIFY_CHECK(t9 >> 22 == x);
|
||||
|
||||
/* Mask off the possible multiple of 2^256 from the final reduction */
|
||||
t9 &= 0x03FFFFFUL;
|
||||
}
|
||||
|
||||
r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
|
||||
r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
|
||||
|
||||
#ifdef VERIFY
|
||||
r->magnitude = 1;
|
||||
r->normalized = 1;
|
||||
secp256k1_fe_verify(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
|
||||
r->n[0] = a;
|
||||
r->n[1] = r->n[2] = r->n[3] = r->n[4] = r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0;
|
||||
|
|
|
@ -102,6 +102,50 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
|
||||
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
|
||||
|
||||
/* Reduce t4 at the start so there will be at most a single carry from the first pass */
|
||||
uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
|
||||
uint64_t m;
|
||||
|
||||
/* The first pass ensures the magnitude is 1, ... */
|
||||
t0 += x * 0x1000003D1ULL;
|
||||
t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
|
||||
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL; m = t1;
|
||||
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL; m &= t2;
|
||||
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL; m &= t3;
|
||||
|
||||
/* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
|
||||
VERIFY_CHECK(t4 >> 49 == 0);
|
||||
|
||||
/* At most a single final reduction is needed; check if the value is >= the field characteristic */
|
||||
x = (t4 >> 48) | ((t4 == 0x0FFFFFFFFFFFFULL) & (m == 0xFFFFFFFFFFFFFULL)
|
||||
& (t0 >= 0xFFFFEFFFFFC2FULL));
|
||||
|
||||
if (x) {
|
||||
t0 += 0x1000003D1ULL;
|
||||
t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
|
||||
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
|
||||
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
|
||||
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
|
||||
|
||||
/* If t4 didn't carry to bit 48 already, then it should have after any final reduction */
|
||||
VERIFY_CHECK(t4 >> 48 == x);
|
||||
|
||||
/* Mask off the possible multiple of 2^256 from the final reduction */
|
||||
t4 &= 0x0FFFFFFFFFFFFULL;
|
||||
}
|
||||
|
||||
r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
|
||||
|
||||
#ifdef VERIFY
|
||||
r->magnitude = 1;
|
||||
r->normalized = 1;
|
||||
secp256k1_fe_verify(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
|
||||
r->n[0] = a;
|
||||
r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
|
||||
|
|
|
@ -46,6 +46,10 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
|
|||
mpn_sub(r->n, r->n, FIELD_LIMBS, secp256k1_field_p, FIELD_LIMBS);
|
||||
}
|
||||
|
||||
static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
|
||||
secp256k1_fe_normalize(r);
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static void secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
|
||||
r->n[0] = a;
|
||||
for (int i=1; i<FIELD_LIMBS+1; i++)
|
||||
|
|
|
@ -66,7 +66,7 @@ static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a, int alen) {
|
|||
return secp256k1_fe_set_b32(r, tmp);
|
||||
}
|
||||
|
||||
static int secp256k1_fe_sqrt(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
|
||||
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
|
||||
* { 2, 22, 223 }. Use an addition chain to calculate 2^n - 1 for each block:
|
||||
|
@ -132,7 +132,7 @@ static int secp256k1_fe_sqrt(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
|
|||
secp256k1_fe_sqr(&t1, r);
|
||||
secp256k1_fe_negate(&t1, &t1, 1);
|
||||
secp256k1_fe_add(&t1, a);
|
||||
secp256k1_fe_normalize(&t1);
|
||||
secp256k1_fe_normalize_var(&t1);
|
||||
return secp256k1_fe_is_zero(&t1);
|
||||
}
|
||||
|
||||
|
@ -206,7 +206,7 @@ static void secp256k1_fe_inv_var(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
|
|||
#elif defined(USE_FIELD_INV_NUM)
|
||||
unsigned char b[32];
|
||||
secp256k1_fe_t c = *a;
|
||||
secp256k1_fe_normalize(&c);
|
||||
secp256k1_fe_normalize_var(&c);
|
||||
secp256k1_fe_get_b32(b, &c);
|
||||
secp256k1_num_t n;
|
||||
secp256k1_num_set_bin(&n, b, 32);
|
||||
|
|
|
@ -51,15 +51,16 @@ static void secp256k1_ge_set_xy(secp256k1_ge_t *r, const secp256k1_fe_t *x, cons
|
|||
|
||||
/** Set a group element (affine) equal to the point with the given X coordinate, and given oddness
|
||||
* for Y. Return value indicates whether the result is valid. */
|
||||
static int secp256k1_ge_set_xo(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd);
|
||||
static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd);
|
||||
|
||||
/** Check whether a group element is the point at infinity. */
|
||||
static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a);
|
||||
|
||||
/** Check whether a group element is valid (i.e., on the curve). */
|
||||
static int secp256k1_ge_is_valid(const secp256k1_ge_t *a);
|
||||
static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a);
|
||||
|
||||
static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a);
|
||||
static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a);
|
||||
|
||||
/** Get a hex representation of a point. *rlen will be overwritten with the real length. */
|
||||
static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a);
|
||||
|
@ -84,7 +85,7 @@ static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a);
|
|||
static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a);
|
||||
|
||||
/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */
|
||||
static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a);
|
||||
static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a);
|
||||
|
||||
/** Check whether a group element is the point at infinity. */
|
||||
static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a);
|
||||
|
|
|
@ -28,13 +28,17 @@ static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a) {
|
|||
}
|
||||
|
||||
static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) {
|
||||
r->infinity = a->infinity;
|
||||
r->x = a->x;
|
||||
r->y = a->y;
|
||||
*r = *a;
|
||||
secp256k1_fe_normalize(&r->y);
|
||||
secp256k1_fe_negate(&r->y, &r->y, 1);
|
||||
}
|
||||
|
||||
static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a) {
|
||||
*r = *a;
|
||||
secp256k1_fe_normalize_var(&r->y);
|
||||
secp256k1_fe_negate(&r->y, &r->y, 1);
|
||||
}
|
||||
|
||||
static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a) {
|
||||
char cx[65]; int lx=65;
|
||||
char cy[65]; int ly=65;
|
||||
|
@ -135,16 +139,16 @@ static void secp256k1_ge_clear(secp256k1_ge_t *r) {
|
|||
secp256k1_fe_clear(&r->y);
|
||||
}
|
||||
|
||||
static int secp256k1_ge_set_xo(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd) {
|
||||
static int secp256k1_ge_set_xo_var(secp256k1_ge_t *r, const secp256k1_fe_t *x, int odd) {
|
||||
r->x = *x;
|
||||
secp256k1_fe_t x2; secp256k1_fe_sqr(&x2, x);
|
||||
secp256k1_fe_t x3; secp256k1_fe_mul(&x3, x, &x2);
|
||||
r->infinity = 0;
|
||||
secp256k1_fe_t c; secp256k1_fe_set_int(&c, 7);
|
||||
secp256k1_fe_add(&c, &x3);
|
||||
if (!secp256k1_fe_sqrt(&r->y, &c))
|
||||
if (!secp256k1_fe_sqrt_var(&r->y, &c))
|
||||
return 0;
|
||||
secp256k1_fe_normalize(&r->y);
|
||||
secp256k1_fe_normalize_var(&r->y);
|
||||
if (secp256k1_fe_is_odd(&r->y) != odd)
|
||||
secp256k1_fe_negate(&r->y, &r->y, 1);
|
||||
return 1;
|
||||
|
@ -162,12 +166,12 @@ static void secp256k1_gej_get_x_var(secp256k1_fe_t *r, const secp256k1_gej_t *a)
|
|||
secp256k1_fe_mul(r, &a->x, &zi2);
|
||||
}
|
||||
|
||||
static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
|
||||
static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
|
||||
r->infinity = a->infinity;
|
||||
r->x = a->x;
|
||||
r->y = a->y;
|
||||
r->z = a->z;
|
||||
secp256k1_fe_normalize(&r->y);
|
||||
secp256k1_fe_normalize_var(&r->y);
|
||||
secp256k1_fe_negate(&r->y, &r->y, 1);
|
||||
}
|
||||
|
||||
|
@ -175,7 +179,7 @@ static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a) {
|
|||
return a->infinity;
|
||||
}
|
||||
|
||||
static int secp256k1_gej_is_valid(const secp256k1_gej_t *a) {
|
||||
static int secp256k1_gej_is_valid_var(const secp256k1_gej_t *a) {
|
||||
if (a->infinity)
|
||||
return 0;
|
||||
/** y^2 = x^3 + 7
|
||||
|
@ -189,12 +193,12 @@ static int secp256k1_gej_is_valid(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(&y2);
|
||||
secp256k1_fe_normalize(&x3);
|
||||
secp256k1_fe_normalize_var(&y2);
|
||||
secp256k1_fe_normalize_var(&x3);
|
||||
return secp256k1_fe_equal(&y2, &x3);
|
||||
}
|
||||
|
||||
static int secp256k1_ge_is_valid(const secp256k1_ge_t *a) {
|
||||
static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a) {
|
||||
if (a->infinity)
|
||||
return 0;
|
||||
/* y^2 = x^3 + 7 */
|
||||
|
@ -202,8 +206,8 @@ static int secp256k1_ge_is_valid(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(&y2);
|
||||
secp256k1_fe_normalize(&x3);
|
||||
secp256k1_fe_normalize_var(&y2);
|
||||
secp256k1_fe_normalize_var(&x3);
|
||||
return secp256k1_fe_equal(&y2, &x3);
|
||||
}
|
||||
|
||||
|
@ -255,11 +259,11 @@ 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(&u1);
|
||||
secp256k1_fe_normalize(&u2);
|
||||
secp256k1_fe_normalize_var(&u1);
|
||||
secp256k1_fe_normalize_var(&u2);
|
||||
if (secp256k1_fe_equal(&u1, &u2)) {
|
||||
secp256k1_fe_normalize(&s1);
|
||||
secp256k1_fe_normalize(&s2);
|
||||
secp256k1_fe_normalize_var(&s1);
|
||||
secp256k1_fe_normalize_var(&s2);
|
||||
if (secp256k1_fe_equal(&s1, &s2)) {
|
||||
secp256k1_gej_double_var(r, a);
|
||||
} else {
|
||||
|
@ -296,12 +300,12 @@ static void secp256k1_gej_add_ge_var(secp256k1_gej_t *r, const secp256k1_gej_t *
|
|||
secp256k1_fe_t z12; secp256k1_fe_sqr(&z12, &a->z);
|
||||
secp256k1_fe_t u1 = a->x;
|
||||
secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &z12);
|
||||
secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize(&s1);
|
||||
secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_var(&s1);
|
||||
secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &z12); secp256k1_fe_mul(&s2, &s2, &a->z);
|
||||
secp256k1_fe_normalize(&u1);
|
||||
secp256k1_fe_normalize(&u2);
|
||||
secp256k1_fe_normalize_var(&u1);
|
||||
secp256k1_fe_normalize_var(&u2);
|
||||
if (secp256k1_fe_equal(&u1, &u2)) {
|
||||
secp256k1_fe_normalize(&s2);
|
||||
secp256k1_fe_normalize_var(&s2);
|
||||
if (secp256k1_fe_equal(&s1, &s2)) {
|
||||
secp256k1_gej_double_var(r, a);
|
||||
} else {
|
||||
|
|
16
src/tests.c
16
src/tests.c
|
@ -46,7 +46,7 @@ void random_group_element_test(secp256k1_ge_t *ge) {
|
|||
secp256k1_fe_t fe;
|
||||
do {
|
||||
random_field_element_test(&fe);
|
||||
if (secp256k1_ge_set_xo(ge, &fe, secp256k1_rand32() & 1))
|
||||
if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_rand32() & 1))
|
||||
break;
|
||||
} while(1);
|
||||
}
|
||||
|
@ -459,7 +459,7 @@ void random_fe_non_zero(secp256k1_fe_t *nz) {
|
|||
void random_fe_non_square(secp256k1_fe_t *ns) {
|
||||
random_fe_non_zero(ns);
|
||||
secp256k1_fe_t r;
|
||||
if (secp256k1_fe_sqrt(&r, ns)) {
|
||||
if (secp256k1_fe_sqrt_var(&r, ns)) {
|
||||
secp256k1_fe_negate(ns, ns, 1);
|
||||
}
|
||||
}
|
||||
|
@ -549,7 +549,7 @@ void run_sqr(void) {
|
|||
|
||||
void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) {
|
||||
secp256k1_fe_t r1, r2;
|
||||
int v = secp256k1_fe_sqrt(&r1, a);
|
||||
int v = secp256k1_fe_sqrt_var(&r1, a);
|
||||
CHECK((v == 0) == (k == NULL));
|
||||
|
||||
if (k != NULL) {
|
||||
|
@ -779,22 +779,22 @@ void test_point_times_order(const secp256k1_gej_t *point) {
|
|||
secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */
|
||||
secp256k1_gej_add_var(&res1, &res1, &res2);
|
||||
CHECK(secp256k1_gej_is_infinity(&res1));
|
||||
CHECK(secp256k1_gej_is_valid(&res1) == 0);
|
||||
CHECK(secp256k1_gej_is_valid_var(&res1) == 0);
|
||||
secp256k1_ge_t res3;
|
||||
secp256k1_ge_set_gej(&res3, &res1);
|
||||
CHECK(secp256k1_ge_is_infinity(&res3));
|
||||
CHECK(secp256k1_ge_is_valid(&res3) == 0);
|
||||
CHECK(secp256k1_ge_is_valid_var(&res3) == 0);
|
||||
}
|
||||
|
||||
void run_point_times_order(void) {
|
||||
secp256k1_fe_t x; VERIFY_CHECK(secp256k1_fe_set_hex(&x, "02", 2));
|
||||
for (int i=0; i<500; i++) {
|
||||
secp256k1_ge_t p;
|
||||
if (secp256k1_ge_set_xo(&p, &x, 1)) {
|
||||
CHECK(secp256k1_ge_is_valid(&p));
|
||||
if (secp256k1_ge_set_xo_var(&p, &x, 1)) {
|
||||
CHECK(secp256k1_ge_is_valid_var(&p));
|
||||
secp256k1_gej_t j;
|
||||
secp256k1_gej_set_ge(&j, &p);
|
||||
CHECK(secp256k1_gej_is_valid(&j));
|
||||
CHECK(secp256k1_gej_is_valid_var(&j));
|
||||
test_point_times_order(&j);
|
||||
}
|
||||
secp256k1_fe_sqr(&x, &x);
|
||||
|
|
Loading…
Add table
Reference in a new issue