aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2017-03-27 20:21:46 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2017-03-27 20:21:46 +0800
commit9b63aca0addf7415ff1af6bd4d6d7d77ec13d156 (patch)
treee22ddb7a33a4fba9b3ed3fc5a832574c49e98856
parent35bf705889b1ee86aea6932c9ed8092f6489885e (diff)
downloaddexon-mcl-9b63aca0addf7415ff1af6bd4d6d7d77ec13d156.tar.gz
dexon-mcl-9b63aca0addf7415ff1af6bd4d6d7d77ec13d156.tar.zst
dexon-mcl-9b63aca0addf7415ff1af6bd4d6d7d77ec13d156.zip
enable glv method for G1
-rw-r--r--include/mcl/bn.hpp51
-rw-r--r--include/mcl/ec.hpp15
2 files changed, 63 insertions, 3 deletions
diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp
index de171db..b99b006 100644
--- a/include/mcl/bn.hpp
+++ b/include/mcl/bn.hpp
@@ -282,6 +282,43 @@ struct GLV {
size_t nB = mcl::gmp::getBitSize(b);
size_t n = std::max(nA, nB);
assert(n > 0);
+#if 0 // slow
+ G1 tbl[16];
+ tbl[0].clear();
+ tbl[1] = A;
+ G1::dbl(tbl[2], tbl[1]);
+ G1::add(tbl[3], tbl[2], tbl[1]);
+ for (int i = 1; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ G1::add(tbl[i * 4 + j], tbl[(i - 1) * 4 + j], P);
+ }
+ }
+ for (int i = 1; i < 16; i++) {
+ tbl[i].normalize();
+ }
+ if (n & 1) {
+ n--;
+ bool ai = mcl::gmp::testBit(a, n);
+ bool bi = mcl::gmp::testBit(b, n);
+ unsigned int idx = bi * 4 + ai;
+ Q = tbl[idx];
+ if (n == 0) return;
+ } else {
+ Q.clear();
+ }
+ for (int i = (int)n - 2; i >= 0; i -= 2) {
+ G1::dbl(Q, Q);
+ G1::dbl(Q, Q);
+ bool a0 = mcl::gmp::testBit(a, i + 0);
+ bool a1 = mcl::gmp::testBit(a, i + 1);
+ bool b0 = mcl::gmp::testBit(b, i + 0);
+ bool b1 = mcl::gmp::testBit(b, i + 1);
+ unsigned int c = b1 * 8 + b0 * 4 + a1 * 2 + a0;
+ if (c > 0) {
+ Q += tbl[c];
+ }
+ }
+#else
G1 tbl[4];
tbl[1] = A; tbl[1].normalize();
tbl[2] = P; tbl[2].normalize();
@@ -291,11 +328,12 @@ struct GLV {
G1::dbl(Q, Q);
bool ai = mcl::gmp::testBit(a, i);
bool bi = mcl::gmp::testBit(b, i);
- int c = bi * 2 + ai;
+ unsigned int c = bi * 2 + ai;
if (c > 0) {
Q += tbl[c];
}
}
+#endif
#else
G1::mul(A, A, a);
G1::mul(B, P, b);
@@ -336,6 +374,7 @@ struct ParamT {
mpz_class exp_c1;
mpz_class exp_c2;
MapToT<Fp> mapTo;
+ GLV<Fp> glv;
// Loop parameter for the Miller loop part of opt. ate pairing.
typedef std::vector<int8_t> SignVec;
@@ -370,6 +409,7 @@ struct ParamT {
G2::init(0, b_div_xi, mcl::ec::Proj);
G2::setOrder(r);
mapTo.init(2 * p - r);
+ glv.init(r, z, isNegative);
Fp2::pow(g[0], xi, (p - 1) / 6); // g = xi^((p-1)/6)
for (size_t i = 1; i < gN; i++) {
@@ -434,9 +474,18 @@ struct BNT {
typedef mcl::Fp2DblT<Fp> Fp2Dbl;
typedef ParamT<Fp> Param;
static Param param;
+ static void mulArrayGLV(G1& z, const G1& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime)
+ {
+ (void)constTime;
+ mpz_class s;
+ mcl::gmp::setArray(s, y, yn);
+ if (isNegative) s = -s;
+ param.glv.mul(z, x, s);
+ }
static void init(const mcl::bn::CurveParam& cp = CurveFp254BNb, fp::Mode mode = fp::FP_AUTO)
{
param.init(cp, mode);
+ G1::setMulArrayGLV(mulArrayGLV);
}
/*
Frobenius
diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp
index 5676e60..f1c2e90 100644
--- a/include/mcl/ec.hpp
+++ b/include/mcl/ec.hpp
@@ -185,11 +185,15 @@ public:
verify the order of *this is equal to order if order != 0
in constructor, set, setStr, operator<<().
*/
- static inline void setOrder(const mpz_class& order)
+ static void setOrder(const mpz_class& order)
{
verifyOrder_ = order != 0;
order_ = order;
}
+ static void setMulArrayGLV(void f(EcT& z, const EcT& x, const fp::Unit *y, size_t yn, bool isNegative, bool constTime))
+ {
+ mulArrayGLV = f;
+ }
// backward compatilibity
static inline void setParam(const std::string& astr, const std::string& bstr, int mode = ec::Jacobi)
{
@@ -764,9 +768,16 @@ public:
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 !operator>(rhs); }
-private:
static inline void mulArray(EcT& z, const EcT& x, const fp::Unit *y, size_t yn, bool isNegative, bool constTime = false)
{
+ if (!constTime && mulArrayGLV && yn * 2 > Fp::BaseFp::getOp().N) {
+ mulArrayGLV(z, x, y, yn, isNegative, constTime);
+ return;
+ }
+ mulArrayBase(z, x, y, yn, isNegative, constTime);
+ }
+ static inline void mulArrayBase(EcT& z, const EcT& x, const fp::Unit *y, size_t yn, bool isNegative, bool constTime)
+ {
EcT tmp;
const EcT *px = &x;
if (&z == &x) {