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;
if (pr.IsInfinity())
return false;
FieldElem xr; pr.GetX(xr);
FieldElem xr; pr.GetX(ct, xr);
unsigned char xrb[32]; xr.GetBytes(xrb);
r2.SetBytes(xrb,32); r2.SetMod(ct,r2,c.order);
}

View File

@ -7,8 +7,12 @@
#include "group.h"
#include "num.h"
// optimal for 128-bit and 256-bit exponents
#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 {
@ -19,18 +23,18 @@ private:
public:
WNAFPrecomp() {}
void Build(const G &base) {
void Build(Context &ctx, const G &base) {
pre[0] = base;
GroupElemJac x(base);
GroupElemJac d; d.SetDouble(x);
for (int i=1; i<(1 << (W-2)); i++) {
x.SetAdd(d,pre[i-1]);
pre[i].SetJac(x);
pre[i].SetJac(ctx, x);
}
}
WNAFPrecomp(const G &base) {
Build(base);
WNAFPrecomp(Context &ctx, const G &base) {
Build(ctx, base);
}
void Get(G &out, int exp) const {
@ -113,13 +117,14 @@ public:
WNAFPrecomp<GroupElem,WINDOW_G> wpg128;
ECMultConsts() {
Context ctx;
const GroupElem &g = GetGroupConst().g;
GroupElemJac g128j(g);
for (int i=0; i<128; i++)
g128j.SetDouble(g128j);
GroupElem g128; g128.SetJac(g128j);
wpg.Build(g);
wpg128.Build(g128);
GroupElem g128; g128.SetJac(ctx, g128j);
wpg.Build(ctx, g);
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> wg2(ct, gn2, WINDOW_G);
GroupElemJac a2; a2.SetMulLambda(a);
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa1(a);
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa2(a2);
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa1(ct, a);
WNAFPrecomp<GroupElemJac,WINDOW_A> wpa2(ct, a2);
const ECMultConsts &c = GetECMultConsts();
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 */
void SetInverse(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);
}
void SetInverse(Context &ctx, const FieldElem &a);
std::string ToString() {
unsigned char tmp[32];
@ -399,6 +368,52 @@ const FieldConstants &GetFieldConst() {
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

23
group.h
View File

@ -54,7 +54,7 @@ public:
return "(" + xc.ToString() + "," + yc.ToString() + ")";
}
void SetJac(GroupElemJac &jac);
void SetJac(Context &ctx, GroupElemJac &jac);
friend class GroupElemJac;
};
@ -73,7 +73,7 @@ public:
GroupElemJac(const GroupElem &in) : GroupElem(in), z(1) {}
void SetJac(GroupElemJac &jac) {
void SetJac(Context &ctx, GroupElemJac &jac) {
*this = jac;
}
@ -95,8 +95,8 @@ public:
}
/** Returns the affine coordinates of this point */
void GetAffine(GroupElem &aff) {
z.SetInverse(z);
void GetAffine(Context &ctx, GroupElem &aff) {
z.SetInverse(ctx, z);
FieldElem z2;
z2.SetSquare(z);
FieldElem z3;
@ -109,9 +109,9 @@ public:
aff.y = y;
}
void GetX(FieldElem &xout) {
void GetX(Context &ctx, FieldElem &xout) {
FieldElem zi;
zi.SetInverse(z);
zi.SetInverse(ctx, z);
zi.SetSquare(zi);
xout.SetMult(x, zi);
}
@ -120,9 +120,9 @@ public:
return fInfinity;
}
void GetY(FieldElem &yout) {
void GetY(Context &ctx, FieldElem &yout) {
FieldElem zi;
zi.SetInverse(z);
zi.SetInverse(ctx, z);
FieldElem zi3; zi3.SetSquare(zi); zi3.SetMult(zi, zi3);
yout.SetMult(y, zi3);
}
@ -260,17 +260,18 @@ public:
}
std::string ToString() const {
Context ctx;
GroupElemJac cop = *this;
GroupElem aff;
cop.GetAffine(aff);
cop.GetAffine(ctx, aff);
return aff.ToString();
}
void SetMulLambda(const GroupElemJac &p);
};
void GroupElem::SetJac(GroupElemJac &jac) {
jac.GetAffine(*this);
void GroupElem::SetJac(Context &ctx, GroupElemJac &jac) {
jac.GetAffine(ctx, *this);
}
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_
#define _SECP256K1_NUM_
// #include "num_gmp.h"
#include "num_openssl.h"
#include "num_gmp.h"
// #include "num_openssl.h"
#endif

View File

@ -68,7 +68,9 @@ public:
int size = (mpz_sizeinbase(bn,2)+7)/8;
assert(size <= 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) {
mpz_set_si(bn, x);