mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-03 09:56:38 -05:00
maybe testable
This commit is contained in:
parent
e8c2a8ec9c
commit
821113d425
5 changed files with 42 additions and 46 deletions
36
ecdsa.h
36
ecdsa.h
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
namespace secp256k1 {
|
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)) {
|
if (size == 33 && (pub[0] == 0x02 || pub[0] == 0x03)) {
|
||||||
FieldElem x;
|
FieldElem x;
|
||||||
x.SetBytes(pub+1);
|
x.SetBytes(pub+1);
|
||||||
|
@ -28,6 +28,22 @@ private:
|
||||||
public:
|
public:
|
||||||
Signature(Context &ctx) : r(ctx), s(ctx) {}
|
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) {
|
bool RecomputeR(Context &ctx, Number &r2, const GroupElemJac &pubkey, const Number &message) {
|
||||||
const GroupConstants &c = GetGroupConst();
|
const GroupConstants &c = GetGroupConst();
|
||||||
|
|
||||||
|
@ -41,16 +57,15 @@ public:
|
||||||
Context ct(ctx);
|
Context ct(ctx);
|
||||||
Number sn(ct), u1(ct), u2(ct);
|
Number sn(ct), u1(ct), u2(ct);
|
||||||
sn.SetModInverse(ct, s, c.order);
|
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);
|
u1.SetModMul(ct, sn, message, c.order);
|
||||||
u2.SetModMul(ct, sn, r, c.order);
|
u2.SetModMul(ct, sn, r, c.order);
|
||||||
GroupElemJac pr; ECMult(ct, pr, pubkey, u2, u1);
|
GroupElemJac pr; ECMult(ct, pr, pubkey, u2, u1);
|
||||||
//GroupElemJac pr = pubkey;
|
|
||||||
if (pr.IsInfinity())
|
if (pr.IsInfinity())
|
||||||
return false;
|
return false;
|
||||||
FieldElem xr; pr.GetX(ct, xr);
|
FieldElem xr; pr.GetX(ct, xr);
|
||||||
unsigned char xrb[32]; xr.GetBytes(xrb);
|
unsigned char xrb[32]; xr.GetBytes(xrb);
|
||||||
r2.SetBytes(xrb,32); r2.SetMod(ct,r2,c.order);
|
r2.SetBytes(xrb,32); r2.SetMod(ct,r2,c.order);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Verify(Context &ctx, const GroupElemJac &pubkey, const Number &message) {
|
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
|
#endif
|
||||||
|
|
2
field.h
2
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,
|
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)
|
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]];
|
tmp[32 - str.length()/2 + i] = (cvt[(unsigned char)str[2*i]] << 4) + cvt[(unsigned char)str[2*i+1]];
|
||||||
}
|
}
|
||||||
|
|
5
group.h
5
group.h
|
@ -317,8 +317,9 @@ public:
|
||||||
const FieldElem beta;
|
const FieldElem beta;
|
||||||
const Number lambda, a1b2, b1, a2;
|
const Number lambda, a1b2, b1, a2;
|
||||||
|
|
||||||
GroupConstants() : order(ctx, order_, sizeof(order_)),
|
GroupConstants() : g_x(g_x_), g_y(g_y_),
|
||||||
g_x(g_x_), g_y(g_y_), g(g_x,g_y),
|
order(ctx, order_, sizeof(order_)),
|
||||||
|
g(g_x,g_y),
|
||||||
beta(beta_),
|
beta(beta_),
|
||||||
lambda(ctx, lambda_, sizeof(lambda_)),
|
lambda(ctx, lambda_, sizeof(lambda_)),
|
||||||
a1b2(ctx, a1b2_, sizeof(a1b2_)),
|
a1b2(ctx, a1b2_, sizeof(a1b2_)),
|
||||||
|
|
10
num_gmp.h
10
num_gmp.h
|
@ -1,5 +1,5 @@
|
||||||
#ifndef _SECP256K1_NUM_OPENSSL_
|
#ifndef _SECP256K1_NUM_GMP_
|
||||||
#define _SECP256K1_NUM_OPENSSL_
|
#define _SECP256K1_NUM_GMP_
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -61,11 +61,11 @@ public:
|
||||||
void SetNumber(const Number &x) {
|
void SetNumber(const Number &x) {
|
||||||
mpz_set(bn, x.bn);
|
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);
|
mpz_import(bn, len, 1, 1, 1, 0, bin);
|
||||||
}
|
}
|
||||||
void GetBytes(unsigned char *bin, int len) {
|
void GetBytes(unsigned char *bin, unsigned int len) {
|
||||||
int size = (mpz_sizeinbase(bn,2)+7)/8;
|
unsigned int size = (mpz_sizeinbase(bn,2)+7)/8;
|
||||||
assert(size <= len);
|
assert(size <= len);
|
||||||
memset(bin,0,len);
|
memset(bin,0,len);
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
|
@ -1,40 +1,5 @@
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "num.h"
|
#include "num.h"
|
||||||
#include "field.h"
|
#include "field.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "ecmult.h"
|
#include "ecmult.h"
|
||||||
#include "ecdsa.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…
Add table
Reference in a new issue