diff --git a/ecdsa.h b/ecdsa.h index bcd970d..8588ad0 100644 --- a/ecdsa.h +++ b/ecdsa.h @@ -3,7 +3,7 @@ namespace secp256k1 { -bool ParsePubkey(GroupElemJac &elem, const unsigned char *pub, int size) { +bool ParsePubKey(GroupElemJac &elem, const unsigned char *pub, int size) { if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) { FieldElem x; x.SetBytes(pub+1); @@ -28,6 +28,22 @@ private: public: Signature(Context &ctx) : r(ctx), s(ctx) {} + bool Parse(const unsigned char *sig, int size) { + if (sig[0] != 0x30) return false; + if (sig[1] != size-2) return false; + int lenr = sig[3]; + if (4+lenr >= size) return false; + int lens = sig[lenr+5]; + if (lenr+lens+6 != size) return false; + if (sig[2] != 0x02) return false; + if (lenr == 0) return false; + if (sig[lenr+4] != 0x02) return false; + if (lens == 0) return false; + r.SetBytes(sig+4, lenr); + s.SetBytes(sig+6+lenr, lens); + return true; + } + bool RecomputeR(Context &ctx, Number &r2, const GroupElemJac &pubkey, const Number &message) { const GroupConstants &c = GetGroupConst(); @@ -41,16 +57,15 @@ public: Context ct(ctx); Number sn(ct), u1(ct), u2(ct); sn.SetModInverse(ct, s, c.order); - // printf("s=%s 1/s=%s\n", s.ToString().c_str(), sn.ToString().c_str()); u1.SetModMul(ct, sn, message, c.order); u2.SetModMul(ct, sn, r, c.order); GroupElemJac pr; ECMult(ct, pr, pubkey, u2, u1); - //GroupElemJac pr = pubkey; if (pr.IsInfinity()) return false; FieldElem xr; pr.GetX(ct, xr); unsigned char xrb[32]; xr.GetBytes(xrb); r2.SetBytes(xrb,32); r2.SetMod(ct,r2,c.order); + return true; } bool Verify(Context &ctx, const GroupElemJac &pubkey, const Number &message) { @@ -67,6 +82,21 @@ public: } }; +int VerifyECDSA(const unsigned char *msg, int msglen, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) { + Context ctx; + Number m(ctx); + Signature s(ctx); + GroupElemJac q; + m.SetBytes(msg, msglen); + if (!ParsePubKey(q, pubkey, pubkeylen)) + return -1; + if (!s.Parse(sig, siglen)) + return -2; + if (!s.Verify(ctx, q, m)) + return 0; + return 1; +} + } #endif diff --git a/field.h b/field.h index 609a33b..1d01957 100644 --- a/field.h +++ b/field.h @@ -340,7 +340,7 @@ public: 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0,0,0}; - for (int i=0; i<32; i++) { + for (unsigned int i=0; i<32; i++) { if (str.length() > i*2) tmp[32 - str.length()/2 + i] = (cvt[(unsigned char)str[2*i]] << 4) + cvt[(unsigned char)str[2*i+1]]; } diff --git a/group.h b/group.h index bb495e6..2032467 100644 --- a/group.h +++ b/group.h @@ -317,8 +317,9 @@ public: const FieldElem beta; const Number lambda, a1b2, b1, a2; - GroupConstants() : order(ctx, order_, sizeof(order_)), - g_x(g_x_), g_y(g_y_), g(g_x,g_y), + GroupConstants() : g_x(g_x_), g_y(g_y_), + order(ctx, order_, sizeof(order_)), + g(g_x,g_y), beta(beta_), lambda(ctx, lambda_, sizeof(lambda_)), a1b2(ctx, a1b2_, sizeof(a1b2_)), diff --git a/num_gmp.h b/num_gmp.h index fe891b7..9b0631d 100644 --- a/num_gmp.h +++ b/num_gmp.h @@ -1,5 +1,5 @@ -#ifndef _SECP256K1_NUM_OPENSSL_ -#define _SECP256K1_NUM_OPENSSL_ +#ifndef _SECP256K1_NUM_GMP_ +#define _SECP256K1_NUM_GMP_ #include #include @@ -61,11 +61,11 @@ public: void SetNumber(const Number &x) { mpz_set(bn, x.bn); } - void SetBytes(const unsigned char *bin, int len) { + void SetBytes(const unsigned char *bin, unsigned int len) { mpz_import(bn, len, 1, 1, 1, 0, bin); } - void GetBytes(unsigned char *bin, int len) { - int size = (mpz_sizeinbase(bn,2)+7)/8; + void GetBytes(unsigned char *bin, unsigned int len) { + unsigned int size = (mpz_sizeinbase(bn,2)+7)/8; assert(size <= len); memset(bin,0,len); size_t count = 0; diff --git a/secp256k1.cpp b/secp256k1.cpp index 3c78d75..dbf83cc 100644 --- a/secp256k1.cpp +++ b/secp256k1.cpp @@ -1,40 +1,5 @@ -#include - #include "num.h" #include "field.h" #include "group.h" #include "ecmult.h" #include "ecdsa.h" - -using namespace secp256k1; - -int main() { - Context ctx; - FieldElem x; - const Number &order = GetGroupConst().order; - Number r(ctx), s(ctx), m(ctx); - Signature sig(ctx); - x.SetHex("a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f"); - int cnt = 0; - int good = 0; - for (int i=0; i<1000000; i++) { -// ECMult(ctx, a, a, an, gn); -// an.SetModMul(ctx, af, order); -// gn.SetModMul(ctx, gf, order); -// an.Inc(); -// gn.Inc(); - r.SetPseudoRand(order); - s.SetPseudoRand(order); - if (i == 0) - x.SetSquare(x); - m.SetPseudoRand(order); - sig.SetRS(r,s); - GroupElemJac pubkey; pubkey.SetCompressed(x, true); - if (pubkey.IsValid()) { - cnt++; - good += sig.Verify(ctx, pubkey, m); - } - } - printf("%i/%i\n", good, cnt); - return 0; -}