diff --git a/ecdsa.cpp b/ecdsa.cpp index fa6f9a6d074..0011907d72f 100644 --- a/ecdsa.cpp +++ b/ecdsa.cpp @@ -79,6 +79,7 @@ bool Signature::RecomputeR(Number &r2, const GroupElemJac &pubkey, const Number if (pr.IsInfinity()) return false; FieldElem xr; pr.GetX(xr); + xr.Normalize(); unsigned char xrb[32]; xr.GetBytes(xrb); r2.SetBytes(xrb,32); r2.SetMod(r2,c.order); return true; @@ -99,6 +100,7 @@ bool Signature::Sign(const Number &seckey, const Number &message, const Number & FieldElem rx; rp.GetX(rx); unsigned char b[32]; + rx.Normalize(); rx.GetBytes(b); r.SetBytes(b, 32); r.SetMod(r, c.order); diff --git a/field.cpp b/field.cpp index 5f7714cd8b0..61710c34b47 100644 --- a/field.cpp +++ b/field.cpp @@ -24,6 +24,7 @@ FieldElem::FieldElem(int x) { n[1] = n[2] = n[3] = n[4] = 0; #ifdef VERIFY_MAGNITUDE magnitude = 1; + normalized = true; #endif } @@ -69,22 +70,29 @@ void FieldElem::Normalize() { } #ifdef VERIFY_MAGNITUDE magnitude = 1; + normalized = true; #endif } -bool inline FieldElem::IsZero() { - Normalize(); +bool inline FieldElem::IsZero() const { +#ifdef VERIFY_MAGNITUDE + assert(normalized); +#endif return (n[0] == 0 && n[1] == 0 && n[2] == 0 && n[3] == 0 && n[4] == 0); } -bool inline operator==(FieldElem &a, FieldElem &b) { - a.Normalize(); - b.Normalize(); +bool inline operator==(const FieldElem &a, const FieldElem &b) { +#ifdef VERIFY_MAGNITUDE + 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]); } void FieldElem::GetBytes(unsigned char *o) { - Normalize(); +#ifdef VERIFY_MAGNITUDE + assert(normalized); +#endif for (int i=0; i<32; i++) { int c = 0; for (int j=0; j<2; j++) { @@ -107,6 +115,7 @@ void FieldElem::SetBytes(const unsigned char *in) { } #ifdef VERIFY_MAGNITUDE magnitude = 1; + normalized = true; #endif } @@ -114,6 +123,7 @@ void inline FieldElem::SetNeg(const FieldElem &a, int magnitudeIn) { #ifdef VERIFY_MAGNITUDE assert(a.magnitude <= magnitudeIn); magnitude = magnitudeIn + 1; + normalized = false; #endif n[0] = 0xFFFFEFFFFFC2FULL * (magnitudeIn + 1) - a.n[0]; 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) { #ifdef VERIFY_MAGNITUDE magnitude *= v; + normalized = false; #endif n[0] *= v; n[1] *= v; @@ -136,6 +147,7 @@ void inline FieldElem::operator*=(int v) { void inline FieldElem::operator+=(const FieldElem &a) { #ifdef VERIFY_MAGNITUDE magnitude += a.magnitude; + normalized = false; #endif n[0] += a.n[0]; n[1] += a.n[1]; @@ -200,6 +212,7 @@ void FieldElem::SetMult(const FieldElem &a, const FieldElem &b) { n[1] = t1 + c; #ifdef VERIFY_MAGNITUDE magnitude = 1; + normalized = false; #endif } @@ -247,6 +260,7 @@ void FieldElem::SetSquare(const FieldElem &a) { n[1] = t1 + c; #ifdef VERIFY_MAGNITUDE assert(a.magnitude <= 8); + normalized = false; #endif } @@ -283,13 +297,16 @@ void FieldElem::SetSquareRoot(const FieldElem &a) { SetMult(x,a780); } -bool FieldElem::IsOdd() { - Normalize(); +bool FieldElem::IsOdd() const { +#ifdef VERIFY_MAGNITUDE + assert(normalized); +#endif return n[0] & 1; } std::string FieldElem::ToString() { unsigned char tmp[32]; + Normalize(); GetBytes(tmp); std::string ret; for (int i=0; i<32; i++) { @@ -371,6 +388,7 @@ void FieldElem::SetInverse(FieldElem &a) { SetMult(x,a45); #else unsigned char b[32]; + a.Normalize(); a.GetBytes(b); { const Number &p = GetFieldConst().field_p; diff --git a/field.h b/field.h index 0584dbabda6..d74e2f98ff5 100644 --- a/field.h +++ b/field.h @@ -25,6 +25,7 @@ private: uint64_t n[5]; #ifdef VERIFY_MAGNITUDE int magnitude; + bool normalized; #endif public: @@ -37,9 +38,9 @@ public: /** Normalizes the internal representation entries. Magnitude=1 */ 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 */ void GetBytes(unsigned char *o); @@ -64,7 +65,7 @@ public: /** Set this to be the (modular) square root of another FieldElem. Magnitude=1 */ void SetSquareRoot(const FieldElem &a); - bool IsOdd(); + bool IsOdd() const; /** Set this to be the (modular) inverse of another FieldElem. Magnitude=1 */ void SetInverse(FieldElem &a); diff --git a/group.cpp b/group.cpp index 3a66174e206..a22a9a8258a 100644 --- a/group.cpp +++ b/group.cpp @@ -71,6 +71,8 @@ bool GroupElemJac::IsValid() const { FieldElem z6; z6.SetSquare(z2); z6.SetMult(z6,z2); z6 *= 7; x3 += z6; + y2.Normalize(); + x3.Normalize(); return y2 == x3; } @@ -122,12 +124,14 @@ void GroupElemJac::SetCompressed(const FieldElem &xin, bool fOdd) { c += x3; y.SetSquareRoot(c); z = FieldElem(1); + y.Normalize(); if (y.IsOdd() != fOdd) y.SetNeg(y,1); } void GroupElemJac::SetDouble(const GroupElemJac &p) { FieldElem t5 = p.y; + t5.Normalize(); if (p.fInfinity || t5.IsZero()) { fInfinity = true; return; @@ -174,7 +178,11 @@ void GroupElemJac::SetAdd(const GroupElemJac &p, const GroupElemJac &q) { FieldElem u2; u2.SetMult(x2, z12); FieldElem s1; s1.SetMult(y1, z22); s1.SetMult(s1, z2); FieldElem s2; s2.SetMult(y2, z12); s2.SetMult(s2, z1); + u1.Normalize(); + u2.Normalize(); if (u1 == u2) { + s1.Normalize(); + s2.Normalize(); if (s1 == s2) { SetDouble(p); } else { @@ -214,7 +222,11 @@ void GroupElemJac::SetAdd(const GroupElemJac &p, const GroupElem &q) { FieldElem u2; u2.SetMult(x2, z12); FieldElem s1 = y1; s1.Normalize(); FieldElem s2; s2.SetMult(y2, z12); s2.SetMult(s2, z1); + u1.Normalize(); + u2.Normalize(); if (u1 == u2) { + s1.Normalize(); + s2.Normalize(); if (s1 == s2) { SetDouble(p); } else {