diff --git a/src/ecdsa.h b/src/ecdsa.h index 3b1e048..5fc5230 100644 --- a/src/ecdsa.h +++ b/src/ecdsa.h @@ -7,17 +7,21 @@ #ifndef _SECP256K1_ECDSA_ #define _SECP256K1_ECDSA_ -#include "num.h" +#include "scalar.h" +#include "group.h" + +static void secp256k1_ecsda_start(void); +static void secp256k1_ecdsa_stop(void); typedef struct { - secp256k1_num_t r, s; + secp256k1_scalar_t r, s; } secp256k1_ecdsa_sig_t; static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size); static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a); -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message); +static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message); static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid); -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_num_t *message, int recid); -static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *r, const secp256k1_num_t *s); +static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid); +static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s); #endif diff --git a/src/ecdsa_impl.h b/src/ecdsa_impl.h index dadf215..525516e 100644 --- a/src/ecdsa_impl.h +++ b/src/ecdsa_impl.h @@ -8,13 +8,47 @@ #ifndef _SECP256K1_ECDSA_IMPL_H_ #define _SECP256K1_ECDSA_IMPL_H_ -#include "num.h" +#include "scalar.h" #include "field.h" #include "group.h" #include "ecmult.h" #include "ecmult_gen.h" #include "ecdsa.h" +typedef struct { + secp256k1_fe_t order_as_fe; + secp256k1_fe_t p_minus_order; +} secp256k1_ecdsa_consts_t; + +static const secp256k1_ecdsa_consts_t *secp256k1_ecdsa_consts = NULL; + +static void secp256k1_ecdsa_start(void) { + if (secp256k1_ecdsa_consts != NULL) + return; + + /* Allocate. */ + secp256k1_ecdsa_consts_t *ret = (secp256k1_ecdsa_consts_t*)malloc(sizeof(secp256k1_ecdsa_consts_t)); + + unsigned char p[32]; + secp256k1_num_get_bin(p, 32, &secp256k1_ge_consts->order); + secp256k1_fe_set_b32(&ret->order_as_fe, p); + + secp256k1_fe_negate(&ret->p_minus_order, &ret->order_as_fe, 1); + secp256k1_fe_normalize(&ret->p_minus_order); + + /* Set the global pointer. */ + secp256k1_ecdsa_consts = ret; +} + +static void secp256k1_ecdsa_stop(void) { + if (secp256k1_ecdsa_consts == NULL) + return; + + secp256k1_ecdsa_consts_t *c = (secp256k1_ecdsa_consts_t*)secp256k1_ecmult_consts; + secp256k1_ecdsa_consts = NULL; + free(c); +} + static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) { if (sig[0] != 0x30) return 0; int lenr = sig[3]; @@ -26,18 +60,37 @@ static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned ch if (lenr == 0) return 0; if (sig[lenr+4] != 0x02) return 0; if (lens == 0) return 0; - secp256k1_num_set_bin(&r->r, sig+4, lenr); - secp256k1_num_set_bin(&r->s, sig+6+lenr, lens); + const unsigned char *sp = sig + 6 + lenr; + while (lens > 0 && sp[0] == 0) { + lens--; + sp++; + } + if (lens > 32) return 0; + const unsigned char *rp = sig + 4; + while (lenr > 0 && rp[0] == 0) { + lenr--; + rp++; + } + if (lenr > 32) return 0; + unsigned char ra[32] = {0}, sa[32] = {0}; + memcpy(ra + 32 - lenr, rp, lenr); + memcpy(sa + 32 - lens, sp, lens); + int overflow = 0; + secp256k1_scalar_set_b32(&r->r, ra, &overflow); + if (overflow) return 0; + secp256k1_scalar_set_b32(&r->s, sa, &overflow); + if (overflow) return 0; return 1; } static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) { - int lenR = (secp256k1_num_bits(&a->r) + 7)/8; - if (lenR == 0 || secp256k1_num_get_bit(&a->r, lenR*8-1)) - lenR++; - int lenS = (secp256k1_num_bits(&a->s) + 7)/8; - if (lenS == 0 || secp256k1_num_get_bit(&a->s, lenS*8-1)) - lenS++; + unsigned char r[33] = {0}, s[33] = {0}; + secp256k1_scalar_get_b32(&r[1], &a->r); + secp256k1_scalar_get_b32(&s[1], &a->s); + unsigned char *rp = r, *sp = s; + int lenR = 33, lenS = 33; + while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; } + while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; } if (*size < 6+lenS+lenR) return 0; *size = 6 + lenS + lenR; @@ -45,98 +98,67 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se sig[1] = 4 + lenS + lenR; sig[2] = 0x02; sig[3] = lenR; - secp256k1_num_get_bin(sig+4, lenR, &a->r); + memcpy(sig+4, rp, lenR); sig[4+lenR] = 0x02; sig[5+lenR] = lenS; - secp256k1_num_get_bin(sig+lenR+6, lenS, &a->s); + memcpy(sig+lenR+6, sp, lenS); return 1; } -static int secp256k1_ecdsa_sig_recompute(secp256k1_num_t *r2, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message) { - const secp256k1_ge_consts_t *c = secp256k1_ge_consts; - - if (secp256k1_num_is_neg(&sig->r) || secp256k1_num_is_neg(&sig->s)) - return 0; - if (secp256k1_num_is_zero(&sig->r) || secp256k1_num_is_zero(&sig->s)) - return 0; - if (secp256k1_num_cmp(&sig->r, &c->order) >= 0 || secp256k1_num_cmp(&sig->s, &c->order) >= 0) +static int secp256k1_ecdsa_sig_recompute(secp256k1_scalar_t *r2, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { + if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) return 0; int ret = 0; - secp256k1_num_t sn, u1, u2; - secp256k1_num_init(&sn); - secp256k1_num_init(&u1); - secp256k1_num_init(&u2); - secp256k1_num_mod_inverse(&sn, &sig->s, &c->order); - secp256k1_num_mod_mul(&u1, &sn, message, &c->order); - secp256k1_num_mod_mul(&u2, &sn, &sig->r, &c->order); + secp256k1_scalar_t sn, u1, u2; + secp256k1_scalar_inverse_var(&sn, &sig->s); + secp256k1_scalar_mul(&u1, &sn, message); + secp256k1_scalar_mul(&u2, &sn, &sig->r); secp256k1_gej_t pubkeyj; secp256k1_gej_set_ge(&pubkeyj, pubkey); 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); unsigned char xrb[32]; secp256k1_fe_get_b32(xrb, &xr); - secp256k1_num_set_bin(r2, xrb, 32); - secp256k1_num_mod(r2, &c->order); + secp256k1_scalar_set_b32(r2, xrb, NULL); ret = 1; } - secp256k1_num_free(&sn); - secp256k1_num_free(&u1); - secp256k1_num_free(&u2); return ret; } -static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_num_t *message, int recid) { - const secp256k1_ge_consts_t *c = secp256k1_ge_consts; - - if (secp256k1_num_is_neg(&sig->r) || secp256k1_num_is_neg(&sig->s)) - return 0; - if (secp256k1_num_is_zero(&sig->r) || secp256k1_num_is_zero(&sig->s)) - return 0; - if (secp256k1_num_cmp(&sig->r, &c->order) >= 0 || secp256k1_num_cmp(&sig->s, &c->order) >= 0) +static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) { + if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s)) return 0; - secp256k1_num_t rx; - secp256k1_num_init(&rx); - secp256k1_num_copy(&rx, &sig->r); - if (recid & 2) { - secp256k1_num_add(&rx, &rx, &c->order); - if (secp256k1_num_cmp(&rx, &secp256k1_fe_consts->p) >= 0) - return 0; - } unsigned char brx[32]; - secp256k1_num_get_bin(brx, 32, &rx); - secp256k1_num_free(&rx); + secp256k1_scalar_get_b32(brx, &sig->r); secp256k1_fe_t fx; - VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* Either rx < n (and n < p), or rx + n < p (checked above). */ + VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* brx comes from a scalar, so is less than the order; certainly less than p */ + if (recid & 2) { + if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_consts->p_minus_order) >= 0) + return 0; + secp256k1_fe_add(&fx, &secp256k1_ecdsa_consts->order_as_fe); + } secp256k1_ge_t x; if (!secp256k1_ge_set_xo(&x, &fx, recid & 1)) return 0; secp256k1_gej_t xj; secp256k1_gej_set_ge(&xj, &x); - secp256k1_num_t rn, u1, u2; - secp256k1_num_init(&rn); - secp256k1_num_init(&u1); - secp256k1_num_init(&u2); - secp256k1_num_mod_inverse(&rn, &sig->r, &c->order); - secp256k1_num_mod_mul(&u1, &rn, message, &c->order); - secp256k1_num_sub(&u1, &c->order, &u1); - secp256k1_num_mod_mul(&u2, &rn, &sig->s, &c->order); + secp256k1_scalar_t rn, u1, u2; + secp256k1_scalar_inverse_var(&rn, &sig->r); + secp256k1_scalar_mul(&u1, &rn, message); + secp256k1_scalar_negate(&u1, &u1); + secp256k1_scalar_mul(&u2, &rn, &sig->s); secp256k1_gej_t qj; secp256k1_ecmult(&qj, &xj, &u2, &u1); secp256k1_ge_set_gej_var(pubkey, &qj); - secp256k1_num_free(&rn); - secp256k1_num_free(&u1); - secp256k1_num_free(&u2); return !secp256k1_gej_is_infinity(&qj); } -static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message) { - secp256k1_num_t r2; - secp256k1_num_init(&r2); +static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) { + secp256k1_scalar_t r2; int ret = 0; - ret = secp256k1_ecdsa_sig_recompute(&r2, sig, pubkey, message) && secp256k1_num_cmp(&sig->r, &r2) == 0; - secp256k1_num_free(&r2); + ret = secp256k1_ecdsa_sig_recompute(&r2, sig, pubkey, message) && secp256k1_scalar_eq(&sig->r, &r2); return ret; } @@ -150,34 +172,30 @@ static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_ secp256k1_fe_normalize(&r.y); secp256k1_fe_get_b32(b, &r.x); int overflow = 0; - secp256k1_scalar_t sigr; - secp256k1_scalar_set_b32(&sigr, b, &overflow); + secp256k1_scalar_set_b32(&sig->r, b, &overflow); if (recid) *recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0); secp256k1_scalar_t n; - secp256k1_scalar_mul(&n, &sigr, seckey); + secp256k1_scalar_mul(&n, &sig->r, seckey); secp256k1_scalar_add(&n, &n, message); - secp256k1_scalar_t sigs; - secp256k1_scalar_inverse(&sigs, nonce); - secp256k1_scalar_mul(&sigs, &sigs, &n); + secp256k1_scalar_inverse(&sig->s, nonce); + secp256k1_scalar_mul(&sig->s, &sig->s, &n); secp256k1_scalar_clear(&n); secp256k1_gej_clear(&rp); secp256k1_ge_clear(&r); - if (secp256k1_scalar_is_zero(&sigs)) + if (secp256k1_scalar_is_zero(&sig->s)) return 0; - if (secp256k1_scalar_is_high(&sigs)) { - secp256k1_scalar_negate(&sigs, &sigs); + if (secp256k1_scalar_is_high(&sig->s)) { + secp256k1_scalar_negate(&sig->s, &sig->s); if (recid) *recid ^= 1; } - secp256k1_scalar_get_num(&sig->s, &sigs); - secp256k1_scalar_get_num(&sig->r, &sigr); return 1; } -static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *r, const secp256k1_num_t *s) { - secp256k1_num_copy(&sig->r, r); - secp256k1_num_copy(&sig->s, s); +static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s) { + sig->r = *r; + sig->s = *s; } #endif diff --git a/src/eckey.h b/src/eckey.h index 024c8b8..6de5dc0 100644 --- a/src/eckey.h +++ b/src/eckey.h @@ -9,7 +9,6 @@ #include "group.h" #include "scalar.h" -#include "num.h" static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size); static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed); @@ -18,8 +17,8 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed); static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak); -static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_num_t *tweak); +static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak); static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak); -static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_num_t *tweak); +static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak); #endif diff --git a/src/eckey_impl.h b/src/eckey_impl.h index bddf51a..0f218ce 100644 --- a/src/eckey_impl.h +++ b/src/eckey_impl.h @@ -9,7 +9,7 @@ #include "eckey.h" -#include "num.h" +#include "scalar.h" #include "field.h" #include "group.h" #include "ecmult_gen.h" @@ -154,17 +154,12 @@ static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp return 1; } -static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_num_t *tweak) { - if (secp256k1_num_cmp(tweak, &secp256k1_ge_consts->order) >= 0) - return 0; - +static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { secp256k1_gej_t pt; secp256k1_gej_set_ge(&pt, key); - secp256k1_num_t one; - secp256k1_num_init(&one); - secp256k1_num_set_int(&one, 1); + secp256k1_scalar_t one; + secp256k1_scalar_set_int(&one, 1); secp256k1_ecmult(&pt, &pt, &one, tweak); - secp256k1_num_free(&one); if (secp256k1_gej_is_infinity(&pt)) return 0; @@ -180,19 +175,15 @@ static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp return 1; } -static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_num_t *tweak) { - if (secp256k1_num_is_zero(tweak)) - return 0; - if (secp256k1_num_cmp(tweak, &secp256k1_ge_consts->order) >= 0) +static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) { + if (secp256k1_scalar_is_zero(tweak)) return 0; - secp256k1_num_t zero; - secp256k1_num_init(&zero); - secp256k1_num_set_int(&zero, 0); + secp256k1_scalar_t zero; + secp256k1_scalar_set_int(&zero, 0); secp256k1_gej_t pt; secp256k1_gej_set_ge(&pt, key); secp256k1_ecmult(&pt, &pt, tweak, &zero); - secp256k1_num_free(&zero); secp256k1_ge_set_gej(key, &pt); return 1; } diff --git a/src/ecmult.h b/src/ecmult.h index e3cf18b..15a7100 100644 --- a/src/ecmult.h +++ b/src/ecmult.h @@ -14,6 +14,6 @@ static void secp256k1_ecmult_start(void); static void secp256k1_ecmult_stop(void); /** Double multiply: R = na*A + ng*G */ -static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_num_t *na, const secp256k1_num_t *ng); +static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng); #endif diff --git a/src/ecmult_impl.h b/src/ecmult_impl.h index 1a55e8b..56e46cd 100644 --- a/src/ecmult_impl.h +++ b/src/ecmult_impl.h @@ -7,7 +7,6 @@ #ifndef _SECP256K1_ECMULT_IMPL_H_ #define _SECP256K1_ECMULT_IMPL_H_ -#include "num.h" #include "group.h" #include "scalar.h" #include "ecmult.h" @@ -125,22 +124,13 @@ static void secp256k1_ecmult_stop(void) { * - the number of set values in wnaf is returned. This number is at most 256, and at most one more * - than the number of bits in the (absolute value) of the input. */ -static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_num_t *a, int w) { - secp256k1_num_t x; - secp256k1_num_copy(&x, a); - int sign = 1; - if (secp256k1_num_is_neg(&x)) { - sign = -1; - secp256k1_num_negate(&x); - } - unsigned char cr[32]; - secp256k1_num_get_bin(cr, 32, &x); - secp256k1_scalar_t s; - secp256k1_scalar_set_b32(&s, cr, NULL); +static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) { + secp256k1_scalar_t s = *a; + int sign = 1; if (secp256k1_scalar_get_bits(&s, 255, 1)) { secp256k1_scalar_negate(&s, &s); - sign *= -1; + sign = -1; } int set_bits = 0; @@ -169,13 +159,13 @@ static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_num_t *a, int w) { return set_bits; } -static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_num_t *na, const secp256k1_num_t *ng) { +static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) { const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts; #ifdef USE_ENDOMORPHISM - secp256k1_num_t na_1, na_lam; + secp256k1_scalar_t na_1, na_lam; /* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */ - secp256k1_gej_split_exp_var(&na_1, &na_lam, na); + secp256k1_scalar_split_lambda_var(&na_1, &na_lam, na); /* build wnaf representation for na_1 and na_lam. */ int wnaf_na_1[129]; int bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A); @@ -198,10 +188,10 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_gej_mul_lambda(&pre_a_lam[i], &pre_a[i]); /* Splitted G factors. */ - secp256k1_num_t ng_1, ng_128; + secp256k1_scalar_t ng_1, ng_128; /* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */ - secp256k1_num_split(&ng_1, &ng_128, ng, 128); + secp256k1_scalar_split_128(&ng_1, &ng_128, ng); /* Build wnaf representation for ng_1 and ng_128 */ int wnaf_ng_1[129]; int bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G); diff --git a/src/field.h b/src/field.h index b56a0a9..cbd48c0 100644 --- a/src/field.h +++ b/src/field.h @@ -34,6 +34,7 @@ typedef struct { secp256k1_num_t p; + secp256k1_fe_t order; } secp256k1_fe_consts_t; static const secp256k1_fe_consts_t *secp256k1_fe_consts = NULL; @@ -59,6 +60,9 @@ 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 both inputs to be normalized */ +static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b); + /** Set a field element equal to 32-byte big endian value. If succesful, the resulting field element is normalized. */ static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a); diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h index de12d56..213b848 100644 --- a/src/field_10x26_impl.h +++ b/src/field_10x26_impl.h @@ -152,6 +152,20 @@ SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const se | (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); + VERIFY_CHECK(b->normalized); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); +#endif + for (int i = 9; i >= 0; i--) { + if (a->n[i] > b->n[i]) return 1; + if (a->n[i] < b->n[i]) return -1; + } + return 0; +} + static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0; diff --git a/src/field_5x52_impl.h b/src/field_5x52_impl.h index e1e7ee1..cc9d0c1 100644 --- a/src/field_5x52_impl.h +++ b/src/field_5x52_impl.h @@ -150,6 +150,20 @@ SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const se 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); + VERIFY_CHECK(b->normalized); + secp256k1_fe_verify(a); + secp256k1_fe_verify(b); +#endif + for (int i = 4; i >= 0; i--) { + if (a->n[i] > b->n[i]) return 1; + if (a->n[i] < b->n[i]) return -1; + } + return 0; +} + static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0; for (int i=0; i<32; i++) { diff --git a/src/field_gmp_impl.h b/src/field_gmp_impl.h index 3104522..4e59fe3 100644 --- a/src/field_gmp_impl.h +++ b/src/field_gmp_impl.h @@ -75,6 +75,14 @@ SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const se return ret; } +SECP256K1_INLINE static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) { + for (int i=FIELD_LIMBS; i>=0; i--) { + if (a->n[i] > b->n[i]) return 1; + if (a->n[i] < b->n[i]) return -1; + } + return 0; +} + static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) { for (int i=0; in[i] = 0; diff --git a/src/scalar.h b/src/scalar.h index cd9d599..64058e9 100644 --- a/src/scalar.h +++ b/src/scalar.h @@ -72,6 +72,9 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a); /** Convert a scalar to a number. */ static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a); +/** Compare two scalars. */ +static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b); + static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a); #ifdef USE_ENDOMORPHISM diff --git a/src/scalar_4x64_impl.h b/src/scalar_4x64_impl.h index d95b775..afa7a54 100644 --- a/src/scalar_4x64_impl.h +++ b/src/scalar_4x64_impl.h @@ -401,4 +401,8 @@ static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_ r2->d[3] = 0; } +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3])) == 0; +} + #endif diff --git a/src/scalar_8x32_impl.h b/src/scalar_8x32_impl.h index 74c47de..0f82bfb 100644 --- a/src/scalar_8x32_impl.h +++ b/src/scalar_8x32_impl.h @@ -634,4 +634,8 @@ static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_ r2->d[7] = 0; } +SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) { + return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0; +} + #endif diff --git a/src/secp256k1.c b/src/secp256k1.c index 1ab5b37..c636145 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -21,6 +21,7 @@ void secp256k1_start(unsigned int flags) { secp256k1_fe_start(); secp256k1_ge_start(); + secp256k1_ecdsa_start(); if (flags & SECP256K1_START_SIGN) { secp256k1_ecmult_gen_start(); } @@ -32,6 +33,7 @@ void secp256k1_start(unsigned int flags) { void secp256k1_stop(void) { secp256k1_ecmult_stop(); secp256k1_ecmult_gen_stop(); + secp256k1_ecdsa_stop(); secp256k1_ge_stop(); secp256k1_fe_stop(); } @@ -43,11 +45,13 @@ int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen, const unsigned DEBUG_CHECK(sig != NULL); DEBUG_CHECK(pubkey != NULL); + unsigned char msg32[32] = {0}; + memcpy(msg32 + 32 - msglen, msg, msglen); int ret = -3; - secp256k1_num_t m; + secp256k1_scalar_t m; secp256k1_ecdsa_sig_t s; secp256k1_ge_t q; - secp256k1_num_set_bin(&m, msg, msglen); + secp256k1_scalar_set_b32(&m, msg32, NULL); if (!secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) { ret = -1; @@ -123,8 +127,8 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, u ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid); } if (ret) { - secp256k1_num_get_bin(sig64, 32, &sig.r); - secp256k1_num_get_bin(sig64 + 32, 32, &sig.s); + secp256k1_scalar_get_b32(sig64, &sig.r); + secp256k1_scalar_get_b32(sig64 + 32, &sig.s); } secp256k1_scalar_clear(&msg); secp256k1_scalar_clear(&non); @@ -142,11 +146,20 @@ int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const DEBUG_CHECK(recid >= 0 && recid <= 3); int ret = 0; - secp256k1_num_t m; + unsigned char msg32[32] = {0}; + memcpy(msg32 + 32 - msglen, msg, msglen); + secp256k1_scalar_t m; secp256k1_ecdsa_sig_t sig; - secp256k1_num_set_bin(&sig.r, sig64, 32); - secp256k1_num_set_bin(&sig.s, sig64 + 32, 32); - secp256k1_num_set_bin(&m, msg, msglen); + int overflow = 0; + secp256k1_scalar_set_b32(&sig.r, sig64, &overflow); + if (overflow) { + return 0; + } + secp256k1_scalar_set_b32(&sig.s, sig64 + 32, &overflow); + if (overflow) { + return 0; + } + secp256k1_scalar_set_b32(&m, msg32, NULL); secp256k1_ge_t q; if (secp256k1_ecdsa_sig_recover(&sig, &q, &m, recid)) { @@ -224,8 +237,12 @@ int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const un DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(tweak != NULL); - secp256k1_num_t term; - secp256k1_num_set_bin(&term, tweak, 32); + secp256k1_scalar_t term; + int overflow = 0; + secp256k1_scalar_set_b32(&term, tweak, &overflow); + if (overflow) { + return 0; + } secp256k1_ge_t p; int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); if (ret) { @@ -264,8 +281,12 @@ int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const un DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(tweak != NULL); - secp256k1_num_t factor; - secp256k1_num_set_bin(&factor, tweak, 32); + secp256k1_scalar_t factor; + int overflow = 0; + secp256k1_scalar_set_b32(&factor, tweak, &overflow); + if (overflow) { + return 0; + } secp256k1_ge_t p; int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); if (ret) { diff --git a/src/tests.c b/src/tests.c index a4d3b6f..a3b1f4f 100644 --- a/src/tests.c +++ b/src/tests.c @@ -100,6 +100,18 @@ void random_scalar_order_test(secp256k1_scalar_t *num) { } while(1); } +void random_scalar_order(secp256k1_scalar_t *num) { + do { + unsigned char b32[32]; + secp256k1_rand256(b32); + int overflow = 0; + secp256k1_scalar_set_b32(num, b32, &overflow); + if (overflow || secp256k1_scalar_is_zero(num)) + continue; + break; + } while(1); +} + void random_num_order(secp256k1_num_t *num) { do { unsigned char b32[32]; @@ -240,14 +252,6 @@ void run_num_smalltests(void) { /***** SCALAR TESTS *****/ -int secp256k1_scalar_eq(const secp256k1_scalar_t *s1, const secp256k1_scalar_t *s2) { - secp256k1_scalar_t t; - secp256k1_scalar_negate(&t, s2); - secp256k1_scalar_add(&t, &t, s1); - int ret = secp256k1_scalar_is_zero(&t); - return ret; -} - void scalar_test(void) { unsigned char c[32]; @@ -746,35 +750,47 @@ void run_ecmult_chain(void) { secp256k1_fe_t ay; VERIFY_CHECK(secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64)); secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay); /* two random initial factors xn and gn */ - secp256k1_num_t xn; - secp256k1_num_set_hex(&xn, "84cc5452f7fde1edb4d38a8ce9b1b84ccef31f146e569be9705d357a42985407", 64); - secp256k1_num_t gn; - secp256k1_num_set_hex(&gn, "a1e58d22553dcd42b23980625d4c57a96e9323d42b3152e5ca2c3990edc7c9de", 64); + static const unsigned char xni[32] = { + 0x84, 0xcc, 0x54, 0x52, 0xf7, 0xfd, 0xe1, 0xed, + 0xb4, 0xd3, 0x8a, 0x8c, 0xe9, 0xb1, 0xb8, 0x4c, + 0xce, 0xf3, 0x1f, 0x14, 0x6e, 0x56, 0x9b, 0xe9, + 0x70, 0x5d, 0x35, 0x7a, 0x42, 0x98, 0x54, 0x07 + }; + secp256k1_scalar_t xn; + secp256k1_scalar_set_b32(&xn, xni, NULL); + static const unsigned char gni[32] = { + 0xa1, 0xe5, 0x8d, 0x22, 0x55, 0x3d, 0xcd, 0x42, + 0xb2, 0x39, 0x80, 0x62, 0x5d, 0x4c, 0x57, 0xa9, + 0x6e, 0x93, 0x23, 0xd4, 0x2b, 0x31, 0x52, 0xe5, + 0xca, 0x2c, 0x39, 0x90, 0xed, 0xc7, 0xc9, 0xde + }; + secp256k1_scalar_t gn; + secp256k1_scalar_set_b32(&gn, gni, NULL); /* two small multipliers to be applied to xn and gn in every iteration: */ - secp256k1_num_t xf; - secp256k1_num_set_hex(&xf, "1337", 4); - secp256k1_num_t gf; - secp256k1_num_set_hex(&gf, "7113", 4); + static const unsigned char xfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x13,0x37}; + secp256k1_scalar_t xf; + secp256k1_scalar_set_b32(&xf, xfi, NULL); + static const unsigned char gfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x71,0x13}; + secp256k1_scalar_t gf; + secp256k1_scalar_set_b32(&gf, gfi, NULL); /* accumulators with the resulting coefficients to A and G */ - secp256k1_num_t ae; - secp256k1_num_set_int(&ae, 1); - secp256k1_num_t ge; - secp256k1_num_set_int(&ge, 0); + secp256k1_scalar_t ae; + secp256k1_scalar_set_int(&ae, 1); + secp256k1_scalar_t ge; + secp256k1_scalar_set_int(&ge, 0); /* the point being computed */ secp256k1_gej_t x = a; - const secp256k1_num_t *order = &secp256k1_ge_consts->order; for (int i=0; i<200*count; i++) { /* in each iteration, compute X = xn*X + gn*G; */ secp256k1_ecmult(&x, &x, &xn, &gn); /* also compute ae and ge: the actual accumulated factors for A and G */ /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */ - secp256k1_num_mod_mul(&ae, &ae, &xn, order); - secp256k1_num_mod_mul(&ge, &ge, &xn, order); - secp256k1_num_add(&ge, &ge, &gn); - secp256k1_num_mod(&ge, order); + secp256k1_scalar_mul(&ae, &ae, &xn); + secp256k1_scalar_mul(&ge, &ge, &xn); + secp256k1_scalar_add(&ge, &ge, &gn); /* modify xn and gn */ - secp256k1_num_mod_mul(&xn, &xn, &xf, order); - secp256k1_num_mod_mul(&gn, &gn, &gf, order); + secp256k1_scalar_mul(&xn, &xn, &xf); + secp256k1_scalar_mul(&gn, &gn, &gf); /* verify */ if (i == 19999) { @@ -795,10 +811,10 @@ void run_ecmult_chain(void) { void test_point_times_order(const secp256k1_gej_t *point) { /* X * (point + G) + (order-X) * (pointer + G) = 0 */ - secp256k1_num_t x; - random_num_order_test(&x); - secp256k1_num_t nx; - secp256k1_num_sub(&nx, &secp256k1_ge_consts->order, &x); + secp256k1_scalar_t x; + random_scalar_order_test(&x); + secp256k1_scalar_t nx; + secp256k1_scalar_negate(&nx, &x); secp256k1_gej_t res1, res2; secp256k1_ecmult(&res1, point, &x, &x); /* calc res1 = x * point + x * G; */ secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */ @@ -824,16 +840,16 @@ void run_point_times_order(void) { CHECK(strcmp(c, "7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45") == 0); } -void test_wnaf(const secp256k1_num_t *number, int w) { - secp256k1_num_t x, two, t; - secp256k1_num_set_int(&x, 0); - secp256k1_num_set_int(&two, 2); +void test_wnaf(const secp256k1_scalar_t *number, int w) { + secp256k1_scalar_t x, two, t; + secp256k1_scalar_set_int(&x, 0); + secp256k1_scalar_set_int(&two, 2); int wnaf[256]; int bits = secp256k1_ecmult_wnaf(wnaf, number, w); CHECK(bits <= 256); int zeroes = -1; for (int i=bits-1; i>=0; i--) { - secp256k1_num_mul(&x, &x, &two); + secp256k1_scalar_mul(&x, &x, &two); int v = wnaf[i]; if (v) { CHECK(zeroes == -1 || zeroes >= w-1); /* check that distance between non-zero elements is at least w-1 */ @@ -845,21 +861,23 @@ void test_wnaf(const secp256k1_num_t *number, int w) { CHECK(zeroes != -1); /* check that no unnecessary zero padding exists */ zeroes++; } - secp256k1_num_set_int(&t, v); - secp256k1_num_add(&x, &x, &t); + if (v >= 0) { + secp256k1_scalar_set_int(&t, v); + } else { + secp256k1_scalar_set_int(&t, -v); + secp256k1_scalar_negate(&t, &t); + } + secp256k1_scalar_add(&x, &x, &t); } - secp256k1_num_t xcopy = x, ncopy = *number; - secp256k1_num_mod(&xcopy, &secp256k1_ge_consts->order); - secp256k1_num_mod(&ncopy, &secp256k1_ge_consts->order); - CHECK(secp256k1_num_eq(&xcopy, &ncopy)); /* check that wnaf represents number */ + CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */ } void run_wnaf(void) { - secp256k1_num_t n; + secp256k1_scalar_t n; for (int i=0; i