From 4f4a8d47eb1e992398f9ea8dac93b93ac09d5453 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Mon, 17 Oct 2016 13:58:32 +0900 Subject: [PATCH] add MapToG2 --- include/mcl/bn.hpp | 37 ++++++++++++++++++++++++++++++++++++- include/mcl/fp_tower.hpp | 7 +++++++ test/bn_test.cpp | 12 +++++++++++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp index 13487ec..d5540e7 100644 --- a/include/mcl/bn.hpp +++ b/include/mcl/bn.hpp @@ -119,6 +119,12 @@ struct MapTo { { return gmp::legendre(x.getMpz(), Fp::getOp().mp); } + int legendre(const Fp2& x) const + { + Fp y; + Fp2::norm(y, x); + return legendre(y); + } MapTo() { if (!Fp::squareRoot(c1, -3)) throw cybozu::Exception("MapTo:c1"); @@ -126,7 +132,7 @@ struct MapTo { } /* P.-A. Fouque and M. Tibouchi, - "Indifferentiable hashing to Barreto Naehrig curves, " in Proc. Int. Conf. Cryptol. Inform. Security Latin Amer., 2012, vol. 7533, pp.1-17. + "Indifferentiable hashing to Barreto Naehrig curves," in Proc. Int. Conf. Cryptol. Inform. Security Latin Amer., 2012, vol. 7533, pp.1-17. w = sqrt(-3) t / (1 + b + t^2) Remark: throw exception if t = 0, c1, -c1 @@ -156,6 +162,35 @@ struct MapTo { ERR_POINT: throw cybozu::Exception("MapTo:calcG1:bad") << t; } + void calcG2(G2& P, const Fp2& t) const + { + Fp2 x, y, w; + bool negative = legendre(t) < 0; + if (t.isZero()) goto ERR_POINT; + Fp2::sqr(w, t); + w += G2::b_; + w.a += Fp::one(); + if (w.isZero()) goto ERR_POINT; + Fp2::inv(w, w); + w.a *= c1; + w.b *= c1; + w *= t; + for (int i = 0; i < 3; i++) { + switch (i) { + case 0: x = - t * w; x.a += c2; break; + case 1: Fp2::neg(x, x); x.a -= Fp::one(); break; + case 2: Fp2::sqr(x, w); Fp2::inv(x, x); x.a += Fp::one(); break; + } + G2::getWeierstrass(y, x); + if (Fp2::squareRoot(y, y)) { + if (negative) Fp2::neg(y, y); + P.set(x, y); + return; + } + } + ERR_POINT: + throw cybozu::Exception("MapTo:calcG2:bad") << t; + } }; template diff --git a/include/mcl/fp_tower.hpp b/include/mcl/fp_tower.hpp index 0e7b53b..8a1cb3c 100644 --- a/include/mcl/fp_tower.hpp +++ b/include/mcl/fp_tower.hpp @@ -153,6 +153,13 @@ public: Fp::mul(y.b, x.b, t2); return true; } + static void inline norm(Fp& y, const Fp2T& x) + { + Fp aa, bb; + Fp::sqr(aa, x.a); + Fp::sqr(bb, x.b); + Fp::add(y, aa, bb); + } static const Fp& getXi_a() { return xi_a_; } static void init(uint32_t xi_a) diff --git a/test/bn_test.cpp b/test/bn_test.cpp index 9728ba8..a37c4fe 100644 --- a/test/bn_test.cpp +++ b/test/bn_test.cpp @@ -95,7 +95,7 @@ CYBOZU_TEST_AUTO(naive) CYBOZU_BENCH("finalExp", BN::finalExp, e1, e1); // 1.3Mclk } -CYBOZU_TEST_AUTO(MapTo) +CYBOZU_TEST_AUTO(MapToG1) { mcl::bn::MapTo mapTo; @@ -108,6 +108,16 @@ CYBOZU_TEST_AUTO(MapTo) CYBOZU_TEST_EXCEPTION(mapTo.calcG1(g, -mapTo.c1), cybozu::Exception); } +CYBOZU_TEST_AUTO(MapToG2) +{ + mcl::bn::MapTo mapTo; + + G2 g; + for (int i = 1; i < 10; i++) { + mapTo.calcG2(g, i); + } +} + CYBOZU_TEST_AUTO(stream) { const TestSet& ts = g_testSetTbl[0];