diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp index 5aa77b0..3b0cc3a 100644 --- a/include/mcl/bn.hpp +++ b/include/mcl/bn.hpp @@ -108,6 +108,46 @@ bool getGoodRepl(Vec& v, const mpz_class& x) } } +template +struct HashMapToG1 { + Fp c1; // sqrt(-3) + Fp c2; // (-1 + sqrt(-3)) / 2 + HashMapToG1() + { + if (!Fp::squareRoot(c1, -3)) throw cybozu::Exception("HashMapToG1:c1"); + c2 = (c1 - 1) / 2; + } + int legendre(const Fp& x) const + { + return gmp::legendre(x.getMpz(), Fp::getOp().mp); + } + /* + 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. + algorithm 1 in "Software Implementation of an Attribute-Based Encryption Scheme", IEEE. trans. on computesr, vol. 64, No.5, May 2015 + */ + void calc(mcl::EcT& P, const Fp& t, int b) const + { + Fp w = t * t + b; + w = (t / (w + 1)) * c1; + bool negative = legendre(t) < 0; + Fp x, y; + for (int i = 0; i < 3; i++) { + switch (i) { + case 0: x = c2 - t * w; break; + case 1: x = -1 - x; break; + case 2: x = 1 + 1 / (w * w); break; + } + y = x * x * x + b; + if (Fp::squareRoot(y, y)) { + if (negative) Fp::neg(y, y); + P.set(x, y); + return; + } + } + } +}; + template struct ParamT { typedef Fp2T Fp2;