#define PUT(x) std::cout << #x "=" << x << std::endl; #define CYBOZU_TEST_DISABLE_AUTO_RUN #include cybozu::CpuClock clk; #include #include #include #include #if defined(__EMSCRIPTEN__) && !defined(MCL_AVOID_EXCEPTION_TEST) #define MCL_AVOID_EXCEPTION_TEST #endif //typedef mcl::bls12::BLS12::Compress Compress; using namespace mcl::bls12_381; mcl::fp::Mode g_mode; const struct TestSet { mcl::bls12::CurveParam cp; const char *name; const char *p; const char *r; struct G2 { const char *aa; const char *ab; const char *ba; const char *bb; } g2; struct G1 { const char *a; const char *b; } g1; const char *e; } g_testSetTbl[] = { { mcl::bls12::CurveFp381, "CurveFp381", "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", { "352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160", "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758", "1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905", "927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582", }, { "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507", "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569", }, "1", }, }; CYBOZU_TEST_AUTO(size) { CYBOZU_TEST_EQUAL(sizeof(Fp), 48u); CYBOZU_TEST_EQUAL(sizeof(Fp2), sizeof(Fp) * 2); CYBOZU_TEST_EQUAL(sizeof(Fp6), sizeof(Fp) * 6); CYBOZU_TEST_EQUAL(sizeof(Fp12), sizeof(Fp) * 12); CYBOZU_TEST_EQUAL(sizeof(G1), sizeof(Fp) * 3); CYBOZU_TEST_EQUAL(sizeof(G2), sizeof(Fp2) * 3); } void testParam(const TestSet& ts) { CYBOZU_TEST_EQUAL(BLS12::param.r, mpz_class(ts.r)); CYBOZU_TEST_EQUAL(BLS12::param.p, mpz_class(ts.p)); } void finalExpC(Fp12& y, const Fp12& x) { const mpz_class& r = BLS12::param.r; const mpz_class& p = BLS12::param.p; mpz_class p2 = p * p; mpz_class p4 = p2 * p2; #if 1 Fp12::pow(y, x, p2 + 1); Fp12::pow(y, y, p4 * p2 - 1); Fp12::pow(y, y, (p4 - p2 + 1) / r * 3); #else Fp12::pow(y, x, (p4 * p4 * p4 - 1) / r * 3); #endif } void pairingC(Fp12& e, const G1& P, const G2& Q) { BLS12::millerLoop(e, P, Q); BLS12::finalExp(e, e); } void testFp2() { const int mode = mcl::IoEcProj | 16; #if 0 const char *fp2Str = "02FBC6AB61804796CEC672F8E448A0A031D60AF32278E0D808F5FCF90FCCECFB7AFC48B6D2F8729B75E717A8926C929B\n" "05D3340AF775CE1F8F51B472564EC638003FE1EF7E6974DE3891AF306F1129619BD1C753DE1E543BAEFBD9122370E50C"; const char *epStr = "4 10A7342E5BB2FEF9DD18082E39A432BABB79122180DCE20D2F87BFF8FA5F02B173DB0A9AD1B6803085AC4809F4D535D4\n" "16F75BC2F77D23DFC00E624A85E219E29792AF3057A56B3677BAEADC3C88F3E8CC0177ED9AAF4ACF58770EDF96B21880\n" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"; const char *epStrX = "10A7342E5BB2FEF9DD18082E39A432BABB79122180DCE20D2F87BFF8FA5F02B173DB0A9AD1B6803085AC4809F4D535D4"; const char *epStrY = "16F75BC2F77D23DFC00E624A85E219E29792AF3057A56B3677BAEADC3C88F3E8CC0177ED9AAF4ACF58770EDF96B21880"; const char *ep2Str = "4 03085259B2F2489939575F142795553C83B2CD5430C0AA6B90D216F49040A0A7A8051CB0633B962B44BF23F2C8791EF2\n" "14E410C0FDB7E7934CBE981D297F4E690E22E55598C894DFFE724005DD3BBBF2A983B225BBADC513D3BE9033B4C7EE15\n" "0467A954FEACA8828BEB1DB5ADD695F8058ADA2468613E30AFE6B4BBA41F6E13564911623179752E639F2E361D346807\n" "0FD33C69B0810B788C778180B58DFA0F15CA743217AF48540DC4F05CDB6AFD19BC65D6B20BF836FCA2D369A0E753B232\n" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; G2 Q1, Q2; Q1.setStr(ep2Str, mode); printf("Q1=");Q1.save(std::cout, mode);puts(""); BLS12::G2withF::Frobenius(Q2, Q1); printf("Q2=");Q2.save(std::cout, mode);puts(""); #endif const mpz_class& r = Fr::getOp().mp; std::cout << r << std::endl; const char *pStr = "4 0FD3977C60EC322BC281C915955ED534B491E39C72E8E800271CEF3F0492D890829FA69C45FCE93D9847A0CAB325D871\n" "17CC2C36C5D283C05BFCECCF48DBB2050332DA058DD67326A9EE520967DBCAEDFCB5F05A085D1A49DF08BB968CC782C5\n" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"; const char *qStr = "4 0B5C339C23F8EAB3647E974BCDDF72C96F97A444346BE72CA73AB1323B83B8F6161257AB34C7E0CF34F6C45086CA5868\n" "13C2235E9F9DFB33344BA2EE5A71435859022880732EDC9EC75AC79AE9DA972593CDC40A0AC334D6D2E8D7FAD1D98D0B\n" "134B8EED8196A00D3B70ADBC26FF963B725A351CF0B73FE1A541788AFB0BB081AF82A438021B5E878B15D53B1D27C6A7\n" "18CC69F847BEE826B939DCB4030D33020D03B046465C9EE103AA8009A175DB169070294E75771586687FE361DB884BCD\n" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; const char *eStr = "195F00B5CAF7F7526D513F13E426D3A551BDBA6447838E5F27938F2D3DF75FA7D65900045D2E86B7E32EE6F715021476\n" "03B75FD210533222694BA18ECBF87B9AAF5C07B41DF8F425DA8F6E0E54D371EB7504F575061CF6582CB2F98F556E20C3\n" "12B10D5B44B414989C5EEE6072CA1242658CBEC1913D92B657E121C4A78D5BA955D3923453EF20BE506A676B9FE79851\n" "184EAE75A0C9CA250A41110F23591C6FA9C8B99C84320F3A864430CC2E59776662A90516D23723D69942388C32262A49\n" "05D32B125451D2E020F678CF890A381DCCBE1466A0B6D1FE1C7A26A5B9EA6C2F1A4808A6E7008C478370E457F0E60244\n" "1756F936AF3FA98060D89D01E66767EE8FE22FFA8405FE20ED541DA2320E9600DFCBD1C6C7A666E62D273F6E87D9E432\n" "10AD5F5EE826231A37D5E738031DDEC3D12BAFB293D8CFAEBCAEA38F35C64A8844D7A72E87438A05FF4D0EF812402F11\n" "060321B2003D21A5D32C2D54BF6386F2A364DDEFA0F34602C10C3426D55D950527BD96DAFE6A5ACAB4DD627973DAA4F2\n" "018E3FAC77147F515D7921BCC43D58902F843BEBE44D723C8018E6412A6FF8E5F63D3D54EC51B52E24966891B6A127DB\n" "0D0C6DCC4A54F70338CE486531ABB977D04166D34610E6B8C82DB3B666836A5F377345F3FF20B4ADA07500A187701F6B\n" "101C8867AF7DBA0703559BFBB78B675167D5F8C1D14589E1AB8922036BC65A09181377174A979ACBD0C35D95F81C0B2C\n" "0B74D753D17ED32C40CC0E38A777975FC0871A01A20F628A7314B353241D4AE8BD6B844898216201B4CE1ADCBFF6F8DD"; G1 P; G2 Q; P.setStr(pStr, mode); Q.setStr(qStr, mode); std::cout << std::hex; std::cout << "P=" << P.getStr(mode) << std::endl; std::cout << "Q=" << Q.getStr(mode) << std::endl; Fp12 e1, e2; e1.setStr(eStr, 16); BLS12::pairing(e2, P, Q); // CYBOZU_TEST_EQUAL(e1, e2); } void testIoAll(const G1& P, const G2& Q) { const int FpTbl[] = { 0, 2, 2|mcl::IoPrefix, 10, 16, 16|mcl::IoPrefix, mcl::IoArray, mcl::IoArrayRaw }; const int EcTbl[] = { mcl::IoEcAffine, mcl::IoEcProj, mcl::IoEcCompY, mcl::IoSerialize }; for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(FpTbl); i++) { for (size_t j = 0; j < CYBOZU_NUM_OF_ARRAY(EcTbl); j++) { G1 P2 = P, P3; G2 Q2 = Q, Q3; int ioMode = FpTbl[i] | EcTbl[j]; std::string s = P2.getStr(ioMode); P3.setStr(s, ioMode); CYBOZU_TEST_EQUAL(P2, P3); s = Q2.getStr(ioMode); Q3.setStr(s, ioMode); CYBOZU_TEST_EQUAL(Q2, Q3); s = P.x.getStr(ioMode); Fp Px; Px.setStr(s, ioMode); CYBOZU_TEST_EQUAL(P.x, Px); s = Q.x.getStr(ioMode); Fp2 Qx; Qx.setStr(s, ioMode); CYBOZU_TEST_EQUAL(Q.x, Qx); } } } void testIo(const G1& P, const G2& Q) { testIoAll(P, Q); G1 Z1; G2 Z2; Z1.clear(); Z2.clear(); testIoAll(Z1, Z2); } void testSetStr(const G2& Q0) { G2::setCompressedExpression(); G2 Q; Q.clear(); for (int i = 0; i < 10; i++) { G2 R; R.setStr(Q.getStr()); CYBOZU_TEST_EQUAL(Q, R); G2::add(Q, Q, Q0); } } #if 0 void testMapToG1() { G1 g; for (int i = 1; i < 10; i++) { BLS12::mapToG1(g, i); CYBOZU_TEST_ASSERT(!g.isZero()); G1 gr; 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() { G2 g; for (int i = 1; i < 10; i++) { BLS12::mapToG2(g, i); CYBOZU_TEST_ASSERT(!g.isZero()); G2 gr; 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()); } void testPrecomputed(const G1& P, const G2& Q) { Fp12 e1, e2; BLS12::pairing(e1, P, Q); std::vector Qcoeff; BLS12::precomputeG2(Qcoeff, Q); BLS12::precomputedMillerLoop(e2, P, Qcoeff); BLS12::finalExp(e2, e2); CYBOZU_TEST_EQUAL(e1, e2); } void testFp12pow(const G1& P, const G2& Q) { Fp12 e, e1, e2; BLS12::pairing(e, P, Q); cybozu::XorShift rg; for (int i = -10; i < 10; i++) { mpz_class xm = i; Fp12::pow(e1, e, xm); Fp12::powGeneric(e2, e, xm); CYBOZU_TEST_EQUAL(e1, e2); } for (int i = 0; i < 10; i++) { Fr x; x.setRand(rg); mpz_class xm = x.getMpz(); Fp12::pow(e1, e, xm); BLS12::param.glv2.pow(e2, e, xm); CYBOZU_TEST_EQUAL(e1, e2); } } void testMillerLoop2(const G1& P1, const G2& Q1) { Fp12 e1, e2; mpz_class c1("12342342423442"); mpz_class c2("329428049820348209482"); G2 Q2; G1 P2; G2::mul(Q2, Q1, c1); G1::mul(P2, P1, c2); BLS12::pairing(e1, P1, Q1); BLS12::pairing(e2, P2, Q2); e1 *= e2; std::vector Q1coeff, Q2coeff; BLS12::precomputeG2(Q1coeff, Q1); BLS12::precomputeG2(Q2coeff, Q2); BLS12::precomputedMillerLoop2(e2, P1, Q1coeff, P2, Q2coeff); BLS12::finalExp(e2, e2); CYBOZU_TEST_EQUAL(e1, e2); } void testPairing(const G1& P, const G2& Q, const char *eStr) { Fp12 e1; BLS12::pairing(e1, P, Q); Fp12 e2; { std::stringstream ss(eStr); ss >> e2; } CYBOZU_TEST_EQUAL(e1, e2); #ifdef ONLY_BENCH for (int i = 0; i < 1000; i++) BLS12::pairing(e1, P, Q); // CYBOZU_BENCH_C("pairing", 1000, BLS12::pairing, e1, P, Q); // 2.4Mclk #else { Fp12 e = e1, ea; G1 Pa; G2 Qa; #if defined(__EMSCRIPTEN__) || MCL_SIZEOF_UNIT == 4 const int count = 100; #else const int count = 1000; #endif mpz_class a; cybozu::XorShift rg; for (int i = 0; i < count; i++) { Fr r; r.setRand(rg); a = r.getMpz(); Fp12::pow(ea, e, a); G1::mul(Pa, P, a); G2::mul(Qa, Q, a); G1 T; G1::mulCT(T, P, a); CYBOZU_TEST_EQUAL(Pa, T); BLS12::pairing(e1, Pa, Q); BLS12::pairing(e2, P, Qa); CYBOZU_TEST_EQUAL(ea, e1); CYBOZU_TEST_EQUAL(ea, e2); } mpz_class z = 3; CYBOZU_BENCH_C("G1::mulCT ", 500, G1::mulCT, Pa, P, a); CYBOZU_BENCH_C("G1::mulCT z", 500, G1::mulCT, Pa, P, z); CYBOZU_BENCH_C("G1::mul ", 500, G1::mul, Pa, Pa, a); CYBOZU_BENCH_C("G1::mul z", 500, G1::mul, Pa, Pa, z); CYBOZU_BENCH_C("G1::add", 500, G1::add, Pa, Pa, P); CYBOZU_BENCH_C("G1::dbl", 500, G1::dbl, Pa, Pa); CYBOZU_BENCH_C("G2::mulCT ", 500, G2::mulCT, Qa, Q, a); CYBOZU_BENCH_C("G2::mulCT z", 500, G2::mulCT, Qa, Q, z); CYBOZU_BENCH_C("G2::mul ", 500, G2::mul, Qa, Qa, a); CYBOZU_BENCH_C("G2::mul z", 500, G2::mul, Qa, Qa, z); CYBOZU_BENCH_C("G2::add", 500, G2::add, Qa, Qa, Q); CYBOZU_BENCH_C("G2::dbl", 500, G2::dbl, Qa, Qa); CYBOZU_BENCH_C("GT::pow", 500, GT::pow, e1, e1, a); CYBOZU_BENCH_C("GT::powGLV", 500, BLS12::param.glv2.pow, e1, e1, a); G1 PP; G2 QQ; CYBOZU_BENCH_C("hashAndMapToG1", 500, BLS12::hashAndMapToG1, PP, "abc", 3); CYBOZU_BENCH_C("hashAndMapToG2", 500, BLS12::hashAndMapToG2, QQ, "abc", 3); } CYBOZU_BENCH("pairing", BLS12::pairing, e1, P, Q); // 2.4Mclk CYBOZU_BENCH("finalExp", BLS12::finalExp, e1, e1); // 1.3Mclk #endif } void testTrivial(const G1& P, const G2& Q) { G1 Z1; Z1.clear(); G2 Z2; Z2.clear(); Fp12 e; BLS12::pairing(e, Z1, Q); CYBOZU_TEST_EQUAL(e, 1); BLS12::pairing(e, P, Z2); CYBOZU_TEST_EQUAL(e, 1); BLS12::pairing(e, Z1, Z2); CYBOZU_TEST_EQUAL(e, 1); std::vector Qcoeff; BLS12::precomputeG2(Qcoeff, Z2); BLS12::precomputedMillerLoop(e, P, Qcoeff); BLS12::finalExp(e, e); CYBOZU_TEST_EQUAL(e, 1); BLS12::precomputeG2(Qcoeff, Q); BLS12::precomputedMillerLoop(e, Z1, Qcoeff); BLS12::finalExp(e, e); CYBOZU_TEST_EQUAL(e, 1); } #endif CYBOZU_TEST_AUTO(naive) { for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(g_testSetTbl); i++) { const TestSet& ts = g_testSetTbl[i]; printf("i=%d curve=%s\n", int(i), ts.name); initPairing(ts.cp, g_mode); const G1 P(Fp(ts.g1.a), Fp(ts.g1.b)); const G2 Q(Fp2(ts.g2.aa, ts.g2.ab), Fp2(ts.g2.ba, ts.g2.bb)); #ifdef ONLY_BENCH testPairing(P, Q, ts.e); clk.put(); return; #endif testParam(ts); testFp2(); // testIo(P, Q); #if 0 testFp12pow(P, Q); testTrivial(P, Q); testSetStr(Q); testMapToG1(); testMapToG2(); testPairing(P, Q, ts.e); testPrecomputed(P, Q); testMillerLoop2(P, Q); #endif } int count = (int)clk.getCount(); if (count) { printf("count=%d ", count); clk.put(); } } CYBOZU_TEST_AUTO(finalExp) { const char *e0Str = "012974491575E232199B73B30FE53FF643FEAE11023BCA7AF961C3600B45DFECFE4B30D52A62E73DA4C0409810304997\n" "05CE2FB890FE65E20EC36347190ECB4884E401A64B666557B53E561F6D0979B7A96AD9E647ED78BD47187195C00F563C\n" "02E85D1E559488603A70FEE99354DA8847215EC97282CA230DE96FED6DD5D4DD4EF4D901DB7F544A1A45EBEBA1450109\n" "048FB1E44DDABF18D55C95704158A24678AA2A6ED0844108762E88306E5880E8C67BF44E24E40AB3F93D9E3713170341\n" "07EF7BE685DC0DBA1B3E1D2E9090CD98EAD1325B60881772F17077386A3182B117F5FD839363F5891D08E82B88EC6F12\n" "17803435700EF7A16C06404C6D17EB4FD84079FE9872207302A36C791B6E90447B33D703BBFE04ECB641C3A573E2CD50\n" "19A494E6A872E46FC85D09FD6D30844B6FF05729BC253A9640F7BE64AAA8C2C8E0AE014A9DD816C53A3EDEBB2FA649EB\n" "020949ABAA14F1DCE17FA9E091DDA963E9E492BA788E12B9B610E80A4D94DB9CC50341ED107C7D50E5738052595D4A27\n" "09E217B513B3603723DAC3188A2F7CBDD84A56E7E5004446E7D4C63D6E378DA26E411C10898E48DB4B0C065E4699A9C5\n" "12393BD23D0EC122082A1EC892A982F3C9AFD14240CE85258D8A3EF0A13CB545D6EF7848FD40DD4AEF1554341C5C5BBF\n" "07EA8A0D6A57C78E5663F94E2B1ABC0D760ED18DBA64305EAD5EE350FB0342A7A81C0D5C8B3AD826D009276B0F32D2C8\n" "16804D0D4A2633ED01568B0F8F06C4497E46E88D05FD191AAE530ACA791D0E114D74874FA88E33FAF48757153B09BB0E"; const char *e1Str = "0E05D19E90D2C501E5502C7AC80D77201C47DF147DD1076440F0DF0179DF9802CA0775E0E73DD9174F1094D2280787B3\n" "14D2F5C84279E7177A3543FBEAE261DE8F6C97EFD5F3FF3F959EC9FC0303F620A4B3AF00DF409496CECADDD0A7F0A164\n" "1414E9B9DF8DF1EAC2E70D5538018377788C62016A54F28B037A68740705089AE431B86756F98CBE19690A5EAC0C2466\n" "12D8B32157836A131CCA3CA313DAAAF909BC3AD6BDD15885BB429922B9CD7D1246D1163E5E6F88D68BF1B75E451EFABB\n" "102C9A839A924E0D603D13F2E08A919E0B9EE2A269FC75727BA13D66027C157B9BB4077977FA94557DE4427BF11B234B\n" "19DBEB7F2E3096AFFD44837655BD8249741B484B0EB0DBEE569DEA8D9E38AE09D210C8BC16AA6DFBC923095B2C9A8B2B\n" "19B9A6DCCD01FA0D04D5CE94D8BDCE1DF64AFEB7FD493B955180A5C6B236E469F0E07CC9BB4203FCAC46AE6F8E5419D6\n" "02BFA87AF7A3726A7ABACDCFDD53694AF651554F3A431AB4274F67D5DAD2D6C88AF794705FF456A936C83594731AD8DC\n" "0F21E0173E3B50DD98EFA815B410631A57399B451FD6E1056FFD09C9FE50EFAD3D026F0C46C8BB1583A50B7853D990DA\n" "02230237AE04B61F9269F6E7CD2FCF1231CEE4690AA658B0018EFC0D0770FD0A56B3B7294086E8D306B1465CDDD858CD\n" "087EB8F6547015661E9CD48D6525C808636FCB8420B867CB2A87E006B2A93BBD5EF675E6CDDA9E6F94519C49EA8BB689\n" "19F5C988B2DD6E33D7D3D34EFB1991F80DC28006AC75E0AB53FD98FC6F2476D05DD4ECA582F5FF72B8DDD9DDDE80FFC9"; Fp12 e0, e1, e2; e0.setStr(e0Str, 16); e1.setStr(e1Str, 16); BLS12::finalExp(e2, e0); // finalExpC(e2, e0); CYBOZU_TEST_EQUAL(e1, e2); CYBOZU_BENCH_C("finalExp", 100, BLS12::finalExp, e2, e0); } CYBOZU_TEST_AUTO(addLine) { const char *l0Str= "0EF586FCDB69442CB41C0DA719AC5C92BD99A916C1F01BCFC7606AA7A23D680C04620FDFC2144E0EA6025F05241A791F\n" "164CFDADE9B91150C6D2C7F7CDF29BC3105A7EA51217283CDF801EBEE9E86CE5078253E322C72129DAA42F6DBAD17D37"; const char *l1Str = "07A124F536BE83CCB3AF8D3DA2AE094942755040B9DA8E0796C462ACE3805D6916ACA7E9281261D8025571E2F31AAF0D\n" "12D05751A9B255143541D0A4E57E120F937D51F9A07D31982390CA6EB5DF8CC0640FD291521069BF9964AE33EDD1323D"; const char *l4Str = "0D609DE41CF1260B332C1A53AA54703F62AB8224777E34FEEAB09AA06187CA71D8C7C2EB66F59D3622D431BE17D0FEE6\n" "0A93C2984041171BE701560017D64D0640B6F61D7DCA8F527FA6B6A1A1033261C0761CAA56A00D4D16C9D3B7371E02D9"; const char *rStr = "4 0A8DFA69FDD43EDCCC6375750373B443157EF4641E5B4CA82FBF23E3E8EA72351EA754168CEC77573D337E6227C0D0DD\n" "12C8508CF1828C52A9A1A71779129D605327191EE459AED3C0B4B14657B08B2927173FADF8E4275188E8D49E57A75B33\n" "12AD7EB96734F2C93B669FD54845CD2FF351AFDF0123E96772021DC3F4F3B456DB1B37CB1C380B1947616165FF0DDAEA\n" "03D80F92C8A6005DEB291AF28406B7B4FCEDD81A244997DBB719B01D162BD7D71F0FD63BF76F8F1AC90618C3702294DF\n" "199F7A719EA1CA2CD03CFFBB9A4BC2FE1BD8BCA7C772D223E6CB20C1313C3D3C52CFBB88445E56C833908C52A4EC68F1\n" "0A3F6B27A6DDA00DB848574ECB06F179271D5844BDA66CD5AE1792A8FDD25E3A504A95839113BAA8B1FCB53EEE5F1FF0"; const char *qStr = "4 0B5C339C23F8EAB3647E974BCDDF72C96F97A444346BE72CA73AB1323B83B8F6161257AB34C7E0CF34F6C45086CA5868\n" "13C2235E9F9DFB33344BA2EE5A71435859022880732EDC9EC75AC79AE9DA972593CDC40A0AC334D6D2E8D7FAD1D98D0B\n" "134B8EED8196A00D3B70ADBC26FF963B725A351CF0B73FE1A541788AFB0BB081AF82A438021B5E878B15D53B1D27C6A7\n" "18CC69F847BEE826B939DCB4030D33020D03B046465C9EE103AA8009A175DB169070294E75771586687FE361DB884BCD\n" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001\n" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; const char *pStr = "4 0FD3977C60EC322BC281C915955ED534B491E39C72E8E800271CEF3F0492D890829FA69C45FCE93D9847A0CAB325D871\n" "17CC2C36C5D283C05BFCECCF48DBB2050332DA058DD67326A9EE520967DBCAEDFCB5F05A085D1A49DF08BB968CC782C5\n" "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"; const char *m0Str = "1010A4F9944514352AAD5D290AFB95C435EB64B5E74519807C9602DABCD6B6F5494E419758AE9A43F539F812252C65E5\n" "1622F7A52BAAC10EBFF0977F61866544BF9B91315FA66ADB6AC200AFF7A3676C1AD3480340B23C66F7C6AE50A703F245"; const char *m1Str = "0905180B20FCE2AA545A73D6B9EA1F82479EF3FB5A3BA8DDB656D9B2A4DA7B63CCF75538D15093949B442E27804C8CE2\n" "0FE834508BBAD2F22DCBF1C3C1BCCD69561827613EB63F4907832A7ABBBC6040CF2E517D0D5E22D3812EEE1EC55640DD"; const char *m4Str = "1197D94A8DAFE6F72B17A31964CA5D0C3B2A12BEFF959F7DF7A37938C64C01508D12C24479E5C3D314F862A9977D6C7D\n" "0B0254A26810307964E2A05680C19DE7C63CCBD7CC3558AD366BA48D9F7049E245BF2C54EA0339301739851E6EB2158F"; const char *r1Str = "4 16A33C4ED01E95833D39EECE223380FE860B6DC1F71B1DDBEE2BE39B5D682B090F18758495E202010D3B9B45A46FF80E\n" "01CECF5CC255E32B833C16EF3F983CCA9996A33504615909AD5685D9F637BF2357442BEC89DAFC747B69EFEF57D5A213\n" "061C33850E5E4A418F3B68D6097C3911A551D6DB3C7E21196410F69D510C1A888635B6B699F98C14912A8D97742D36A9\n" "0457FB78282C2B8F8BA803E77D058EF3BF6B06C6241D6FA6E2B1607F3E9D7597D1A10B7AA4E06B89FBA01736901AD826\n" "0B45E9B7D311B8C37F7E9262227A4D721F2D148DE6F12EC5D599B45E4790F35B37A1D6928709F438849324A807EC1913\n" "0E771545F892C247A5365BA1F14934D8ED37483A6B7DD3EB4C3FBA0AC884D7EE9C080C3B39ADA64AE545E7339F83AFB0"; const int mode = mcl::IoEcProj | 16; Fp6 l, m; G2 R, Q, R1; G1 P; R.setStr(rStr, mode); Q.setStr(qStr, mode); P.setStr(pStr, mode); l.a.setStr(l0Str, mode); l.b.setStr(l4Str, mode); l.c.setStr(l1Str, mode); BLS12::addLine(l, R, Q, P); m.a.setStr(m0Str, mode); m.b.setStr(m4Str, mode); m.c.setStr(m1Str, mode); R1.setStr(r1Str, mode); CYBOZU_TEST_EQUAL(l, m); CYBOZU_TEST_EQUAL(R, R1); } CYBOZU_TEST_AUTO(dblLine) { const char *l0Str= "0905F47F07FA2177E4B73559D93D9B41A2FD20E0440167E63A0F62321EB73C784405DE360477245F5E4AE8FA2EAEC6FF\n" "02DA455C573517EE8BD4E40A60851E2EC85CF514351681B89B1B72664E384A3678A25DC5C4CF84C086C13968BC701F91"; const char *l1Str = "0F48059E31CEF9546D41DEF31FB3BFD13BBCC38248E4846AFD216350B4B661FA1382E74BCF904BE8E33C26FF0D29ABA0\n" "0D7FAEE426E4A6F32E4DE1CCB76BBA870A183113589CF58A358DC9C284C82B54C65A754F9A71EAD87304744CFD105051"; const char *l4Str = "162AE8B029F8420BEDE5A399BA19C09FED01DE2748F4458065DBE51044FBFE749B28EF1B7F79A5E4545EB550DD0CFE02\n" "091042B589FD59FBF286D21475CCCF444D8DCC49389EA3B98AF864DDB9C08BDDEB320D6D88F0C07D7CD1733A41404C1F"; const char *qStr = "4 047ACF79048EDCA97A19DB1779A44CE610CEA9FDCC62D1C4014B335834BC63414F55B670CCF15A86E58BC3737FB70919\n" "11D8063B2FFA2E1F5224593FF74D0E9650CAB6AF702B74159F7F97E2CF0843FBCD561D41FEC779BEB48746CD2F30FF74\n" "17684E8EA85C990DF5472B4EBAF51002CDBBECF79BA2988FC610A5CE09F4A584248DCC506E78C39C9BB4F6008115DE64\n" "1334CA7263ED9395BBEDBB6C938C642200C239FB0CADF1F652332A037FFBC7E567CCE09540939F25316CBC4FC68CE4DB\n" "0670DCF344F027CB92F7B1F569B281C8FF756D83CD7B65EB118FE95FBE16ED28649B8F739FE3A2BECA1979FC18484ECD\n" "13E3E30759DCC1FA9F1A62D54BEF0EE1CC75E194A559F2D6BE3025BE4BEB9F7351A7608FE8D4CCAD30BA2A8748205487"; const char *pStr = "4 1579B48AE944AFE8FC69B38A7CD0D2C6B93E5F506535A5410E25FB1C1707938D6932F3D620A2BBB90ED7E2601971DEA8\n" "0234E5B373AD62D9EF1EBAE6FA6FFAD26144717F65AE9F98BD4280978ED52B3621F60FA4A8F6E5B5DAF64469733827E6\n" "0B4D1755924541041F75FF399E3B5F535BC85D5A982AEEC5FC2404F06AC7F062C090C4545D1602C3D8B559801EE7B9A2"; const char *m0Str = "198D1123A9817C40A914A3FF9E29BB16DD2F0DF98D0AB5C3A6014D60E31AE973051C35ADCEA0A41F32BB16E6688DC73F\n" "10339DB2F26D1B867FD3E60A24F938210EABEFC51536845A490F28A088A4AC53575DBBAA218D70D34E28EBDE14DB3465\n"; const char *m1Str = "066852248D915F6378B3F4A8E6173AC748FBFAE236AAEEAECC3F34D2D22706A06B925A83DD8276B2B240F61D761587B0\n" "17CC8195E6607FF19A26AA69CA50C32487E35D2D75301AC4B6988F1B77523BF472927EE5710DF49A563534D86C684BE0\n"; const char *m4Str = "10B67D1A0CE430B7AD74F64DD6C2E44C4788EADF8340909843C96B918BF54703CC14686B26E350EB1140ACC3337EEEB4\n" "0F5D52E6F0B10A081EFF885CC858109241B379985ADD8982E6B8A202FD283897EFBA4CBE444C29751410A61FC8346545"; const char *q1Str = "4 17B5E51EC931E724ABACE9C7F8AFDD51F3929478B47C222F99844D166936063D3BFCDF7AD7079EEF4BE8514E3D09EF0F\n" "0F5794F38BAEC0FA3C30AC4C0B8E9024B2047F2F4576434F91768F2B51AD58C48E88414B1D4B7A9119A947D3CFEDEF0A\n" "1320714A8B7E23C4C558D2B1C556CC8FB6B41F3669EFD70B6D204C2A7C6EF2E0CBCA945AA7BACB402E00ED338F7D12FC\n" "0C2846E386161F123344704528D9944677806C3F784E3997857C91D2F3F37AB6AD92360CD97CABD5D631E9FC74708AD3\n" "17F92FF3D71B473B802F2DE90C19A5F5DBFAA397293871AB58E5B813F7D686EA8E1814C69C50C02D062F3A13C1D045E1\n" "05214392858DE04B3B468B2D0C703A485508C29157D81E9F799BAB2FEF0F514C99D5F8085D8062281418C6CCE5621D18\n"; const int mode = mcl::IoEcProj | 16; Fp6 l, m; G2 Q, Q1; G1 P; Q.setStr(qStr, mode); P.setStr(pStr, mode); l.a.setStr(l0Str, mode); l.b.setStr(l4Str, mode); l.c.setStr(l1Str, mode); BLS12::dblLine(l, Q, P); m.a.setStr(m0Str, mode); m.b.setStr(m4Str, mode); m.c.setStr(m1Str, mode); Q1.setStr(q1Str, mode); CYBOZU_TEST_EQUAL(l, m); CYBOZU_TEST_EQUAL(Q, Q1); } int main(int argc, char *argv[]) try { cybozu::Option opt; std::string mode; opt.appendOpt(&mode, "auto", "m", ": mode(gmp/gmp_mont/llvm/llvm_mont/xbyak)"); if (!opt.parse(argc, argv)) { opt.usage(); return 1; } g_mode = mcl::fp::StrToMode(mode); printf("JIT %d\n", mcl::fp::isEnableJIT()); return cybozu::test::autoRun.run(argc, argv); } catch (std::exception& e) { printf("ERR %s\n", e.what()); return 1; }