diff --git a/src/impl/group.h b/src/impl/group.h index b2ff24515d..f7b3c516d1 100644 --- a/src/impl/group.h +++ b/src/impl/group.h @@ -299,8 +299,6 @@ void static secp256k1_gej_split_exp(secp256k1_num_t *r1, secp256k1_num_t *r2, co secp256k1_num_mul(&check, r2, &c->lambda); secp256k1_num_add(&check, &check, r1); secp256k1_num_mod(&check, &c->order); - secp256k1_num_add(&check, &check, &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); diff --git a/src/impl/num_gmp.h b/src/impl/num_gmp.h index 0d6353d8ee..a7e0011397 100644 --- a/src/impl/num_gmp.h +++ b/src/impl/num_gmp.h @@ -64,6 +64,22 @@ void static secp256k1_num_set_int(secp256k1_num_t *r, int a) { r->data[0] = (a < 0) ? -a : a; } +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_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { secp256k1_num_sanity(r); secp256k1_num_sanity(m); @@ -73,7 +89,11 @@ void static secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) { 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; + } + + if (r->neg && (r->limbs > 1 || r->data[0] != 0)) { + secp256k1_num_sub_abs(r, m, r); + r->neg = 0; } } @@ -142,22 +162,6 @@ int static secp256k1_num_cmp(const secp256k1_num_t *a, const secp256k1_num_t *b) 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; diff --git a/src/num.h b/src/num.h index 633200cdf0..1604bf167a 100644 --- a/src/num.h +++ b/src/num.h @@ -51,7 +51,8 @@ void static secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, cons /** Divide two (signed) numbers. */ void static secp256k1_num_div(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b); -/** Replace a number by its modulus. */ +/** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1, + even if r was negative. */ 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. */