bugfixes and num-based Field::Inverse

This commit is contained in:
Pieter Wuille 2013-03-11 03:09:07 +01:00
parent d8f05980e3
commit e8c2a8ec9c
6 changed files with 80 additions and 57 deletions

View File

@ -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);
} }

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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

View File

@ -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);