From e8c2a8ec9c47674e6e34d33d4598138f6f05be3b Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 11 Mar 2013 03:09:07 +0100 Subject: [PATCH] bugfixes and num-based Field::Inverse --- ecdsa.h | 2 +- ecmult.h | 25 +++++++++++------- field.h | 79 +++++++++++++++++++++++++++++++++---------------------- group.h | 23 ++++++++-------- num.h | 4 +-- num_gmp.h | 4 ++- 6 files changed, 80 insertions(+), 57 deletions(-) diff --git a/ecdsa.h b/ecdsa.h index 14f6b5f668d..bcd970df0b0 100644 --- a/ecdsa.h +++ b/ecdsa.h @@ -48,7 +48,7 @@ public: //GroupElemJac pr = pubkey; if (pr.IsInfinity()) return false; - FieldElem xr; pr.GetX(xr); + FieldElem xr; pr.GetX(ct, xr); unsigned char xrb[32]; xr.GetBytes(xrb); r2.SetBytes(xrb,32); r2.SetMod(ct,r2,c.order); } diff --git a/ecmult.h b/ecmult.h index 036a0142b38..f0fc4757ea9 100644 --- a/ecmult.h +++ b/ecmult.h @@ -7,8 +7,12 @@ #include "group.h" #include "num.h" +// optimal for 128-bit and 256-bit exponents #define WINDOW_A 5 -#define WINDOW_G 13 + +// larger numbers may result in slightly better performance, at the cost of +// exponentially larger precomputed tables. WINDOW_G == 13 results in 640 KiB. +#define WINDOW_G 14 namespace secp256k1 { @@ -19,18 +23,18 @@ private: public: WNAFPrecomp() {} - void Build(const G &base) { + void Build(Context &ctx, const G &base) { pre[0] = base; GroupElemJac x(base); GroupElemJac d; d.SetDouble(x); for (int i=1; i<(1 << (W-2)); i++) { x.SetAdd(d,pre[i-1]); - pre[i].SetJac(x); + pre[i].SetJac(ctx, x); } } - WNAFPrecomp(const G &base) { - Build(base); + WNAFPrecomp(Context &ctx, const G &base) { + Build(ctx, base); } void Get(G &out, int exp) const { @@ -113,13 +117,14 @@ public: WNAFPrecomp wpg128; ECMultConsts() { + Context ctx; const GroupElem &g = GetGroupConst().g; GroupElemJac g128j(g); for (int i=0; i<128; i++) g128j.SetDouble(g128j); - GroupElem g128; g128.SetJac(g128j); - wpg.Build(g); - wpg128.Build(g128); + GroupElem g128; g128.SetJac(ctx, g128j); + wpg.Build(ctx, g); + wpg128.Build(ctx, g128); } }; @@ -146,8 +151,8 @@ void ECMult(Context &ctx, GroupElemJac &out, const GroupElemJac &a, const Number WNAF<128> wg1(ct, gn1, WINDOW_G); WNAF<128> wg2(ct, gn2, WINDOW_G); GroupElemJac a2; a2.SetMulLambda(a); - WNAFPrecomp wpa1(a); - WNAFPrecomp wpa2(a2); + WNAFPrecomp wpa1(ct, a); + WNAFPrecomp wpa2(ct, a2); const ECMultConsts &c = GetECMultConsts(); int size_a1 = wa1.GetSize(); diff --git a/field.h b/field.h index c7f510e6d98..609a33baaed 100644 --- a/field.h +++ b/field.h @@ -308,38 +308,7 @@ public: } /** Set this to be the (modular) inverse of another FieldElem. Magnitude=1 */ - void SetInverse(const FieldElem &a) { - // calculate a^p, with p={45,63,1019,1023} - FieldElem a2; a2.SetSquare(a); - FieldElem a3; a3.SetMult(a2,a); - FieldElem a4; a4.SetSquare(a2); - FieldElem a5; a5.SetMult(a4,a); - FieldElem a10; a10.SetSquare(a5); - FieldElem a11; a11.SetMult(a10,a); - FieldElem a21; a21.SetMult(a11,a10); - FieldElem a42; a42.SetSquare(a21); - FieldElem a45; a45.SetMult(a42,a3); - FieldElem a63; a63.SetMult(a42,a21); - FieldElem a126; a126.SetSquare(a63); - FieldElem a252; a252.SetSquare(a126); - FieldElem a504; a504.SetSquare(a252); - FieldElem a1008; a1008.SetSquare(a504); - FieldElem a1019; a1019.SetMult(a1008,a11); - FieldElem a1023; a1023.SetMult(a1019,a4); - FieldElem x = a63; - for (int i=0; i<21; i++) { - for (int j=0; j<10; j++) x.SetSquare(x); - x.SetMult(x,a1023); - } - for (int j=0; j<10; j++) x.SetSquare(x); - x.SetMult(x,a1019); - for (int i=0; i<2; i++) { - for (int j=0; j<10; j++) x.SetSquare(x); - x.SetMult(x,a1023); - } - for (int j=0; j<10; j++) x.SetSquare(x); - SetMult(x,a45); - } + void SetInverse(Context &ctx, const FieldElem &a); std::string ToString() { unsigned char tmp[32]; @@ -399,6 +368,52 @@ const FieldConstants &GetFieldConst() { return field_const; } +void FieldElem::SetInverse(Context &ctx, const FieldElem &a) { +#if 0 + // calculate a^p, with p={45,63,1019,1023} + FieldElem a2; a2.SetSquare(a); + FieldElem a3; a3.SetMult(a2,a); + FieldElem a4; a4.SetSquare(a2); + FieldElem a5; a5.SetMult(a4,a); + FieldElem a10; a10.SetSquare(a5); + FieldElem a11; a11.SetMult(a10,a); + FieldElem a21; a21.SetMult(a11,a10); + FieldElem a42; a42.SetSquare(a21); + FieldElem a45; a45.SetMult(a42,a3); + FieldElem a63; a63.SetMult(a42,a21); + FieldElem a126; a126.SetSquare(a63); + FieldElem a252; a252.SetSquare(a126); + FieldElem a504; a504.SetSquare(a252); + FieldElem a1008; a1008.SetSquare(a504); + FieldElem a1019; a1019.SetMult(a1008,a11); + FieldElem a1023; a1023.SetMult(a1019,a4); + FieldElem x = a63; + for (int i=0; i<21; i++) { + for (int j=0; j<10; j++) x.SetSquare(x); + x.SetMult(x,a1023); + } + for (int j=0; j<10; j++) x.SetSquare(x); + x.SetMult(x,a1019); + for (int i=0; i<2; i++) { + for (int j=0; j<10; j++) x.SetSquare(x); + x.SetMult(x,a1023); + } + for (int j=0; j<10; j++) x.SetSquare(x); + SetMult(x,a45); +#else + unsigned char b[32]; + GetBytes(b); + { + const Number &p = GetFieldConst().field_p; + Context ct(ctx); + Number n(ct); n.SetBytes(b, 32); + n.SetModInverse(ct, n, p); + n.GetBytes(b, 32); + } + SetBytes(b); +#endif +} + } #endif diff --git a/group.h b/group.h index 0f39648c1a3..bb495e67471 100644 --- a/group.h +++ b/group.h @@ -54,7 +54,7 @@ public: return "(" + xc.ToString() + "," + yc.ToString() + ")"; } - void SetJac(GroupElemJac &jac); + void SetJac(Context &ctx, GroupElemJac &jac); friend class GroupElemJac; }; @@ -73,7 +73,7 @@ public: GroupElemJac(const GroupElem &in) : GroupElem(in), z(1) {} - void SetJac(GroupElemJac &jac) { + void SetJac(Context &ctx, GroupElemJac &jac) { *this = jac; } @@ -95,8 +95,8 @@ public: } /** Returns the affine coordinates of this point */ - void GetAffine(GroupElem &aff) { - z.SetInverse(z); + void GetAffine(Context &ctx, GroupElem &aff) { + z.SetInverse(ctx, z); FieldElem z2; z2.SetSquare(z); FieldElem z3; @@ -109,9 +109,9 @@ public: aff.y = y; } - void GetX(FieldElem &xout) { + void GetX(Context &ctx, FieldElem &xout) { FieldElem zi; - zi.SetInverse(z); + zi.SetInverse(ctx, z); zi.SetSquare(zi); xout.SetMult(x, zi); } @@ -120,9 +120,9 @@ public: return fInfinity; } - void GetY(FieldElem &yout) { + void GetY(Context &ctx, FieldElem &yout) { FieldElem zi; - zi.SetInverse(z); + zi.SetInverse(ctx, z); FieldElem zi3; zi3.SetSquare(zi); zi3.SetMult(zi, zi3); yout.SetMult(y, zi3); } @@ -260,17 +260,18 @@ public: } std::string ToString() const { + Context ctx; GroupElemJac cop = *this; GroupElem aff; - cop.GetAffine(aff); + cop.GetAffine(ctx, aff); return aff.ToString(); } void SetMulLambda(const GroupElemJac &p); }; -void GroupElem::SetJac(GroupElemJac &jac) { - jac.GetAffine(*this); +void GroupElem::SetJac(Context &ctx, GroupElemJac &jac) { + jac.GetAffine(ctx, *this); } static const unsigned char order_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, diff --git a/num.h b/num.h index 3bb8af360c6..db1563b9637 100644 --- a/num.h +++ b/num.h @@ -1,7 +1,7 @@ #ifndef _SECP256K1_NUM_ #define _SECP256K1_NUM_ -// #include "num_gmp.h" -#include "num_openssl.h" +#include "num_gmp.h" +// #include "num_openssl.h" #endif diff --git a/num_gmp.h b/num_gmp.h index a71cb7ff44f..fe891b77244 100644 --- a/num_gmp.h +++ b/num_gmp.h @@ -68,7 +68,9 @@ public: int size = (mpz_sizeinbase(bn,2)+7)/8; assert(size <= len); memset(bin,0,len); - mpz_export(bin + size - len, NULL, 1, 1, 1, 0, bn); + size_t count = 0; + mpz_export(bin + len - size, &count, 1, 1, 1, 0, bn); + assert(size == count); } void SetInt(int x) { mpz_set_si(bn, x);