diff --git a/include/mcl/bn.h b/include/mcl/bn.h index 6e5d1ff..78f8f27 100644 --- a/include/mcl/bn.h +++ b/include/mcl/bn.h @@ -191,10 +191,16 @@ MCLBN_DLL_API mclSize mclBn_getFieldOrder(char *buf, mclSize maxBufSize); /* set ETH serialization mode for BLS12-381 - @param ETHserialization [in] 1:enable, 0:disable + @param enable [in] 1:enable, 0:disable @note ignore the flag if curve is not BLS12-381 */ -MCLBN_DLL_API void mclBn_setETHserialization(int ETHserialization); +MCLBN_DLL_API void mclBn_setETHserialization(int enable); +/* + use mapToGi according to + https://github.com/ethereum/eth2.0-specs/blob/dev/specs/bls_signature.md#modular_squareroot +*/ +MCLBN_DLL_API void mclBn_setETHmaptTo(int enable); + //////////////////////////////////////////////// /* deserialize diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp index 3a8d61b..b1b2cf9 100644 --- a/include/mcl/bn.hpp +++ b/include/mcl/bn.hpp @@ -326,6 +326,7 @@ struct MapTo { mpz_class cofactor_; int type_; bool useNaiveMapTo_; + bool useETHsquareRoot_; int legendre(bool *pb, const Fp& x) const { @@ -495,6 +496,23 @@ struct MapTo { (void)b; c2_ = (c1_ - 1) / 2; } + // enable if standard Ec + void setNaiveMapTo(bool enable) + { + if (type_ == STD_ECtype) { + useNaiveMapTo_ = true; + } else { + useNaiveMapTo_ = enable; + } + } + void setETHsquareRoot(bool enable) + { + if (type_ == BLS12type) { + useETHsquareRoot_ = enable; + } else { + useETHsquareRoot_ = false; + } + } /* if type == STD_ECtype, then cofactor, z are not used. */ @@ -505,14 +523,8 @@ struct MapTo { } else { type_ = STD_ECtype; } - if (type_ == STD_ECtype) { - useNaiveMapTo_ = true; - } else { - useNaiveMapTo_ = false; - } -#ifdef MCL_USE_OLD_MAPTO_FOR_BLS12 - if (type == BLS12type) useNaiveMapTo_ = true; -#endif + setNaiveMapTo(false); + setETHsquareRoot(false); if (type_ == BNtype) { initBN(cofactor, z, curveType); } else if (type_ == BLS12type) { @@ -553,13 +565,26 @@ struct MapTo { } assert(P.isValid()); } - template - bool calc(G& P, const F& t) const + bool calc(G1& P, const Fp& t) const { if (!mapToEc(P, t)) return false; mulByCofactor(P); return true; } + bool calc(G2& P, const Fp2& t) const + { + if (!mapToEc(P, t)) return false; + if (useETHsquareRoot_) { + Fp2 negY; + Fp2::neg(negY, P.y); + int cmp = Fp::compare(P.y.b, negY.b); + if (!(cmp > 0 || (cmp == 0 && P.y.a > negY.a))) { + P.y = negY; + } + } + mulByCofactor(P); + return true; + } }; @@ -2068,6 +2093,14 @@ inline void millerLoopVec(Fp12& f, const G1* Pvec, const G2* Qvec, size_t n) } } +inline void setETHmapTo(bool enable) +{ + local::StaticVar<>::param.mapTo.setNaiveMapTo(enable); +} +inline void setETHsquareRoot(bool enable) +{ + local::StaticVar<>::param.mapTo.setETHsquareRoot(enable); +} inline void mapToG1(bool *pb, G1& P, const Fp& x) { *pb = BN::param.mapTo.calc(P, x); } inline void mapToG2(bool *pb, G2& P, const Fp2& x) { *pb = BN::param.mapTo.calc(P, x); } #ifndef CYBOZU_DONT_USE_EXCEPTION diff --git a/include/mcl/impl/bn_c_impl.hpp b/include/mcl/impl/bn_c_impl.hpp index 51112a7..1d8fe04 100644 --- a/include/mcl/impl/bn_c_impl.hpp +++ b/include/mcl/impl/bn_c_impl.hpp @@ -113,9 +113,14 @@ mclSize mclBn_getFieldOrder(char *buf, mclSize maxBufSize) return Fp::getModulo(buf, maxBufSize); } -void mclBn_setETHserialization(int ETHserialization) +void mclBn_setETHserialization(int enable) { - Fp::setETHserialization(ETHserialization == 1); + Fp::setETHserialization(enable == 1); +} + +void mclBn_setETHmaptTo(int enable) +{ + setETHmapTo(enable == 1); } ////////////////////////////////////////////////