diff --git a/include/mcl/bls12.hpp b/include/mcl/bls12.hpp index 950607d..ff0d207 100644 --- a/include/mcl/bls12.hpp +++ b/include/mcl/bls12.hpp @@ -14,16 +14,75 @@ namespace mcl { namespace bls12 { using mcl::CurveParam; using mcl::getCurveParam; +template +struct MapToT { + typedef mcl::Fp2T Fp2; + typedef mcl::EcT G1; + typedef mcl::EcT G2; + typedef util::HaveFrobenius G2withF; + mpz_class z_; + /* + Q = (z(z-1)-1)P + Frob((z-1)P) + Frob^2(2P) + */ + void mulByCofactor(G2& Q, const G2& P) const + { + G2 T0, T1; + G2::mulGeneric(T0, P, z_ - 1); + G2::mulGeneric(T1, T0, z_); + T1 -= P; + G2withF::Frobenius(T0, T0); + T0 += T1; + G2::dbl(T1, P); + G2withF::Frobenius2(T1, T1); + G2::add(Q, T0, T1); + } + void init(const mpz_class& z) + { + z_ = z; + } + template + void calc(G& P, const F& t) const + { + F x = t; + for (;;) { + F y; + G::getWeierstrass(y, x); + if (F::squareRoot(y, y)) { + P.set(x, y, false); + return; + } + *x.getFp0() += Fp::one(); + } + } + void calcG1(G1& P, const Fp& t) const + { + calc(P, t); + assert(P.isValid()); + } + /* + get the element in G2 by multiplying the cofactor + */ + void calcG2(G2& P, const Fp2& t) const + { + calc(P, t); + assert(cofactor_ != 0); + mulByCofactor(P, P); + assert(!P.isZero()); + } +}; + template struct ParamT : public util::CommonParamT { typedef util::CommonParamT Common; typedef Fp2T Fp2; typedef mcl::EcT G1; typedef mcl::EcT G2; + MapToT mapTo; void init(const CurveParam& cp = CurveFp381, fp::Mode mode = fp::FP_AUTO) { Common::initCommonParam(cp, mode, true); + mapTo.init(this->z); } }; @@ -107,6 +166,29 @@ struct BLS12T { #endif } //////////////////////////////////////////////////////////////////////////////////// + static void mapToG1(G1& P, const Fp& x) { param.mapTo.calcG1(P, x); } + static void mapToG2(G2& P, const Fp2& x) { param.mapTo.calcG2(P, x); } + static void hashAndMapToG1(G1& P, const void *buf, size_t bufSize) + { + Fp t; + t.setHashOf(buf, bufSize); + mapToG1(P, t); + } + static void hashAndMapToG2(G2& P, const void *buf, size_t bufSize) + { + Fp2 t; + t.a.setHashOf(buf, bufSize); + t.b.clear(); + mapToG2(P, t); + } + static void hashAndMapToG1(G1& P, const std::string& str) + { + hashAndMapToG1(P, str.c_str(), str.size()); + } + static void hashAndMapToG2(G2& P, const std::string& str) + { + hashAndMapToG2(P, str.c_str(), str.size()); + } }; template diff --git a/test/bls12_test.cpp b/test/bls12_test.cpp index 8e41b28..373fc12 100644 --- a/test/bls12_test.cpp +++ b/test/bls12_test.cpp @@ -149,7 +149,6 @@ void testSetStr(const G2& Q0) } } -#if 0 void testMapToG1() { G1 g; @@ -160,13 +159,6 @@ void testMapToG1() G1::mul(gr, g, BLS12::param.r); CYBOZU_TEST_ASSERT(gr.isZero()); } -#ifndef MCL_AVOID_EXCEPTION_TEST - if (BLS12::param.b == 2) { - CYBOZU_TEST_EXCEPTION(BLS12::mapToG1(g, 0), cybozu::Exception); - CYBOZU_TEST_EXCEPTION(BLS12::mapToG1(g, BLS12::param.mapTo.c1), cybozu::Exception); - CYBOZU_TEST_EXCEPTION(BLS12::mapToG1(g, -BLS12::param.mapTo.c1), cybozu::Exception); - } -#endif } void testMapToG2() @@ -179,17 +171,11 @@ void testMapToG2() G2::mul(gr, g, BLS12::param.r); CYBOZU_TEST_ASSERT(gr.isZero()); } -#ifndef MCL_AVOID_EXCEPTION_TEST - if (BLS12::param.b == 2) { - CYBOZU_TEST_EXCEPTION(BLS12::mapToG2(g, 0), cybozu::Exception); - } -#endif Fp x; x.setHashOf("abc"); BLS12::mapToG2(g, Fp2(x, 0)); CYBOZU_TEST_ASSERT(g.isValid()); } -#endif void testPrecomputed(const G1& P, const G2& Q) { @@ -354,7 +340,7 @@ CYBOZU_TEST_AUTO(naive) testTrivial(P, Q); testSetStr(Q); // testMapToG1(); -// testMapToG2(); + testMapToG2(); testPairing(P, Q, ts.e); testPrecomputed(P, Q); testMillerLoop2(P, Q); diff --git a/test/bn_test.cpp b/test/bn_test.cpp index d5f2669..785b154 100644 --- a/test/bn_test.cpp +++ b/test/bn_test.cpp @@ -339,31 +339,6 @@ CYBOZU_TEST_AUTO(naive) const TestSet& ts = g_testSetTbl[i]; printf("i=%d curve=%s\n", int(i), ts.name); initPairing(ts.cp, g_mode); -if(0){ - G1 P(ts.g1.a, ts.g1.b); - G2 Q(Fp2(ts.g2.aa, ts.g2.ab), Fp2(ts.g2.ba, ts.g2.bb)); - Fp12 z1, z2; - Fp6 x; - for (int i = 0; i < 12; i++) z1.getFp0()[i] = i * i + i + 3; - for (int i = 0; i < 6; i++) x.getFp0()[i] = i * i * i + i * 2 + 4; - z2 = z1; - Fp12 t; - mcl::util::convertFp6toFp12(t, x); - z1 *= t; - BN::mul_025(z2, x); - for (int i = 0; i < 12; i++) { - printf("i=%d\n", i); - CYBOZU_TEST_EQUAL(z1.getFp0()[i], z2.getFp0()[i]); - } -// CYBOZU_BENCH_C("addLine", 100000, BN::addLine, z1.a, Q, Q, P); -// CYBOZU_BENCH_C("dblLine", 100000, BN::dblLine, z1.a, Q, P); -BN::Fp2Dbl D; - CYBOZU_BENCH_C("Fp2Dbl::mulPre", 100000, BN::Fp2Dbl::mulPre, D, x.a, x.b); - CYBOZU_BENCH_C("Fp6mul_01", 1000000, BN::Fp6mul_01, x, x, x.a, x.b); - CYBOZU_BENCH_C("mul_025", 1000000, BN::mul_025, z2,z2.a); - CYBOZU_BENCH_C("mulSparse", 1000000, BN::mulSparse, z2,z2.a); - exit(1); -} const G1 P(ts.g1.a, ts.g1.b); const G2 Q(Fp2(ts.g2.aa, ts.g2.ab), Fp2(ts.g2.ba, ts.g2.bb)); #ifdef ONLY_BENCH