0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-08 14:34:53 -05:00

Make Field::Normalize explicit

This commit is contained in:
Pieter Wuille 2013-03-21 01:10:30 +01:00
parent 0a07e62f6f
commit 8a926ee91f
4 changed files with 44 additions and 11 deletions

View file

@ -79,6 +79,7 @@ bool Signature::RecomputeR(Number &r2, const GroupElemJac &pubkey, const Number
if (pr.IsInfinity()) if (pr.IsInfinity())
return false; return false;
FieldElem xr; pr.GetX(xr); FieldElem xr; pr.GetX(xr);
xr.Normalize();
unsigned char xrb[32]; xr.GetBytes(xrb); unsigned char xrb[32]; xr.GetBytes(xrb);
r2.SetBytes(xrb,32); r2.SetMod(r2,c.order); r2.SetBytes(xrb,32); r2.SetMod(r2,c.order);
return true; return true;
@ -99,6 +100,7 @@ bool Signature::Sign(const Number &seckey, const Number &message, const Number &
FieldElem rx; FieldElem rx;
rp.GetX(rx); rp.GetX(rx);
unsigned char b[32]; unsigned char b[32];
rx.Normalize();
rx.GetBytes(b); rx.GetBytes(b);
r.SetBytes(b, 32); r.SetBytes(b, 32);
r.SetMod(r, c.order); r.SetMod(r, c.order);

View file

@ -24,6 +24,7 @@ FieldElem::FieldElem(int x) {
n[1] = n[2] = n[3] = n[4] = 0; n[1] = n[2] = n[3] = n[4] = 0;
#ifdef VERIFY_MAGNITUDE #ifdef VERIFY_MAGNITUDE
magnitude = 1; magnitude = 1;
normalized = true;
#endif #endif
} }
@ -69,22 +70,29 @@ void FieldElem::Normalize() {
} }
#ifdef VERIFY_MAGNITUDE #ifdef VERIFY_MAGNITUDE
magnitude = 1; magnitude = 1;
normalized = true;
#endif #endif
} }
bool inline FieldElem::IsZero() { bool inline FieldElem::IsZero() const {
Normalize(); #ifdef VERIFY_MAGNITUDE
assert(normalized);
#endif
return (n[0] == 0 && n[1] == 0 && n[2] == 0 && n[3] == 0 && n[4] == 0); return (n[0] == 0 && n[1] == 0 && n[2] == 0 && n[3] == 0 && n[4] == 0);
} }
bool inline operator==(FieldElem &a, FieldElem &b) { bool inline operator==(const FieldElem &a, const FieldElem &b) {
a.Normalize(); #ifdef VERIFY_MAGNITUDE
b.Normalize(); assert(a.normalized);
assert(b.normalized);
#endif
return (a.n[0] == b.n[0] && a.n[1] == b.n[1] && a.n[2] == b.n[2] && a.n[3] == b.n[3] && a.n[4] == b.n[4]); return (a.n[0] == b.n[0] && a.n[1] == b.n[1] && a.n[2] == b.n[2] && a.n[3] == b.n[3] && a.n[4] == b.n[4]);
} }
void FieldElem::GetBytes(unsigned char *o) { void FieldElem::GetBytes(unsigned char *o) {
Normalize(); #ifdef VERIFY_MAGNITUDE
assert(normalized);
#endif
for (int i=0; i<32; i++) { for (int i=0; i<32; i++) {
int c = 0; int c = 0;
for (int j=0; j<2; j++) { for (int j=0; j<2; j++) {
@ -107,6 +115,7 @@ void FieldElem::SetBytes(const unsigned char *in) {
} }
#ifdef VERIFY_MAGNITUDE #ifdef VERIFY_MAGNITUDE
magnitude = 1; magnitude = 1;
normalized = true;
#endif #endif
} }
@ -114,6 +123,7 @@ void inline FieldElem::SetNeg(const FieldElem &a, int magnitudeIn) {
#ifdef VERIFY_MAGNITUDE #ifdef VERIFY_MAGNITUDE
assert(a.magnitude <= magnitudeIn); assert(a.magnitude <= magnitudeIn);
magnitude = magnitudeIn + 1; magnitude = magnitudeIn + 1;
normalized = false;
#endif #endif
n[0] = 0xFFFFEFFFFFC2FULL * (magnitudeIn + 1) - a.n[0]; n[0] = 0xFFFFEFFFFFC2FULL * (magnitudeIn + 1) - a.n[0];
n[1] = 0xFFFFFFFFFFFFFULL * (magnitudeIn + 1) - a.n[1]; n[1] = 0xFFFFFFFFFFFFFULL * (magnitudeIn + 1) - a.n[1];
@ -125,6 +135,7 @@ void inline FieldElem::SetNeg(const FieldElem &a, int magnitudeIn) {
void inline FieldElem::operator*=(int v) { void inline FieldElem::operator*=(int v) {
#ifdef VERIFY_MAGNITUDE #ifdef VERIFY_MAGNITUDE
magnitude *= v; magnitude *= v;
normalized = false;
#endif #endif
n[0] *= v; n[0] *= v;
n[1] *= v; n[1] *= v;
@ -136,6 +147,7 @@ void inline FieldElem::operator*=(int v) {
void inline FieldElem::operator+=(const FieldElem &a) { void inline FieldElem::operator+=(const FieldElem &a) {
#ifdef VERIFY_MAGNITUDE #ifdef VERIFY_MAGNITUDE
magnitude += a.magnitude; magnitude += a.magnitude;
normalized = false;
#endif #endif
n[0] += a.n[0]; n[0] += a.n[0];
n[1] += a.n[1]; n[1] += a.n[1];
@ -200,6 +212,7 @@ void FieldElem::SetMult(const FieldElem &a, const FieldElem &b) {
n[1] = t1 + c; n[1] = t1 + c;
#ifdef VERIFY_MAGNITUDE #ifdef VERIFY_MAGNITUDE
magnitude = 1; magnitude = 1;
normalized = false;
#endif #endif
} }
@ -247,6 +260,7 @@ void FieldElem::SetSquare(const FieldElem &a) {
n[1] = t1 + c; n[1] = t1 + c;
#ifdef VERIFY_MAGNITUDE #ifdef VERIFY_MAGNITUDE
assert(a.magnitude <= 8); assert(a.magnitude <= 8);
normalized = false;
#endif #endif
} }
@ -283,13 +297,16 @@ void FieldElem::SetSquareRoot(const FieldElem &a) {
SetMult(x,a780); SetMult(x,a780);
} }
bool FieldElem::IsOdd() { bool FieldElem::IsOdd() const {
Normalize(); #ifdef VERIFY_MAGNITUDE
assert(normalized);
#endif
return n[0] & 1; return n[0] & 1;
} }
std::string FieldElem::ToString() { std::string FieldElem::ToString() {
unsigned char tmp[32]; unsigned char tmp[32];
Normalize();
GetBytes(tmp); GetBytes(tmp);
std::string ret; std::string ret;
for (int i=0; i<32; i++) { for (int i=0; i<32; i++) {
@ -371,6 +388,7 @@ void FieldElem::SetInverse(FieldElem &a) {
SetMult(x,a45); SetMult(x,a45);
#else #else
unsigned char b[32]; unsigned char b[32];
a.Normalize();
a.GetBytes(b); a.GetBytes(b);
{ {
const Number &p = GetFieldConst().field_p; const Number &p = GetFieldConst().field_p;

View file

@ -25,6 +25,7 @@ private:
uint64_t n[5]; uint64_t n[5];
#ifdef VERIFY_MAGNITUDE #ifdef VERIFY_MAGNITUDE
int magnitude; int magnitude;
bool normalized;
#endif #endif
public: public:
@ -37,9 +38,9 @@ public:
/** Normalizes the internal representation entries. Magnitude=1 */ /** Normalizes the internal representation entries. Magnitude=1 */
void Normalize(); void Normalize();
bool IsZero(); bool IsZero() const;
bool friend operator==(FieldElem &a, FieldElem &b); bool friend operator==(const FieldElem &a, const FieldElem &b);
/** extract as 32-byte big endian array */ /** extract as 32-byte big endian array */
void GetBytes(unsigned char *o); void GetBytes(unsigned char *o);
@ -64,7 +65,7 @@ public:
/** Set this to be the (modular) square root of another FieldElem. Magnitude=1 */ /** Set this to be the (modular) square root of another FieldElem. Magnitude=1 */
void SetSquareRoot(const FieldElem &a); void SetSquareRoot(const FieldElem &a);
bool IsOdd(); bool IsOdd() const;
/** 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(FieldElem &a); void SetInverse(FieldElem &a);

View file

@ -71,6 +71,8 @@ bool GroupElemJac::IsValid() const {
FieldElem z6; z6.SetSquare(z2); z6.SetMult(z6,z2); FieldElem z6; z6.SetSquare(z2); z6.SetMult(z6,z2);
z6 *= 7; z6 *= 7;
x3 += z6; x3 += z6;
y2.Normalize();
x3.Normalize();
return y2 == x3; return y2 == x3;
} }
@ -122,12 +124,14 @@ void GroupElemJac::SetCompressed(const FieldElem &xin, bool fOdd) {
c += x3; c += x3;
y.SetSquareRoot(c); y.SetSquareRoot(c);
z = FieldElem(1); z = FieldElem(1);
y.Normalize();
if (y.IsOdd() != fOdd) if (y.IsOdd() != fOdd)
y.SetNeg(y,1); y.SetNeg(y,1);
} }
void GroupElemJac::SetDouble(const GroupElemJac &p) { void GroupElemJac::SetDouble(const GroupElemJac &p) {
FieldElem t5 = p.y; FieldElem t5 = p.y;
t5.Normalize();
if (p.fInfinity || t5.IsZero()) { if (p.fInfinity || t5.IsZero()) {
fInfinity = true; fInfinity = true;
return; return;
@ -174,7 +178,11 @@ void GroupElemJac::SetAdd(const GroupElemJac &p, const GroupElemJac &q) {
FieldElem u2; u2.SetMult(x2, z12); FieldElem u2; u2.SetMult(x2, z12);
FieldElem s1; s1.SetMult(y1, z22); s1.SetMult(s1, z2); FieldElem s1; s1.SetMult(y1, z22); s1.SetMult(s1, z2);
FieldElem s2; s2.SetMult(y2, z12); s2.SetMult(s2, z1); FieldElem s2; s2.SetMult(y2, z12); s2.SetMult(s2, z1);
u1.Normalize();
u2.Normalize();
if (u1 == u2) { if (u1 == u2) {
s1.Normalize();
s2.Normalize();
if (s1 == s2) { if (s1 == s2) {
SetDouble(p); SetDouble(p);
} else { } else {
@ -214,7 +222,11 @@ void GroupElemJac::SetAdd(const GroupElemJac &p, const GroupElem &q) {
FieldElem u2; u2.SetMult(x2, z12); FieldElem u2; u2.SetMult(x2, z12);
FieldElem s1 = y1; s1.Normalize(); FieldElem s1 = y1; s1.Normalize();
FieldElem s2; s2.SetMult(y2, z12); s2.SetMult(s2, z1); FieldElem s2; s2.SetMult(y2, z12); s2.SetMult(s2, z1);
u1.Normalize();
u2.Normalize();
if (u1 == u2) { if (u1 == u2) {
s1.Normalize();
s2.Normalize();
if (s1 == s2) { if (s1 == s2) {
SetDouble(p); SetDouble(p);
} else { } else {