From d6229da5aaf6ed0e9154c918e731c4a09b629177 Mon Sep 17 00:00:00 2001 From: MITSUNARI Shigeo Date: Thu, 14 Feb 2019 16:12:51 +0900 Subject: [PATCH] add G1only --- include/mcl/bn.h | 7 +++ include/mcl/bn.hpp | 104 ++++++++++++++++++++++++++------- include/mcl/curve_type.h | 19 +++++- include/mcl/ec.hpp | 1 + include/mcl/ecparam.hpp | 51 ++++++++++++---- include/mcl/impl/bn_c_impl.hpp | 14 +++++ test/bn_c_test.hpp | 46 ++++++++++++++- test/bn_test.cpp | 7 ++- 8 files changed, 210 insertions(+), 39 deletions(-) diff --git a/include/mcl/bn.h b/include/mcl/bn.h index c4797a5..6499280 100644 --- a/include/mcl/bn.h +++ b/include/mcl/bn.h @@ -402,6 +402,13 @@ MCLBN_DLL_API int mclBn_G2EvaluatePolynomial(mclBnG2 *out, const mclBnG2 *cVec, MCLBN_DLL_API void mclBn_verifyOrderG1(int doVerify); MCLBN_DLL_API void mclBn_verifyOrderG2(int doVerify); +/* + EXPERIMENTAL + only for curve = MCL_SECP* or MCL_NIST* + return standard base point of the current elliptic curve +*/ +MCLBN_DLL_API int mclBnG1_getBasePoint(mclBnG1 *x); + #ifdef __cplusplus } #endif diff --git a/include/mcl/bn.hpp b/include/mcl/bn.hpp index 708e97d..5ebe5d9 100644 --- a/include/mcl/bn.hpp +++ b/include/mcl/bn.hpp @@ -315,11 +315,18 @@ public: }; struct MapTo { + enum { + BNtype, + BLS12type, + STD_ECtype + }; Fp c1_; // sqrt(-3) Fp c2_; // (-1 + sqrt(-3)) / 2 mpz_class z_; mpz_class cofactor_; - bool isBN_; + int type_; + bool useNaiveMapTo_; + int legendre(bool *pb, const Fp& x) const { mpz_class xx; @@ -488,27 +495,44 @@ struct MapTo { (void)b; c2_ = (c1_ - 1) / 2; } - void init(const mpz_class& cofactor, const mpz_class &z, bool isBN, int curveType = -1) + /* + if type == STD_ECtype, then cofactor, z are not used. + */ + void init(const mpz_class& cofactor, const mpz_class &z, int curveType) { - isBN_ = isBN; - if (isBN_) { - initBN(cofactor, z, curveType); + if (0 <= curveType && curveType < MCL_EC_BEGIN) { + type_ = curveType == MCL_BLS12_381 ? BLS12type : BNtype; + } 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 + if (type_ == BNtype) { + initBN(cofactor, z, curveType); + } else if (type_ == BLS12type) { initBLS12(z); } } bool calcG1(G1& P, const Fp& t) const { - if (isBN_) { - if (!calcBN(P, t)) return false; - // no subgroup - } else { -#ifdef MCL_USE_OLD_MAPTO_FOR_BLS12 + if (useNaiveMapTo_) { naiveMapTo(P, t); -#else + } else { if (!calcBN(P, t)) return false; -#endif + } + switch (type_) { + case BNtype: + // no subgroup + break; + case BLS12type: mulByCofactorBLS12(P, P); + break; } assert(P.isValid()); return true; @@ -518,16 +542,18 @@ struct MapTo { */ bool calcG2(G2& P, const Fp2& t) const { - if (isBN_) { - if (!calcBN(P, t)) return false; - mulByCofactorBN(P, P); - } else { -#ifdef MCL_USE_OLD_MAPTO_FOR_BLS12 + if (useNaiveMapTo_) { naiveMapTo(P, t); -#else + } else { if (!calcBN(P, t)) return false; -#endif + } + switch(type_) { + case BNtype: + mulByCofactorBN(P, P); + break; + case BLS12type: mulByCofactorBLS12(P, P); + break; } assert(P.isValid()); return true; @@ -1018,6 +1044,9 @@ struct Param { bool useNAF; local::SignVec zReplTbl; + // for initG1only + G1 basePoint; + void init(bool *pb, const mcl::CurveParam& cp, fp::Mode mode) { this->cp = cp; @@ -1099,14 +1128,31 @@ struct Param { } */ if (isBLS12) { - mapTo.init(0, z, false); + mapTo.init(0, z, cp.curveType); } else { - mapTo.init(2 * p - r, z, true, cp.curveType); + mapTo.init(2 * p - r, z, cp.curveType); } glv1.init(r, z, isBLS12, cp.curveType); glv2.init(r, z, isBLS12); + basePoint.clear(); *pb = true; } + void initG1only(bool *pb, const mcl::EcParam& para) + { + Fp::init(pb, para.p); + if (!*pb) return; + Fr::init(pb, para.n); + if (!*pb) return; + G1::init(pb, para.a, para.b); + if (!*pb) return; + G1::setOrder(Fr::getOp().mp); + mapTo.init(0, 0, para.curveType); + Fp x0, y0; + x0.setStr(pb, para.gx); + if (!*pb) return; + y0.setStr(pb, para.gy); + basePoint.set(pb, x0, y0); + } #ifndef CYBOZU_DONT_USE_EXCEPTION void init(const mcl::CurveParam& cp, fp::Mode mode) { @@ -2195,5 +2241,21 @@ inline void initPairing(const mcl::CurveParam& cp = mcl::BN254, fp::Mode mode = } #endif +inline void initG1only(bool *pb, const mcl::EcParam& para) +{ + local::StaticVar<>::param.initG1only(pb, para); + if (!*pb) return; + G1::setMulArrayGLV(0); + G2::setMulArrayGLV(0); + Fp12::setPowArrayGLV(0); + G1::setCompressedExpression(); + G2::setCompressedExpression(); +} + +inline const G1& getG1basePoint() +{ + return local::StaticVar<>::param.basePoint; +} + } } // mcl::bn diff --git a/include/mcl/curve_type.h b/include/mcl/curve_type.h index 5957d1a..9e4a941 100644 --- a/include/mcl/curve_type.h +++ b/include/mcl/curve_type.h @@ -14,5 +14,22 @@ enum { MCL_BN462 = 3, MCL_BN_SNARK1 = 4, MCL_BLS12_381 = 5, - MCL_BN160 = 6 + MCL_BN160 = 6, + + /* + for only G1 + the size of curve must be less or equal to MCLBN_FP_UNIT_SIZE + */ + MCL_EC_BEGIN = 100, + MCL_SECP192K1 = MCL_EC_BEGIN, + MCL_SECP224K1 = 101, + MCL_SECP256K1 = 102, + MCL_SECP384R1 = 103, + MCL_SECP521R1 = 104, + MCL_NIST_P192 = 105, + MCL_NIST_P224 = 106, + MCL_NIST_P256 = 107, + MCL_EC_END = MCL_NIST_P256 + 1, + MCL_NIST_P384 = MCL_SECP384R1, + MCL_NIST_P521 = MCL_SECP521R1 }; diff --git a/include/mcl/ec.hpp b/include/mcl/ec.hpp index 5ad2410..840fa01 100644 --- a/include/mcl/ec.hpp +++ b/include/mcl/ec.hpp @@ -1004,6 +1004,7 @@ struct EcParam { const char *gy; const char *n; size_t bitSize; // bit length of p + int curveType; }; } // mcl diff --git a/include/mcl/ecparam.hpp b/include/mcl/ecparam.hpp index 19b76bf..087bf8b 100644 --- a/include/mcl/ecparam.hpp +++ b/include/mcl/ecparam.hpp @@ -7,6 +7,7 @@ http://opensource.org/licenses/BSD-3-Clause */ #include +#include namespace mcl { namespace ecparam { @@ -18,7 +19,8 @@ const struct mcl::EcParam secp160k1 = { "0x3b4c382ce37aa192a4019e763036f4f5dd4d7ebb", "0x938cf935318fdced6bc28286531733c3f03c4fee", "0x100000000000000000001b8fa16dfab9aca16b6b3", - 160 + 160, + -1 }; // p=2^160 + 7 const struct mcl::EcParam p160_1 = { @@ -29,7 +31,8 @@ const struct mcl::EcParam p160_1 = { "1", "1236612389951462151661156731535316138439983579284", "1461501637330902918203683518218126812711137002561", - 161 + 161, + -1 }; const struct mcl::EcParam secp192k1 = { "secp192k1", @@ -39,7 +42,8 @@ const struct mcl::EcParam secp192k1 = { "0xdb4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d", "0x9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d", "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d", - 192 + 192, + MCL_SECP192K1 }; const struct mcl::EcParam secp224k1 = { "secp224k1", @@ -49,7 +53,8 @@ const struct mcl::EcParam secp224k1 = { "0xa1455b334df099df30fc28a169a467e9e47075a90f7e650eb6b7a45c", "0x7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5", "0x10000000000000000000000000001dce8d2ec6184caf0a971769fb1f7", - 224 + 224, + MCL_SECP224K1 }; const struct mcl::EcParam secp256k1 = { "secp256k1", @@ -59,7 +64,8 @@ const struct mcl::EcParam secp256k1 = { "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - 256 + 256, + MCL_SECP256K1 }; const struct mcl::EcParam secp384r1 = { "secp384r1", @@ -69,7 +75,8 @@ const struct mcl::EcParam secp384r1 = { "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973", - 384 + 384, + MCL_SECP384R1 }; const struct mcl::EcParam secp521r1 = { "secp521r1", @@ -79,7 +86,8 @@ const struct mcl::EcParam secp521r1 = { "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - 521 + 521, + MCL_SECP521R1 }; const struct mcl::EcParam NIST_P192 = { "NIST_P192", @@ -89,7 +97,8 @@ const struct mcl::EcParam NIST_P192 = { "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", - 192 + 192, + MCL_NIST_P192 }; const struct mcl::EcParam NIST_P224 = { "NIST_P224", @@ -99,7 +108,8 @@ const struct mcl::EcParam NIST_P224 = { "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d", - 224 + 224, + MCL_NIST_P224 }; const struct mcl::EcParam NIST_P256 = { "NIST_P256", @@ -109,7 +119,8 @@ const struct mcl::EcParam NIST_P256 = { "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - 256 + 256, + MCL_NIST_P256 }; // same secp384r1 const struct mcl::EcParam NIST_P384 = { @@ -120,7 +131,8 @@ const struct mcl::EcParam NIST_P384 = { "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973", - 384 + 384, + MCL_NIST_P384 }; // same secp521r1 const struct mcl::EcParam NIST_P521 = { @@ -131,7 +143,8 @@ const struct mcl::EcParam NIST_P521 = { "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - 521 + 521, + MCL_NIST_P521 }; } // mcl::ecparam @@ -161,4 +174,18 @@ static inline const mcl::EcParam* getEcParam(const std::string& name) } #endif +inline const mcl::EcParam* getEcParam(int curve) +{ + switch (curve) { + case MCL_SECP192K1: return &ecparam::secp192k1; + case MCL_SECP224K1: return &ecparam::secp224k1; + case MCL_SECP256K1: return &ecparam::secp256k1; + case MCL_SECP384R1: return &ecparam::secp384r1; + case MCL_NIST_P192: return &ecparam::NIST_P192; + case MCL_NIST_P224: return &ecparam::NIST_P224; + case MCL_NIST_P256: return &ecparam::NIST_P256; + default: return 0; + } +} + } // mcl diff --git a/include/mcl/impl/bn_c_impl.hpp b/include/mcl/impl/bn_c_impl.hpp index d043764..4a78b0b 100644 --- a/include/mcl/impl/bn_c_impl.hpp +++ b/include/mcl/impl/bn_c_impl.hpp @@ -17,6 +17,7 @@ #error "not supported size" #endif #include +#include using namespace mcl::bn; static Fr *cast(mclBnFr *p) { return reinterpret_cast(p); } @@ -64,6 +65,13 @@ int mclBn_init(int curve, int compiledTimeVar) if (compiledTimeVar != MCLBN_COMPILED_TIME_VAR) { return -(compiledTimeVar | (MCLBN_COMPILED_TIME_VAR * 100)); } + if (MCL_EC_BEGIN <= curve && curve < MCL_EC_END) { + const mcl::EcParam *para = mcl::getEcParam(curve); + if (para == 0) return -2; + bool b; + initG1only(&b, *para); + return b ? 0 : -1; + } const mcl::CurveParam& cp = mcl::getCurveParam(curve); bool b; initPairing(&b, cp); @@ -602,3 +610,9 @@ int mclBnFp2_mapToG2(mclBnG2 *y, const mclBnFp2 *x) return b ? 0 : -1; } +int mclBnG1_getBasePoint(mclBnG1 *x) +{ + *cast(x) = mcl::bn::getG1basePoint(); + return 0; +} + diff --git a/test/bn_c_test.hpp b/test/bn_c_test.hpp index d6926a4..8631ef1 100644 --- a/test/bn_c_test.hpp +++ b/test/bn_c_test.hpp @@ -2,6 +2,7 @@ include from bn_if256_test.cpp and bn_if384_test.cpp */ #include +#include #include #include @@ -132,7 +133,7 @@ CYBOZU_TEST_AUTO(Fr) } } -CYBOZU_TEST_AUTO(G1) +void G1test() { mclBnG1 x, y, z; memset(&x, 0x1, sizeof(x)); @@ -149,10 +150,10 @@ CYBOZU_TEST_AUTO(G1) char buf[1024]; size_t size; - size = mclBnG1_getStr(buf, sizeof(buf), &x, 10); + size = mclBnG1_getStr(buf, sizeof(buf), &y, 10); CYBOZU_TEST_ASSERT(size > 0); CYBOZU_TEST_EQUAL(size, strlen(buf)); - CYBOZU_TEST_ASSERT(!mclBnG1_setStr(&y, buf, strlen(buf), 10)); + CYBOZU_TEST_ASSERT(!mclBnG1_setStr(&x, buf, strlen(buf), 10)); CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&x, &y)); mclBnG1_neg(&x, &x); @@ -176,6 +177,11 @@ CYBOZU_TEST_AUTO(G1) CYBOZU_TEST_ASSERT(mclBnG1_isEqual(&y, &z)); } +CYBOZU_TEST_AUTO(G1) +{ + G1test(); +} + CYBOZU_TEST_AUTO(G2) { mclBnG2 x, y, z; @@ -628,3 +634,37 @@ CYBOZU_TEST_AUTO(mapToG2) mclBnG2_hashAndMapTo(&P2, "abc", 3); CYBOZU_TEST_ASSERT(mclBnG2_isEqual(&P1, &P2)); } + +void G1onlyTest(int curve) +{ + printf("curve=%d\n", curve); + int ret; + ret = mclBn_init(curve, MCLBN_COMPILED_TIME_VAR); + CYBOZU_TEST_EQUAL(ret, 0); + mclBnG1 P0; + ret = mclBnG1_getBasePoint(&P0); + CYBOZU_TEST_EQUAL(ret, 0); + char buf[256]; + ret = mclBnG1_getStr(buf, sizeof(buf), &P0, 16); + CYBOZU_TEST_ASSERT(ret > 0); + printf("basePoint=%s\n", buf); + G1test(); +} + +CYBOZU_TEST_AUTO(G1only) +{ + const int tbl[] = { + MCL_SECP192K1, + MCL_NIST_P192, + MCL_SECP224K1, + MCL_NIST_P224, // hashAndMapTo is error + MCL_SECP256K1, + MCL_NIST_P256, +#if MCLBN_FP_UNIT_SIZE >= 6 && MCLBN_FR_UNIT_SIZE >= 6 + MCL_SECP384R1, +#endif + }; + for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { + G1onlyTest(tbl[i]); + } +} diff --git a/test/bn_test.cpp b/test/bn_test.cpp index 4ee2980..52a48d6 100644 --- a/test/bn_test.cpp +++ b/test/bn_test.cpp @@ -118,9 +118,12 @@ void testMapToG1() } #ifndef MCL_AVOID_EXCEPTION_TEST if (BN::param.cp.b == 2) { + Fp c1; + bool b = Fp::squareRoot(c1, -3); + CYBOZU_TEST_ASSERT(b); CYBOZU_TEST_EXCEPTION(mapToG1(g, 0), cybozu::Exception); - CYBOZU_TEST_EXCEPTION(mapToG1(g, BN::param.mapTo.c1_), cybozu::Exception); - CYBOZU_TEST_EXCEPTION(mapToG1(g, -BN::param.mapTo.c1_), cybozu::Exception); + CYBOZU_TEST_EXCEPTION(mapToG1(g, c1), cybozu::Exception); + CYBOZU_TEST_EXCEPTION(mapToG1(g, -c1), cybozu::Exception); } #endif }