Browse Source

maybe testable

master
Pieter Wuille 10 years ago
parent
commit
821113d425
  1. 36
      ecdsa.h
  2. 2
      field.h
  3. 5
      group.h
  4. 10
      num_gmp.h
  5. 35
      secp256k1.cpp

36
ecdsa.h

@ -3,7 +3,7 @@ @@ -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: @@ -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: @@ -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: @@ -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

2
field.h

@ -340,7 +340,7 @@ public: @@ -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]];
}

5
group.h

@ -317,8 +317,9 @@ public: @@ -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_)),

10
num_gmp.h

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
#ifndef _SECP256K1_NUM_OPENSSL_
#define _SECP256K1_NUM_OPENSSL_
#ifndef _SECP256K1_NUM_GMP_
#define _SECP256K1_NUM_GMP_
#include <assert.h>
#include <string>
@ -61,11 +61,11 @@ public: @@ -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;

35
secp256k1.cpp

@ -1,40 +1,5 @@ @@ -1,40 +1,5 @@
#include <stdio.h>
#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;
}

Loading…
Cancel
Save