mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-10 10:52:31 -05:00
remove Context interface... it doesn't help much
This commit is contained in:
parent
7b292b8108
commit
d5f62719de
7 changed files with 179 additions and 207 deletions
33
ecdsa.h
33
ecdsa.h
|
@ -26,8 +26,6 @@ private:
|
||||||
Number r,s;
|
Number r,s;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Signature(Context &ctx) : r(ctx), s(ctx) {}
|
|
||||||
|
|
||||||
bool Parse(const unsigned char *sig, int size) {
|
bool Parse(const unsigned char *sig, int size) {
|
||||||
if (sig[0] != 0x30) return false;
|
if (sig[0] != 0x30) return false;
|
||||||
int lenr = sig[3];
|
int lenr = sig[3];
|
||||||
|
@ -44,7 +42,7 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RecomputeR(Context &ctx, Number &r2, const GroupElemJac &pubkey, const Number &message) {
|
bool RecomputeR(Number &r2, const GroupElemJac &pubkey, const Number &message) {
|
||||||
const GroupConstants &c = GetGroupConst();
|
const GroupConstants &c = GetGroupConst();
|
||||||
|
|
||||||
if (r.IsNeg() || s.IsNeg())
|
if (r.IsNeg() || s.IsNeg())
|
||||||
|
@ -54,24 +52,22 @@ public:
|
||||||
if (r.Compare(c.order) >= 0 || s.Compare(c.order) >= 0)
|
if (r.Compare(c.order) >= 0 || s.Compare(c.order) >= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Context ct(ctx);
|
Number sn, u1, u2;
|
||||||
Number sn(ct), u1(ct), u2(ct);
|
sn.SetModInverse(s, c.order);
|
||||||
sn.SetModInverse(ct, s, c.order);
|
u1.SetModMul(sn, message, c.order);
|
||||||
u1.SetModMul(ct, sn, message, c.order);
|
u2.SetModMul(sn, r, c.order);
|
||||||
u2.SetModMul(ct, sn, r, c.order);
|
GroupElemJac pr; ECMult(pr, pubkey, u2, u1);
|
||||||
GroupElemJac pr; ECMult(ct, pr, pubkey, u2, u1);
|
|
||||||
if (pr.IsInfinity())
|
if (pr.IsInfinity())
|
||||||
return false;
|
return false;
|
||||||
FieldElem xr; pr.GetX(ct, xr);
|
FieldElem xr; pr.GetX(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(r2,c.order);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Verify(Context &ctx, const GroupElemJac &pubkey, const Number &message) {
|
bool Verify(const GroupElemJac &pubkey, const Number &message) {
|
||||||
Context ct(ctx);
|
Number r2;
|
||||||
Number r2(ct);
|
if (!RecomputeR(r2, pubkey, message))
|
||||||
if (!RecomputeR(ct, r2, pubkey, message))
|
|
||||||
return false;
|
return false;
|
||||||
return r2.Compare(r) == 0;
|
return r2.Compare(r) == 0;
|
||||||
}
|
}
|
||||||
|
@ -87,9 +83,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
int VerifyECDSA(const unsigned char *msg, int msglen, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) {
|
int VerifyECDSA(const unsigned char *msg, int msglen, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) {
|
||||||
Context ctx;
|
Number m;
|
||||||
Number m(ctx);
|
Signature s;
|
||||||
Signature s(ctx);
|
|
||||||
GroupElemJac q;
|
GroupElemJac q;
|
||||||
m.SetBytes(msg, msglen);
|
m.SetBytes(msg, msglen);
|
||||||
if (!ParsePubKey(q, pubkey, pubkeylen))
|
if (!ParsePubKey(q, pubkey, pubkeylen))
|
||||||
|
@ -101,7 +96,7 @@ int VerifyECDSA(const unsigned char *msg, int msglen, const unsigned char *sig,
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
// fprintf(stderr, "Verifying ECDSA: msg=%s pubkey=%s sig=%s\n", m.ToString().c_str(), q.ToString().c_str(), s.ToString().c_str());
|
// fprintf(stderr, "Verifying ECDSA: msg=%s pubkey=%s sig=%s\n", m.ToString().c_str(), q.ToString().c_str(), s.ToString().c_str());
|
||||||
if (!s.Verify(ctx, q, m))
|
if (!s.Verify(q, m))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
45
ecmult.h
45
ecmult.h
|
@ -23,18 +23,18 @@ private:
|
||||||
public:
|
public:
|
||||||
WNAFPrecomp() {}
|
WNAFPrecomp() {}
|
||||||
|
|
||||||
void Build(Context &ctx, const G &base) {
|
void Build(const G &base) {
|
||||||
pre[0] = base;
|
pre[0] = base;
|
||||||
GroupElemJac x(base);
|
GroupElemJac x(base);
|
||||||
GroupElemJac d; d.SetDouble(x);
|
GroupElemJac d; d.SetDouble(x);
|
||||||
for (int i=1; i<(1 << (W-2)); i++) {
|
for (int i=1; i<(1 << (W-2)); i++) {
|
||||||
x.SetAdd(d,pre[i-1]);
|
x.SetAdd(d,pre[i-1]);
|
||||||
pre[i].SetJac(ctx, x);
|
pre[i].SetJac(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WNAFPrecomp(Context &ctx, const G &base) {
|
WNAFPrecomp(const G &base) {
|
||||||
Build(ctx, base);
|
Build(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get(G &out, int exp) const {
|
void Get(G &out, int exp) const {
|
||||||
|
@ -63,10 +63,9 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WNAF(Context &ctx, const Number &exp, int w) : used(0) {
|
WNAF(const Number &exp, int w) : used(0) {
|
||||||
int zeroes = 0;
|
int zeroes = 0;
|
||||||
Context ct(ctx);
|
Number x;
|
||||||
Number x(ct);
|
|
||||||
x.SetNumber(exp);
|
x.SetNumber(exp);
|
||||||
int sign = 1;
|
int sign = 1;
|
||||||
if (x.IsNeg()) {
|
if (x.IsNeg()) {
|
||||||
|
@ -78,7 +77,7 @@ public:
|
||||||
zeroes++;
|
zeroes++;
|
||||||
x.Shift1();
|
x.Shift1();
|
||||||
}
|
}
|
||||||
int word = x.ShiftLowBits(ct,w);
|
int word = x.ShiftLowBits(w);
|
||||||
if (word & (1 << (w-1))) {
|
if (word & (1 << (w-1))) {
|
||||||
x.Inc();
|
x.Inc();
|
||||||
PushNAF(sign * (word - (1 << w)), zeroes);
|
PushNAF(sign * (word - (1 << w)), zeroes);
|
||||||
|
@ -117,14 +116,13 @@ public:
|
||||||
WNAFPrecomp<GroupElem,WINDOW_G> wpg128;
|
WNAFPrecomp<GroupElem,WINDOW_G> wpg128;
|
||||||
|
|
||||||
ECMultConsts() {
|
ECMultConsts() {
|
||||||
Context ctx;
|
|
||||||
const GroupElem &g = GetGroupConst().g;
|
const GroupElem &g = GetGroupConst().g;
|
||||||
GroupElemJac g128j(g);
|
GroupElemJac g128j(g);
|
||||||
for (int i=0; i<128; i++)
|
for (int i=0; i<128; i++)
|
||||||
g128j.SetDouble(g128j);
|
g128j.SetDouble(g128j);
|
||||||
GroupElem g128; g128.SetJac(ctx, g128j);
|
GroupElem g128; g128.SetJac(g128j);
|
||||||
wpg.Build(ctx, g);
|
wpg.Build(g);
|
||||||
wpg128.Build(ctx, g128);
|
wpg128.Build(g128);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,26 +131,25 @@ const ECMultConsts &GetECMultConsts() {
|
||||||
return ecmult_consts;
|
return ecmult_consts;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ECMult(Context &ctx, GroupElemJac &out, const GroupElemJac &a, const Number &an, const Number &gn) {
|
void ECMult(GroupElemJac &out, const GroupElemJac &a, const Number &an, const Number &gn) {
|
||||||
Context ct(ctx);
|
Number an1, an2;
|
||||||
Number an1(ct), an2(ct);
|
Number gn1, gn2;
|
||||||
Number gn1(ct), gn2(ct);
|
|
||||||
|
|
||||||
SplitExp(ct, an, an1, an2);
|
SplitExp(an, an1, an2);
|
||||||
// printf("an=%s\n", an.ToString().c_str());
|
// printf("an=%s\n", an.ToString().c_str());
|
||||||
// printf("an1=%s\n", an1.ToString().c_str());
|
// printf("an1=%s\n", an1.ToString().c_str());
|
||||||
// printf("an2=%s\n", an2.ToString().c_str());
|
// printf("an2=%s\n", an2.ToString().c_str());
|
||||||
// printf("an1.len=%i\n", an1.GetBits());
|
// printf("an1.len=%i\n", an1.GetBits());
|
||||||
// printf("an2.len=%i\n", an2.GetBits());
|
// printf("an2.len=%i\n", an2.GetBits());
|
||||||
gn.SplitInto(ct, 128, gn1, gn2);
|
gn.SplitInto(128, gn1, gn2);
|
||||||
|
|
||||||
WNAF<128> wa1(ct, an1, WINDOW_A);
|
WNAF<128> wa1(an1, WINDOW_A);
|
||||||
WNAF<128> wa2(ct, an2, WINDOW_A);
|
WNAF<128> wa2(an2, WINDOW_A);
|
||||||
WNAF<128> wg1(ct, gn1, WINDOW_G);
|
WNAF<128> wg1(gn1, WINDOW_G);
|
||||||
WNAF<128> wg2(ct, gn2, WINDOW_G);
|
WNAF<128> wg2(gn2, WINDOW_G);
|
||||||
GroupElemJac a2; a2.SetMulLambda(a);
|
GroupElemJac a2; a2.SetMulLambda(a);
|
||||||
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa1(ct, a);
|
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa1(a);
|
||||||
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa2(ct, a2);
|
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa2(a2);
|
||||||
const ECMultConsts &c = GetECMultConsts();
|
const ECMultConsts &c = GetECMultConsts();
|
||||||
|
|
||||||
int size_a1 = wa1.GetSize();
|
int size_a1 = wa1.GetSize();
|
||||||
|
|
14
field.h
14
field.h
|
@ -308,7 +308,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set this to be the (modular) inverse of another FieldElem. Magnitude=1 */
|
/** Set this to be the (modular) inverse of another FieldElem. Magnitude=1 */
|
||||||
void SetInverse(Context &ctx, FieldElem &a);
|
void SetInverse(FieldElem &a);
|
||||||
|
|
||||||
std::string ToString() {
|
std::string ToString() {
|
||||||
unsigned char tmp[32];
|
unsigned char tmp[32];
|
||||||
|
@ -354,13 +354,10 @@ static const unsigned char field_p_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
|
||||||
0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F};
|
0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFC,0x2F};
|
||||||
|
|
||||||
class FieldConstants {
|
class FieldConstants {
|
||||||
private:
|
|
||||||
Context ctx;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Number field_p;
|
const Number field_p;
|
||||||
|
|
||||||
FieldConstants() : field_p(ctx, field_p_, sizeof(field_p_)) {}
|
FieldConstants() : field_p(field_p_, sizeof(field_p_)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const FieldConstants &GetFieldConst() {
|
const FieldConstants &GetFieldConst() {
|
||||||
|
@ -368,7 +365,7 @@ const FieldConstants &GetFieldConst() {
|
||||||
return field_const;
|
return field_const;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldElem::SetInverse(Context &ctx, FieldElem &a) {
|
void FieldElem::SetInverse(FieldElem &a) {
|
||||||
#if defined(USE_FIELDINVERSE_BUILTIN)
|
#if defined(USE_FIELDINVERSE_BUILTIN)
|
||||||
// calculate a^p, with p={45,63,1019,1023}
|
// calculate a^p, with p={45,63,1019,1023}
|
||||||
FieldElem a2; a2.SetSquare(a);
|
FieldElem a2; a2.SetSquare(a);
|
||||||
|
@ -405,9 +402,8 @@ void FieldElem::SetInverse(Context &ctx, FieldElem &a) {
|
||||||
a.GetBytes(b);
|
a.GetBytes(b);
|
||||||
{
|
{
|
||||||
const Number &p = GetFieldConst().field_p;
|
const Number &p = GetFieldConst().field_p;
|
||||||
Context ct(ctx);
|
Number n; n.SetBytes(b, 32);
|
||||||
Number n(ct); n.SetBytes(b, 32);
|
n.SetModInverse(n, p);
|
||||||
n.SetModInverse(ct, n, p);
|
|
||||||
n.GetBytes(b, 32);
|
n.GetBytes(b, 32);
|
||||||
}
|
}
|
||||||
SetBytes(b);
|
SetBytes(b);
|
||||||
|
|
69
group.h
69
group.h
|
@ -39,11 +39,11 @@ public:
|
||||||
y.SetNeg(y, 1);
|
y.SetNeg(y, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetX(Context &ctx, FieldElem &xout) {
|
void GetX(FieldElem &xout) {
|
||||||
xout = x;
|
xout = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetY(Context &ctx, FieldElem &yout) {
|
void GetY(FieldElem &yout) {
|
||||||
yout = y;
|
yout = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ public:
|
||||||
return "(" + xc.ToString() + "," + yc.ToString() + ")";
|
return "(" + xc.ToString() + "," + yc.ToString() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetJac(Context &ctx, GroupElemJac &jac);
|
void SetJac(GroupElemJac &jac);
|
||||||
|
|
||||||
friend class GroupElemJac;
|
friend class GroupElemJac;
|
||||||
};
|
};
|
||||||
|
@ -73,7 +73,7 @@ public:
|
||||||
|
|
||||||
GroupElemJac(const GroupElem &in) : GroupElem(in), z(1) {}
|
GroupElemJac(const GroupElem &in) : GroupElem(in), z(1) {}
|
||||||
|
|
||||||
void SetJac(Context &ctx, GroupElemJac &jac) {
|
void SetJac(GroupElemJac &jac) {
|
||||||
*this = jac;
|
*this = jac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,8 +95,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the affine coordinates of this point */
|
/** Returns the affine coordinates of this point */
|
||||||
void GetAffine(Context &ctx, GroupElem &aff) {
|
void GetAffine(GroupElem &aff) {
|
||||||
z.SetInverse(ctx, z);
|
z.SetInverse(z);
|
||||||
FieldElem z2;
|
FieldElem z2;
|
||||||
z2.SetSquare(z);
|
z2.SetSquare(z);
|
||||||
FieldElem z3;
|
FieldElem z3;
|
||||||
|
@ -109,9 +109,9 @@ public:
|
||||||
aff.y = y;
|
aff.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetX(Context &ctx, FieldElem &xout) {
|
void GetX(FieldElem &xout) {
|
||||||
FieldElem zi;
|
FieldElem zi;
|
||||||
zi.SetInverse(ctx, z);
|
zi.SetInverse(z);
|
||||||
zi.SetSquare(zi);
|
zi.SetSquare(zi);
|
||||||
xout.SetMult(x, zi);
|
xout.SetMult(x, zi);
|
||||||
}
|
}
|
||||||
|
@ -120,9 +120,9 @@ public:
|
||||||
return fInfinity;
|
return fInfinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetY(Context &ctx, FieldElem &yout) {
|
void GetY(FieldElem &yout) {
|
||||||
FieldElem zi;
|
FieldElem zi;
|
||||||
zi.SetInverse(ctx, z);
|
zi.SetInverse(z);
|
||||||
FieldElem zi3; zi3.SetSquare(zi); zi3.SetMult(zi, zi3);
|
FieldElem zi3; zi3.SetSquare(zi); zi3.SetMult(zi, zi3);
|
||||||
yout.SetMult(y, zi3);
|
yout.SetMult(y, zi3);
|
||||||
}
|
}
|
||||||
|
@ -260,18 +260,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString() const {
|
std::string ToString() const {
|
||||||
Context ctx;
|
|
||||||
GroupElemJac cop = *this;
|
GroupElemJac cop = *this;
|
||||||
GroupElem aff;
|
GroupElem aff;
|
||||||
cop.GetAffine(ctx, aff);
|
cop.GetAffine(aff);
|
||||||
return aff.ToString();
|
return aff.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMulLambda(const GroupElemJac &p);
|
void SetMulLambda(const GroupElemJac &p);
|
||||||
};
|
};
|
||||||
|
|
||||||
void GroupElem::SetJac(Context &ctx, GroupElemJac &jac) {
|
void GroupElem::SetJac(GroupElemJac &jac) {
|
||||||
jac.GetAffine(ctx, *this);
|
jac.GetAffine(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const unsigned char order_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
static const unsigned char order_[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||||
|
@ -307,7 +306,6 @@ static const unsigned char a2_[] = {0x01,
|
||||||
0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8};
|
0x57,0xc1,0x10,0x8d,0x9d,0x44,0xcf,0xd8};
|
||||||
class GroupConstants {
|
class GroupConstants {
|
||||||
private:
|
private:
|
||||||
Context ctx;
|
|
||||||
const FieldElem g_x;
|
const FieldElem g_x;
|
||||||
const FieldElem g_y;
|
const FieldElem g_y;
|
||||||
|
|
||||||
|
@ -318,13 +316,13 @@ public:
|
||||||
const Number lambda, a1b2, b1, a2;
|
const Number lambda, a1b2, b1, a2;
|
||||||
|
|
||||||
GroupConstants() : g_x(g_x_), g_y(g_y_),
|
GroupConstants() : g_x(g_x_), g_y(g_y_),
|
||||||
order(ctx, order_, sizeof(order_)),
|
order(order_, sizeof(order_)),
|
||||||
g(g_x,g_y),
|
g(g_x,g_y),
|
||||||
beta(beta_),
|
beta(beta_),
|
||||||
lambda(ctx, lambda_, sizeof(lambda_)),
|
lambda(lambda_, sizeof(lambda_)),
|
||||||
a1b2(ctx, a1b2_, sizeof(a1b2_)),
|
a1b2(a1b2_, sizeof(a1b2_)),
|
||||||
b1(ctx, b1_, sizeof(b1_)),
|
b1(b1_, sizeof(b1_)),
|
||||||
a2(ctx, a2_, sizeof(a2_)) {}
|
a2(a2_, sizeof(a2_)) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const GroupConstants &GetGroupConst() {
|
const GroupConstants &GetGroupConst() {
|
||||||
|
@ -338,28 +336,27 @@ void GroupElemJac::SetMulLambda(const GroupElemJac &p) {
|
||||||
x.SetMult(x, beta);
|
x.SetMult(x, beta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitExp(Context &ctx, const Number &exp, Number &exp1, Number &exp2) {
|
void SplitExp(const Number &exp, Number &exp1, Number &exp2) {
|
||||||
const GroupConstants &c = GetGroupConst();
|
const GroupConstants &c = GetGroupConst();
|
||||||
Context ct(ctx);
|
Number bnc1, bnc2, bnt1, bnt2, bnn2;
|
||||||
Number bnc1(ct), bnc2(ct), bnt1(ct), bnt2(ct), bnn2(ct);
|
|
||||||
bnn2.SetNumber(c.order);
|
bnn2.SetNumber(c.order);
|
||||||
bnn2.Shift1();
|
bnn2.Shift1();
|
||||||
|
|
||||||
bnc1.SetMult(ct, exp, c.a1b2);
|
bnc1.SetMult(exp, c.a1b2);
|
||||||
bnc1.SetAdd(ct, bnc1, bnn2);
|
bnc1.SetAdd(bnc1, bnn2);
|
||||||
bnc1.SetDiv(ct, bnc1, c.order);
|
bnc1.SetDiv(bnc1, c.order);
|
||||||
|
|
||||||
bnc2.SetMult(ct, exp, c.b1);
|
bnc2.SetMult(exp, c.b1);
|
||||||
bnc2.SetAdd(ct, bnc2, bnn2);
|
bnc2.SetAdd(bnc2, bnn2);
|
||||||
bnc2.SetDiv(ct, bnc2, c.order);
|
bnc2.SetDiv(bnc2, c.order);
|
||||||
|
|
||||||
bnt1.SetMult(ct, bnc1, c.a1b2);
|
bnt1.SetMult(bnc1, c.a1b2);
|
||||||
bnt2.SetMult(ct, bnc2, c.a2);
|
bnt2.SetMult(bnc2, c.a2);
|
||||||
bnt1.SetAdd(ct, bnt1, bnt2);
|
bnt1.SetAdd(bnt1, bnt2);
|
||||||
exp1.SetSub(ct, exp, bnt1);
|
exp1.SetSub(exp, bnt1);
|
||||||
bnt1.SetMult(ct, bnc1, c.b1);
|
bnt1.SetMult(bnc1, c.b1);
|
||||||
bnt2.SetMult(ct, bnc2, c.a1b2);
|
bnt2.SetMult(bnc2, c.a1b2);
|
||||||
exp2.SetSub(ct, bnt1, bnt2);
|
exp2.SetSub(bnt1, bnt2);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
31
num_gmp.h
31
num_gmp.h
|
@ -9,15 +9,6 @@
|
||||||
|
|
||||||
namespace secp256k1 {
|
namespace secp256k1 {
|
||||||
|
|
||||||
class Context {
|
|
||||||
public:
|
|
||||||
Context() {
|
|
||||||
}
|
|
||||||
|
|
||||||
Context(Context &par) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class NumberState {
|
class NumberState {
|
||||||
private:
|
private:
|
||||||
gmp_randstate_t rng;
|
gmp_randstate_t rng;
|
||||||
|
@ -44,13 +35,13 @@ private:
|
||||||
Number(const Number &x) {
|
Number(const Number &x) {
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
Number(Context &ctx) {
|
Number() {
|
||||||
mpz_init(bn);
|
mpz_init(bn);
|
||||||
}
|
}
|
||||||
~Number() {
|
~Number() {
|
||||||
mpz_clear(bn);
|
mpz_clear(bn);
|
||||||
}
|
}
|
||||||
Number(Context &ctx, const unsigned char *bin, int len) {
|
Number(const unsigned char *bin, int len) {
|
||||||
mpz_init(bn);
|
mpz_init(bn);
|
||||||
SetBytes(bin,len);
|
SetBytes(bin,len);
|
||||||
}
|
}
|
||||||
|
@ -75,26 +66,26 @@ public:
|
||||||
void SetInt(int x) {
|
void SetInt(int x) {
|
||||||
mpz_set_si(bn, x);
|
mpz_set_si(bn, x);
|
||||||
}
|
}
|
||||||
void SetModInverse(Context &ctx, const Number &x, const Number &m) {
|
void SetModInverse(const Number &x, const Number &m) {
|
||||||
mpz_invert(bn, x.bn, m.bn);
|
mpz_invert(bn, x.bn, m.bn);
|
||||||
}
|
}
|
||||||
void SetModMul(Context &ctx, const Number &a, const Number &b, const Number &m) {
|
void SetModMul(const Number &a, const Number &b, const Number &m) {
|
||||||
mpz_mul(bn, a.bn, b.bn);
|
mpz_mul(bn, a.bn, b.bn);
|
||||||
mpz_mod(bn, bn, m.bn);
|
mpz_mod(bn, bn, m.bn);
|
||||||
}
|
}
|
||||||
void SetAdd(Context &ctx, const Number &a1, const Number &a2) {
|
void SetAdd(const Number &a1, const Number &a2) {
|
||||||
mpz_add(bn, a1.bn, a2.bn);
|
mpz_add(bn, a1.bn, a2.bn);
|
||||||
}
|
}
|
||||||
void SetSub(Context &ctx, const Number &a1, const Number &a2) {
|
void SetSub(const Number &a1, const Number &a2) {
|
||||||
mpz_sub(bn, a1.bn, a2.bn);
|
mpz_sub(bn, a1.bn, a2.bn);
|
||||||
}
|
}
|
||||||
void SetMult(Context &ctx, const Number &a1, const Number &a2) {
|
void SetMult(const Number &a1, const Number &a2) {
|
||||||
mpz_mul(bn, a1.bn, a2.bn);
|
mpz_mul(bn, a1.bn, a2.bn);
|
||||||
}
|
}
|
||||||
void SetDiv(Context &ctx, const Number &a1, const Number &a2) {
|
void SetDiv(const Number &a1, const Number &a2) {
|
||||||
mpz_tdiv_q(bn, a1.bn, a2.bn);
|
mpz_tdiv_q(bn, a1.bn, a2.bn);
|
||||||
}
|
}
|
||||||
void SetMod(Context &ctx, const Number &a, const Number &m) {
|
void SetMod(const Number &a, const Number &m) {
|
||||||
mpz_mod(bn, a.bn, m.bn);
|
mpz_mod(bn, a.bn, m.bn);
|
||||||
}
|
}
|
||||||
int Compare(const Number &a) const {
|
int Compare(const Number &a) const {
|
||||||
|
@ -104,7 +95,7 @@ public:
|
||||||
return mpz_sizeinbase(bn,2);
|
return mpz_sizeinbase(bn,2);
|
||||||
}
|
}
|
||||||
// return the lowest (rightmost) bits bits, and rshift them away
|
// return the lowest (rightmost) bits bits, and rshift them away
|
||||||
int ShiftLowBits(Context &ctx, int bits) {
|
int ShiftLowBits(int bits) {
|
||||||
int ret = mpz_get_ui(bn) & ((1 << bits) - 1);
|
int ret = mpz_get_ui(bn) & ((1 << bits) - 1);
|
||||||
mpz_fdiv_q_2exp(bn, bn, bits);
|
mpz_fdiv_q_2exp(bn, bn, bits);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -134,7 +125,7 @@ public:
|
||||||
void SetPseudoRand(const Number &max) {
|
void SetPseudoRand(const Number &max) {
|
||||||
number_state.gen(bn, max.bn);
|
number_state.gen(bn, max.bn);
|
||||||
}
|
}
|
||||||
void SplitInto(Context &ctx, int bits, Number &low, Number &high) const {
|
void SplitInto(int bits, Number &low, Number &high) const {
|
||||||
mpz_t tmp;
|
mpz_t tmp;
|
||||||
mpz_init_set_ui(tmp,1);
|
mpz_init_set_ui(tmp,1);
|
||||||
mpz_mul_2exp(tmp,tmp,bits);
|
mpz_mul_2exp(tmp,tmp,bits);
|
||||||
|
|
145
num_openssl.h
145
num_openssl.h
|
@ -7,150 +7,151 @@
|
||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace secp256k1 {
|
namespace secp256k1 {
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
private:
|
private:
|
||||||
BN_CTX *bn_ctx;
|
BN_CTX *ctx;
|
||||||
bool root;
|
|
||||||
bool offspring;
|
|
||||||
|
|
||||||
public:
|
|
||||||
operator BN_CTX*() {
|
operator BN_CTX*() {
|
||||||
return bn_ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
friend class Number;
|
||||||
|
public:
|
||||||
Context() {
|
Context() {
|
||||||
bn_ctx = BN_CTX_new();
|
ctx = BN_CTX_new();
|
||||||
BN_CTX_start(bn_ctx);
|
|
||||||
root = true;
|
|
||||||
offspring = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Context(Context &par) {
|
|
||||||
bn_ctx = par.bn_ctx;
|
|
||||||
root = false;
|
|
||||||
offspring = false;
|
|
||||||
par.offspring = true;
|
|
||||||
BN_CTX_start(bn_ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~Context() {
|
~Context() {
|
||||||
BN_CTX_end(bn_ctx);
|
BN_CTX_free(ctx);
|
||||||
if (root)
|
|
||||||
BN_CTX_free(bn_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
BIGNUM *Get() {
|
|
||||||
assert(offspring == false);
|
|
||||||
return BN_CTX_get(bn_ctx);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Number {
|
class Number {
|
||||||
private:
|
private:
|
||||||
BIGNUM *bn;
|
BIGNUM b;
|
||||||
Number(const Number &x) {}
|
Number(const Number &x) {}
|
||||||
|
|
||||||
|
operator const BIGNUM*() const {
|
||||||
|
return &b;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator BIGNUM*() {
|
||||||
|
return &b;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
Number(Context &ctx) : bn(ctx.Get()) {}
|
Number() {
|
||||||
Number(Context &ctx, const unsigned char *bin, int len) : bn(ctx.Get()) {
|
BN_init(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Number() {
|
||||||
|
BN_free(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Number(const unsigned char *bin, int len) {
|
||||||
|
BN_init(*this);
|
||||||
SetBytes(bin,len);
|
SetBytes(bin,len);
|
||||||
}
|
}
|
||||||
void SetNumber(const Number &x) {
|
void SetNumber(const Number &x) {
|
||||||
BN_copy(bn, x.bn);
|
BN_copy(*this, x);
|
||||||
}
|
}
|
||||||
Number &operator=(const Number &x) {
|
Number &operator=(const Number &x) {
|
||||||
BN_copy(bn, x.bn);
|
BN_copy(*this, x);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
void SetBytes(const unsigned char *bin, int len) {
|
void SetBytes(const unsigned char *bin, int len) {
|
||||||
BN_bin2bn(bin, len, bn);
|
BN_bin2bn(bin, len, *this);
|
||||||
}
|
}
|
||||||
void GetBytes(unsigned char *bin, int len) {
|
void GetBytes(unsigned char *bin, int len) {
|
||||||
int size = BN_num_bytes(bn);
|
int size = BN_num_bytes(*this);
|
||||||
assert(size <= len);
|
assert(size <= len);
|
||||||
memset(bin,0,len);
|
memset(bin,0,len);
|
||||||
BN_bn2bin(bn, bin + len - size);
|
BN_bn2bin(*this, bin + len - size);
|
||||||
}
|
}
|
||||||
void SetInt(int x) {
|
void SetInt(int x) {
|
||||||
if (x >= 0) {
|
if (x >= 0) {
|
||||||
BN_set_word(bn, x);
|
BN_set_word(*this, x);
|
||||||
} else {
|
} else {
|
||||||
BN_set_word(bn, -x);
|
BN_set_word(*this, -x);
|
||||||
BN_set_negative(bn, 1);
|
BN_set_negative(*this, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SetModInverse(Context &ctx, const Number &x, const Number &m) {
|
void SetModInverse(const Number &x, const Number &m) {
|
||||||
BN_mod_inverse(bn, x.bn, m.bn, ctx);
|
Context ctx;
|
||||||
|
BN_mod_inverse(*this, x, m, ctx);
|
||||||
}
|
}
|
||||||
void SetModMul(Context &ctx, const Number &a, const Number &b, const Number &m) {
|
void SetModMul(const Number &a, const Number &b, const Number &m) {
|
||||||
BN_mod_mul(bn, a.bn, b.bn, m.bn, ctx);
|
Context ctx;
|
||||||
|
BN_mod_mul(*this, a, b, m, ctx);
|
||||||
}
|
}
|
||||||
void SetAdd(Context &ctx, const Number &a1, const Number &a2) {
|
void SetAdd(const Number &a1, const Number &a2) {
|
||||||
BN_add(bn, a1.bn, a2.bn);
|
BN_add(*this, a1, a2);
|
||||||
}
|
}
|
||||||
void SetSub(Context &ctx, const Number &a1, const Number &a2) {
|
void SetSub(const Number &a1, const Number &a2) {
|
||||||
BN_sub(bn, a1.bn, a2.bn);
|
BN_sub(*this, a1, a2);
|
||||||
}
|
}
|
||||||
void SetMult(Context &ctx, const Number &a1, const Number &a2) {
|
void SetMult(const Number &a1, const Number &a2) {
|
||||||
BN_mul(bn, a1.bn, a2.bn, ctx);
|
Context ctx;
|
||||||
|
BN_mul(*this, a1, a2, ctx);
|
||||||
}
|
}
|
||||||
void SetDiv(Context &ctx, const Number &a1, const Number &a2) {
|
void SetDiv(const Number &a1, const Number &a2) {
|
||||||
BN_div(bn, NULL, a1.bn, a2.bn, ctx);
|
Context ctx;
|
||||||
|
BN_div(*this, NULL, a1, a2, ctx);
|
||||||
}
|
}
|
||||||
void SetMod(Context &ctx, const Number &a, const Number &m) {
|
void SetMod(const Number &a, const Number &m) {
|
||||||
BN_nnmod(bn, a.bn, m.bn, ctx);
|
Context ctx;
|
||||||
|
BN_nnmod(*this, a, m, ctx);
|
||||||
}
|
}
|
||||||
int Compare(const Number &a) const {
|
int Compare(const Number &a) const {
|
||||||
return BN_cmp(bn, a.bn);
|
return BN_cmp(*this, a);
|
||||||
}
|
}
|
||||||
int GetBits() const {
|
int GetBits() const {
|
||||||
return BN_num_bits(bn);
|
return BN_num_bits(*this);
|
||||||
}
|
}
|
||||||
// return the lowest (rightmost) bits bits, and rshift them away
|
// return the lowest (rightmost) bits bits, and rshift them away
|
||||||
int ShiftLowBits(Context &ctx, int bits) {
|
int ShiftLowBits(int bits) {
|
||||||
Context ct(ctx);
|
BIGNUM *bn = *this;
|
||||||
BIGNUM *tmp = ct.Get();
|
int ret = BN_is_zero(bn) ? 0 : bn->d[0] & ((1 << bits) - 1);
|
||||||
BN_copy(tmp, bn);
|
BN_rshift(*this, *this, bits);
|
||||||
BN_mask_bits(tmp, bits);
|
|
||||||
int ret = BN_get_word(tmp);
|
|
||||||
BN_rshift(bn, bn, bits);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
// check whether number is 0,
|
// check whether number is 0,
|
||||||
bool IsZero() const {
|
bool IsZero() const {
|
||||||
return BN_is_zero(bn);
|
return BN_is_zero((const BIGNUM*)*this);
|
||||||
}
|
}
|
||||||
bool IsOdd() const {
|
bool IsOdd() const {
|
||||||
return BN_is_odd(bn);
|
return BN_is_odd((const BIGNUM*)*this);
|
||||||
}
|
}
|
||||||
bool IsNeg() const {
|
bool IsNeg() const {
|
||||||
return BN_is_negative(bn);
|
return BN_is_negative((const BIGNUM*)*this);
|
||||||
}
|
}
|
||||||
void Negate() {
|
void Negate() {
|
||||||
BN_set_negative(bn, !IsNeg());
|
BN_set_negative(*this, !IsNeg());
|
||||||
}
|
}
|
||||||
void Shift1() {
|
void Shift1() {
|
||||||
BN_rshift1(bn,bn);
|
BN_rshift1(*this,*this);
|
||||||
}
|
}
|
||||||
void Inc() {
|
void Inc() {
|
||||||
BN_add_word(bn,1);
|
BN_add_word(*this,1);
|
||||||
}
|
}
|
||||||
void SetHex(const std::string &str) {
|
void SetHex(const std::string &str) {
|
||||||
|
BIGNUM *bn = *this;
|
||||||
BN_hex2bn(&bn, str.c_str());
|
BN_hex2bn(&bn, str.c_str());
|
||||||
}
|
}
|
||||||
void SetPseudoRand(const Number &max) {
|
void SetPseudoRand(const Number &max) {
|
||||||
BN_pseudo_rand_range(bn, max.bn);
|
BN_pseudo_rand_range(*this, max);
|
||||||
}
|
}
|
||||||
void SplitInto(Context &ctx, int bits, Number &low, Number &high) const {
|
void SplitInto(int bits, Number &low, Number &high) const {
|
||||||
BN_copy(low.bn, bn);
|
BN_copy(low, *this);
|
||||||
BN_mask_bits(low.bn, bits);
|
BN_mask_bits(low, bits);
|
||||||
BN_rshift(high.bn, bn, bits);
|
BN_rshift(high, *this, bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString() const {
|
std::string ToString() const {
|
||||||
char *str = BN_bn2hex(bn);
|
char *str = BN_bn2hex(*this);
|
||||||
std::string ret(str);
|
std::string ret(str);
|
||||||
OPENSSL_free(str);
|
OPENSSL_free(str);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
49
tests.cpp
49
tests.cpp
|
@ -9,40 +9,39 @@
|
||||||
using namespace secp256k1;
|
using namespace secp256k1;
|
||||||
|
|
||||||
void test_run_ecmult_chain() {
|
void test_run_ecmult_chain() {
|
||||||
Context ctx;
|
|
||||||
// random starting point A (on the curve)
|
// random starting point A (on the curve)
|
||||||
FieldElem ax; ax.SetHex("8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004");
|
FieldElem ax; ax.SetHex("8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004");
|
||||||
FieldElem ay; ay.SetHex("a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f");
|
FieldElem ay; ay.SetHex("a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f");
|
||||||
GroupElemJac a(ax,ay);
|
GroupElemJac a(ax,ay);
|
||||||
// two random initial factors xn and gn
|
// two random initial factors xn and gn
|
||||||
Number xn(ctx); xn.SetHex("84cc5452f7fde1edb4d38a8ce9b1b84ccef31f146e569be9705d357a42985407");
|
Number xn; xn.SetHex("84cc5452f7fde1edb4d38a8ce9b1b84ccef31f146e569be9705d357a42985407");
|
||||||
Number gn(ctx); gn.SetHex("a1e58d22553dcd42b23980625d4c57a96e9323d42b3152e5ca2c3990edc7c9de");
|
Number gn; gn.SetHex("a1e58d22553dcd42b23980625d4c57a96e9323d42b3152e5ca2c3990edc7c9de");
|
||||||
// two small multipliers to be applied to xn and gn in every iteration:
|
// two small multipliers to be applied to xn and gn in every iteration:
|
||||||
Number xf(ctx); xf.SetHex("1337");
|
Number xf; xf.SetHex("1337");
|
||||||
Number gf(ctx); gf.SetHex("7113");
|
Number gf; gf.SetHex("7113");
|
||||||
// accumulators with the resulting coefficients to A and G
|
// accumulators with the resulting coefficients to A and G
|
||||||
Number ae(ctx); ae.SetHex("01");
|
Number ae; ae.SetHex("01");
|
||||||
Number ge(ctx); ge.SetHex("00");
|
Number ge; ge.SetHex("00");
|
||||||
// the point being computed
|
// the point being computed
|
||||||
GroupElemJac x = a;
|
GroupElemJac x = a;
|
||||||
const Number &order = GetGroupConst().order;
|
const Number &order = GetGroupConst().order;
|
||||||
for (int i=0; i<20000; i++) {
|
for (int i=0; i<20000; i++) {
|
||||||
// in each iteration, compute X = xn*X + gn*G;
|
// in each iteration, compute X = xn*X + gn*G;
|
||||||
ECMult(ctx, x, x, xn, gn);
|
ECMult(x, x, xn, gn);
|
||||||
// also compute ae and ge: the actual accumulated factors for A and G
|
// also compute ae and ge: the actual accumulated factors for A and G
|
||||||
// if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G)
|
// if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G)
|
||||||
ae.SetModMul(ctx, ae, xn, order);
|
ae.SetModMul(ae, xn, order);
|
||||||
ge.SetModMul(ctx, ge, xn, order);
|
ge.SetModMul(ge, xn, order);
|
||||||
ge.SetAdd(ctx, ge, gn);
|
ge.SetAdd(ge, gn);
|
||||||
ge.SetMod(ctx, ge, order);
|
ge.SetMod(ge, order);
|
||||||
// modify xn and gn
|
// modify xn and gn
|
||||||
xn.SetModMul(ctx, xn, xf, order);
|
xn.SetModMul(xn, xf, order);
|
||||||
gn.SetModMul(ctx, gn, gf, order);
|
gn.SetModMul(gn, gf, order);
|
||||||
}
|
}
|
||||||
std::string res = x.ToString();
|
std::string res = x.ToString();
|
||||||
assert(res == "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)");
|
assert(res == "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)");
|
||||||
// redo the computation, but directly with the resulting ae and ge coefficients:
|
// redo the computation, but directly with the resulting ae and ge coefficients:
|
||||||
GroupElemJac x2; ECMult(ctx, x2, a, ae, ge);
|
GroupElemJac x2; ECMult(x2, a, ae, ge);
|
||||||
std::string res2 = x2.ToString();
|
std::string res2 = x2.ToString();
|
||||||
assert(res == res2);
|
assert(res == res2);
|
||||||
}
|
}
|
||||||
|
@ -53,15 +52,13 @@ void test_point_times_order(const GroupElemJac &point) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const GroupConstants &c = GetGroupConst();
|
const GroupConstants &c = GetGroupConst();
|
||||||
Context ctx;
|
Number zero; zero.SetInt(0);
|
||||||
Number zero(ctx); zero.SetInt(0);
|
|
||||||
GroupElemJac res;
|
GroupElemJac res;
|
||||||
ECMult(ctx, res, point, c.order, zero); // calc res = order * point + 0 * G;
|
ECMult(res, point, c.order, zero); // calc res = order * point + 0 * G;
|
||||||
assert(res.IsInfinity());
|
assert(res.IsInfinity());
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_run_point_times_order() {
|
void test_run_point_times_order() {
|
||||||
Context ctx;
|
|
||||||
FieldElem x; x.SetHex("02");
|
FieldElem x; x.SetHex("02");
|
||||||
for (int i=0; i<500; i++) {
|
for (int i=0; i<500; i++) {
|
||||||
GroupElemJac j; j.SetCompressed(x, true);
|
GroupElemJac j; j.SetCompressed(x, true);
|
||||||
|
@ -72,14 +69,13 @@ void test_run_point_times_order() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_wnaf(const Number &number, int w) {
|
void test_wnaf(const Number &number, int w) {
|
||||||
Context ctx;
|
Number x, two, t;
|
||||||
Number x(ctx), two(ctx), t(ctx);
|
|
||||||
x.SetInt(0);
|
x.SetInt(0);
|
||||||
two.SetInt(2);
|
two.SetInt(2);
|
||||||
WNAF<1023> wnaf(ctx, number, w);
|
WNAF<1023> wnaf(number, w);
|
||||||
int zeroes = -1;
|
int zeroes = -1;
|
||||||
for (int i=wnaf.GetSize()-1; i>=0; i--) {
|
for (int i=wnaf.GetSize()-1; i>=0; i--) {
|
||||||
x.SetMult(ctx, x, two);
|
x.SetMult(x, two);
|
||||||
int v = wnaf.Get(i);
|
int v = wnaf.Get(i);
|
||||||
if (v) {
|
if (v) {
|
||||||
assert(zeroes == -1 || zeroes >= w-1); // check that distance between non-zero elements is at least w-1
|
assert(zeroes == -1 || zeroes >= w-1); // check that distance between non-zero elements is at least w-1
|
||||||
|
@ -92,18 +88,17 @@ void test_wnaf(const Number &number, int w) {
|
||||||
zeroes++;
|
zeroes++;
|
||||||
}
|
}
|
||||||
t.SetInt(v);
|
t.SetInt(v);
|
||||||
x.SetAdd(ctx, x, t);
|
x.SetAdd(x, t);
|
||||||
}
|
}
|
||||||
assert(x.Compare(number) == 0); // check that wnaf represents number
|
assert(x.Compare(number) == 0); // check that wnaf represents number
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_run_wnaf() {
|
void test_run_wnaf() {
|
||||||
Context ctx;
|
Number range, min, n;
|
||||||
Number range(ctx), min(ctx), n(ctx);
|
|
||||||
range.SetHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); // 2^1024-1
|
range.SetHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"); // 2^1024-1
|
||||||
min = range; min.Shift1(); min.Negate();
|
min = range; min.Shift1(); min.Negate();
|
||||||
for (int i=0; i<100; i++) {
|
for (int i=0; i<100; i++) {
|
||||||
n.SetPseudoRand(range); n.SetAdd(ctx,n,min);
|
n.SetPseudoRand(range); n.SetAdd(n,min);
|
||||||
test_wnaf(n, 4+(i%10));
|
test_wnaf(n, 4+(i%10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue