diff --git a/Makefile b/Makefile index 3080b50f1a..c2ff2b72ad 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ bench: $(FILES) src/bench.c $(OBJS) $(CC) -fPIC -std=c99 $(CFLAGS) $(CFLAGS_EXTRA) -DNDEBUG -O2 src/bench.c $(OBJS) $(LDFLAGS_EXTRA) -o bench tests: $(FILES) src/tests.c $(OBJS) - $(CC) -std=c99 $(CFLAGS) $(CFLAGS_EXTRA) -DVERIFY -O1 src/tests.c $(OBJS) $(LDFLAGS_EXTRA) -o tests + $(CC) -std=c99 $(CFLAGS) $(CFLAGS_EXTRA) -DVERIFY -O0 -ggdb3 src/tests.c $(OBJS) $(LDFLAGS_EXTRA) -o tests libsecp256k1.a: obj/secp256k1.o $(OBJS) $(AR) -rs $@ $(OBJS) obj/secp256k1.o diff --git a/src/impl/ecdsa.h b/src/impl/ecdsa.h index 8589a225fc..d5820141e1 100644 --- a/src/impl/ecdsa.h +++ b/src/impl/ecdsa.h @@ -130,6 +130,7 @@ int static secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_ secp256k1_num_init(&n); secp256k1_num_mod_mul(&n, &sig->r, seckey, &c->order); secp256k1_num_add(&n, &n, message); + secp256k1_num_mod(&n, &n, &c->order); secp256k1_num_mod_inverse(&sig->s, nonce, &c->order); secp256k1_num_mod_mul(&sig->s, &sig->s, &n, &c->order); secp256k1_num_free(&n); diff --git a/src/impl/field.h b/src/impl/field.h index a0112fdbfc..9f891c946b 100644 --- a/src/impl/field.h +++ b/src/impl/field.h @@ -149,7 +149,7 @@ void static secp256k1_fe_start(void) { }; if (secp256k1_fe_consts == NULL) { secp256k1_fe_inner_start(); - secp256k1_fe_consts_t *ret = (secp256k1_fe_consts_t*)malloc(sizeof(secp256k1_fe_t)); + secp256k1_fe_consts_t *ret = (secp256k1_fe_consts_t*)malloc(sizeof(secp256k1_fe_consts_t)); secp256k1_num_init(&ret->p); secp256k1_num_set_bin(&ret->p, secp256k1_fe_consts_p, sizeof(secp256k1_fe_consts_p)); secp256k1_fe_consts = ret; diff --git a/src/impl/group.h b/src/impl/group.h index 6c0386952c..a0f02d34e1 100644 --- a/src/impl/group.h +++ b/src/impl/group.h @@ -259,6 +259,12 @@ void static secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t * } void static secp256k1_gej_split_exp(secp256k1_num_t *r1, secp256k1_num_t *r2, const secp256k1_num_t *a) { +#ifdef VERIFY + secp256k1_num_t a2; + secp256k1_num_init(&a2); + secp256k1_num_copy(&a2, a); +#endif + const secp256k1_ge_consts_t *c = secp256k1_ge_consts; secp256k1_num_t bnc1, bnc2, bnt1, bnt2, bnn2; @@ -287,6 +293,20 @@ void static secp256k1_gej_split_exp(secp256k1_num_t *r1, secp256k1_num_t *r2, co secp256k1_num_mul(&bnt2, &bnc2, &c->a1b2); secp256k1_num_sub(r2, &bnt1, &bnt2); +#ifdef VERIFY + secp256k1_num_t check; + secp256k1_num_init(&check); + secp256k1_num_mul(&check, r2, &c->lambda); + secp256k1_num_add(&check, &check, r1); + secp256k1_num_mod(&check, &check, &c->order); + secp256k1_num_add(&check, &check, &c->order); + secp256k1_num_mod(&check, &check, &c->order); + secp256k1_num_mod(&a2, &a2, &c->order); + assert(secp256k1_num_cmp(&check, &a2) == 0); + secp256k1_num_free(&check); + secp256k1_num_free(&a2); +#endif + secp256k1_num_free(&bnc1); secp256k1_num_free(&bnc2); secp256k1_num_free(&bnt1); diff --git a/src/impl/num.h b/src/impl/num.h index f27f0d1f10..58513a45a7 100644 --- a/src/impl/num.h +++ b/src/impl/num.h @@ -3,7 +3,9 @@ #include "../num.h" -#if defined(USE_NUM_GMP) +#if defined(USE_NUM_GMPN) +#include "num_gmpn.h" +#elif defined(USE_NUM_GMP) #include "num_gmp.h" #elif defined(USE_NUM_OPENSSL) #include "num_openssl.h" diff --git a/src/impl/num_gmp.h b/src/impl/num_gmp.h index f3599ddc67..ebb4695fab 100644 --- a/src/impl/num_gmp.h +++ b/src/impl/num_gmp.h @@ -8,153 +8,393 @@ #include "num.h" -typedef struct { - int initialized; - gmp_randstate_t rng; -} secp256k1_num_state_t; - -static secp256k1_num_state_t secp256k1_num_state = {}; +#ifdef VERIFY +void static secp256k1_num_sanity(const secp256k1_num_t *a) { + assert(a->limbs == 1 || (a->limbs > 1 && a->data[a->limbs-1] != 0)); +} +#else +#define secp256k1_num_sanity(a) do { } while(0) +#endif void static secp256k1_num_start(void) { - if (secp256k1_num_state.initialized) - return; - secp256k1_num_state.initialized = 1; - gmp_randinit_default(secp256k1_num_state.rng); } void static secp256k1_num_stop(void) { - if (!secp256k1_num_state.initialized) - return; - secp256k1_num_state.initialized = 0; - gmp_randclear(secp256k1_num_state.rng); } void static secp256k1_num_init(secp256k1_num_t *r) { - mpz_init(r->bn); + r->neg = 0; + r->limbs = 1; + r->data[0] = 0; } void static secp256k1_num_free(secp256k1_num_t *r) { - mpz_clear(r->bn); } void static secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a) { - mpz_set(r->bn, a->bn); -} - -void static secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) { - unsigned int size = (mpz_sizeinbase(a->bn,2)+7)/8; - assert(size <= rlen); - memset(r,0,rlen); - size_t count = 0; - mpz_export(r + rlen - size, &count, 1, 1, 1, 0, a->bn); - assert(count == 0 || size == count); -} - -void static secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen) { - mpz_import(r->bn, alen, 1, 1, 1, 0, a); -} - -void static secp256k1_num_set_int(secp256k1_num_t *r, int a) { - mpz_set_si(r->bn, a); -} - -void static secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m) { - mpz_invert(r->bn, a->bn, m->bn); -} - -void static secp256k1_num_mod_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b, const secp256k1_num_t *m) { - mpz_mul(r->bn, a->bn, b->bn); - mpz_mod(r->bn, r->bn, m->bn); -} - -int static secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b) { - return mpz_cmp(a->bn, b->bn); -} - -void static secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { - mpz_add(r->bn, a->bn, b->bn); -} - -void static secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { - mpz_sub(r->bn, a->bn, b->bn); -} - -void static secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { - mpz_mul(r->bn, a->bn, b->bn); -} - -void static secp256k1_num_div(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { - mpz_tdiv_q(r->bn, a->bn, b->bn); -} - -void static secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { - mpz_mod(r->bn, a->bn, b->bn); + *r = *a; } int static secp256k1_num_bits(const secp256k1_num_t *a) { - return mpz_sizeinbase(a->bn,2); -} - -int static secp256k1_num_shift(secp256k1_num_t *r, int bits) { - int ret = mpz_get_ui(r->bn) & ((1 << bits) - 1); - mpz_fdiv_q_2exp(r->bn, r->bn, bits); + int ret=(a->limbs-1)*GMP_NUMB_BITS; + mp_limb_t x=a->data[a->limbs-1]; + while (x) { + x >>= 1; + ret++; + } return ret; } + +void static secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) { + unsigned char tmp[65]; + int len = mpn_get_str(tmp, 256, (mp_limb_t*)a->data, a->limbs); + assert(len <= rlen); + memset(r, 0, rlen - len); + memcpy(r + rlen - len, tmp, len); +} + +void static secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen) { + assert(alen > 0); + assert(alen <= 64); + int len = mpn_set_str(r->data, a, alen, 256); + assert(len <= NUM_LIMBS*2); + r->limbs = len; + r->neg = 0; + while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--; +} + +void static secp256k1_num_set_int(secp256k1_num_t *r, int a) { + r->limbs = 1; + r->neg = (a < 0); + r->data[0] = (a < 0) ? -a : a; +} + +void static secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + + r->neg = a->neg; + if (a->limbs >= b->limbs) { + mp_limb_t q[2*NUM_LIMBS+1]; + mp_limb_t t[2*NUM_LIMBS+1]; + mpn_tdiv_qr(t, q, 0, a->data, a->limbs, b->data, b->limbs); + r->limbs = b->limbs; + while (r->limbs > 1 && q[r->limbs-1]==0) r->limbs--; + mpn_copyi(r->data, q, r->limbs); + } else { + *r = *a; + } +} + +void static secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m) { + secp256k1_num_sanity(a); + secp256k1_num_sanity(m); + +#ifdef VERIFY + secp256k1_num_t a2 = *a; + secp256k1_num_t m2 = *m; +#endif + + // mpn_gcdext computes: (G,S) = gcdext(U,V), where + // * G = gcd(U,V) + // * G = U*S + V*T + // * U has equal or more limbs than V, and V has no padding + // If we set U to be (a padded version of) a, and V = m: + // G = a*S + m*T + // G = a*S mod m + // Assuming G=1: + // S = 1/a mod m + assert(m->limbs <= NUM_LIMBS); + assert(m->data[m->limbs-1] != 0); + mp_limb_t g[NUM_LIMBS+1]; + mp_limb_t u[NUM_LIMBS+1]; + mp_limb_t v[NUM_LIMBS+1]; + for (int i=0; i < m->limbs; i++) { + u[i] = (i < a->limbs) ? a->data[i] : 0; + v[i] = m->data[i]; + } + mp_size_t sn = NUM_LIMBS+1; + mp_size_t gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs); + assert(gn == 1); + assert(g[0] == 1); + r->neg = a->neg ^ m->neg; + if (sn < 0) { + mpn_sub(r->data, m->data, m->limbs, r->data, -sn); + r->limbs = m->limbs; + while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--; + } else { + r->limbs = sn; + } + +#ifdef VERIFY + secp256k1_num_t c; + secp256k1_num_mod_mul(&c, &a2, r, m); + assert(c.limbs == 1 && c.data[0] == 1); +#endif +} + int static secp256k1_num_is_zero(const secp256k1_num_t *a) { - return mpz_size(a->bn) == 0; + return (a->limbs == 1 && a->data[0] == 0); } int static secp256k1_num_is_odd(const secp256k1_num_t *a) { - return mpz_get_ui(a->bn) & 1; + return a->data[0] & 1; } int static secp256k1_num_is_neg(const secp256k1_num_t *a) { - return mpz_sgn(a->bn) < 0; + return (a->limbs > 1 || a->data[0] != 0) && a->neg; +} + +int static secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b) { + if (a->limbs > b->limbs) return 1; + if (a->limbs < b->limbs) return -1; + return mpn_cmp(a->data, b->data, a->limbs); +} + +void static secp256k1_num_add_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { + mp_limb_t c = mpn_add(r->data, a->data, a->limbs, b->data, b->limbs); + r->limbs = a->limbs; + if (c != 0) { + assert(r->limbs < 2*NUM_LIMBS); + r->data[r->limbs++] = c; + } +} + +void static secp256k1_num_sub_abs(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { + mp_limb_t c = mpn_sub(r->data, a->data, a->limbs, b->data, b->limbs); + assert(c == 0); + r->limbs = a->limbs; + while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--; +} + +void static secp256k1_num_subadd(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b, int bneg) { + if (!(b->neg ^ bneg ^ a->neg)) { // a and b have the same sign + r->neg = a->neg; + if (a->limbs >= b->limbs) { + secp256k1_num_add_abs(r, a, b); + } else { + secp256k1_num_add_abs(r, b, a); + } + } else { + if (secp256k1_num_cmp(a, b) > 0) { + r->neg = a->neg; + secp256k1_num_sub_abs(r, a, b); + } else { + r->neg = b->neg ^ bneg; + secp256k1_num_sub_abs(r, b, a); + } + } +} + +void static secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + +#ifdef VERIFY + secp256k1_num_t a2 = *a; + secp256k1_num_t b2 = *b; +#endif + + secp256k1_num_subadd(r, a, b, 0); + +#ifdef VERIFY + secp256k1_num_t c = *r; + secp256k1_num_subadd(&c, &c, &b2, 1); + assert(secp256k1_num_cmp(&c, &a2) == 0); +#endif +} + +void static secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +#ifdef VERIFY + secp256k1_num_t a2 = *a; + secp256k1_num_t b2 = *b; +#endif + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + + secp256k1_num_subadd(r, a, b, 1); + +#ifdef VERIFY + secp256k1_num_t c; + secp256k1_num_subadd(&c, r, &b2, 0); + assert(secp256k1_num_cmp(&c, &a2) == 0); +#endif +} + +void static secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +#ifdef VERIFY + secp256k1_num_t a2 = *a; + secp256k1_num_t b2 = *b; +#endif + + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + + mp_limb_t tmp[2*NUM_LIMBS+1]; + assert(a->limbs + b->limbs <= 2*NUM_LIMBS+1); + if ((a->limbs==1 && a->data[0]==0) || (b->limbs==1 && b->data[0]==0)) { + r->limbs = 1; + r->neg = 0; + r->data[0] = 0; + return; + } + if (a->limbs >= b->limbs) + mpn_mul(tmp, a->data, a->limbs, b->data, b->limbs); + else + mpn_mul(tmp, b->data, b->limbs, a->data, a->limbs); + r->limbs = a->limbs + b->limbs; + if (r->limbs > 1 && tmp[r->limbs - 1]==0) r->limbs--; + assert(r->limbs <= 2*NUM_LIMBS); + mpn_copyi(r->data, tmp, r->limbs); + r->neg = a->neg ^ b->neg; + + secp256k1_num_sanity(&a2); + secp256k1_num_sanity(&b2); + +#ifdef VERIFY + secp256k1_num_t c; + secp256k1_num_div(&c, r, &b2); + assert(secp256k1_num_cmp(&a2, &c) == 0); + secp256k1_num_div(&c, r, &a2); + assert(secp256k1_num_cmp(&b2, &c) == 0); +#endif +} + +void static secp256k1_num_div(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { + secp256k1_num_sanity(a); + secp256k1_num_sanity(b); + if (b->limbs > a->limbs) { + r->limbs = 1; + r->data[0] = 0; + r->neg = 0; + return; + } + + mp_limb_t quo[2*NUM_LIMBS+1]; + mp_limb_t rem[2*NUM_LIMBS+1]; + mpn_tdiv_qr(quo, rem, 0, a->data, a->limbs, b->data, b->limbs); + mpn_copyi(r->data, quo, a->limbs - b->limbs + 1); + r->limbs = a->limbs - b->limbs + 1; + while (r->limbs > 1 && r->data[r->limbs - 1]==0) r->limbs--; + r->neg = a->neg ^ b->neg; +} + +void static secp256k1_num_mod_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b, const secp256k1_num_t *m) { + secp256k1_num_t tmp; + secp256k1_num_mul(&tmp, a, b); + secp256k1_num_mod(r, &tmp, m); +} + + +int static secp256k1_num_shift(secp256k1_num_t *r, int bits) { + assert(bits <= GMP_NUMB_BITS); + mp_limb_t ret = mpn_rshift(r->data, r->data, r->limbs, bits); + if (r->limbs>1 && r->data[r->limbs-1]==0) r->limbs--; + ret >>= (GMP_NUMB_BITS - bits); + return ret; } int static secp256k1_num_get_bit(const secp256k1_num_t *a, int pos) { - return mpz_tstbit(a->bn, pos); + return (a->limbs*GMP_NUMB_BITS > pos) && ((a->data[pos/GMP_NUMB_BITS] >> (pos % GMP_NUMB_BITS)) & 1); } void static secp256k1_num_inc(secp256k1_num_t *r) { - mpz_add_ui(r->bn, r->bn, 1); + mp_limb_t ret = mpn_add_1(r->data, r->data, r->limbs, (mp_limb_t)1); + if (ret) { + assert(r->limbs < 2*NUM_LIMBS); + r->data[r->limbs++] = ret; + } } void static secp256k1_num_set_hex(secp256k1_num_t *r, const char *a, int alen) { - char *str = (char*)malloc(alen+1); - memcpy(str, a, alen); - str[alen] = 0; - mpz_set_str(r->bn, str, 16); - free(str); + static const unsigned char cvt[256] = { + 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,0,0, + 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, + 0, 1, 2, 3, 4, 5, 6,7,8,9,0,0,0,0,0,0, + 0,10,11,12,13,14,15,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,10,11,12,13,14,15,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, 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, 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, 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,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,0,0,0 + }; + char num[257] = {}; + for (int i=0; ilimbs = mpn_set_str(r->data, num, alen, 16); + while (r->limbs > 1 && r->data[r->limbs-1] == 0) r->limbs--; } -void static secp256k1_num_get_hex(char *r, int *rlen, const secp256k1_num_t *a) { - int len = mpz_sizeinbase(a->bn, 16) + 2; - if (*rlen < len) { - *rlen = len; - return; +void static secp256k1_num_get_hex(char *r, int rlen, const secp256k1_num_t *a) { + static const unsigned char cvt[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; + unsigned char *tmp = malloc(257); + mp_size_t len = mpn_get_str(tmp, 16, (mp_limb_t*)a->data, a->limbs); + assert(len <= rlen); + for (int i=0; i= 0); + assert(rlen-len+i < rlen); + assert(tmp[i] >= 0); + assert(tmp[i] < 16); + r[rlen-len+i] = cvt[tmp[i]]; } - mpz_get_str(r, 16, a->bn); - *rlen = len; + for (int i=0; i= 0); + assert(i < rlen); + r[i] = cvt[0]; + } + free(tmp); } void static secp256k1_num_split(secp256k1_num_t *rl, secp256k1_num_t *rh, const secp256k1_num_t *a, int bits) { - mpz_t tmp; - mpz_init_set_ui(tmp,1); - mpz_mul_2exp(tmp, tmp, bits); - mpz_sub_ui(tmp,tmp,1); - mpz_and(rl->bn, a->bn, tmp); - mpz_clear(tmp); - mpz_fdiv_q_2exp(rh->bn, a->bn, bits); + assert(bits > 0); + rh->neg = a->neg; + if (bits >= a->limbs * GMP_NUMB_BITS) { + *rl = *a; + rh->limbs = 1; + rh->data[0] = 0; + return; + } + rl->limbs = 0; + rl->neg = a->neg; + int left = bits; + while (left >= GMP_NUMB_BITS) { + rl->data[rl->limbs] = a->data[rl->limbs]; + rl->limbs++; + left -= GMP_NUMB_BITS; + } + if (left == 0) { + mpn_copyi(rh->data, a->data + rl->limbs, a->limbs - rl->limbs); + rh->limbs = a->limbs - rl->limbs; + } else { + mpn_rshift(rh->data, a->data + rl->limbs, a->limbs - rl->limbs, left); + rh->limbs = a->limbs - rl->limbs; + while (rh->limbs>1 && rh->data[rh->limbs-1]==0) rh->limbs--; + } + if (left > 0) { + rl->data[rl->limbs] = a->data[rl->limbs] & ((((mp_limb_t)1) << left) - 1); + rl->limbs++; + } + while (rl->limbs>1 && rl->data[rl->limbs-1]==0) rl->limbs--; } void static secp256k1_num_negate(secp256k1_num_t *r) { - mpz_neg(r->bn, r->bn); + r->neg ^= 1; } void static secp256k1_num_set_rand(secp256k1_num_t *r, const secp256k1_num_t *a) { - mpz_urandomm(r->bn, secp256k1_num_state.rng, a->bn); + mpn_random(r->data, a->limbs); + r->limbs = a->limbs; + r->neg = 0; + secp256k1_num_mod(r, r, a); } #endif diff --git a/src/impl/num_openssl.h b/src/impl/num_openssl.h index 93b26d7db8..27c9b11cae 100644 --- a/src/impl/num_openssl.h +++ b/src/impl/num_openssl.h @@ -125,17 +125,14 @@ void static secp256k1_num_set_hex(secp256k1_num_t *r, const char *a, int alen) { free(str); } -void static secp256k1_num_get_hex(char *r, int *rlen, const secp256k1_num_t *a) { +void static secp256k1_num_get_hex(char *r, int rlen, const secp256k1_num_t *a) { char *str = BN_bn2hex(&a->bn); - int len = strlen(str) + 1; - if (len > *rlen) { - *rlen = strlen(str); - OPENSSL_free(str); - return; - } - memcpy(r, str, len); + int len = strlen(str); + assert(rlen >= len); + for (int i=0; i +#define NUM_LIMBS ((256+GMP_NUMB_BITS-1)/GMP_NUMB_BITS) + typedef struct { - mpz_t bn; + mp_limb_t data[2*NUM_LIMBS]; + int neg; + int limbs; } secp256k1_num_t; #endif diff --git a/src/tests.c b/src/tests.c index 1d5b48cdfc..62f27938a3 100644 --- a/src/tests.c +++ b/src/tests.c @@ -104,7 +104,7 @@ void test_wnaf(const secp256k1_num_t *number, int w) { secp256k1_num_init(&t); secp256k1_num_set_int(&x, 0); secp256k1_num_set_int(&two, 2); - int wnaf[1024]; + int wnaf[257]; int bits = secp256k1_ecmult_wnaf(wnaf, number, w); int zeroes = -1; for (int i=bits-1; i>=0; i--) { @@ -134,7 +134,7 @@ void test_run_wnaf() { secp256k1_num_init(&range); secp256k1_num_init(&min); secp256k1_num_init(&n); - secp256k1_num_set_hex(&range, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 256); + secp256k1_num_set_hex(&range, "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 66); secp256k1_num_copy(&min, &range); secp256k1_num_shift(&min, 1); secp256k1_num_negate(&min);