diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp index 9ded39e..ddecdf5 100644 --- a/include/mcl/bn.hpp +++ b/include/mcl/bn.hpp @@ -1172,8 +1172,10 @@ struct BNT { #endif exp_d1(y, y); } - static void millerLoop(Fp12& f, const G1& P, const G2& Q) + static void millerLoop(Fp12& f, const G1& P_, const G2& Q_) { + G1 P(P_); + G2 Q(Q_); P.normalize(); Q.normalize(); G2 T = Q; @@ -1234,9 +1236,10 @@ struct BNT { /* allocate param.precomputedQcoeffSize elements of Fp6 for Qcoeff */ - static void precomputeG2(Fp6 *Qcoeff, const G2& Q) + static void precomputeG2(Fp6 *Qcoeff, const G2& Q_) { size_t idx = 0; + G2 Q(Q_); Q.normalize(); G2 T = Q; G2 negQ; @@ -1271,8 +1274,9 @@ struct BNT { { precomputedMillerLoop(f, P, Qcoeff.data()); } - static void precomputedMillerLoop(Fp12& f, const G1& P, const Fp6* Qcoeff) + static void precomputedMillerLoop(Fp12& f, const G1& P_, const Fp6* Qcoeff) { + G1 P(P_); P.normalize(); size_t idx = 0; Fp6 d, e; @@ -1312,8 +1316,9 @@ struct BNT { { precomputedMillerLoop2(f, P1, Q1coeff.data(), P2, Q2coeff.data()); } - static void precomputedMillerLoop2(Fp12& f, const G1& P1, const Fp6* Q1coeff, const G1& P2, const Fp6* Q2coeff) + static void precomputedMillerLoop2(Fp12& f, const G1& P1_, const Fp6* Q1coeff, const G1& P2_, const Fp6* Q2coeff) { + G1 P1(P1_), P2(P2_); P1.normalize(); P2.normalize(); size_t idx = 0; diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp index 8ddd456..fcd7d99 100644 --- a/include/mcl/ec.hpp +++ b/include/mcl/ec.hpp @@ -48,7 +48,7 @@ public: Fp x, y; bool inf_; #else - mutable Fp x, y, z; + Fp x, y, z; static int mode_; #endif static Fp a_; @@ -78,7 +78,7 @@ public: } #ifndef MCL_EC_USE_AFFINE private: - void normalizeJacobi() const + void normalizeJacobi() { assert(!z.isZero()); Fp rz2; @@ -89,7 +89,7 @@ private: y *= z; z = 1; } - void normalizeProj() const + void normalizeProj() { assert(!z.isZero()); Fp::inv(z, z); @@ -141,7 +141,7 @@ private: } public: #endif - void normalize() const + void normalize() { #ifndef MCL_EC_USE_AFFINE if (isNormalized()) return; @@ -608,18 +608,20 @@ public: /* 0 <= P for any P (Px, Py) <= (P'x, P'y) iff Px < P'x or Px == P'x and Py <= P'y + @note compare function calls normalize() */ template - static inline int compareFunc(const EcT& P, const EcT& Q, F comp) + static inline int compareFunc(const EcT& P_, const EcT& Q_, F comp) { - P.normalize(); - Q.normalize(); - const bool QisZero = Q.isZero(); - if (P.isZero()) { + const bool QisZero = Q_.isZero(); + if (P_.isZero()) { if (QisZero) return 0; return -1; } if (QisZero) return 1; + EcT P(P_), Q(Q_); + P.normalize(); + Q.normalize(); int c = comp(P.x, Q.x); if (c > 0) return 1; if (c < 0) return -1; @@ -659,7 +661,7 @@ public: */ void getStr(std::string& str, int ioMode = 10) const { - normalize(); + EcT P(*this); P.normalize(); if (ioMode & IoTight) { if (!isIoTightSupported()) throw cybozu::Exception("EcT:getStr:not supported ioMode") << ioMode; const size_t n = Fp::getByteSize(); @@ -667,9 +669,9 @@ public: str.resize(n, 0); return; } - x.getStr(str, ioMode); + P.x.getStr(str, ioMode); assert(str.size() == n && (str[n - 1] & 0x80) == 0); - if (y.isOdd()) { + if (P.y.isOdd()) { str[n - 1] |= 0x80; } return; @@ -680,15 +682,15 @@ public: } const char *sep = Fp::BaseFp::getIoSeparator(); if (compressedExpression_) { - str = y.isOdd() ? '3' : '2'; + str = P.y.isOdd() ? '3' : '2'; str += sep; - str += x.getStr(ioMode); + str += P.x.getStr(ioMode); } else { str = '1'; str += sep; - str += x.getStr(ioMode); + str += P.x.getStr(ioMode); str += sep; - str += y.getStr(ioMode); + str += P.y.getStr(ioMode); } } std::string getStr(int ioMode = 10) const @@ -809,16 +811,7 @@ public: bool operator!=(const EcT& rhs) const { return !operator==(rhs); } bool operator<(const EcT& rhs) const { - if (isZero()) { - return !rhs.isZero(); - } - if (rhs.isZero()) return false; - normalize(); - rhs.normalize(); - int cmp = Fp::compare(x, rhs.x); - if (cmp < 0) return true; - if (cmp > 0) return false; - return y < rhs.y; + return compare(*this, rhs) < 0; } bool operator>=(const EcT& rhs) const { return !operator<(rhs); } bool operator>(const EcT& rhs) const { return rhs < *this; } @@ -879,10 +872,10 @@ struct EcParam { #ifdef CYBOZU_USE_BOOST namespace mcl { template -size_t hash_value(const mcl::EcT& P) +size_t hash_value(const mcl::EcT& P_) { - if (P.isZero()) return 0; - P.normalize(); + if (P_.isZero()) return 0; + mcl::EcT P(P_); P.normalize(); return mcl::hash_value(P.y, mcl::hash_value(P.x)); } @@ -892,10 +885,10 @@ namespace std { CYBOZU_NAMESPACE_TR1_BEGIN template struct hash > { - size_t operator()(const mcl::EcT& P) const + size_t operator()(const mcl::EcT& P_) const { - if (P.isZero()) return 0; - P.normalize(); + if (P_.isZero()) return 0; + mcl::EcT P(P_); P.normalize(); return hash()(P.y, hash()(P.x)); } }; diff --git a/test/ec_test.cpp b/test/ec_test.cpp index 39d58e7..bda3951 100644 --- a/test/ec_test.cpp +++ b/test/ec_test.cpp @@ -350,6 +350,29 @@ struct Test { CYBOZU_TEST_EQUAL(Q1, Q2); } } + void compare() const + { + Fp x(para.gx); + Fp y(para.gy); + Ec P1(x, y); + Ec P2(x, -y); + int c = Ec::compare(P1, P2); + int cx = Fp::compare(y, -y); + CYBOZU_TEST_EQUAL(c, cx); + c = Ec::compare(P2, P1); + cx = Fp::compare(-y, y); + CYBOZU_TEST_EQUAL(c, cx); + CYBOZU_TEST_EQUAL(Ec::compare(P1, P1), 0); + bool b1, b2; + b1 = P1 <= P2; + b2 = y <= -y; + CYBOZU_TEST_EQUAL(b1, b2); + b1 = P1 < P2; + b2 = y < -y; + CYBOZU_TEST_EQUAL(b1, b2); + CYBOZU_TEST_ASSERT(!(P1 < P1)); + CYBOZU_TEST_ASSERT((P1 <= P1)); + } template void test(F f, const char *msg) const @@ -389,6 +412,7 @@ mul 499.00usec str(); ioMode(); mulCT(); + compare(); } private: Test(const Test&);