From cb4d29c81eec5af9a9a7b1115a0986c227374b22 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 9 Mar 2013 22:47:40 +0100 Subject: [PATCH] compiles... --- consts.h | 34 ------------------ ecmult.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++++--- field.h | 39 ++++++++++++++------- group.h | 64 ++++++++++++++++++++++++++++++--- num.h | 41 ++++++++++++++++++++-- scalar.h | 4 +-- secp256k1.cpp | 23 +++--------- 7 files changed, 224 insertions(+), 78 deletions(-) delete mode 100644 consts.h diff --git a/consts.h b/consts.h deleted file mode 100644 index af84afe9..00000000 --- a/consts.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _SECP256K1_CONSTS_ -#define _SECP256K1_CONSTS_ - -#include "num.h" - -namespace secp256k1 { - -static const unsigned char order_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41}; - -static const unsigned char field_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F}; - -class Constants { -private: - Context ctx; - -public: - const Number order; - const Number field; - - Constants() : order(ctx, order_, sizeof(order_)), - field(ctx, field_, sizeof(field_)) {} -}; - -const Constants consts; - -} - -#endif diff --git a/ecmult.h b/ecmult.h index ce43b0e8..663ab107 100644 --- a/ecmult.h +++ b/ecmult.h @@ -1,6 +1,9 @@ #ifndef _SECP256K1_ECMULT_ #define _SECP256K1_ECMULT_ +#include +#include + #include "group.h" #include "scalar.h" @@ -11,17 +14,17 @@ private: G pre[1 << (W-2)]; public: - WNAFPrecomp(G &base) { + WNAFPrecomp(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] = x; + pre[i].SetJac(x); } } - void Get(G &out, int exp) { + void Get(G &out, int exp) const { assert((exp & 1) == 1); assert(exp >= -((1 << (W-1)) - 1)); assert(exp <= ((1 << (W-1)) - 1)); @@ -33,11 +36,97 @@ public: } }; -class WNAF { +template class WNAF { private: + int naf[B+1]; + int used; + void PushNAF(int num, int zeroes) { + for (int i=0; i wpg; + + ECMultConsts() : wpg(GetGroupConst().g) {} +}; + +const ECMultConsts &GetECMultConsts() { + static const ECMultConsts ecmult_consts; + return ecmult_consts; +} + +void ECMult(Context &ctx, GroupElemJac &out, GroupElemJac &a, Scalar &an, Scalar &gn) { + WNAF<256> wa(ctx, an, 5); + WNAF<256> wg(ctx, gn, 10); + WNAFPrecomp wpa(a); + const WNAFPrecomp &wpg = GetECMultConsts().wpg; + + int size = std::max(wa.GetSize(), wg.GetSize()); + + out = GroupElemJac(); + GroupElemJac tmpj; + GroupElem tmpa; + + for (int i=0; i #include #include #include "num.h" -#include "consts.h" // #define VERIFY_MAGNITUDE 1 @@ -38,6 +39,10 @@ public: #endif } + FieldElem(const unsigned char *b32) { + SetBytes(b32); + } + /** Normalizes the internal representation entries. Magnitude=1 */ void Normalize() { uint64_t c; @@ -302,18 +307,6 @@ public: return n[0] & 1; } - void SetInverse_Number(Context &ctx, FieldElem &a) { - unsigned char tmp[32]; - a.GetBytes(tmp); - { - Context cctx(ctx); - Number n(cctx, tmp, 32); - n.SetModInverse(cctx, n, consts.field); - n.GetBytes(tmp, 32); - } - SetBytes(tmp); - } - /** 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} @@ -386,6 +379,26 @@ public: } }; +static const unsigned char field_p_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F}; + +class FieldConstants { +private: + Context ctx; + +public: + const Number field_p; + + FieldConstants() : field_p(ctx, field_p_, sizeof(field_p_)) {} +}; + +const FieldConstants &GetFieldConst() { + static const FieldConstants field_const; + return field_const; +} + } #endif diff --git a/group.h b/group.h index e38653bc..de49f49c 100644 --- a/group.h +++ b/group.h @@ -5,6 +5,8 @@ namespace secp256k1 { +class GroupElemJac; + /** Defines a point on the secp256k1 curve (y^2 = x^3 + 7) */ class GroupElem { protected: @@ -31,11 +33,10 @@ public: return fInfinity; } - void SetNeg(GroupElem &p) { - fInfinity = p.fInfinity; - x = p.x; - p.y.Normalize(); - y.SetNeg(p.y, 1); + void SetNeg(const GroupElem &p) { + *this = p; + y.Normalize(); + y.SetNeg(y, 1); } std::string ToString() { @@ -44,6 +45,8 @@ public: return "(" + x.ToString() + "," + y.ToString() + ")"; } + void SetJac(GroupElemJac &jac); + friend class GroupElemJac; }; @@ -59,6 +62,12 @@ public: /** Creates the point with given affine coordinates */ GroupElemJac(const FieldElem &xin, const FieldElem &yin) : GroupElem(xin,yin), z(1) {} + GroupElemJac(const GroupElem &in) : GroupElem(in), z(1) {} + + void SetJac(GroupElemJac &jac) { + *this = jac; + } + /** Checks whether this is a non-infinite point on the curve */ bool IsValid() { if (IsInfinity()) @@ -91,6 +100,12 @@ public: aff.y = y; } + void SetNeg(const GroupElemJac &p) { + *this = p; + y.Normalize(); + y.SetNeg(y, 1); + } + /** Sets this point to have a given X coordinate & given Y oddness */ void SetCompressed(const FieldElem &xin, bool fOdd) { x = xin; @@ -222,6 +237,45 @@ public: } }; +void GroupElem::SetJac(GroupElemJac &jac) { + jac.GetAffine(*this); +} + +static const unsigned char order_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, + 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x41}; + +static const unsigned char g_x_[] = {0x79,0xBE,0x66,0x7E,0xF9,0xDC,0xBB,0xAC, + 0x55,0xA0,0x62,0x95,0xCE,0x87,0x0B,0x07, + 0x02,0x9B,0xFC,0xDB,0x2D,0xCE,0x28,0xD9, + 0x59,0xF2,0x81,0x5B,0x16,0xF8,0x17,0x98}; + +static const unsigned char g_y_[] = {0x48,0x3A,0xDA,0x77,0x26,0xA3,0xC4,0x65, + 0x5D,0xA4,0xFB,0xFC,0x0E,0x11,0x08,0xA8, + 0xFD,0x17,0xB4,0x48,0xA6,0x85,0x54,0x19, + 0x9C,0x47,0xD0,0x8F,0xFB,0x10,0xD4,0xB8}; + +class GroupConstants { +private: + Context ctx; + const FieldElem g_x; + const FieldElem g_y; + +public: + const Number order; + const GroupElem g; + + GroupConstants() : order(ctx, order_, sizeof(order_)), + g_x(g_x_), g_y(g_y_), + g(g_x,g_y) {} +}; + +const GroupConstants &GetGroupConst() { + static const GroupConstants group_const; + return group_const; +} + } #endif diff --git a/num.h b/num.h index 6e5c45c7..ce12cb8c 100644 --- a/num.h +++ b/num.h @@ -2,8 +2,10 @@ #define _SECP256K1_NUM_ #include +#include #include #include +#include namespace secp256k1 { @@ -60,15 +62,50 @@ public: void GetBytes(unsigned char *bin, int len) { int size = BN_num_bytes(bn); assert(size <= len); - ::memset(bin,0,len); + memset(bin,0,len); BN_bn2bin(bn, bin + size - len); } void SetModInverse(Context &ctx, const Number &x, const Number &m) { BN_mod_inverse(bn, x.bn, m.bn, ctx); } + int GetBits() const { + return BN_num_bits(bn); + } + // return the lowest (rightmost) bits bits, and rshift them away + int ShiftLowBits(Context &ctx, int bits) { + Context ct(ctx); + BIGNUM *tmp = ct.Get(); + BN_copy(tmp, bn); + BN_mask_bits(tmp, bits); + int ret = BN_get_word(tmp); + BN_rshift(bn, bn, bits); + return ret; + } + // check whether number is 0 + bool IsZero() { + return BN_is_zero(bn); + } + // right-shift as many zeroes as possible + int IsOdd() { + return BN_is_odd(bn); + } + void Shift1() { + BN_rshift1(bn,bn); + } + void Inc() { + BN_add_word(bn,1); + } + void SetHex(const std::string &str) { + BN_hex2bn(&bn, str.c_str()); + } + std::string ToString() { + char *str = BN_bn2hex(bn); + std::string ret(str); + OPENSSL_free(str); + return ret; + } }; } #endif - diff --git a/scalar.h b/scalar.h index 10f5ec26..494a98d1 100644 --- a/scalar.h +++ b/scalar.h @@ -2,14 +2,14 @@ #define _SECP256K1_SCALAR_ #include "num.h" -#include "consts.h" namespace secp256k1 { /** Implements arithmetic modulo FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141, * using OpenSSL's BIGNUM */ -class Scalar : private Number { +class Scalar : public Number { public: + Scalar(Context &ctx) : Number(ctx) {} }; } diff --git a/secp256k1.cpp b/secp256k1.cpp index dfdef523..f7e7ebc4 100644 --- a/secp256k1.cpp +++ b/secp256k1.cpp @@ -1,7 +1,6 @@ #include #include "num.h" -#include "consts.h" #include "scalar.h" #include "field.h" #include "group.h" @@ -11,22 +10,10 @@ using namespace secp256k1; int main() { Context ctx; - FieldElem f1,f2; - f1.SetHex("8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846115"); -// f2.SetHex("8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846115"); - printf("%s\n",f1.ToString().c_str()); -// printf("%s\n",f2.ToString().c_str()); - for (int i=0; i<1000000; i++) { - f1.SetInverse_Number(ctx,f1); -// f2.SetInverse_(f2); -// if (!(f1 == f2)) { -// printf("f1 %i: %s\n",i,f1.ToString().c_str()); -// printf("f2 %i: %s\n",i,f2.ToString().c_str()); -// } -// f1 *= 2; -// f2 *= 2; - } - printf("%s\n",f1.ToString().c_str()); -// printf("%s\n",f2.ToString().c_str()); + Scalar scal(ctx); + scal.SetHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); + printf("scal=%s\n", scal.ToString().c_str()); + WNAF<256> w(ctx, scal, 5); + printf("wnaf=%s\n", w.ToString().c_str()); return 0; }