diff --git a/src/bench.cpp b/src/bench.cpp index d86025f64b..ca7f789bda 100644 --- a/src/bench.cpp +++ b/src/bench.cpp @@ -12,6 +12,7 @@ int main() { secp256k1_num_start(); secp256k1_fe_start(); secp256k1_ge_start(); + secp256k1_ecmult_start(); secp256k1_fe_t x; const secp256k1_num_t *order = &secp256k1_ge_consts->order; @@ -39,6 +40,7 @@ int main() { secp256k1_num_free(&s); secp256k1_num_free(&m); + secp256k1_ecmult_stop(); secp256k1_ge_stop(); secp256k1_fe_stop(); secp256k1_num_stop(); diff --git a/src/ecdsa.cpp b/src/ecdsa.cpp index 6ef1fab6d3..97ff6d6f72 100644 --- a/src/ecdsa.cpp +++ b/src/ecdsa.cpp @@ -79,7 +79,7 @@ bool Signature::RecomputeR(secp256k1_num_t &r2, const secp256k1_gej_t &pubkey, c secp256k1_num_mod_inverse(&sn, &s, &c.order); secp256k1_num_mod_mul(&u1, &sn, &message, &c.order); secp256k1_num_mod_mul(&u2, &sn, &r, &c.order); - secp256k1_gej_t pr; ECMult(pr, pubkey, u2, u1); + secp256k1_gej_t pr; secp256k1_ecmult(&pr, &pubkey, &u2, &u1); if (!secp256k1_gej_is_infinity(&pr)) { secp256k1_fe_t xr; secp256k1_gej_get_x(&xr, &pr); secp256k1_fe_normalize(&xr); @@ -107,7 +107,7 @@ bool Signature::Sign(const secp256k1_num_t &seckey, const secp256k1_num_t &messa const secp256k1_ge_consts_t &c = *secp256k1_ge_consts; secp256k1_gej_t rp; - ECMultBase(rp, nonce); + secp256k1_ecmult_gen(&rp, &nonce); secp256k1_fe_t rx; secp256k1_gej_get_x(&rx, &rp); unsigned char b[32]; diff --git a/src/ecmult.cpp b/src/ecmult.cpp index 2493f68659..2c0cf8750f 100644 --- a/src/ecmult.cpp +++ b/src/ecmult.cpp @@ -12,245 +12,221 @@ // exponentially larger precomputed tables. WINDOW_G == 13 results in 640 KiB. #define WINDOW_G 14 -namespace secp256k1 { +extern "C" { -template class WNAFPrecompJac { -private: - secp256k1_gej_t pre[1 << (W-2)]; +/** Fill a table 'pre' with precomputed odd multiples of a. W determines the size of the table. + * pre will contains the values [1*a,3*a,5*a,...,(2^(w-1)-1)*a], so it needs place for + * 2^(w-2) entries. + * + * There are two versions of this function: + * - secp256k1_ecmult_precomp_wnaf_gej, which operates on group elements in jacobian notation, + * fast to precompute, but slower to use in later additions. + * - secp256k1_ecmult_precomp_wnaf_ge, which operates on group elements in affine notations, + * (much) slower to precompute, but a bit faster to use in later additions. + * To compute a*P + b*G, we use the jacobian version for P, and the affine version for G, as + * G is constant, so it only needs to be done once in advance. + */ +void static secp256k1_ecmult_table_precomp_gej(secp256k1_gej_t *pre, const secp256k1_gej_t *a, int w) { + pre[0] = *a; + secp256k1_gej_t d; secp256k1_gej_double(&d, &pre[0]); + for (int i=1; i<(1 << (w-2)); i++) + secp256k1_gej_add(&pre[i], &d, &pre[i-1]); +} -public: - WNAFPrecompJac() {} - - void Build(const secp256k1_gej_t &base) { - pre[0] = base; - secp256k1_gej_t d; secp256k1_gej_double(&d, &pre[0]); - for (int i=1; i<(1 << (W-2)); i++) - secp256k1_gej_add(&pre[i], &d, &pre[i-1]); +void static secp256k1_ecmult_table_precomp_ge(secp256k1_ge_t *pre, const secp256k1_ge_t *a, int w) { + pre[0] = *a; + secp256k1_gej_t x; secp256k1_gej_set_ge(&x, a); + secp256k1_gej_t d; secp256k1_gej_double(&d, &x); + for (int i=1; i<(1 << (w-2)); i++) { + secp256k1_gej_add_ge(&x, &d, &pre[i-1]); + secp256k1_ge_set_gej(&pre[i], &x); } +} - WNAFPrecompJac(const secp256k1_gej_t &base) { - Build(base); - } +/** The number of entries a table with precomputed multiples needs to have. */ +#define ECMULT_TABLE_SIZE(w) (1 << ((w)-2)) - void Get(secp256k1_gej_t &out, int exp) const { - assert((exp & 1) == 1); - assert(exp >= -((1 << (W-1)) - 1)); - assert(exp <= ((1 << (W-1)) - 1)); - if (exp > 0) { - out = pre[(exp-1)/2]; - } else { - secp256k1_gej_neg(&out, &pre[(-exp-1)/2]); - } - } -}; +/** The following two macro retrieves a particular odd multiple from a table + * of precomputed multiples. */ +#define ECMULT_TABLE_GET(r,pre,n,w,neg) do { \ + assert(((n) & 1) == 1); \ + assert((n) >= -((1 << ((w)-1)) - 1)); \ + assert((n) <= ((1 << ((w)-1)) - 1)); \ + if ((n) > 0) \ + *(r) = (pre)[((n)-1)/2]; \ + else \ + (neg)((r), &(pre)[(-(n)-1)/2]); \ +} while(0) -template class WNAFPrecompAff { -private: - secp256k1_ge_t pre[1 << (W-2)]; +#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg) +#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg) -public: - WNAFPrecompAff() {} - - void Build(const secp256k1_ge_t &base) { - pre[0] = base; - secp256k1_gej_t x; secp256k1_gej_set_ge(&x, &base); - secp256k1_gej_t d; secp256k1_gej_double(&d, &x); - for (int i=1; i<(1 << (W-2)); i++) { - secp256k1_gej_add_ge(&x, &d, &pre[i-1]); - secp256k1_ge_set_gej(&pre[i], &x); - } - } - - WNAFPrecompAff(const secp256k1_ge_t &base) { - Build(base); - } - - void Get(secp256k1_ge_t &out, int exp) const { - assert((exp & 1) == 1); - assert(exp >= -((1 << (W-1)) - 1)); - assert(exp <= ((1 << (W-1)) - 1)); - if (exp > 0) { - out = pre[(exp-1)/2]; - } else { - secp256k1_ge_neg(&out, &pre[(-exp-1)/2]); - } - } -}; - -template class WNAF { -private: - int naf[B+1]; - int used; - - void PushNAF(int num, int zeroes) { - assert(used < B+1); - for (int i=0; i= 0 && pos < used); - return naf[pos]; - } - - std::string ToString() { - std::stringstream ss; - ss << "("; - for (int i=0; i wpg; - WNAFPrecompAff wpg128; +typedef struct { + secp256k1_ge_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; // odd multiples of the generator + secp256k1_ge_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; // odd multiples of 2^128*generator secp256k1_ge_t prec[64][16]; // prec[j][i] = 16^j * (i+1) * G secp256k1_ge_t fin; // -(sum(prec[j][0], j=0..63)) +} secp256k1_ecmult_consts_t; - ECMultConsts() { - const secp256k1_ge_t &g = secp256k1_ge_consts->g; - secp256k1_gej_t g128j; secp256k1_gej_set_ge(&g128j, &g); - for (int i=0; i<128; i++) - secp256k1_gej_double(&g128j, &g128j); - secp256k1_ge_t g128; secp256k1_ge_set_gej(&g128, &g128j); - wpg.Build(g); - wpg128.Build(g128); - secp256k1_gej_t gg; secp256k1_gej_set_ge(&gg, &g); - secp256k1_ge_t ad = g; - secp256k1_gej_t fn; secp256k1_gej_set_infinity(&fn); - for (int j=0; j<64; j++) { - secp256k1_ge_set_gej(&prec[j][0], &gg); - secp256k1_gej_add(&fn, &fn, &gg); - for (int i=1; i<16; i++) { - secp256k1_gej_add_ge(&gg, &gg, &ad); - secp256k1_ge_set_gej(&prec[j][i], &gg); - } - ad = prec[j][15]; +static secp256k1_ecmult_consts_t *secp256k1_ecmult_consts = NULL; + +static void secp256k1_ecmult_start(void) { + if (secp256k1_ecmult_consts != NULL) + return; + + secp256k1_ecmult_consts_t *ret = (secp256k1_ecmult_consts_t*)malloc(sizeof(secp256k1_ecmult_consts_t)); + secp256k1_ecmult_consts = ret; + + // get the generator + const secp256k1_ge_t *g = &secp256k1_ge_consts->g; + + // calculate 2^128*generator + secp256k1_gej_t g_128j; secp256k1_gej_set_ge(&g_128j, g); + for (int i=0; i<128; i++) + secp256k1_gej_double(&g_128j, &g_128j); + secp256k1_ge_t g_128; secp256k1_ge_set_gej(&g_128, &g_128j); + + // precompute the tables with odd multiples + secp256k1_ecmult_table_precomp_ge(ret->pre_g, g, WINDOW_G); + secp256k1_ecmult_table_precomp_ge(ret->pre_g_128, &g_128, WINDOW_G); + + // compute prec and fin + secp256k1_gej_t gg; secp256k1_gej_set_ge(&gg, g); + secp256k1_ge_t ad = *g; + secp256k1_gej_t fn; secp256k1_gej_set_infinity(&fn); + for (int j=0; j<64; j++) { + secp256k1_ge_set_gej(&ret->prec[j][0], &gg); + secp256k1_gej_add(&fn, &fn, &gg); + for (int i=1; i<16; i++) { + secp256k1_gej_add_ge(&gg, &gg, &ad); + secp256k1_ge_set_gej(&ret->prec[j][i], &gg); } - secp256k1_ge_set_gej(&fin, &fn); - secp256k1_ge_neg(&fin, &fin); + ad = ret->prec[j][15]; } -}; - -const ECMultConsts &GetECMultConsts() { - static const ECMultConsts ecmult_consts; - return ecmult_consts; + secp256k1_ge_set_gej(&ret->fin, &fn); + secp256k1_ge_neg(&ret->fin, &ret->fin); } -void ECMultBase(secp256k1_gej_t &out, const secp256k1_num_t &gn) { +static void secp256k1_ecmult_stop(void) { + if (secp256k1_ecmult_consts == NULL) + return; + + free(secp256k1_ecmult_consts); + secp256k1_ecmult_consts = NULL; +} + +/** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits), + * with the following guarantees: + * - each wnaf[i] is either 0, or an odd integer between -(1<<(w-1) - 1) and (1<<(w-1) - 1) + * - two non-zero entries in wnaf are separated by at least w-1 zeroes. + * - the index of the highest non-zero entry in wnaf (=return value-1) is at most bits, where + * bits is the number of bits necessary to represent the absolute value of the input. + */ +static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_num_t *a, int w) { + int ret = 0; + int zeroes = 0; + secp256k1_num_t x; + secp256k1_num_init(&x); + secp256k1_num_copy(&x, a); + int sign = 1; + if (secp256k1_num_is_neg(&x)) { + sign = -1; + secp256k1_num_negate(&x); + } + while (!secp256k1_num_is_zero(&x)) { + while (!secp256k1_num_is_odd(&x)) { + zeroes++; + secp256k1_num_shift(&x, 1); + } + int word = secp256k1_num_shift(&x, w); + while (zeroes) { + wnaf[ret++] = 0; + zeroes--; + } + if (word & (1 << (w-1))) { + secp256k1_num_inc(&x); + wnaf[ret++] = sign * (word - (1 << w)); + } else { + wnaf[ret++] = sign * word; + } + zeroes = w-1; + } + secp256k1_num_free(&x); + return ret; +} + +void static secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_num_t *gn) { secp256k1_num_t n; secp256k1_num_init(&n); - secp256k1_num_copy(&n, &gn); - const ECMultConsts &c = GetECMultConsts(); - secp256k1_gej_set_ge(&out, &c.prec[0][secp256k1_num_shift(&n, 4)]); - for (int j=1; j<64; j++) { - secp256k1_gej_add_ge(&out, &out, &c.prec[j][secp256k1_num_shift(&n, 4)]); - } + secp256k1_num_copy(&n, gn); + const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts; + secp256k1_gej_set_ge(r, &c->prec[0][secp256k1_num_shift(&n, 4)]); + for (int j=1; j<64; j++) + secp256k1_gej_add_ge(r, r, &c->prec[j][secp256k1_num_shift(&n, 4)]); secp256k1_num_free(&n); - secp256k1_gej_add_ge(&out, &out, &c.fin); + secp256k1_gej_add_ge(r, r, &c->fin); } -void ECMult(secp256k1_gej_t &out, const secp256k1_gej_t &a, const secp256k1_num_t &an, const secp256k1_num_t &gn) { - secp256k1_num_t an1, an2; - secp256k1_num_t gn1, gn2; +void static secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_num_t *na, const secp256k1_num_t *ng) { + const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts; - secp256k1_num_init(&an1); - secp256k1_num_init(&an2); - secp256k1_num_init(&gn1); - secp256k1_num_init(&gn2); + secp256k1_num_t na_1, na_lam; + secp256k1_num_t ng_1, ng_128; + secp256k1_num_init(&na_1); + secp256k1_num_init(&na_lam); + secp256k1_num_init(&ng_1); + secp256k1_num_init(&ng_128); - secp256k1_gej_split_exp(&an1, &an2, &an); -// printf("an=%s\n", an.ToString().c_str()); -// printf("an1=%s\n", an1.ToString().c_str()); -// printf("an2=%s\n", an2.ToString().c_str()); -// printf("an1.len=%i\n", an1.GetBits()); -// printf("an2.len=%i\n", an2.GetBits()); - secp256k1_num_split(&gn1, &gn2, &gn, 128); + // 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(&na_1, &na_lam, na); + // 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); - WNAF<128> wa1(an1, WINDOW_A); - WNAF<128> wa2(an2, WINDOW_A); - WNAF<128> wg1(gn1, WINDOW_G); - WNAF<128> wg2(gn2, WINDOW_G); - secp256k1_gej_t a2; secp256k1_gej_mul_lambda(&a2, &a); - WNAFPrecompJac wpa1(a); - WNAFPrecompJac wpa2(a2); - const ECMultConsts &c = GetECMultConsts(); + // build wnaf representation for na_1, na_lam, ng_1, ng_128 + int wnaf_na_1[129]; int bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A); + int wnaf_na_lam[129]; int bits_na_lam = secp256k1_ecmult_wnaf(wnaf_na_lam, &na_lam, WINDOW_A); + int wnaf_ng_1[129]; int bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G); + int wnaf_ng_128[129]; int bits_ng_128 = secp256k1_ecmult_wnaf(wnaf_ng_128, &ng_128, WINDOW_G); - int size_a1 = wa1.GetSize(); - int size_a2 = wa2.GetSize(); - int size_g1 = wg1.GetSize(); - int size_g2 = wg2.GetSize(); - int size = std::max(std::max(size_a1, size_a2), std::max(size_g1, size_g2)); + // calculate a_lam = a*lambda + secp256k1_gej_t a_lam; secp256k1_gej_mul_lambda(&a_lam, a); - out; secp256k1_gej_set_infinity(&out); + // calculate odd multiples of a and a_lam + secp256k1_gej_t pre_a_1[ECMULT_TABLE_SIZE(WINDOW_A)], pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)]; + secp256k1_ecmult_table_precomp_gej(pre_a_1, a, WINDOW_A); + secp256k1_ecmult_table_precomp_gej(pre_a_lam, &a_lam, WINDOW_A); + + int bits = std::max(std::max(bits_na_1, bits_na_lam), std::max(bits_ng_1, bits_ng_128)); + + secp256k1_gej_set_infinity(r); secp256k1_gej_t tmpj; secp256k1_ge_t tmpa; - for (int i=size-1; i>=0; i--) { - secp256k1_gej_double(&out, &out); - int nw; - if (i < size_a1 && (nw = wa1.Get(i))) { - wpa1.Get(tmpj, nw); - secp256k1_gej_add(&out, &out, &tmpj); + for (int i=bits-1; i>=0; i--) { + secp256k1_gej_double(r, r); + int n; + if (i < bits_na_1 && (n = wnaf_na_1[i])) { + ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_1, n, WINDOW_A); + secp256k1_gej_add(r, r, &tmpj); } - if (i < size_a2 && (nw = wa2.Get(i))) { - wpa2.Get(tmpj, nw); - secp256k1_gej_add(&out, &out, &tmpj); + if (i < bits_na_lam && (n = wnaf_na_lam[i])) { + ECMULT_TABLE_GET_GEJ(&tmpj, pre_a_lam, n, WINDOW_A); + secp256k1_gej_add(r, r, &tmpj); } - if (i < size_g1 && (nw = wg1.Get(i))) { - c.wpg.Get(tmpa, nw); - secp256k1_gej_add_ge(&out, &out, &tmpa); + if (i < bits_ng_1 && (n = wnaf_ng_1[i])) { + ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G); + secp256k1_gej_add_ge(r, r, &tmpa); } - if (i < size_g2 && (nw = wg2.Get(i))) { - c.wpg128.Get(tmpa, nw); - secp256k1_gej_add_ge(&out, &out, &tmpa); + if (i < bits_ng_128 && (n = wnaf_ng_128[i])) { + ECMULT_TABLE_GET_GE(&tmpa, c->pre_g_128, n, WINDOW_G); + secp256k1_gej_add_ge(r, r, &tmpa); } } - secp256k1_num_free(&an1); - secp256k1_num_free(&an2); - secp256k1_num_free(&gn1); - secp256k1_num_free(&gn2); + secp256k1_num_free(&na_1); + secp256k1_num_free(&na_lam); + secp256k1_num_free(&ng_1); + secp256k1_num_free(&ng_128); } } diff --git a/src/ecmult.h b/src/ecmult.h index b7c028a7f3..1f7ac9941e 100644 --- a/src/ecmult.h +++ b/src/ecmult.h @@ -4,10 +4,15 @@ #include "num.h" #include "group.h" -namespace secp256k1 { +extern "C" { -void ECMultBase(secp256k1_gej_t &out, const secp256k1_num_t &gn); -void ECMult(secp256k1_gej_t &out, const secp256k1_gej_t &a, const secp256k1_num_t &an, const secp256k1_num_t &gn); +static void secp256k1_ecmult_start(void); +static void secp256k1_ecmult_stop(void); + +/** Multiply with the generator: R = a*G */ +static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_num_t *a); +/** 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); } diff --git a/src/num_openssl_.cpp b/src/num_openssl_.cpp deleted file mode 100644 index cd2673ea53..0000000000 --- a/src/num_openssl_.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include -#include -#include -#include -#include - -#include "num_openssl.h" - -namespace secp256k1 { - -class Context { -private: - BN_CTX *ctx; - - operator BN_CTX*() { - return ctx; - } - - friend class Number; -public: - Context() { - ctx = BN_CTX_new(); - } - - ~Context() { - BN_CTX_free(ctx); - } -}; - -Number::operator const BIGNUM*() const { - return &b; -} - -Number::operator BIGNUM*() { - return &b; -} - -Number::Number() { - BN_init(*this); -} - -Number::~Number() { - BN_free(*this); -} - -Number::Number(const unsigned char *bin, int len) { - BN_init(*this); - SetBytes(bin,len); -} - -void Number::SetNumber(const Number &x) { - BN_copy(*this, x); -} - -Number::Number(const Number &x) { - BN_init(*this); - BN_copy(*this, x); -} - -Number &Number::operator=(const Number &x) { - BN_copy(*this, x); - return *this; -} - -void Number::SetBytes(const unsigned char *bin, int len) { - BN_bin2bn(bin, len, *this); -} - -void Number::GetBytes(unsigned char *bin, int len) { - int size = BN_num_bytes(*this); - assert(size <= len); - memset(bin,0,len); - BN_bn2bin(*this, bin + len - size); -} - -void Number::SetInt(int x) { - if (x >= 0) { - BN_set_word(*this, x); - } else { - BN_set_word(*this, -x); - BN_set_negative(*this, 1); - } -} - -void Number::SetModInverse(const Number &x, const Number &m) { - Context ctx; - BN_mod_inverse(*this, x, m, ctx); -} - -void Number::SetModMul(const Number &a, const Number &b, const Number &m) { - Context ctx; - BN_mod_mul(*this, a, b, m, ctx); -} - -void Number::SetAdd(const Number &a1, const Number &a2) { - BN_add(*this, a1, a2); -} - -void Number::SetSub(const Number &a1, const Number &a2) { - BN_sub(*this, a1, a2); -} - -void Number::SetMult(const Number &a1, const Number &a2) { - Context ctx; - BN_mul(*this, a1, a2, ctx); -} - -void Number::SetDiv(const Number &a1, const Number &a2) { - Context ctx; - BN_div(*this, NULL, a1, a2, ctx); -} - -void Number::SetMod(const Number &a, const Number &m) { - Context ctx; - BN_nnmod(*this, a, m, ctx); -} - -int Number::Compare(const Number &a) const { - return BN_cmp(*this, a); -} - -int Number::GetBits() const { - return BN_num_bits(*this); -} - -int Number::ShiftLowBits(int bits) { - BIGNUM *bn = *this; - int ret = BN_is_zero(bn) ? 0 : bn->d[0] & ((1 << bits) - 1); - BN_rshift(*this, *this, bits); - return ret; -} - -bool Number::IsZero() const { - return BN_is_zero((const BIGNUM*)*this); -} - -bool Number::IsOdd() const { - return BN_is_odd((const BIGNUM*)*this); -} - -bool Number::CheckBit(int pos) const { - return BN_is_bit_set((const BIGNUM*)*this, pos); -} - -bool Number::IsNeg() const { - return BN_is_negative((const BIGNUM*)*this); -} - -void Number::Negate() { - BN_set_negative(*this, !IsNeg()); -} - -void Number::Shift1() { - BN_rshift1(*this,*this); -} - -void Number::Inc() { - BN_add_word(*this,1); -} - -void Number::SetHex(const std::string &str) { - BIGNUM *bn = *this; - BN_hex2bn(&bn, str.c_str()); -} - -void Number::SetPseudoRand(const Number &max) { - BN_pseudo_rand_range(*this, max); -} - -void Number::SplitInto(int bits, Number &low, Number &high) const { - BN_copy(low, *this); - BN_mask_bits(low, bits); - BN_rshift(high, *this, bits); -} - -std::string Number::ToString() const { - char *str = BN_bn2hex(*this); - std::string ret(str); - OPENSSL_free(str); - return ret; -} - -} diff --git a/src/secp256k1.cpp b/src/secp256k1.cpp index a8d3860f63..8a614ded3b 100644 --- a/src/secp256k1.cpp +++ b/src/secp256k1.cpp @@ -11,10 +11,11 @@ extern "C" void secp256k1_start(void) { secp256k1_num_start(); secp256k1_fe_start(); secp256k1_ge_start(); - GetECMultConsts(); + secp256k1_ecmult_start(); } extern "C" void secp256k1_stop(void) { + secp256k1_ecmult_stop(); secp256k1_ge_stop(); secp256k1_fe_stop(); secp256k1_num_stop(); diff --git a/src/tests.cpp b/src/tests.cpp index ac3f673450..05f4371896 100644 --- a/src/tests.cpp +++ b/src/tests.cpp @@ -42,7 +42,7 @@ void test_run_ecmult_chain() { 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; - ECMult(x, x, xn, gn); + 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); @@ -59,7 +59,7 @@ void test_run_ecmult_chain() { assert(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0); } // redo the computation, but directly with the resulting ae and ge coefficients: - secp256k1_gej_t x2; ECMult(x2, a, ae, ge); + secp256k1_gej_t x2; secp256k1_ecmult(&x2, &a, &ae, &ge); char res2[132]; int resl2 = 132; secp256k1_gej_get_hex(res2, &resl2, &x2); assert(strcmp(res, res2) == 0); @@ -82,7 +82,7 @@ void test_point_times_order(const secp256k1_gej_t &point) { secp256k1_num_init(&zero); secp256k1_num_set_int(&zero, 0); secp256k1_gej_t res; - ECMult(res, point, *order, zero); // calc res = order * point + 0 * G; + secp256k1_ecmult(&res, &point, order, order); // calc res = order * point + order * G; assert(secp256k1_gej_is_infinity(&res)); secp256k1_num_free(&zero); } @@ -106,11 +106,12 @@ 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); - WNAF<1023> wnaf(number, w); + int wnaf[1024]; + int bits = secp256k1_ecmult_wnaf(wnaf, &number, w); int zeroes = -1; - for (int i=wnaf.GetSize()-1; i>=0; i--) { + for (int i=bits-1; i>=0; i--) { secp256k1_num_mul(&x, &x, &two); - int v = wnaf.Get(i); + int v = wnaf[i]; if (v) { assert(zeroes == -1 || zeroes >= w-1); // check that distance between non-zero elements is at least w-1 zeroes=0; @@ -157,7 +158,7 @@ void test_ecdsa_sign_verify() { secp256k1_num_init(&key); secp256k1_num_set_rand(&key, &c.order); secp256k1_num_init(&nonce); - secp256k1_gej_t pub; ECMultBase(pub, key); + secp256k1_gej_t pub; secp256k1_ecmult_gen(&pub, &key); Signature sig; do { secp256k1_num_set_rand(&nonce, &c.order); @@ -180,12 +181,14 @@ int main(void) { secp256k1_num_start(); secp256k1_fe_start(); secp256k1_ge_start(); + secp256k1_ecmult_start(); test_run_wnaf(); test_run_point_times_order(); test_run_ecmult_chain(); test_run_ecdsa_sign_verify(); + secp256k1_ecmult_stop(); secp256k1_ge_stop(); secp256k1_fe_stop(); secp256k1_num_stop();