From 8118e08dc27153dd3bac0264b1774e92e6173ad1 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Tue, 23 Jul 2019 19:37:39 +0900 Subject: [PATCH 1/8] add FixedVec::value_type --- include/mcl/array.hpp | 1 + include/mcl/gmp_util.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mcl/array.hpp b/include/mcl/array.hpp index 5fa49e6..33d4aab 100644 --- a/include/mcl/array.hpp +++ b/include/mcl/array.hpp @@ -118,6 +118,7 @@ class FixedArray { y = t; } public: + typedef T value_type; FixedArray() : n_(0) {} bool resize(size_t n) { diff --git a/include/mcl/gmp_util.hpp b/include/mcl/gmp_util.hpp index 384c052..42ec6a7 100644 --- a/include/mcl/gmp_util.hpp +++ b/include/mcl/gmp_util.hpp @@ -642,7 +642,7 @@ void getNAFwidth(bool *pb, Vec& naf, mpz_class x, size_t w) x++; v -= maxW; } - naf.push(pb, v); + naf.push(pb, typename Vec::value_type(v)); if (!*pb) return; zeroNum = w - 1; } From 2762669e4c7f11198bce7a86290b80982447320c Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Wed, 24 Jul 2019 16:58:52 +0900 Subject: [PATCH 2/8] test of GLV for secp256k1 --- test/ecdsa_test.cpp | 167 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 1 deletion(-) diff --git a/test/ecdsa_test.cpp b/test/ecdsa_test.cpp index 332c9ee..8a766ea 100644 --- a/test/ecdsa_test.cpp +++ b/test/ecdsa_test.cpp @@ -1,4 +1,4 @@ -#define PUT(x) std::cout << #x "=" << x << std::endl; +#define PUT(x) std::cout << #x "=" << (x) << std::endl; #include #include void put(const void *buf, size_t bufSize) @@ -15,9 +15,174 @@ void put(const void *buf, size_t bufSize) using namespace mcl::ecdsa; +typedef mcl::FixedArray NafArray; + +template +void addTbl(G& Q, const G *tbl, const NafArray& naf, size_t i) +{ + if (i >= naf.size()) return; + int n = naf[i]; + if (n > 0) { + Q += tbl[(n - 1) >> 1]; + } else if (n < 0) { + Q -= tbl[(-n - 1) >> 1]; + } +} + +using namespace mcl; + +template +struct GLV1 { + Fp rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 + size_t rBitSize; + mpz_class v0, v1; + mpz_class B[2][2]; + mpz_class r; +private: +public: + bool operator==(const GLV1& rhs) const + { + return rw == rhs.rw && rBitSize == rhs.rBitSize && v0 == rhs.v0 && v1 == rhs.v1 + && B[0][0] == rhs.B[0][0] && B[0][1] == rhs.B[0][1] && B[1][0] == rhs.B[1][0] + && B[1][1] == rhs.B[1][1] && r == rhs.r; + } + bool operator!=(const GLV1& rhs) const { return !operator==(rhs); } +#ifndef CYBOZU_DONT_USE_STRING + void dump(const mpz_class& x) const + { + printf("\"%s\",\n", mcl::gmp::getStr(x, 16).c_str()); + } + void dump() const + { + printf("\"%s\",\n", rw.getStr(16).c_str()); + printf("%d,\n", (int)rBitSize); + dump(v0); + dump(v1); + dump(B[0][0]); dump(B[0][1]); dump(B[1][0]); dump(B[1][1]); + dump(r); + } +#endif + void init(const mpz_class& r, const mpz_class& z, bool isBLS12 = false, int curveType = -1) + { + } + /* + L = lambda = p^4 + L (x, y) = (rw x, y) + */ + void mulLambda(G1& Q, const G1& P) const + { + Fp::mul(Q.x, P.x, rw); + Q.y = P.y; + Q.z = P.z; + } + /* + x = a + b * lambda mod r + */ + void split(mpz_class& a, mpz_class& b, const mpz_class& x) const + { + mpz_class t; +// t = (x * v0) >> rBitSize; +// b = (x * v1) >> rBitSize; +t = (B[1][1] * x) / r; +b = (-B[0][1] * x) / r; + a = x - (t * B[0][0] + b * B[1][0]); + b = - (t * B[0][1] + b * B[1][1]); + } + void mul(G1& Q, const G1& P, mpz_class x, bool constTime = false) const + { + const int w = 5; + const size_t tblSize = 1 << (w - 2); + NafArray naf[2]; + mpz_class u[2]; + G1 tbl[2][tblSize]; + bool b; + + x %= r; + if (x == 0) { + Q.clear(); + if (!constTime) return; + } + if (x < 0) { + x += r; + } + split(u[0], u[1], x); + gmp::getNAFwidth(&b, naf[0], u[0], w); + assert(b); (void)b; + gmp::getNAFwidth(&b, naf[1], u[1], w); + assert(b); (void)b; + + tbl[0][0] = P; + mulLambda(tbl[1][0], tbl[0][0]); + { + G1 P2; + G1::dbl(P2, P); + for (size_t i = 1; i < tblSize; i++) { + G1::add(tbl[0][i], tbl[0][i - 1], P2); + mulLambda(tbl[1][i], tbl[0][i]); + } + } + const size_t maxBit = fp::max_(naf[0].size(), naf[1].size()); + Q.clear(); + for (size_t i = 0; i < maxBit; i++) { + G1::dbl(Q, Q); + addTbl(Q, tbl[0], naf[0], maxBit - 1 - i); + addTbl(Q, tbl[1], naf[1], maxBit - 1 - i); + } + } +}; + +static GLV1 glv1; + +inline void mulArrayEc(Ec& z, const Ec& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime) +{ + mpz_class s; + bool b; + mcl::gmp::setArray(&b, s, y, yn); + assert(b); + if (isNegative) s = -s; + glv1.mul(z, x, s, constTime); +} + +void initGLV() +{ + const mcl::ecdsa::local::Param& p = mcl::ecdsa::local::getParam(); + const mcl::EcParam& ecParam = p.ecParam; + { + Fp& rw = glv1.rw; + bool b = Fp::squareRoot(rw, -3); + assert(b); + printf("b=%d\n", b); + if (!b) exit(1); + rw = -(rw + 1) / 2; + glv1.r = ecParam.n; + glv1.rBitSize = gmp::getBitSize(glv1.r); + glv1.rBitSize = (glv1.rBitSize + fp::UnitBitSize - 1) & ~(fp::UnitBitSize - 1); + gmp::setStr(glv1.B[0][0], "0x3086d221a7d46bcde86c90e49284eb15"); + gmp::setStr(glv1.B[0][1], "-0xe4437ed6010e88286f547fa90abfe4c3"); + gmp::setStr(glv1.B[1][0], "0x114ca50f7a8e2f3f657c1108d9d44cfd8"); + glv1.B[1][1] = glv1.B[0][0]; + glv1.v0 = ((-glv1.B[1][1]) << glv1.rBitSize) / glv1.r; + glv1.v1 = ((glv1.B[1][0]) << glv1.rBitSize) / glv1.r; + } + PUT(p.P); + Ec Q1, Q2; + mpz_class L; + gmp::setStr(L, "0x5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72"); + PUT(L); + Ec::mul(Q1, p.P, L); + PUT(Q1); + glv1.mulLambda(Q2, p.P); + PUT(Q2); + PUT(Q1 == Q2); + // enable GLV + Ec::setMulArrayGLV(mulArrayEc); +} + + CYBOZU_TEST_AUTO(ecdsa) { init(); + initGLV(); SecretKey sec; PublicKey pub; sec.setByCSPRNG(); From 53028c4a98817ad62ac916ad90c008d4a13cc567 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Thu, 25 Jul 2019 14:56:45 +0900 Subject: [PATCH 3/8] GLV1 is template class --- include/mcl/bn.hpp | 86 ++++++++++++++++++++++++--------------------- test/ecdsa_test.cpp | 12 +++---- test/glv_test.cpp | 20 +++++------ 3 files changed, 62 insertions(+), 56 deletions(-) diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp index 02f58f2..3c5959b 100644 --- a/include/mcl/bn.hpp +++ b/include/mcl/bn.hpp @@ -577,14 +577,15 @@ void addTbl(G& Q, const G *tbl, const NafArray& naf, size_t i) Software implementation of Attribute-Based Encryption: Appendixes GLV for G1 on BN/BLS12 */ -struct GLV1 { - Fp rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 - size_t rBitSize; - mpz_class v0, v1; - mpz_class B[2][2]; - mpz_class r; +template +struct GLV1T { + static F rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 + static size_t rBitSize; + static mpz_class v0, v1; + static mpz_class B[2][2]; + static mpz_class r; private: - bool usePrecomputedTable(int curveType) + static bool usePrecomputedTable(int curveType) { if (curveType < 0) return false; const struct Tbl { @@ -631,19 +632,12 @@ private: return false; } public: - bool operator==(const GLV1& rhs) const - { - return rw == rhs.rw && rBitSize == rhs.rBitSize && v0 == rhs.v0 && v1 == rhs.v1 - && B[0][0] == rhs.B[0][0] && B[0][1] == rhs.B[0][1] && B[1][0] == rhs.B[1][0] - && B[1][1] == rhs.B[1][1] && r == rhs.r; - } - bool operator!=(const GLV1& rhs) const { return !operator==(rhs); } #ifndef CYBOZU_DONT_USE_STRING - void dump(const mpz_class& x) const + static void dump(const mpz_class& x) { printf("\"%s\",\n", mcl::gmp::getStr(x, 16).c_str()); } - void dump() const + static void dump() { printf("\"%s\",\n", rw.getStr(16).c_str()); printf("%d,\n", (int)rBitSize); @@ -653,14 +647,14 @@ public: dump(r); } #endif - void init(const mpz_class& r, const mpz_class& z, bool isBLS12 = false, int curveType = -1) + static void init(const mpz_class& _r, const mpz_class& z, bool isBLS12 = false, int curveType = -1) { if (usePrecomputedTable(curveType)) return; - bool b = Fp::squareRoot(rw, -3); + bool b = F::squareRoot(rw, -3); assert(b); (void)b; rw = -(rw + 1) / 2; - this->r = r; + r = _r; rBitSize = gmp::getBitSize(r); rBitSize = (rBitSize + fp::UnitBitSize - 1) & ~(fp::UnitBitSize - 1);// a little better size if (isBLS12) { @@ -694,16 +688,16 @@ public: L = lambda = p^4 L (x, y) = (rw x, y) */ - void mulLambda(G1& Q, const G1& P) const + static void mulLambda(G& Q, const G& P) { - Fp::mul(Q.x, P.x, rw); + F::mul(Q.x, P.x, rw); Q.y = P.y; Q.z = P.z; } /* x = a + b * lambda mod r */ - void split(mpz_class& a, mpz_class& b, const mpz_class& x) const + static void split(mpz_class& a, mpz_class& b, const mpz_class& x) { mpz_class t; t = (x * v0) >> rBitSize; @@ -711,13 +705,13 @@ public: a = x - (t * B[0][0] + b * B[1][0]); b = - (t * B[0][1] + b * B[1][1]); } - void mul(G1& Q, const G1& P, mpz_class x, bool constTime = false) const + static void mul(G& Q, const G& P, mpz_class x, bool constTime = false) { const int w = 5; const size_t tblSize = 1 << (w - 2); NafArray naf[2]; mpz_class u[2]; - G1 tbl[2][tblSize]; + G tbl[2][tblSize]; bool b; x %= r; @@ -737,22 +731,43 @@ public: tbl[0][0] = P; mulLambda(tbl[1][0], tbl[0][0]); { - G1 P2; - G1::dbl(P2, P); + G P2; + G::dbl(P2, P); for (size_t i = 1; i < tblSize; i++) { - G1::add(tbl[0][i], tbl[0][i - 1], P2); + G::add(tbl[0][i], tbl[0][i - 1], P2); mulLambda(tbl[1][i], tbl[0][i]); } } const size_t maxBit = fp::max_(naf[0].size(), naf[1].size()); Q.clear(); for (size_t i = 0; i < maxBit; i++) { - G1::dbl(Q, Q); + G::dbl(Q, Q); addTbl(Q, tbl[0], naf[0], maxBit - 1 - i); addTbl(Q, tbl[1], naf[1], maxBit - 1 - i); } } + static void mulArray(G& z, const G& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime) + { + mpz_class s; + bool b; + mcl::gmp::setArray(&b, s, y, yn); + assert(b); + if (isNegative) s = -s; + mul(z, x, s, constTime); + } }; +template +F GLV1T::rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 +template +size_t GLV1T::rBitSize; +template +mpz_class GLV1T::v0; +template +mpz_class GLV1T::v1; +template +mpz_class GLV1T::B[2][2]; +template +mpz_class GLV1T::r; /* GLV method for G2 and GT on BN/BLS12 @@ -1035,7 +1050,7 @@ struct Param { mpz_class p; mpz_class r; local::MapTo mapTo; - local::GLV1 glv1; + typedef local::GLV1T GLV1; local::GLV2 glv2; // for G2 Frobenius Fp2 g2; @@ -1151,7 +1166,7 @@ struct Param { } else { mapTo.init(2 * p - r, z, cp.curveType); } - glv1.init(r, z, isBLS12, cp.curveType); + GLV1::init(r, z, isBLS12, cp.curveType); glv2.init(r, z, isBLS12); basePoint.clear(); *pb = true; @@ -1200,15 +1215,6 @@ static const local::Param& param = local::StaticVar<>::param; namespace local { -inline void mulArrayGLV1(G1& z, const G1& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime) -{ - mpz_class s; - bool b; - mcl::gmp::setArray(&b, s, y, yn); - assert(b); - if (isNegative) s = -s; - BN::param.glv1.mul(z, x, s, constTime); -} inline void mulArrayGLV2(G2& z, const G2& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime) { mpz_class s; @@ -2227,7 +2233,7 @@ inline void init(bool *pb, const mcl::CurveParam& cp = mcl::BN254, fp::Mode mode { local::StaticVar<>::param.init(pb, cp, mode); if (!*pb) return; - G1::setMulArrayGLV(local::mulArrayGLV1); + G1::setMulArrayGLV(bn::local::Param::GLV1::mulArray); G2::setMulArrayGLV(local::mulArrayGLV2); Fp12::setPowArrayGLV(local::powArrayGLV2); G1::setCompressedExpression(); diff --git a/test/ecdsa_test.cpp b/test/ecdsa_test.cpp index 8a766ea..28f689e 100644 --- a/test/ecdsa_test.cpp +++ b/test/ecdsa_test.cpp @@ -81,10 +81,10 @@ public: void split(mpz_class& a, mpz_class& b, const mpz_class& x) const { mpz_class t; -// t = (x * v0) >> rBitSize; -// b = (x * v1) >> rBitSize; -t = (B[1][1] * x) / r; -b = (-B[0][1] * x) / r; + t = (x * v0) >> rBitSize; + b = (x * v1) >> rBitSize; +//t = (B[1][1] * x) / r; +//b = (-B[0][1] * x) / r; a = x - (t * B[0][0] + b * B[1][0]); b = - (t * B[0][1] + b * B[1][1]); } @@ -161,8 +161,8 @@ void initGLV() gmp::setStr(glv1.B[0][1], "-0xe4437ed6010e88286f547fa90abfe4c3"); gmp::setStr(glv1.B[1][0], "0x114ca50f7a8e2f3f657c1108d9d44cfd8"); glv1.B[1][1] = glv1.B[0][0]; - glv1.v0 = ((-glv1.B[1][1]) << glv1.rBitSize) / glv1.r; - glv1.v1 = ((glv1.B[1][0]) << glv1.rBitSize) / glv1.r; + glv1.v0 = ((glv1.B[1][1]) << glv1.rBitSize) / glv1.r; + glv1.v1 = ((-glv1.B[0][1]) << glv1.rBitSize) / glv1.r; } PUT(p.P); Ec Q1, Q2; diff --git a/test/glv_test.cpp b/test/glv_test.cpp index 0e6fccd..79d378f 100644 --- a/test/glv_test.cpp +++ b/test/glv_test.cpp @@ -77,7 +77,7 @@ struct oldGLV { }; template -void compareLength(const GLV1& rhs, const GLV2& lhs) +void compareLength(const GLV2& lhs) { cybozu::XorShift rg; int lt = 0; @@ -88,7 +88,7 @@ void compareLength(const GLV1& rhs, const GLV2& lhs) for (int i = 1; i < 1000; i++) { r.setRand(rg); x = r.getMpz(); - rhs.split(R0, R1, x); + GLV1::split(R0, R1, x); lhs.split(L0, L1, x); size_t R0n = mcl::gmp::getBitSize(R0); @@ -121,10 +121,10 @@ void testGLV1() oldGlv.init(BN::param.r, BN::param.z); } - mcl::bn::local::GLV1 glv; - glv.init(BN::param.r, BN::param.z, BN::param.isBLS12); + typedef mcl::bn::local::Param::GLV1 GLV1; + GLV1::init(BN::param.r, BN::param.z, BN::param.isBLS12); if (!BN::param.isBLS12) { - compareLength(glv, oldGlv); + compareLength(oldGlv); } for (int i = 1; i < 100; i++) { @@ -133,9 +133,9 @@ void testGLV1() s.setRand(rg); mpz_class ss = s.getMpz(); G1::mulGeneric(P1, P0, ss); - glv.mul(P2, P0, ss); + GLV1::mul(P2, P0, ss); CYBOZU_TEST_EQUAL(P1, P2); - glv.mul(P2, P0, ss, true); + GLV1::mul(P2, P0, ss, true); CYBOZU_TEST_EQUAL(P1, P2); if (!BN::param.isBLS12) { oldGlv.mul(P2, P0, ss); @@ -145,15 +145,15 @@ void testGLV1() for (int i = -100; i < 100; i++) { mpz_class ss = i; G1::mulGeneric(P1, P0, ss); - glv.mul(P2, P0, ss); + GLV1::mul(P2, P0, ss); CYBOZU_TEST_EQUAL(P1, P2); - glv.mul(P2, P0, ss, true); + GLV1::mul(P2, P0, ss, true); CYBOZU_TEST_EQUAL(P1, P2); } Fr s; mapToG1(P0, 123); CYBOZU_BENCH_C("Ec::mul", 100, P1 = P0; s.setRand(rg); G1::mulGeneric, P2, P1, s.getMpz()); - CYBOZU_BENCH_C("Ec::glv", 100, P1 = P0; s.setRand(rg); glv.mul, P2, P1, s.getMpz()); + CYBOZU_BENCH_C("Ec::glv", 100, P1 = P0; s.setRand(rg); GLV1::mul, P2, P1, s.getMpz()); } /* From 14465da20501105f6d492d7d06fef68fa4965b9d Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Thu, 25 Jul 2019 15:44:59 +0900 Subject: [PATCH 4/8] move GLV1 to ec.hpp --- include/mcl/bn.hpp | 263 ++++----------------------------------------- include/mcl/ec.hpp | 125 +++++++++++++++++++++ test/glv_test.cpp | 6 +- 3 files changed, 146 insertions(+), 248 deletions(-) diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp index 3c5959b..d1cb9f7 100644 --- a/include/mcl/bn.hpp +++ b/include/mcl/bn.hpp @@ -561,30 +561,13 @@ struct MapTo { }; typedef mcl::FixedArray NafArray; -template -void addTbl(G& Q, const G *tbl, const NafArray& naf, size_t i) -{ - if (i >= naf.size()) return; - int n = naf[i]; - if (n > 0) { - Q += tbl[(n - 1) >> 1]; - } else if (n < 0) { - Q -= tbl[(-n - 1) >> 1]; - } -} /* Software implementation of Attribute-Based Encryption: Appendixes GLV for G1 on BN/BLS12 */ -template -struct GLV1T { - static F rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 - static size_t rBitSize; - static mpz_class v0, v1; - static mpz_class B[2][2]; - static mpz_class r; -private: + +struct GLV1 : mcl::GLV1T { static bool usePrecomputedTable(int curveType) { if (curveType < 0) return false; @@ -620,37 +603,21 @@ private: bool b; rw.setStr(&b, tbl[i].rw, 16); if (!b) continue; rBitSize = tbl[i].rBitSize; - mcl::gmp::setStr(&b, v0, tbl[i].v0, 16); if (!b) continue; - mcl::gmp::setStr(&b, v1, tbl[i].v1, 16); if (!b) continue; - mcl::gmp::setStr(&b, B[0][0], tbl[i].B[0][0], 16); if (!b) continue; - mcl::gmp::setStr(&b, B[0][1], tbl[i].B[0][1], 16); if (!b) continue; - mcl::gmp::setStr(&b, B[1][0], tbl[i].B[1][0], 16); if (!b) continue; - mcl::gmp::setStr(&b, B[1][1], tbl[i].B[1][1], 16); if (!b) continue; - mcl::gmp::setStr(&b, r, tbl[i].r, 16); if (!b) continue; + gmp::setStr(&b, v0, tbl[i].v0, 16); if (!b) continue; + gmp::setStr(&b, v1, tbl[i].v1, 16); if (!b) continue; + gmp::setStr(&b, B[0][0], tbl[i].B[0][0], 16); if (!b) continue; + gmp::setStr(&b, B[0][1], tbl[i].B[0][1], 16); if (!b) continue; + gmp::setStr(&b, B[1][0], tbl[i].B[1][0], 16); if (!b) continue; + gmp::setStr(&b, B[1][1], tbl[i].B[1][1], 16); if (!b) continue; + gmp::setStr(&b, r, tbl[i].r, 16); if (!b) continue; return true; } return false; } -public: -#ifndef CYBOZU_DONT_USE_STRING - static void dump(const mpz_class& x) - { - printf("\"%s\",\n", mcl::gmp::getStr(x, 16).c_str()); - } - static void dump() - { - printf("\"%s\",\n", rw.getStr(16).c_str()); - printf("%d,\n", (int)rBitSize); - dump(v0); - dump(v1); - dump(B[0][0]); dump(B[0][1]); dump(B[1][0]); dump(B[1][1]); - dump(r); - } -#endif - static void init(const mpz_class& _r, const mpz_class& z, bool isBLS12 = false, int curveType = -1) + static void initForBN(const mpz_class& _r, const mpz_class& z, bool isBLS12 = false, int curveType = -1) { if (usePrecomputedTable(curveType)) return; - bool b = F::squareRoot(rw, -3); + bool b = Fp::squareRoot(rw, -3); assert(b); (void)b; rw = -(rw + 1) / 2; @@ -684,90 +651,7 @@ public: v0 = ((-B[1][1]) << rBitSize) / r; v1 = ((B[1][0]) << rBitSize) / r; } - /* - L = lambda = p^4 - L (x, y) = (rw x, y) - */ - static void mulLambda(G& Q, const G& P) - { - F::mul(Q.x, P.x, rw); - Q.y = P.y; - Q.z = P.z; - } - /* - x = a + b * lambda mod r - */ - static void split(mpz_class& a, mpz_class& b, const mpz_class& x) - { - mpz_class t; - t = (x * v0) >> rBitSize; - b = (x * v1) >> rBitSize; - a = x - (t * B[0][0] + b * B[1][0]); - b = - (t * B[0][1] + b * B[1][1]); - } - static void mul(G& Q, const G& P, mpz_class x, bool constTime = false) - { - const int w = 5; - const size_t tblSize = 1 << (w - 2); - NafArray naf[2]; - mpz_class u[2]; - G tbl[2][tblSize]; - bool b; - - x %= r; - if (x == 0) { - Q.clear(); - if (!constTime) return; - } - if (x < 0) { - x += r; - } - split(u[0], u[1], x); - gmp::getNAFwidth(&b, naf[0], u[0], w); - assert(b); (void)b; - gmp::getNAFwidth(&b, naf[1], u[1], w); - assert(b); (void)b; - - tbl[0][0] = P; - mulLambda(tbl[1][0], tbl[0][0]); - { - G P2; - G::dbl(P2, P); - for (size_t i = 1; i < tblSize; i++) { - G::add(tbl[0][i], tbl[0][i - 1], P2); - mulLambda(tbl[1][i], tbl[0][i]); - } - } - const size_t maxBit = fp::max_(naf[0].size(), naf[1].size()); - Q.clear(); - for (size_t i = 0; i < maxBit; i++) { - G::dbl(Q, Q); - addTbl(Q, tbl[0], naf[0], maxBit - 1 - i); - addTbl(Q, tbl[1], naf[1], maxBit - 1 - i); - } - } - static void mulArray(G& z, const G& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime) - { - mpz_class s; - bool b; - mcl::gmp::setArray(&b, s, y, yn); - assert(b); - if (isNegative) s = -s; - mul(z, x, s, constTime); - } }; -template -F GLV1T::rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 -template -size_t GLV1T::rBitSize; -template -mpz_class GLV1T::v0; -template -mpz_class GLV1T::v1; -template -mpz_class GLV1T::B[2][2]; -template -mpz_class GLV1T::r; /* GLV method for G2 and GT on BN/BLS12 @@ -787,7 +671,7 @@ struct GLV2 { this->z = z; this->abs_z = z < 0 ? -z : z; this->isBLS12 = isBLS12; - rBitSize = mcl::gmp::getBitSize(r); + rBitSize = gmp::getBitSize(r); rBitSize = (rBitSize + mcl::fp::UnitBitSize - 1) & ~(mcl::fp::UnitBitSize - 1);// a little better size mpz_class z2p1 = z * 2 + 1; B[0][0] = z + 1; @@ -874,7 +758,6 @@ struct GLV2 { template void mul(T& Q, const T& P, mpz_class x, bool constTime = false) const { -#if 1 const int w = 5; const size_t tblSize = 1 << (w - 2); const size_t splitN = 4; @@ -917,120 +800,11 @@ struct GLV2 { Q.clear(); for (size_t i = 0; i < maxBit; i++) { T::dbl(Q, Q); - addTbl(Q, tbl[0], naf[0], maxBit - 1 - i); - addTbl(Q, tbl[1], naf[1], maxBit - 1 - i); - addTbl(Q, tbl[2], naf[2], maxBit - 1 - i); - addTbl(Q, tbl[3], naf[3], maxBit - 1 - i); - } -#else -#if 0 // #ifndef NDEBUG - { - T R; - T::mulGeneric(R, P, r); - assert(R.isZero()); - } -#endif - typedef mcl::fp::Unit Unit; - const size_t maxUnit = 512 / 2 / mcl::fp::UnitBitSize; - const int splitN = 4; - mpz_class u[splitN]; - T in[splitN]; - T tbl[16]; - int bitTbl[splitN]; // bit size of u[i] - Unit w[splitN][maxUnit]; // unit array of u[i] - int maxBit = 0; // max bit of u[i] - int maxN = 0; - int remainBit = 0; - - x %= r; - if (x == 0) { - Q.clear(); - if (constTime) goto DummyLoop; - return; + mcl::local::addTbl(Q, tbl[0], naf[0], maxBit - 1 - i); + mcl::local::addTbl(Q, tbl[1], naf[1], maxBit - 1 - i); + mcl::local::addTbl(Q, tbl[2], naf[2], maxBit - 1 - i); + mcl::local::addTbl(Q, tbl[3], naf[3], maxBit - 1 - i); } - if (x < 0) { - x += r; - } - split(u, x); - in[0] = P; - Frobenius(in[1], in[0]); - Frobenius(in[2], in[1]); - Frobenius(in[3], in[2]); - for (int i = 0; i < splitN; i++) { - if (u[i] < 0) { - u[i] = -u[i]; - T::neg(in[i], in[i]); - } -// in[i].normalize(); // slow - } -#if 0 - for (int i = 0; i < splitN; i++) { - T::mulGeneric(in[i], in[i], u[i]); - } - T::add(Q, in[0], in[1]); - Q += in[2]; - Q += in[3]; - return; -#else - tbl[0] = in[0]; - for (size_t i = 1; i < 16; i++) { - tbl[i].clear(); - if (i & 1) { - tbl[i] += in[0]; - } - if (i & 2) { - tbl[i] += in[1]; - } - if (i & 4) { - tbl[i] += in[2]; - } - if (i & 8) { - tbl[i] += in[3]; - } -// tbl[i].normalize(); - } - for (int i = 0; i < splitN; i++) { - bool b; - mcl::gmp::getArray(&b, w[i], maxUnit, u[i]); - assert(b); - bitTbl[i] = (int)mcl::gmp::getBitSize(u[i]); - maxBit = fp::max_(maxBit, bitTbl[i]); - } - maxBit--; - /* - maxBit = maxN * UnitBitSize + remainBit - 0 < remainBit <= UnitBitSize - */ - maxN = maxBit / mcl::fp::UnitBitSize; - remainBit = maxBit % mcl::fp::UnitBitSize; - remainBit++; - Q.clear(); - for (int i = maxN; i >= 0; i--) { - for (int j = remainBit - 1; j >= 0; j--) { - T::dbl(Q, Q); - uint32_t b0 = (w[0][i] >> j) & 1; - uint32_t b1 = (w[1][i] >> j) & 1; - uint32_t b2 = (w[2][i] >> j) & 1; - uint32_t b3 = (w[3][i] >> j) & 1; - uint32_t c = b3 * 8 + b2 * 4 + b1 * 2 + b0; - if (c == 0) { - if (constTime) tbl[0] += tbl[1]; - } else { - Q += tbl[c]; - } - } - remainBit = (int)mcl::fp::UnitBitSize; - } -#endif - DummyLoop: - if (!constTime) return; - const int limitBit = (int)rBitSize / splitN; - T D = tbl[0]; - for (int i = maxBit + 1; i < limitBit; i++) { - T::dbl(D, D); - D += tbl[0]; - } -#endif } void pow(Fp12& z, const Fp12& x, mpz_class y, bool constTime = false) const { @@ -1050,7 +824,6 @@ struct Param { mpz_class p; mpz_class r; local::MapTo mapTo; - typedef local::GLV1T GLV1; local::GLV2 glv2; // for G2 Frobenius Fp2 g2; @@ -1166,7 +939,7 @@ struct Param { } else { mapTo.init(2 * p - r, z, cp.curveType); } - GLV1::init(r, z, isBLS12, cp.curveType); + GLV1::initForBN(r, z, isBLS12, cp.curveType); glv2.init(r, z, isBLS12); basePoint.clear(); *pb = true; @@ -2233,7 +2006,7 @@ inline void init(bool *pb, const mcl::CurveParam& cp = mcl::BN254, fp::Mode mode { local::StaticVar<>::param.init(pb, cp, mode); if (!*pb) return; - G1::setMulArrayGLV(bn::local::Param::GLV1::mulArray); + G1::setMulArrayGLV(local::GLV1::mulArray); G2::setMulArrayGLV(local::mulArrayGLV2); Fp12::setPowArrayGLV(local::powArrayGLV2); G1::setCompressedExpression(); diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp index ad6e6db..115a8de 100644 --- a/include/mcl/ec.hpp +++ b/include/mcl/ec.hpp @@ -10,6 +10,7 @@ #include #include #include +#include //#define MCL_EC_USE_AFFINE @@ -1068,6 +1069,130 @@ template void (*EcT::mulArrayGLV)(EcT& z, const EcT& x, const fp:: template int EcT::mode_; #endif +namespace local { + +template +void addTbl(G& Q, const G *tbl, const Vec& naf, size_t i) +{ + if (i >= naf.size()) return; + int n = naf[i]; + if (n > 0) { + Q += tbl[(n - 1) >> 1]; + } else if (n < 0) { + Q -= tbl[(-n - 1) >> 1]; + } +} + +} // mcl::local + +template +struct GLV1T { + static F rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 + static size_t rBitSize; + static mpz_class v0, v1; + static mpz_class B[2][2]; + static mpz_class r; +public: +#ifndef CYBOZU_DONT_USE_STRING + static void dump(const mpz_class& x) + { + printf("\"%s\",\n", mcl::gmp::getStr(x, 16).c_str()); + } + static void dump() + { + printf("\"%s\",\n", rw.getStr(16).c_str()); + printf("%d,\n", (int)rBitSize); + dump(v0); + dump(v1); + dump(B[0][0]); dump(B[0][1]); dump(B[1][0]); dump(B[1][1]); + dump(r); + } +#endif + /* + initGLV1() is defined in bn.hpp + */ + /* + L = lambda = p^4 + L (x, y) = (rw x, y) + */ + static void mulLambda(G& Q, const G& P) + { + F::mul(Q.x, P.x, rw); + Q.y = P.y; + Q.z = P.z; + } + /* + x = a + b * lambda mod r + */ + static void split(mpz_class& a, mpz_class& b, const mpz_class& x) + { + mpz_class t; + t = (x * v0) >> rBitSize; + b = (x * v1) >> rBitSize; + a = x - (t * B[0][0] + b * B[1][0]); + b = - (t * B[0][1] + b * B[1][1]); + } + static void mul(G& Q, const G& P, mpz_class x, bool constTime = false) + { + const int w = 5; + const size_t tblSize = 1 << (w - 2); + typedef mcl::FixedArray NafArray; + NafArray naf[2]; + mpz_class u[2]; + G tbl[2][tblSize]; + bool b; + + x %= r; + if (x == 0) { + Q.clear(); + if (!constTime) return; + } + if (x < 0) { + x += r; + } + split(u[0], u[1], x); + gmp::getNAFwidth(&b, naf[0], u[0], w); + assert(b); (void)b; + gmp::getNAFwidth(&b, naf[1], u[1], w); + assert(b); (void)b; + + tbl[0][0] = P; + mulLambda(tbl[1][0], tbl[0][0]); + { + G P2; + G::dbl(P2, P); + for (size_t i = 1; i < tblSize; i++) { + G::add(tbl[0][i], tbl[0][i - 1], P2); + mulLambda(tbl[1][i], tbl[0][i]); + } + } + const size_t maxBit = fp::max_(naf[0].size(), naf[1].size()); + Q.clear(); + for (size_t i = 0; i < maxBit; i++) { + G::dbl(Q, Q); + local::addTbl(Q, tbl[0], naf[0], maxBit - 1 - i); + local::addTbl(Q, tbl[1], naf[1], maxBit - 1 - i); + } + } + static void mulArray(G& z, const G& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime) + { + mpz_class s; + bool b; + mcl::gmp::setArray(&b, s, y, yn); + assert(b); + if (isNegative) s = -s; + mul(z, x, s, constTime); + } +}; + +// rw = 1 / w = (-1 - sqrt(-3)) / 2 +template F GLV1T::rw; +template size_t GLV1T::rBitSize; +template mpz_class GLV1T::v0; +template mpz_class GLV1T::v1; +template mpz_class GLV1T::B[2][2]; +template mpz_class GLV1T::r; + struct EcParam { const char *name; const char *p; diff --git a/test/glv_test.cpp b/test/glv_test.cpp index 79d378f..61f2062 100644 --- a/test/glv_test.cpp +++ b/test/glv_test.cpp @@ -88,7 +88,7 @@ void compareLength(const GLV2& lhs) for (int i = 1; i < 1000; i++) { r.setRand(rg); x = r.getMpz(); - GLV1::split(R0, R1, x); + mcl::bn::local::GLV1::split(R0, R1, x); lhs.split(L0, L1, x); size_t R0n = mcl::gmp::getBitSize(R0); @@ -121,8 +121,8 @@ void testGLV1() oldGlv.init(BN::param.r, BN::param.z); } - typedef mcl::bn::local::Param::GLV1 GLV1; - GLV1::init(BN::param.r, BN::param.z, BN::param.isBLS12); + typedef mcl::bn::local::GLV1 GLV1; + GLV1::initForBN(BN::param.r, BN::param.z, BN::param.isBLS12); if (!BN::param.isBLS12) { compareLength(oldGlv); } From 626663b8db188819985dffe88eddb2c33d20441d Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Thu, 25 Jul 2019 16:44:21 +0900 Subject: [PATCH 5/8] secp256k1 supports GLV method --- include/mcl/ec.hpp | 27 +++++-- test/ecdsa_test.cpp | 167 +------------------------------------------- 2 files changed, 24 insertions(+), 170 deletions(-) diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp index 115a8de..dd77193 100644 --- a/include/mcl/ec.hpp +++ b/include/mcl/ec.hpp @@ -10,7 +10,6 @@ #include #include #include -#include //#define MCL_EC_USE_AFFINE @@ -1109,10 +1108,6 @@ public: } #endif /* - initGLV1() is defined in bn.hpp - */ - /* - L = lambda = p^4 L (x, y) = (rw x, y) */ static void mulLambda(G& Q, const G& P) @@ -1183,6 +1178,28 @@ public: if (isNegative) s = -s; mul(z, x, s, constTime); } + /* + initForBN() is defined in bn.hpp + */ + static void initForSecp256k1(const mpz_class& _r) + { + bool b = F::squareRoot(rw, -3); + assert(b); + (void)b; + rw = -(rw + 1) / 2; + r = _r; + rBitSize = gmp::getBitSize(r); + rBitSize = (rBitSize + fp::UnitBitSize - 1) & ~(fp::UnitBitSize - 1); + gmp::setStr(&b, B[0][0], "0x3086d221a7d46bcde86c90e49284eb15"); + assert(b); (void)b; + gmp::setStr(&b, B[0][1], "-0xe4437ed6010e88286f547fa90abfe4c3"); + assert(b); (void)b; + gmp::setStr(&b, B[1][0], "0x114ca50f7a8e2f3f657c1108d9d44cfd8"); + assert(b); (void)b; + B[1][1] = B[0][0]; + v0 = ((B[1][1]) << rBitSize) / r; + v1 = ((-B[0][1]) << rBitSize) / r; + } }; // rw = 1 / w = (-1 - sqrt(-3)) / 2 diff --git a/test/ecdsa_test.cpp b/test/ecdsa_test.cpp index 28f689e..f015514 100644 --- a/test/ecdsa_test.cpp +++ b/test/ecdsa_test.cpp @@ -15,174 +15,11 @@ void put(const void *buf, size_t bufSize) using namespace mcl::ecdsa; -typedef mcl::FixedArray NafArray; - -template -void addTbl(G& Q, const G *tbl, const NafArray& naf, size_t i) -{ - if (i >= naf.size()) return; - int n = naf[i]; - if (n > 0) { - Q += tbl[(n - 1) >> 1]; - } else if (n < 0) { - Q -= tbl[(-n - 1) >> 1]; - } -} - -using namespace mcl; - -template -struct GLV1 { - Fp rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 - size_t rBitSize; - mpz_class v0, v1; - mpz_class B[2][2]; - mpz_class r; -private: -public: - bool operator==(const GLV1& rhs) const - { - return rw == rhs.rw && rBitSize == rhs.rBitSize && v0 == rhs.v0 && v1 == rhs.v1 - && B[0][0] == rhs.B[0][0] && B[0][1] == rhs.B[0][1] && B[1][0] == rhs.B[1][0] - && B[1][1] == rhs.B[1][1] && r == rhs.r; - } - bool operator!=(const GLV1& rhs) const { return !operator==(rhs); } -#ifndef CYBOZU_DONT_USE_STRING - void dump(const mpz_class& x) const - { - printf("\"%s\",\n", mcl::gmp::getStr(x, 16).c_str()); - } - void dump() const - { - printf("\"%s\",\n", rw.getStr(16).c_str()); - printf("%d,\n", (int)rBitSize); - dump(v0); - dump(v1); - dump(B[0][0]); dump(B[0][1]); dump(B[1][0]); dump(B[1][1]); - dump(r); - } -#endif - void init(const mpz_class& r, const mpz_class& z, bool isBLS12 = false, int curveType = -1) - { - } - /* - L = lambda = p^4 - L (x, y) = (rw x, y) - */ - void mulLambda(G1& Q, const G1& P) const - { - Fp::mul(Q.x, P.x, rw); - Q.y = P.y; - Q.z = P.z; - } - /* - x = a + b * lambda mod r - */ - void split(mpz_class& a, mpz_class& b, const mpz_class& x) const - { - mpz_class t; - t = (x * v0) >> rBitSize; - b = (x * v1) >> rBitSize; -//t = (B[1][1] * x) / r; -//b = (-B[0][1] * x) / r; - a = x - (t * B[0][0] + b * B[1][0]); - b = - (t * B[0][1] + b * B[1][1]); - } - void mul(G1& Q, const G1& P, mpz_class x, bool constTime = false) const - { - const int w = 5; - const size_t tblSize = 1 << (w - 2); - NafArray naf[2]; - mpz_class u[2]; - G1 tbl[2][tblSize]; - bool b; - - x %= r; - if (x == 0) { - Q.clear(); - if (!constTime) return; - } - if (x < 0) { - x += r; - } - split(u[0], u[1], x); - gmp::getNAFwidth(&b, naf[0], u[0], w); - assert(b); (void)b; - gmp::getNAFwidth(&b, naf[1], u[1], w); - assert(b); (void)b; - - tbl[0][0] = P; - mulLambda(tbl[1][0], tbl[0][0]); - { - G1 P2; - G1::dbl(P2, P); - for (size_t i = 1; i < tblSize; i++) { - G1::add(tbl[0][i], tbl[0][i - 1], P2); - mulLambda(tbl[1][i], tbl[0][i]); - } - } - const size_t maxBit = fp::max_(naf[0].size(), naf[1].size()); - Q.clear(); - for (size_t i = 0; i < maxBit; i++) { - G1::dbl(Q, Q); - addTbl(Q, tbl[0], naf[0], maxBit - 1 - i); - addTbl(Q, tbl[1], naf[1], maxBit - 1 - i); - } - } -}; - -static GLV1 glv1; - -inline void mulArrayEc(Ec& z, const Ec& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime) -{ - mpz_class s; - bool b; - mcl::gmp::setArray(&b, s, y, yn); - assert(b); - if (isNegative) s = -s; - glv1.mul(z, x, s, constTime); -} - -void initGLV() -{ - const mcl::ecdsa::local::Param& p = mcl::ecdsa::local::getParam(); - const mcl::EcParam& ecParam = p.ecParam; - { - Fp& rw = glv1.rw; - bool b = Fp::squareRoot(rw, -3); - assert(b); - printf("b=%d\n", b); - if (!b) exit(1); - rw = -(rw + 1) / 2; - glv1.r = ecParam.n; - glv1.rBitSize = gmp::getBitSize(glv1.r); - glv1.rBitSize = (glv1.rBitSize + fp::UnitBitSize - 1) & ~(fp::UnitBitSize - 1); - gmp::setStr(glv1.B[0][0], "0x3086d221a7d46bcde86c90e49284eb15"); - gmp::setStr(glv1.B[0][1], "-0xe4437ed6010e88286f547fa90abfe4c3"); - gmp::setStr(glv1.B[1][0], "0x114ca50f7a8e2f3f657c1108d9d44cfd8"); - glv1.B[1][1] = glv1.B[0][0]; - glv1.v0 = ((glv1.B[1][1]) << glv1.rBitSize) / glv1.r; - glv1.v1 = ((-glv1.B[0][1]) << glv1.rBitSize) / glv1.r; - } - PUT(p.P); - Ec Q1, Q2; - mpz_class L; - gmp::setStr(L, "0x5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72"); - PUT(L); - Ec::mul(Q1, p.P, L); - PUT(Q1); - glv1.mulLambda(Q2, p.P); - PUT(Q2); - PUT(Q1 == Q2); - // enable GLV - Ec::setMulArrayGLV(mulArrayEc); -} - - CYBOZU_TEST_AUTO(ecdsa) { init(); - initGLV(); + mcl::GLV1T::initForSecp256k1(Zn::getOp().mp); + Ec::setMulArrayGLV(mcl::GLV1T::mulArray); SecretKey sec; PublicKey pub; sec.setByCSPRNG(); From 2053b495a7b90be7268ef74e3a5ce0e84910e202 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Thu, 25 Jul 2019 22:10:49 +0900 Subject: [PATCH 6/8] simplify GLV1T class --- include/mcl/bn.hpp | 2 +- include/mcl/ec.hpp | 43 ++++++++++++++++++++++--------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp index d1cb9f7..147f8bb 100644 --- a/include/mcl/bn.hpp +++ b/include/mcl/bn.hpp @@ -567,7 +567,7 @@ typedef mcl::FixedArray NafArray; GLV for G1 on BN/BLS12 */ -struct GLV1 : mcl::GLV1T { +struct GLV1 : mcl::GLV1T { static bool usePrecomputedTable(int curveType) { if (curveType < 0) return false; diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp index dd77193..1d0ad49 100644 --- a/include/mcl/ec.hpp +++ b/include/mcl/ec.hpp @@ -1070,8 +1070,8 @@ template int EcT::mode_; namespace local { -template -void addTbl(G& Q, const G *tbl, const Vec& naf, size_t i) +template +void addTbl(Ec& Q, const Ec *tbl, const Vec& naf, size_t i) { if (i >= naf.size()) return; int n = naf[i]; @@ -1084,9 +1084,10 @@ void addTbl(G& Q, const G *tbl, const Vec& naf, size_t i) } // mcl::local -template +template struct GLV1T { - static F rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 + typedef typename Ec::Fp Fp; + static Fp rw; // rw = 1 / w = (-1 - sqrt(-3)) / 2 static size_t rBitSize; static mpz_class v0, v1; static mpz_class B[2][2]; @@ -1110,9 +1111,9 @@ public: /* L (x, y) = (rw x, y) */ - static void mulLambda(G& Q, const G& P) + static void mulLambda(Ec& Q, const Ec& P) { - F::mul(Q.x, P.x, rw); + Fp::mul(Q.x, P.x, rw); Q.y = P.y; Q.z = P.z; } @@ -1127,14 +1128,14 @@ public: a = x - (t * B[0][0] + b * B[1][0]); b = - (t * B[0][1] + b * B[1][1]); } - static void mul(G& Q, const G& P, mpz_class x, bool constTime = false) + static void mul(Ec& Q, const Ec& P, mpz_class x, bool constTime = false) { const int w = 5; const size_t tblSize = 1 << (w - 2); - typedef mcl::FixedArray NafArray; + typedef mcl::FixedArray NafArray; NafArray naf[2]; mpz_class u[2]; - G tbl[2][tblSize]; + Ec tbl[2][tblSize]; bool b; x %= r; @@ -1154,22 +1155,22 @@ public: tbl[0][0] = P; mulLambda(tbl[1][0], tbl[0][0]); { - G P2; - G::dbl(P2, P); + Ec P2; + Ec::dbl(P2, P); for (size_t i = 1; i < tblSize; i++) { - G::add(tbl[0][i], tbl[0][i - 1], P2); + Ec::add(tbl[0][i], tbl[0][i - 1], P2); mulLambda(tbl[1][i], tbl[0][i]); } } const size_t maxBit = fp::max_(naf[0].size(), naf[1].size()); Q.clear(); for (size_t i = 0; i < maxBit; i++) { - G::dbl(Q, Q); + Ec::dbl(Q, Q); local::addTbl(Q, tbl[0], naf[0], maxBit - 1 - i); local::addTbl(Q, tbl[1], naf[1], maxBit - 1 - i); } } - static void mulArray(G& z, const G& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime) + static void mulArray(Ec& z, const Ec& x, const mcl::fp::Unit *y, size_t yn, bool isNegative, bool constTime) { mpz_class s; bool b; @@ -1183,7 +1184,7 @@ public: */ static void initForSecp256k1(const mpz_class& _r) { - bool b = F::squareRoot(rw, -3); + bool b = Fp::squareRoot(rw, -3); assert(b); (void)b; rw = -(rw + 1) / 2; @@ -1203,12 +1204,12 @@ public: }; // rw = 1 / w = (-1 - sqrt(-3)) / 2 -template F GLV1T::rw; -template size_t GLV1T::rBitSize; -template mpz_class GLV1T::v0; -template mpz_class GLV1T::v1; -template mpz_class GLV1T::B[2][2]; -template mpz_class GLV1T::r; +template typename Ec::Fp GLV1T::rw; +template size_t GLV1T::rBitSize; +template mpz_class GLV1T::v0; +template mpz_class GLV1T::v1; +template mpz_class GLV1T::B[2][2]; +template mpz_class GLV1T::r; struct EcParam { const char *name; From 3c98ac00c8209f722f8c718109674bd3b56a458b Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Thu, 25 Jul 2019 22:10:59 +0900 Subject: [PATCH 7/8] enable GLV for secp256k1 --- include/mcl/ecdsa.hpp | 2 ++ include/mcl/she.hpp | 5 +++++ test/ecdsa_test.cpp | 2 -- test/she_test.cpp | 5 +++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/mcl/ecdsa.hpp b/include/mcl/ecdsa.hpp index cf3ed3f..6540c19 100644 --- a/include/mcl/ecdsa.hpp +++ b/include/mcl/ecdsa.hpp @@ -99,6 +99,8 @@ inline void init(bool *pb) p.P.set(pb, x, y); if (!*pb) return; p.Pbase.init(pb, p.P, ecParam.bitSize, local::winSize); + mcl::GLV1T::initForSecp256k1(Zn::getOp().mp); + Ec::setMulArrayGLV(mcl::GLV1T::mulArray); } #ifndef CYBOZU_DONT_USE_EXCEPTION diff --git a/include/mcl/she.hpp b/include/mcl/she.hpp index 282f2fe..84f3e55 100644 --- a/include/mcl/she.hpp +++ b/include/mcl/she.hpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace mcl { namespace she { @@ -588,6 +589,10 @@ public: useDecG2ViaGT_ = false; isG1only_ = true; setTryNum(tryNum); + if (std::string(para.name) == mcl::ecparam::secp256k1.name) { + mcl::GLV1T::initForSecp256k1(Fr::getOp().mp); + G1::setMulArrayGLV(mcl::GLV1T::mulArray); + } } /* set range for G1-DLP diff --git a/test/ecdsa_test.cpp b/test/ecdsa_test.cpp index f015514..80de88a 100644 --- a/test/ecdsa_test.cpp +++ b/test/ecdsa_test.cpp @@ -18,8 +18,6 @@ using namespace mcl::ecdsa; CYBOZU_TEST_AUTO(ecdsa) { init(); - mcl::GLV1T::initForSecp256k1(Zn::getOp().mp); - Ec::setMulArrayGLV(mcl::GLV1T::mulArray); SecretKey sec; PublicKey pub; sec.setByCSPRNG(); diff --git a/test/she_test.cpp b/test/she_test.cpp index cb64478..0782eda 100644 --- a/test/she_test.cpp +++ b/test/she_test.cpp @@ -716,8 +716,9 @@ CYBOZU_TEST_AUTO(hashBench) CYBOZU_TEST_AUTO(liftedElGamal) { const size_t hashSize = 1024; - initG1only(mcl::ecparam::secp192k1, hashSize); - const size_t byteSize = 192 / 8; + const mcl::EcParam& param = mcl::ecparam::secp256k1; + initG1only(param, hashSize); + const size_t byteSize = (param.bitSize + 7) / 8; SecretKey sec; sec.setByCSPRNG(); PublicKey pub; From 5b453fda2beb773d8cb1a3a80ab4e6848b9011d0 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Thu, 25 Jul 2019 22:13:18 +0900 Subject: [PATCH 8/8] v0.96 --- include/mcl/op.hpp | 2 +- readme.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mcl/op.hpp b/include/mcl/op.hpp index c31b7d1..a8b47e5 100644 --- a/include/mcl/op.hpp +++ b/include/mcl/op.hpp @@ -23,7 +23,7 @@ namespace mcl { -static const int version = 0x095; /* 0xABC = A.BC */ +static const int version = 0x096; /* 0xABC = A.BC */ /* specifies available string format mode for X::setIoMode() diff --git a/readme.md b/readme.md index 40ae5a8..0510f1f 100644 --- a/readme.md +++ b/readme.md @@ -10,6 +10,7 @@ mcl is a library for pairing-based cryptography. The current version supports the optimal Ate pairing over BN curves and BLS12-381 curves. # News +* v0.96 improved scalar multiplication * mclBn_setETHserialization(true) (de)serialize acoording to [ETH2.0 serialization of BLS12-381](https://github.com/ethereum/eth2.0-specs/blob/dev/specs/bls_signature.md#point-representations) when BLS12-381 is used. * (Break backward compatibility) libmcl_dy.a is renamed to libmcl.a * The option SHARE_BASENAME_SUF is removed