bugfixes and num-based Field::Inverse
This commit is contained in:
parent
d8f05980e3
commit
e8c2a8ec9c
2
ecdsa.h
2
ecdsa.h
@ -48,7 +48,7 @@ public:
|
|||||||
//GroupElemJac pr = pubkey;
|
//GroupElemJac pr = pubkey;
|
||||||
if (pr.IsInfinity())
|
if (pr.IsInfinity())
|
||||||
return false;
|
return false;
|
||||||
FieldElem xr; pr.GetX(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);
|
||||||
}
|
}
|
||||||
|
25
ecmult.h
25
ecmult.h
@ -7,8 +7,12 @@
|
|||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "num.h"
|
#include "num.h"
|
||||||
|
|
||||||
|
// optimal for 128-bit and 256-bit exponents
|
||||||
#define WINDOW_A 5
|
#define WINDOW_A 5
|
||||||
#define WINDOW_G 13
|
|
||||||
|
// larger numbers may result in slightly better performance, at the cost of
|
||||||
|
// exponentially larger precomputed tables. WINDOW_G == 13 results in 640 KiB.
|
||||||
|
#define WINDOW_G 14
|
||||||
|
|
||||||
namespace secp256k1 {
|
namespace secp256k1 {
|
||||||
|
|
||||||
@ -19,18 +23,18 @@ private:
|
|||||||
public:
|
public:
|
||||||
WNAFPrecomp() {}
|
WNAFPrecomp() {}
|
||||||
|
|
||||||
void Build(const G &base) {
|
void Build(Context &ctx, 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(x);
|
pre[i].SetJac(ctx, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WNAFPrecomp(const G &base) {
|
WNAFPrecomp(Context &ctx, const G &base) {
|
||||||
Build(base);
|
Build(ctx, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Get(G &out, int exp) const {
|
void Get(G &out, int exp) const {
|
||||||
@ -113,13 +117,14 @@ 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(g128j);
|
GroupElem g128; g128.SetJac(ctx, g128j);
|
||||||
wpg.Build(g);
|
wpg.Build(ctx, g);
|
||||||
wpg128.Build(g128);
|
wpg128.Build(ctx, g128);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -146,8 +151,8 @@ void ECMult(Context &ctx, GroupElemJac &out, const GroupElemJac &a, const Number
|
|||||||
WNAF<128> wg1(ct, gn1, WINDOW_G);
|
WNAF<128> wg1(ct, gn1, WINDOW_G);
|
||||||
WNAF<128> wg2(ct, gn2, WINDOW_G);
|
WNAF<128> wg2(ct, gn2, WINDOW_G);
|
||||||
GroupElemJac a2; a2.SetMulLambda(a);
|
GroupElemJac a2; a2.SetMulLambda(a);
|
||||||
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa1(a);
|
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa1(ct, a);
|
||||||
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa2(a2);
|
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa2(ct, a2);
|
||||||
const ECMultConsts &c = GetECMultConsts();
|
const ECMultConsts &c = GetECMultConsts();
|
||||||
|
|
||||||
int size_a1 = wa1.GetSize();
|
int size_a1 = wa1.GetSize();
|
||||||
|
79
field.h
79
field.h
@ -308,38 +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(const FieldElem &a) {
|
void SetInverse(Context &ctx, const FieldElem &a);
|
||||||
// calculate a^p, with p={45,63,1019,1023}
|
|
||||||
FieldElem a2; a2.SetSquare(a);
|
|
||||||
FieldElem a3; a3.SetMult(a2,a);
|
|
||||||
FieldElem a4; a4.SetSquare(a2);
|
|
||||||
FieldElem a5; a5.SetMult(a4,a);
|
|
||||||
FieldElem a10; a10.SetSquare(a5);
|
|
||||||
FieldElem a11; a11.SetMult(a10,a);
|
|
||||||
FieldElem a21; a21.SetMult(a11,a10);
|
|
||||||
FieldElem a42; a42.SetSquare(a21);
|
|
||||||
FieldElem a45; a45.SetMult(a42,a3);
|
|
||||||
FieldElem a63; a63.SetMult(a42,a21);
|
|
||||||
FieldElem a126; a126.SetSquare(a63);
|
|
||||||
FieldElem a252; a252.SetSquare(a126);
|
|
||||||
FieldElem a504; a504.SetSquare(a252);
|
|
||||||
FieldElem a1008; a1008.SetSquare(a504);
|
|
||||||
FieldElem a1019; a1019.SetMult(a1008,a11);
|
|
||||||
FieldElem a1023; a1023.SetMult(a1019,a4);
|
|
||||||
FieldElem x = a63;
|
|
||||||
for (int i=0; i<21; i++) {
|
|
||||||
for (int j=0; j<10; j++) x.SetSquare(x);
|
|
||||||
x.SetMult(x,a1023);
|
|
||||||
}
|
|
||||||
for (int j=0; j<10; j++) x.SetSquare(x);
|
|
||||||
x.SetMult(x,a1019);
|
|
||||||
for (int i=0; i<2; i++) {
|
|
||||||
for (int j=0; j<10; j++) x.SetSquare(x);
|
|
||||||
x.SetMult(x,a1023);
|
|
||||||
}
|
|
||||||
for (int j=0; j<10; j++) x.SetSquare(x);
|
|
||||||
SetMult(x,a45);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string ToString() {
|
std::string ToString() {
|
||||||
unsigned char tmp[32];
|
unsigned char tmp[32];
|
||||||
@ -399,6 +368,52 @@ const FieldConstants &GetFieldConst() {
|
|||||||
return field_const;
|
return field_const;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FieldElem::SetInverse(Context &ctx, const FieldElem &a) {
|
||||||
|
#if 0
|
||||||
|
// calculate a^p, with p={45,63,1019,1023}
|
||||||
|
FieldElem a2; a2.SetSquare(a);
|
||||||
|
FieldElem a3; a3.SetMult(a2,a);
|
||||||
|
FieldElem a4; a4.SetSquare(a2);
|
||||||
|
FieldElem a5; a5.SetMult(a4,a);
|
||||||
|
FieldElem a10; a10.SetSquare(a5);
|
||||||
|
FieldElem a11; a11.SetMult(a10,a);
|
||||||
|
FieldElem a21; a21.SetMult(a11,a10);
|
||||||
|
FieldElem a42; a42.SetSquare(a21);
|
||||||
|
FieldElem a45; a45.SetMult(a42,a3);
|
||||||
|
FieldElem a63; a63.SetMult(a42,a21);
|
||||||
|
FieldElem a126; a126.SetSquare(a63);
|
||||||
|
FieldElem a252; a252.SetSquare(a126);
|
||||||
|
FieldElem a504; a504.SetSquare(a252);
|
||||||
|
FieldElem a1008; a1008.SetSquare(a504);
|
||||||
|
FieldElem a1019; a1019.SetMult(a1008,a11);
|
||||||
|
FieldElem a1023; a1023.SetMult(a1019,a4);
|
||||||
|
FieldElem x = a63;
|
||||||
|
for (int i=0; i<21; i++) {
|
||||||
|
for (int j=0; j<10; j++) x.SetSquare(x);
|
||||||
|
x.SetMult(x,a1023);
|
||||||
|
}
|
||||||
|
for (int j=0; j<10; j++) x.SetSquare(x);
|
||||||
|
x.SetMult(x,a1019);
|
||||||
|
for (int i=0; i<2; i++) {
|
||||||
|
for (int j=0; j<10; j++) x.SetSquare(x);
|
||||||
|
x.SetMult(x,a1023);
|
||||||
|
}
|
||||||
|
for (int j=0; j<10; j++) x.SetSquare(x);
|
||||||
|
SetMult(x,a45);
|
||||||
|
#else
|
||||||
|
unsigned char b[32];
|
||||||
|
GetBytes(b);
|
||||||
|
{
|
||||||
|
const Number &p = GetFieldConst().field_p;
|
||||||
|
Context ct(ctx);
|
||||||
|
Number n(ct); n.SetBytes(b, 32);
|
||||||
|
n.SetModInverse(ct, n, p);
|
||||||
|
n.GetBytes(b, 32);
|
||||||
|
}
|
||||||
|
SetBytes(b);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
23
group.h
23
group.h
@ -54,7 +54,7 @@ public:
|
|||||||
return "(" + xc.ToString() + "," + yc.ToString() + ")";
|
return "(" + xc.ToString() + "," + yc.ToString() + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetJac(GroupElemJac &jac);
|
void SetJac(Context &ctx, 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(GroupElemJac &jac) {
|
void SetJac(Context &ctx, 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(GroupElem &aff) {
|
void GetAffine(Context &ctx, GroupElem &aff) {
|
||||||
z.SetInverse(z);
|
z.SetInverse(ctx, 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(FieldElem &xout) {
|
void GetX(Context &ctx, FieldElem &xout) {
|
||||||
FieldElem zi;
|
FieldElem zi;
|
||||||
zi.SetInverse(z);
|
zi.SetInverse(ctx, 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(FieldElem &yout) {
|
void GetY(Context &ctx, FieldElem &yout) {
|
||||||
FieldElem zi;
|
FieldElem zi;
|
||||||
zi.SetInverse(z);
|
zi.SetInverse(ctx, 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,17 +260,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString() const {
|
std::string ToString() const {
|
||||||
|
Context ctx;
|
||||||
GroupElemJac cop = *this;
|
GroupElemJac cop = *this;
|
||||||
GroupElem aff;
|
GroupElem aff;
|
||||||
cop.GetAffine(aff);
|
cop.GetAffine(ctx, aff);
|
||||||
return aff.ToString();
|
return aff.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMulLambda(const GroupElemJac &p);
|
void SetMulLambda(const GroupElemJac &p);
|
||||||
};
|
};
|
||||||
|
|
||||||
void GroupElem::SetJac(GroupElemJac &jac) {
|
void GroupElem::SetJac(Context &ctx, GroupElemJac &jac) {
|
||||||
jac.GetAffine(*this);
|
jac.GetAffine(ctx, *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,
|
||||||
|
4
num.h
4
num.h
@ -1,7 +1,7 @@
|
|||||||
#ifndef _SECP256K1_NUM_
|
#ifndef _SECP256K1_NUM_
|
||||||
#define _SECP256K1_NUM_
|
#define _SECP256K1_NUM_
|
||||||
|
|
||||||
// #include "num_gmp.h"
|
#include "num_gmp.h"
|
||||||
#include "num_openssl.h"
|
// #include "num_openssl.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -68,7 +68,9 @@ public:
|
|||||||
int size = (mpz_sizeinbase(bn,2)+7)/8;
|
int size = (mpz_sizeinbase(bn,2)+7)/8;
|
||||||
assert(size <= len);
|
assert(size <= len);
|
||||||
memset(bin,0,len);
|
memset(bin,0,len);
|
||||||
mpz_export(bin + size - len, NULL, 1, 1, 1, 0, bn);
|
size_t count = 0;
|
||||||
|
mpz_export(bin + len - size, &count, 1, 1, 1, 0, bn);
|
||||||
|
assert(size == count);
|
||||||
}
|
}
|
||||||
void SetInt(int x) {
|
void SetInt(int x) {
|
||||||
mpz_set_si(bn, x);
|
mpz_set_si(bn, x);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user