add mode for proj/jacobi

dev
MITSUNARI Shigeo 9 years ago
parent 80da55f658
commit 90286a497f
  1. 145
      include/mcl/ec.hpp

@ -47,6 +47,7 @@ public:
static Fp b_;
static int specialA_;
static bool compressedExpression_;
static int mode_;
#if MCL_EC_COORD == MCL_EC_USE_AFFINE
EcT() : inf_(true) {}
#else
@ -56,8 +57,39 @@ public:
{
set(_x, _y);
}
void normalizeJacobi() const
{
if (isZero() || z.isOne()) return;
Fp rz, rz2;
Fp::inv(rz, z);
rz2 = rz * rz;
x *= rz2;
y *= rz2 * rz;
z = 1;
}
void normalizeProj() const
{
if (isZero() || z.isOne()) return;
Fp rz;
Fp::inv(rz, z);
x *= rz;
y *= rz;
z = 1;
}
void normalize() const
{
#if 1
#if MCL_EC_COORD != MCL_EC_USE_AFFINE
switch (mode_) {
case MCL_EC_USE_JACOBI:
normalizeJacobi();
break;
case MCL_EC_USE_PROJ:
normalizeProj();
break;
}
#endif
#else
#if MCL_EC_COORD == MCL_EC_USE_JACOBI
if (isZero() || z.isOne()) return;
Fp rz, rz2;
@ -73,10 +105,11 @@ public:
x *= rz;
y *= rz;
z = 1;
#endif
#endif
}
static inline void setParam(const std::string& astr, const std::string& bstr)
static inline void setParam(const std::string& astr, const std::string& bstr, int mode = MCL_EC_USE_JACOBI)
{
a_.setStr(astr);
b_.setStr(bstr);
@ -87,6 +120,14 @@ public:
} else {
specialA_ = generic;
}
switch (mode) {
case MCL_EC_USE_JACOBI:
case MCL_EC_USE_PROJ:
mode_ = mode;
break;
default:
throw cybozu::Exception("ec:EcT:setParam:bad mode") << mode;
}
}
static inline bool isValid(const Fp& _x, const Fp& _y)
{
@ -113,9 +154,8 @@ public:
y.clear();
}
static inline void dblNoVerifyInf(EcT& R, const EcT& P)
static inline void dblNoVerifyInfJacobi(EcT& R, const EcT& P)
{
#if MCL_EC_COORD == MCL_EC_USE_JACOBI
Fp S, M, t, y2;
Fp::square(y2, P.y);
Fp::mul(S, P.x, y2);
@ -169,7 +209,9 @@ public:
Fp::sub(R.y, S, R.x);
R.y *= M;
R.y -= y2;
#elif MCL_EC_COORD == MCL_EC_USE_PROJ
}
static inline void dblNoVerifyInfProj(EcT& R, const EcT& P)
{
const bool isPzOne = P.z.isOne();
Fp w, t, h;
switch (specialA_) {
@ -226,7 +268,10 @@ public:
R.z *= h;
Fp::sub(R.y, t, w);
R.y -= w;
#else
}
static inline void dblNoVerifyInf(EcT& R, const EcT& P)
{
#if MCL_EC_COORD == MCL_EC_USE_AFFINE
Fp t, s;
Fp::square(t, P.x);
Fp::add(s, t, t);
@ -243,6 +288,15 @@ public:
Fp::sub(R.y, s, P.y);
R.x = x3;
R.inf_ = false;
#else
switch (mode_) {
case MCL_EC_USE_JACOBI:
dblNoVerifyInfJacobi(R, P);
break;
case MCL_EC_USE_PROJ:
dblNoVerifyInfProj(R, P);
break;
}
#endif
}
static inline void dbl(EcT& R, const EcT& P)
@ -253,28 +307,9 @@ public:
}
dblNoVerifyInf(R, P);
}
static inline void add(EcT& R, const EcT& _P, const EcT& _Q)
static inline void addJacobi(EcT& R, const EcT& P, const EcT& Q)
{
if (_P.isZero()) { R = _Q; return; }
if (_Q.isZero()) { R = _P; return; }
if (&_P == &_Q) {
dblNoVerifyInf(R, _P);
return;
}
#if MCL_EC_COORD == MCL_EC_USE_AFFINE
const EcT& P(_P);
const ECT& Q(_Q);
#else
const EcT *pP = &_P;
const EcT *pQ = &_Q;
if (pP->z.isOne()) {
std::swap(pP, pQ);
}
const EcT& P(*pP);
const EcT& Q(*pQ);
const bool isQzOne = Q.z.isOne();
#endif
#if MCL_EC_COORD == MCL_EC_USE_JACOBI
Fp r, U1, S1, H, H3;
Fp::square(r, P.z);
if (isQzOne) {
@ -319,7 +354,10 @@ public:
U1 *= r;
H3 *= S1;
Fp::sub(R.y, U1, H3);
#elif MCL_EC_COORD == MCL_EC_USE_PROJ
}
static inline void addProj(EcT& R, const EcT& P, const EcT& Q)
{
const bool isQzOne = Q.z.isOne();
Fp r, PyQz, v, A, vv;
if (isQzOne) {
r = P.x;
@ -359,7 +397,18 @@ public:
r -= A;
R.y *= r;
R.y -= vv;
#else
}
static inline void add(EcT& R, const EcT& _P, const EcT& _Q)
{
if (_P.isZero()) { R = _Q; return; }
if (_Q.isZero()) { R = _P; return; }
if (&_P == &_Q) {
dblNoVerifyInf(R, _P);
return;
}
#if MCL_EC_COORD == MCL_EC_USE_AFFINE
const EcT& P(_P);
const ECT& Q(_Q);
Fp t;
Fp::neg(t, Q.y);
if (P.y == t) { R.clear(); return; }
@ -380,38 +429,29 @@ public:
s *= t;
Fp::sub(R.y, s, P.y);
R.x = x3;
#else
const EcT *pP = &_P;
const EcT *pQ = &_Q;
if (pP->z.isOne()) {
std::swap(pP, pQ);
}
const EcT& P(*pP);
const EcT& Q(*pQ);
switch (mode_) {
case MCL_EC_USE_JACOBI:
addJacobi(R, P, Q);
break;
case MCL_EC_USE_PROJ:
addProj(R, P, Q);
break;
}
#endif
}
static inline void sub(EcT& R, const EcT& P, const EcT& Q)
{
#if 0
if (P.inf_) { neg(R, Q); return; }
if (Q.inf_) { R = P; return; }
if (P.y == Q.y) { R.clear(); return; }
Fp t;
Fp::sub(t, Q.x, P.x);
if (t.isZero()) {
dblNoVerifyInf(R, P);
return;
}
Fp s;
Fp::add(s, Q.y, P.y);
Fp::neg(s, s);
Fp::div(t, s, t);
R.inf_ = false;
Fp x3;
Fp::mul(x3, t, t);
x3 -= P.x;
x3 -= Q.x;
Fp::sub(s, P.x, x3);
s *= t;
Fp::sub(R.y, s, P.y);
R.x = x3;
#else
EcT nQ;
neg(nQ, Q);
add(R, P, nQ);
#endif
}
static inline void neg(EcT& R, const EcT& P)
{
@ -574,6 +614,7 @@ template<class Fp> Fp EcT<Fp>::a_;
template<class Fp> Fp EcT<Fp>::b_;
template<class Fp> int EcT<Fp>::specialA_;
template<class Fp> bool EcT<Fp>::compressedExpression_;
template<class Fp> int EcT<Fp>::mode_;;
struct EcParam {
const char *name;

Loading…
Cancel
Save