diff options
Diffstat (limited to 'vendor/github.com/tangerine-network/mcl/test/bn_test.cpp')
-rw-r--r-- | vendor/github.com/tangerine-network/mcl/test/bn_test.cpp | 408 |
1 files changed, 408 insertions, 0 deletions
diff --git a/vendor/github.com/tangerine-network/mcl/test/bn_test.cpp b/vendor/github.com/tangerine-network/mcl/test/bn_test.cpp new file mode 100644 index 000000000..071ec706c --- /dev/null +++ b/vendor/github.com/tangerine-network/mcl/test/bn_test.cpp @@ -0,0 +1,408 @@ +#define PUT(x) std::cout << #x "=" << x << std::endl; +#define CYBOZU_TEST_DISABLE_AUTO_RUN +#include <cybozu/benchmark.hpp> +cybozu::CpuClock clk; +#include <cybozu/test.hpp> +#include <mcl/bn256.hpp> +#include <cybozu/option.hpp> +#include <cybozu/xorshift.hpp> + +#if defined(__EMSCRIPTEN__) && !defined(MCL_AVOID_EXCEPTION_TEST) + #define MCL_AVOID_EXCEPTION_TEST +#endif + +typedef mcl::bn::local::Compress Compress; +using namespace mcl::bn; + +mcl::fp::Mode g_mode; + +const struct TestSet { + mcl::CurveParam cp; + const char *name; + struct G2 { + const char *aa; + const char *ab; + const char *ba; + const char *bb; + } g2; + struct G1 { + int a; + int b; + } g1; + const char *e; +} g_testSetTbl[] = { + { + mcl::BN254, + "BN254", + { + "12723517038133731887338407189719511622662176727675373276651903807414909099441", + "4168783608814932154536427934509895782246573715297911553964171371032945126671", + "13891744915211034074451795021214165905772212241412891944830863846330766296736", + "7937318970632701341203597196594272556916396164729705624521405069090520231616", + }, + { + -1, 1 + }, + "8118772341496577043438385328606447626730215814727396173233264007541007797690 " + "6742571767760762192519140673058087976840103832045324348366170860928670686713 " + "9727912590495366720378364920530546614235713408261568635512172059018197267630 " + "10180700148605185348549931182990442059136187839792856455707820203302941578832 " + "5054507763444412917986776641611331046146804026682679569910978464879371792565 " + "6917005519826733659554708445125877487590687705432214234949972860245110398023 " + "10448556317747236258066222816126375978842661908560317699736569642190930635294 " + "1516980358051268127904344653343215863076753141133525905743113718749531324025 " + "9794836735385959178744195210089532061310424844916928682580569566332541022353 " + "9375574834170998962484906689780052970915033987453510324648351251071086068423 " + "710778048594563655498360873129325895716179849942646859397874562033386335205 " + "10688745994254573144943003027511098295097561129365638275727908595677791826005" + }, + { + mcl::BN_SNARK1, + "BN_SNARK1", + { + "15267802884793550383558706039165621050290089775961208824303765753922461897946", + "9034493566019742339402378670461897774509967669562610788113215988055021632533", + "644888581738283025171396578091639672120333224302184904896215738366765861164", + "20532875081203448695448744255224543661959516361327385779878476709582931298750", + }, + { + 1, 2 + }, + "15163392945550945552839911839294582974434771053565812675833291179413834896953 " + "20389211011850518572149982239826345669421868561029856883955740401696801984953 " + "17766795911013516700216709333389761327222334145011922123798810516425387779347 " + "6064163297423711021549973931984064750876944939004405231004441199168710504090 " + "296093106139306574860102680862436174771023602986903675151017278048818344347 " + "1573596951222456889652521728261836933382094474023551133585236991207205981715 " + "3511871642997169996730611220058787939468653751355351269812083879279936651479 " + "17848534184080172844395614793152774197360421729995967636680357250333093768504 " + "3273860031361637906105800996652640969711942192883181518057117446820546419132 " + "7212721189663231589365009629980400132745687533815732336503876102977912682966 " + "18569236611881855981733896549089319395087993987737891870319625215675547032585 " + "10088832670068482545658647976676953228519838542958787800193793260459700064172 " + }, +}; + +CYBOZU_TEST_AUTO(size) +{ + CYBOZU_TEST_EQUAL(sizeof(Fp), 32u); + 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 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); + } +} + +void testMapToG1() +{ + G1 g; + for (int i = 1; i < 10; i++) { + mapToG1(g, i); + CYBOZU_TEST_ASSERT(!g.isZero()); + G1 gr; + G1::mulGeneric(gr, g, BN::param.r); + CYBOZU_TEST_ASSERT(gr.isZero()); + } +#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, c1), cybozu::Exception); + CYBOZU_TEST_EXCEPTION(mapToG1(g, -c1), cybozu::Exception); + } +#endif +} + +void testMapToG2() +{ + G2 g; + for (int i = 1; i < 10; i++) { + mapToG2(g, i); + CYBOZU_TEST_ASSERT(!g.isZero()); + G2 gr; + G2::mulGeneric(gr, g, BN::param.r); + CYBOZU_TEST_ASSERT(gr.isZero()); + } +#ifndef MCL_AVOID_EXCEPTION_TEST + if (BN::param.cp.b == 2) { + CYBOZU_TEST_EXCEPTION(mapToG2(g, 0), cybozu::Exception); + } +#endif + Fp x; + x.setHashOf("abc"); + mapToG2(g, Fp2(x, 0)); + CYBOZU_TEST_ASSERT(g.isValid()); +} + +void testCyclotomic() +{ + Fp12 a; + for (int i = 0; i < 12; ++i) { + a.getFp0()[i] = i * i; + } + local::mapToCyclotomic(a, a); + Fp12 d; + Compress b(d, a); + a *= a; + Fp12 d2; + Compress c(d2, b); + Compress::square_n(c, 1); + c.decompress(); + CYBOZU_TEST_EQUAL(a, d2); + Compress::square_n(b, 1); + b.decompress(); + CYBOZU_TEST_EQUAL(a, d); +} + +void testCompress(const G1& P, const G2& Q) +{ + if (BN::param.cp.curveType != MCL_BN254) return; + Fp12 a; + pairing(a, P, Q); + local::mapToCyclotomic(a, a); + Fp12 b; + Compress::fixed_power(b, a); + Fp12 c; + Fp12::pow(c, a, BN::param.abs_z); + CYBOZU_TEST_EQUAL(b, c); +} + +void testPrecomputed(const G1& P, const G2& Q) +{ + Fp12 e1, e2; + pairing(e1, P, Q); + std::vector<Fp6> Qcoeff; + precomputeG2(Qcoeff, Q); + precomputedMillerLoop(e2, P, Qcoeff); + finalExp(e2, e2); + CYBOZU_TEST_EQUAL(e1, e2); +} + +void testFp12pow(const G1& P, const G2& Q) +{ + Fp12 e, e1, e2; + 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); + BN::param.glv2.pow(e2, e, xm); + CYBOZU_TEST_EQUAL(e1, e2); + } +} + +void testMillerLoop2(const G1& P1, const G2& Q1) +{ + Fp12 e1, e2, e3; + mpz_class c1("12342342423442"); + mpz_class c2("329428049820348209482"); + G2 Q2; + G1 P2; + G2::mul(Q2, Q1, c1); + G1::mul(P2, P1, c2); + pairing(e1, P1, Q1); + pairing(e2, P2, Q2); + e1 *= e2; + + std::vector<Fp6> Q1coeff, Q2coeff; + precomputeG2(Q1coeff, Q1); + precomputeG2(Q2coeff, Q2); + precomputedMillerLoop2(e2, P1, Q1coeff, P2, Q2coeff); + precomputedMillerLoop2mixed(e3, P1, Q1, P2, Q2coeff); + CYBOZU_TEST_EQUAL(e2, e3); + finalExp(e2, e2); + CYBOZU_TEST_EQUAL(e1, e2); + + // special value + G2 Z; + Z.clear(); + Q2 += Q2; + precomputeG2(Q1coeff, Z); + precomputeG2(Q2coeff, Q2); + precomputedMillerLoop2(e2, P1, Q1coeff, P2, Q2coeff); + precomputedMillerLoop2mixed(e3, P1, Z, P2, Q2coeff); + finalExp(e2, e2); + finalExp(e3, e3); + CYBOZU_TEST_EQUAL(e2, e3); +} + +void testPairing(const G1& P, const G2& Q, const char *eStr) +{ + Fp12 e1; + pairing(e1, P, Q); + Fp12 e2; + { + std::stringstream ss(eStr); + ss >> e2; + } + CYBOZU_TEST_EQUAL(e1, e2); + + 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); + pairing(e1, Pa, Q); + pairing(e2, P, Qa); + CYBOZU_TEST_EQUAL(ea, e1); + CYBOZU_TEST_EQUAL(ea, e2); + } +} + +void testTrivial(const G1& P, const G2& Q) +{ + G1 Z1; Z1.clear(); + G2 Z2; Z2.clear(); + Fp12 e; + pairing(e, Z1, Q); + CYBOZU_TEST_EQUAL(e, 1); + pairing(e, P, Z2); + CYBOZU_TEST_EQUAL(e, 1); + pairing(e, Z1, Z2); + CYBOZU_TEST_EQUAL(e, 1); + + std::vector<Fp6> Qcoeff; + precomputeG2(Qcoeff, Z2); + precomputedMillerLoop(e, P, Qcoeff); + finalExp(e, e); + CYBOZU_TEST_EQUAL(e, 1); + + precomputeG2(Qcoeff, Q); + precomputedMillerLoop(e, Z1, Qcoeff); + finalExp(e, e); + CYBOZU_TEST_EQUAL(e, 1); +} + +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); +} + +#include "bench.hpp" + +CYBOZU_TEST_AUTO(naive) +{ + printf("mcl version=%03x\n", mcl::version); + 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(ts.g1.a, ts.g1.b); + const G2 Q(Fp2(ts.g2.aa, ts.g2.ab), Fp2(ts.g2.ba, ts.g2.bb)); +#ifdef ONLY_BENCH + { + Fp12 e; + for (int i = 0; i < 10000; i++) { clk.begin(); pairing(e, P, Q); clk.end(); } + } + clk.put(); + return; +#endif + testFp12pow(P, Q); + testIo(P, Q); + testTrivial(P, Q); + testSetStr(Q); + testMapToG1(); + testMapToG2(); + testCyclotomic(); + testCompress(P, Q); + testPairing(P, Q, ts.e); + testPrecomputed(P, Q); + testMillerLoop2(P, Q); + testBench(P, Q); + benchAddDblG1(); + benchAddDblG2(); + } + int count = (int)clk.getCount(); + if (count) { + printf("count=%d ", count); + clk.put(); + } +} + +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; +} |