diff --git a/src/impl/ecdsa.h b/src/impl/ecdsa.h index d5820141e1..1e98a75aef 100644 --- a/src/impl/ecdsa.h +++ b/src/impl/ecdsa.h @@ -96,7 +96,7 @@ int static secp256k1_ecdsa_sig_recompute(secp256k1_num_t *r2, const secp256k1_ec 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, r2, &c->order); + secp256k1_num_mod(r2, &c->order); ret = 1; } secp256k1_num_free(&sn); @@ -125,12 +125,12 @@ int static secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_ secp256k1_fe_normalize(&rx); secp256k1_fe_get_b32(b, &rx); secp256k1_num_set_bin(&sig->r, b, 32); - secp256k1_num_mod(&sig->r, &sig->r, &c->order); + secp256k1_num_mod(&sig->r, &c->order); secp256k1_num_t n; 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(&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/group.h b/src/impl/group.h index a0f02d34e1..b2ff24515d 100644 --- a/src/impl/group.h +++ b/src/impl/group.h @@ -298,10 +298,10 @@ void static secp256k1_gej_split_exp(secp256k1_num_t *r1, secp256k1_num_t *r2, co 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_mod(&check, &c->order); secp256k1_num_add(&check, &check, &c->order); - secp256k1_num_mod(&check, &check, &c->order); - secp256k1_num_mod(&a2, &a2, &c->order); + secp256k1_num_mod(&check, &c->order); + secp256k1_num_mod(&a2, &c->order); assert(secp256k1_num_cmp(&check, &a2) == 0); secp256k1_num_free(&check); secp256k1_num_free(&a2); diff --git a/src/impl/num_gmp.h b/src/impl/num_gmp.h index ebb4695fab..a43be1f7cb 100644 --- a/src/impl/num_gmp.h +++ b/src/impl/num_gmp.h @@ -70,20 +70,16 @@ void static secp256k1_num_set_int(secp256k1_num_t *r, int a) { 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); +void static secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { + secp256k1_num_sanity(r); + secp256k1_num_sanity(m); - 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; + if (r->limbs >= m->limbs) { + mp_limb_t t[2*NUM_LIMBS]; + mpn_tdiv_qr(t, r->data, 0, r->data, r->limbs, m->data, m->limbs); + r->limbs = m->limbs; + while (r->limbs > 1 && r->data[r->limbs-1]==0) r->limbs--; + r->neg ^= m->neg; } } @@ -281,9 +277,8 @@ void static secp256k1_num_div(secp256k1_num_t *r, const secp256k1_num_t *a, cons } 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); + secp256k1_num_mul(r, a, b); + secp256k1_num_mod(r, m); } @@ -394,7 +389,7 @@ void static secp256k1_num_set_rand(secp256k1_num_t *r, const secp256k1_num_t *a) mpn_random(r->data, a->limbs); r->limbs = a->limbs; r->neg = 0; - secp256k1_num_mod(r, r, a); + secp256k1_num_mod(r, a); } #endif diff --git a/src/impl/num_openssl.h b/src/impl/num_openssl.h index 27c9b11cae..cb3f951ba2 100644 --- a/src/impl/num_openssl.h +++ b/src/impl/num_openssl.h @@ -80,9 +80,9 @@ void static secp256k1_num_div(secp256k1_num_t *r, const secp256k1_num_t *a, cons BN_CTX_free(ctx); } -void static secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) { +void static secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { BN_CTX *ctx = BN_CTX_new(); - BN_nnmod(&r->bn, &a->bn, &b->bn, ctx); + BN_nnmod(&r->bn, &r->bn, &m->bn, ctx); BN_CTX_free(ctx); } diff --git a/src/num.h b/src/num.h index 9c571578cb..060ea64744 100644 --- a/src/num.h +++ b/src/num.h @@ -11,33 +11,89 @@ #error "Please select num implementation" #endif +/** Initialize the num module. */ void static secp256k1_num_start(void); + +/** De-initialize the num module. */ void static secp256k1_num_stop(void); + +/** Initialize a number. */ void static secp256k1_num_init(secp256k1_num_t *r); + +/** Free a number. */ void static secp256k1_num_free(secp256k1_num_t *r); + +/** Copy a number. */ void static secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a); + +/** Convert a number's absolute value to a binary big-endian string. + * There must be enough place. */ void static secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a); + +/** Set a number to the value of a binary big-endian string. */ void static secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen); + +/** Set a number equal to a (signed) integer. */ void static secp256k1_num_set_int(secp256k1_num_t *r, int a); + +/** Compute a modular inverse. The input must be less than the modulus. */ void static secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m); + +/** Multiply two numbers modulo another. */ 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); + +/** Compare the absolute value of two numbers. */ int static secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b); + +/** Add two (signed) numbers. */ void static secp256k1_num_add(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); + +/** Subtract two (signed) numbers. */ void static secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); + +/** Multiply two (signed) numbers. */ void static secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); + +/** Divide two (signed) numbers. */ void static secp256k1_num_div(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); -void static secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); + +/** Replace a number by its modulus. */ +void static secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m); + +/** Calculate the number of bits in (the absolute value of) a number. */ int static secp256k1_num_bits(const secp256k1_num_t *a); + +/** Right-shift the passed number by bits bits, and return those bits. */ int static secp256k1_num_shift(secp256k1_num_t *r, int bits); + +/** Check whether a number is zero. */ int static secp256k1_num_is_zero(const secp256k1_num_t *a); + +/** Check whether a number is odd. */ int static secp256k1_num_is_odd(const secp256k1_num_t *a); + +/** Check whether a number is strictly negative. */ int static secp256k1_num_is_neg(const secp256k1_num_t *a); + +/** Check whether a particular bit is set in a number. */ int static secp256k1_num_get_bit(const secp256k1_num_t *a, int pos); + +/** Increase a number by 1. */ void static secp256k1_num_inc(secp256k1_num_t *r); + +/** Set a number equal to the value of a hex string (unsigned). */ void static secp256k1_num_set_hex(secp256k1_num_t *r, const char *a, int alen); + +/** Convert (the absolute value of) a number to a hexadecimal string. */ void static secp256k1_num_get_hex(char *r, int rlen, const secp256k1_num_t *a); + +/** Split a number into a low and high part. */ void static secp256k1_num_split(secp256k1_num_t *rl, secp256k1_num_t *rh, const secp256k1_num_t *a, int bits); + +/** Change a number's sign. */ void static secp256k1_num_negate(secp256k1_num_t *r); + +/** Set a number to an random value below the passed number. */ void static secp256k1_num_set_rand(secp256k1_num_t *r, const secp256k1_num_t *a); #endif diff --git a/src/tests.c b/src/tests.c index 62f27938a3..51f42f6354 100644 --- a/src/tests.c +++ b/src/tests.c @@ -46,7 +46,7 @@ void test_run_ecmult_chain() { 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, &ge, order); + secp256k1_num_mod(&ge, order); // modify xn and gn secp256k1_num_mod_mul(&xn, &xn, &xf, order); secp256k1_num_mod_mul(&gn, &gn, &gf, order);