mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-09 10:43:19 -05:00
Use GMP's low-level routines for num (mpn_)
This commit is contained in:
parent
a16c3a905b
commit
898cecb3b3
10 changed files with 382 additions and 116 deletions
2
Makefile
2
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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; i<alen; i++) {
|
||||
num[i] = cvt[a[i]];
|
||||
}
|
||||
r->limbs = 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<len; i++) {
|
||||
assert(rlen-len+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<rlen-len; i++) {
|
||||
assert(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
|
||||
|
|
|
@ -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<rlen-len; i++)
|
||||
r[i] = '0';
|
||||
memcpy(r+rlen-len, str, len);
|
||||
OPENSSL_free(str);
|
||||
*rlen = len;
|
||||
}
|
||||
|
||||
void static secp256k1_num_split(secp256k1_num_t *rl, secp256k1_num_t *rh, const secp256k1_num_t *a, int bits) {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef _SECP256K1_NUM_
|
||||
#define _SECP256K1_NUM_
|
||||
|
||||
#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"
|
||||
|
@ -33,7 +35,7 @@ int static secp256k1_num_is_neg(const secp256k1_num_t *a);
|
|||
int static secp256k1_num_get_bit(const secp256k1_num_t *a, int pos);
|
||||
void static secp256k1_num_inc(secp256k1_num_t *r);
|
||||
void static secp256k1_num_set_hex(secp256k1_num_t *r, const char *a, int alen);
|
||||
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);
|
||||
void static secp256k1_num_split(secp256k1_num_t *rl, secp256k1_num_t *rh, const secp256k1_num_t *a, int bits);
|
||||
void static secp256k1_num_negate(secp256k1_num_t *r);
|
||||
void static secp256k1_num_set_rand(secp256k1_num_t *r, const secp256k1_num_t *a);
|
||||
|
|
|
@ -3,8 +3,12 @@
|
|||
|
||||
#include <gmp.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue