change 'Ec::normalize() const' to 'Ec::normalize()'

dev
MITSUNARI Shigeo 8 years ago
parent dd69b60975
commit edf8d48129
  1. 13
      include/mcl/bn.hpp
  2. 57
      include/mcl/ec.hpp
  3. 24
      test/ec_test.cpp

@ -1172,8 +1172,10 @@ struct BNT {
#endif #endif
exp_d1(y, y); 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(); P.normalize();
Q.normalize(); Q.normalize();
G2 T = Q; G2 T = Q;
@ -1234,9 +1236,10 @@ struct BNT {
/* /*
allocate param.precomputedQcoeffSize elements of Fp6 for Qcoeff 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; size_t idx = 0;
G2 Q(Q_);
Q.normalize(); Q.normalize();
G2 T = Q; G2 T = Q;
G2 negQ; G2 negQ;
@ -1271,8 +1274,9 @@ struct BNT {
{ {
precomputedMillerLoop(f, P, Qcoeff.data()); 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(); P.normalize();
size_t idx = 0; size_t idx = 0;
Fp6 d, e; Fp6 d, e;
@ -1312,8 +1316,9 @@ struct BNT {
{ {
precomputedMillerLoop2(f, P1, Q1coeff.data(), P2, Q2coeff.data()); 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(); P1.normalize();
P2.normalize(); P2.normalize();
size_t idx = 0; size_t idx = 0;

@ -48,7 +48,7 @@ public:
Fp x, y; Fp x, y;
bool inf_; bool inf_;
#else #else
mutable Fp x, y, z; Fp x, y, z;
static int mode_; static int mode_;
#endif #endif
static Fp a_; static Fp a_;
@ -78,7 +78,7 @@ public:
} }
#ifndef MCL_EC_USE_AFFINE #ifndef MCL_EC_USE_AFFINE
private: private:
void normalizeJacobi() const void normalizeJacobi()
{ {
assert(!z.isZero()); assert(!z.isZero());
Fp rz2; Fp rz2;
@ -89,7 +89,7 @@ private:
y *= z; y *= z;
z = 1; z = 1;
} }
void normalizeProj() const void normalizeProj()
{ {
assert(!z.isZero()); assert(!z.isZero());
Fp::inv(z, z); Fp::inv(z, z);
@ -141,7 +141,7 @@ private:
} }
public: public:
#endif #endif
void normalize() const void normalize()
{ {
#ifndef MCL_EC_USE_AFFINE #ifndef MCL_EC_USE_AFFINE
if (isNormalized()) return; if (isNormalized()) return;
@ -608,18 +608,20 @@ public:
/* /*
0 <= P for any P 0 <= P for any P
(Px, Py) <= (P'x, P'y) iff Px < P'x or Px == P'x and Py <= P'y (Px, Py) <= (P'x, P'y) iff Px < P'x or Px == P'x and Py <= P'y
@note compare function calls normalize()
*/ */
template<class F> template<class F>
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(); const bool QisZero = Q_.isZero();
Q.normalize(); if (P_.isZero()) {
const bool QisZero = Q.isZero();
if (P.isZero()) {
if (QisZero) return 0; if (QisZero) return 0;
return -1; return -1;
} }
if (QisZero) return 1; if (QisZero) return 1;
EcT P(P_), Q(Q_);
P.normalize();
Q.normalize();
int c = comp(P.x, Q.x); int c = comp(P.x, Q.x);
if (c > 0) return 1; if (c > 0) return 1;
if (c < 0) return -1; if (c < 0) return -1;
@ -659,7 +661,7 @@ public:
*/ */
void getStr(std::string& str, int ioMode = 10) const void getStr(std::string& str, int ioMode = 10) const
{ {
normalize(); EcT P(*this); P.normalize();
if (ioMode & IoTight) { if (ioMode & IoTight) {
if (!isIoTightSupported()) throw cybozu::Exception("EcT:getStr:not supported ioMode") << ioMode; if (!isIoTightSupported()) throw cybozu::Exception("EcT:getStr:not supported ioMode") << ioMode;
const size_t n = Fp::getByteSize(); const size_t n = Fp::getByteSize();
@ -667,9 +669,9 @@ public:
str.resize(n, 0); str.resize(n, 0);
return; return;
} }
x.getStr(str, ioMode); P.x.getStr(str, ioMode);
assert(str.size() == n && (str[n - 1] & 0x80) == 0); assert(str.size() == n && (str[n - 1] & 0x80) == 0);
if (y.isOdd()) { if (P.y.isOdd()) {
str[n - 1] |= 0x80; str[n - 1] |= 0x80;
} }
return; return;
@ -680,15 +682,15 @@ public:
} }
const char *sep = Fp::BaseFp::getIoSeparator(); const char *sep = Fp::BaseFp::getIoSeparator();
if (compressedExpression_) { if (compressedExpression_) {
str = y.isOdd() ? '3' : '2'; str = P.y.isOdd() ? '3' : '2';
str += sep; str += sep;
str += x.getStr(ioMode); str += P.x.getStr(ioMode);
} else { } else {
str = '1'; str = '1';
str += sep; str += sep;
str += x.getStr(ioMode); str += P.x.getStr(ioMode);
str += sep; str += sep;
str += y.getStr(ioMode); str += P.y.getStr(ioMode);
} }
} }
std::string getStr(int ioMode = 10) const 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 { return !operator==(rhs); }
bool operator<(const EcT& rhs) const bool operator<(const EcT& rhs) const
{ {
if (isZero()) { return compare(*this, rhs) < 0;
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;
} }
bool operator>=(const EcT& rhs) const { return !operator<(rhs); } bool operator>=(const EcT& rhs) const { return !operator<(rhs); }
bool operator>(const EcT& rhs) const { return rhs < *this; } bool operator>(const EcT& rhs) const { return rhs < *this; }
@ -879,10 +872,10 @@ struct EcParam {
#ifdef CYBOZU_USE_BOOST #ifdef CYBOZU_USE_BOOST
namespace mcl { namespace mcl {
template<class Fp> template<class Fp>
size_t hash_value(const mcl::EcT<Fp>& P) size_t hash_value(const mcl::EcT<Fp>& P_)
{ {
if (P.isZero()) return 0; if (P_.isZero()) return 0;
P.normalize(); mcl::EcT<Fp> P(P_); P.normalize();
return mcl::hash_value(P.y, mcl::hash_value(P.x)); return mcl::hash_value(P.y, mcl::hash_value(P.x));
} }
@ -892,10 +885,10 @@ namespace std { CYBOZU_NAMESPACE_TR1_BEGIN
template<class Fp> template<class Fp>
struct hash<mcl::EcT<Fp> > { struct hash<mcl::EcT<Fp> > {
size_t operator()(const mcl::EcT<Fp>& P) const size_t operator()(const mcl::EcT<Fp>& P_) const
{ {
if (P.isZero()) return 0; if (P_.isZero()) return 0;
P.normalize(); mcl::EcT<Fp> P(P_); P.normalize();
return hash<Fp>()(P.y, hash<Fp>()(P.x)); return hash<Fp>()(P.y, hash<Fp>()(P.x));
} }
}; };

@ -350,6 +350,29 @@ struct Test {
CYBOZU_TEST_EQUAL(Q1, Q2); 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<class F> template<class F>
void test(F f, const char *msg) const void test(F f, const char *msg) const
@ -389,6 +412,7 @@ mul 499.00usec
str(); str();
ioMode(); ioMode();
mulCT(); mulCT();
compare();
} }
private: private:
Test(const Test&); Test(const Test&);

Loading…
Cancel
Save