aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/tangerine-network/mcl/sample
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tangerine-network/mcl/sample')
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/bench.cpp233
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/bls_sig.cpp70
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/ecdh.cpp64
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/large.cpp125
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/pairing.cpp56
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/pairing_c.c52
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/random.cpp29
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/rawbench.cpp180
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/she_make_dlp_table.cpp69
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/she_smpl.cpp125
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/tri-dh.cpp97
-rw-r--r--vendor/github.com/tangerine-network/mcl/sample/vote.cpp206
12 files changed, 1306 insertions, 0 deletions
diff --git a/vendor/github.com/tangerine-network/mcl/sample/bench.cpp b/vendor/github.com/tangerine-network/mcl/sample/bench.cpp
new file mode 100644
index 000000000..0f865b189
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/bench.cpp
@@ -0,0 +1,233 @@
+#include <cybozu/benchmark.hpp>
+#include <cybozu/option.hpp>
+#include <cybozu/xorshift.hpp>
+#include <mcl/fp.hpp>
+#include <mcl/conversion.hpp>
+#include <mcl/ecparam.hpp>
+
+typedef mcl::FpT<> Fp;
+typedef mcl::FpT<mcl::ZnTag> Zn;
+typedef mcl::EcT<Fp> Ec;
+
+void benchFpSub(const char *pStr, const char *xStr, const char *yStr, mcl::fp::Mode mode)
+{
+ const char *s = mcl::fp::ModeToStr(mode);
+ Fp::init(pStr, mode);
+ Fp x(xStr);
+ Fp y(yStr);
+
+ double addT, subT, mulT, sqrT, invT;
+ CYBOZU_BENCH_T(addT, Fp::add, x, x, x);
+ CYBOZU_BENCH_T(subT, Fp::sub, x, x, y);
+ CYBOZU_BENCH_T(mulT, Fp::mul, x, x, x);
+ CYBOZU_BENCH_T(sqrT, Fp::sqr, x, x);
+ CYBOZU_BENCH_T(invT, x += y;Fp::inv, x, x); // avoid same jmp
+ printf("%10s bit % 3d add %8.2f sub %8.2f mul %8.2f sqr %8.2f inv %8.2f\n", s, (int)Fp::getBitSize(), addT, subT, mulT, sqrT, invT);
+}
+
+void benchFp(size_t bitSize, int mode)
+{
+ const struct {
+ size_t bitSize;
+ const char *p;
+ const char *x;
+ const char *y;
+ } tbl[] = {
+ {
+ 192,
+ "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d",
+ "0x148094810948190412345678901234567900342423332197",
+ "0x7fffffffffffffffffffffe26f2fc170f69466a74defd8d",
+ },
+ {
+ 256,
+ "0x2523648240000001ba344d80000000086121000000000013a700000000000013",
+ "0x1480948109481904123456789234234242423424201234567900342423332197",
+ "0x151342342342341517fffffffffffffffffffffe26f2fc170f69466a74defd8d",
+ },
+ {
+ 384,
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+ "0x19481084109481094820948209482094820984290482212345678901234567900342308472047204720422423332197",
+ "0x209348209481094820984209842094820948204204243123456789012345679003423084720472047204224233321972",
+
+ },
+ {
+ 521,
+ "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "0x2908209582095820941098410948109482094820984209840294829049240294242498540975555312345678901234567900342308472047204720422423332197",
+ "0x3948384209834029834092384204920349820948205872380573205782385729385729385723985837ffffffffffffffffffffffe26f2fc170f69466a74defd8d",
+
+ },
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ if (bitSize != 0 && tbl[i].bitSize != bitSize) continue;
+ if (mode & 1) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_GMP);
+ if (mode & 2) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_GMP_MONT);
+#ifdef MCL_USE_LLVM
+ if (mode & 4) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_LLVM);
+ if (mode & 8) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_LLVM_MONT);
+#endif
+#ifdef MCL_USE_XBYAK
+ if (mode & 16) benchFpSub(tbl[i].p, tbl[i].x, tbl[i].y, mcl::fp::FP_XBYAK);
+#endif
+ }
+}
+
+void benchEcSub(const mcl::EcParam& para, mcl::fp::Mode mode, mcl::ec::Mode ecMode)
+{
+ Fp::init(para.p, mode);
+ Zn::init(para.n);
+ Ec::init(para.a, para.b, ecMode);
+ Fp x(para.gx);
+ Fp y(para.gy);
+ Ec P(x, y);
+ Ec P2; Ec::add(P2, P, P);
+ Ec Q = P + P + P;
+ double addT, add2T, subT, dblT, mulT, mulCTT, mulRandT, mulCTRandT, normT;
+ CYBOZU_BENCH_T(addT, P = P2; Ec::add, Q, P, Q);
+ P.normalize();
+ CYBOZU_BENCH_T(add2T, Ec::add, Q, P, Q);
+ CYBOZU_BENCH_T(subT, Ec::sub, Q, P, Q);
+ CYBOZU_BENCH_T(dblT, Ec::dbl, P, P);
+ Zn z("3");
+ CYBOZU_BENCH_T(mulT, Ec::mul, Q, P, z);
+ CYBOZU_BENCH_T(mulCTT, Ec::mulCT, Q, P, z);
+ cybozu::XorShift rg;
+ z.setRand(rg);
+ CYBOZU_BENCH_T(mulRandT, Ec::mul, Q, P, z);
+ CYBOZU_BENCH_T(mulCTRandT, Ec::mulCT, Q, P, z);
+ CYBOZU_BENCH_T(normT, Q = P; Q.normalize);
+ printf("%10s %10s add %8.2f add2 %8.2f sub %8.2f dbl %8.2f mul(3) %8.2f mulCT(3) %8.2f mul(rand) %8.2f mulCT(rand) %8.2f norm %8.2f\n", para.name, mcl::fp::ModeToStr(mode), addT, add2T, subT, dblT, mulT, mulCTT, mulRandT, mulCTRandT, normT);
+
+}
+void benchEc(size_t bitSize, int mode, mcl::ec::Mode ecMode)
+{
+ const struct mcl::EcParam tbl[] = {
+ mcl::ecparam::p160_1,
+ mcl::ecparam::secp160k1,
+ mcl::ecparam::secp192k1,
+ mcl::ecparam::NIST_P192,
+ mcl::ecparam::secp224k1,
+ mcl::ecparam::secp256k1,
+ mcl::ecparam::NIST_P224,
+ mcl::ecparam::NIST_P256,
+// mcl::ecparam::secp384r1,
+ mcl::ecparam::NIST_P384,
+// mcl::ecparam::secp521r1,
+ mcl::ecparam::NIST_P521,
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ if (bitSize != 0 && tbl[i].bitSize != bitSize) continue;
+ benchEcSub(tbl[i], mcl::fp::FP_AUTO, ecMode);
+ if (mode & 1) benchEcSub(tbl[i], mcl::fp::FP_GMP, ecMode);
+ if (mode & 2) benchEcSub(tbl[i], mcl::fp::FP_GMP_MONT, ecMode);
+#ifdef MCL_USE_LLVM
+ if (mode & 4) benchEcSub(tbl[i], mcl::fp::FP_LLVM, ecMode);
+ if (mode & 8) benchEcSub(tbl[i], mcl::fp::FP_LLVM_MONT, ecMode);
+#endif
+#ifdef MCL_USE_XBYAK
+ if (mode & 16) benchEcSub(tbl[i], mcl::fp::FP_XBYAK, ecMode);
+#endif
+ }
+}
+
+void benchToStr16()
+{
+ puts("benchToStr16");
+ const char *tbl[] = {
+ "0x0",
+ "0x5",
+ "0x123",
+ "0x123456789012345679adbc",
+ "0xffffffff26f2fc170f69466a74defd8d",
+ "0x100000000000000000000000000000033",
+ "0x11ee12312312940000000000000000000000000002342343"
+ };
+ Fp::init("0xffffffffffffffffffffffffffffffffffffffffffffff13");
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ char buf[128];
+ std::string str;
+ Fp x(tbl[i]);
+ CYBOZU_BENCH("fp::arrayToHex", mcl::fp::arrayToHex, buf, sizeof(buf), x.getUnit(), x.getUnitSize(), true);
+ mpz_class y(tbl[i]);
+ CYBOZU_BENCH("gmp:getStr ", mcl::gmp::getStr, str, y, 16);
+ }
+}
+
+void benchFromStr16()
+{
+ puts("benchFromStr16");
+ const char *tbl[] = {
+ "0",
+ "5",
+ "123",
+ "123456789012345679adbc",
+ "ffffffff26f2fc170f69466a74defd8d",
+ "100000000000000000000000000000033",
+ "11ee12312312940000000000000000000000000002342343"
+ };
+ Fp::init("0xffffffffffffffffffffffffffffffffffffffffffffff13");
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ std::string str = tbl[i];
+ Fp x;
+ const size_t N = 64;
+ mcl::fp::Unit buf[N];
+ CYBOZU_BENCH("fp:hexToArray", mcl::fp::hexToArray, buf, N, str.c_str(), str.size());
+
+ mpz_class y;
+ CYBOZU_BENCH("gmp:setStr ", mcl::gmp::setStr, y, str, 16);
+ }
+}
+
+int main(int argc, char *argv[])
+ try
+{
+ size_t bitSize;
+ int mode;
+ bool ecOnly;
+ bool fpOnly;
+ bool misc;
+ mcl::ec::Mode ecMode;
+ std::string ecModeStr;
+ cybozu::Option opt;
+ opt.appendOpt(&bitSize, 0, "s", ": bitSize");
+ opt.appendOpt(&mode, 0, "m", ": mode(0:all, sum of 1:gmp, 2:gmp+mont, 4:llvm, 8:llvm+mont, 16:xbyak");
+ opt.appendBoolOpt(&ecOnly, "ec", ": ec only");
+ opt.appendBoolOpt(&fpOnly, "fp", ": fp only");
+ opt.appendBoolOpt(&misc, "misc", ": other benchmark");
+ opt.appendOpt(&ecModeStr, "jacobi", "ecmode", ": jacobi or proj");
+ opt.appendHelp("h", ": show this message");
+ if (!opt.parse(argc, argv)) {
+ opt.usage();
+ return 1;
+ }
+ if (ecModeStr == "jacobi") {
+ ecMode = mcl::ec::Jacobi;
+ } else if (ecModeStr == "proj") {
+ ecMode = mcl::ec::Proj;
+ } else {
+ printf("bad ecstr %s\n", ecModeStr.c_str());
+ opt.usage();
+ return 1;
+ }
+ if (mode < 0 || mode > 31) {
+ printf("bad mode %d\n", mode);
+ opt.usage();
+ return 1;
+ }
+ if (mode == 0) mode = 31;
+ if (misc) {
+ benchToStr16();
+ benchFromStr16();
+ } else {
+ if (!ecOnly) benchFp(bitSize, mode);
+ if (!fpOnly) {
+ printf("ecMode=%s\n", ecModeStr.c_str());
+ benchEc(bitSize, mode, ecMode);
+ }
+ }
+} catch (std::exception& e) {
+ printf("ERR %s\n", e.what());
+}
+
diff --git a/vendor/github.com/tangerine-network/mcl/sample/bls_sig.cpp b/vendor/github.com/tangerine-network/mcl/sample/bls_sig.cpp
new file mode 100644
index 000000000..d75f7d427
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/bls_sig.cpp
@@ -0,0 +1,70 @@
+/**
+ @file
+ @brief a sample of BLS signature
+ see https://github.com/herumi/bls
+ @author MITSUNARI Shigeo(@herumi)
+ @license modified new BSD license
+ http://opensource.org/licenses/BSD-3-Clause
+
+*/
+#include <mcl/bn256.hpp>
+#include <iostream>
+
+using namespace mcl::bn256;
+
+void Hash(G1& P, const std::string& m)
+{
+ Fp t;
+ t.setHashOf(m);
+ mapToG1(P, t);
+}
+
+void KeyGen(Fr& s, G2& pub, const G2& Q)
+{
+ s.setRand();
+ G2::mul(pub, Q, s); // pub = sQ
+}
+
+void Sign(G1& sign, const Fr& s, const std::string& m)
+{
+ G1 Hm;
+ Hash(Hm, m);
+ G1::mul(sign, Hm, s); // sign = s H(m)
+}
+
+bool Verify(const G1& sign, const G2& Q, const G2& pub, const std::string& m)
+{
+ Fp12 e1, e2;
+ G1 Hm;
+ Hash(Hm, m);
+ pairing(e1, sign, Q); // e1 = e(sign, Q)
+ pairing(e2, Hm, pub); // e2 = e(Hm, sQ)
+ return e1 == e2;
+}
+
+int main(int argc, char *argv[])
+{
+ std::string m = argc == 1 ? "hello mcl" : argv[1];
+
+ // setup parameter
+ initPairing();
+ G2 Q;
+ mapToG2(Q, 1);
+
+ // generate secret key and public key
+ Fr s;
+ G2 pub;
+ KeyGen(s, pub, Q);
+ std::cout << "secret key " << s << std::endl;
+ std::cout << "public key " << pub << std::endl;
+
+ // sign
+ G1 sign;
+ Sign(sign, s, m);
+ std::cout << "msg " << m << std::endl;
+ std::cout << "sign " << sign << std::endl;
+
+ // verify
+ bool ok = Verify(sign, Q, pub, m);
+ std::cout << "verify " << (ok ? "ok" : "ng") << std::endl;
+}
diff --git a/vendor/github.com/tangerine-network/mcl/sample/ecdh.cpp b/vendor/github.com/tangerine-network/mcl/sample/ecdh.cpp
new file mode 100644
index 000000000..d5c4a31b2
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/ecdh.cpp
@@ -0,0 +1,64 @@
+/*
+ sample of Elliptic Curve Diffie-Hellman key sharing
+*/
+#include <iostream>
+#include <fstream>
+#include <cybozu/random_generator.hpp>
+#include <mcl/fp.hpp>
+#include <mcl/ecparam.hpp>
+
+typedef mcl::FpT<> Fp;
+typedef mcl::FpT<mcl::ZnTag> Zn;
+typedef mcl::EcT<Fp> Ec;
+
+int main()
+{
+ cybozu::RandomGenerator rg;
+ /*
+ system setup with a parameter secp192k1 recommended by SECG
+ Ec is an elliptic curve over Fp
+ the cyclic group of <P> is isomorphic to Zn
+ */
+ const mcl::EcParam& para = mcl::ecparam::secp192k1;
+ Zn::init(para.n);
+ Fp::init(para.p);
+ Ec::init(para.a, para.b);
+ const Ec P(Fp(para.gx), Fp(para.gy));
+
+ /*
+ Alice setups a private key a and public key aP
+ */
+ Zn a;
+ Ec aP;
+
+ a.setRand(rg);
+ Ec::mul(aP, P, a); // aP = a * P;
+
+ std::cout << "aP=" << aP << std::endl;
+
+ /*
+ Bob setups a private key b and public key bP
+ */
+ Zn b;
+ Ec bP;
+
+ b.setRand(rg);
+ Ec::mul(bP, P, b); // bP = b * P;
+
+ std::cout << "bP=" << bP << std::endl;
+
+ Ec abP, baP;
+
+ // Alice uses bP(B's public key) and a(A's priavte key)
+ Ec::mul(abP, bP, a); // abP = a * (bP)
+
+ // Bob uses aP(A's public key) and b(B's private key)
+ Ec::mul(baP, aP, b); // baP = b * (aP)
+
+ if (abP == baP) {
+ std::cout << "key sharing succeed:" << abP << std::endl;
+ } else {
+ std::cout << "ERR(not here)" << std::endl;
+ }
+}
+
diff --git a/vendor/github.com/tangerine-network/mcl/sample/large.cpp b/vendor/github.com/tangerine-network/mcl/sample/large.cpp
new file mode 100644
index 000000000..60b2ac900
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/large.cpp
@@ -0,0 +1,125 @@
+/*
+ large prime sample for 64-bit arch
+ make MCL_USE_LLVM=1 MCL_MAX_BIT_SIZE=768
+*/
+#include <mcl/fp.hpp>
+#include <cybozu/benchmark.hpp>
+#include <iostream>
+#include "../src/low_func.hpp"
+
+typedef mcl::FpT<> Fp;
+
+using namespace mcl::fp;
+const size_t N = 12;
+
+void testMul()
+{
+ Unit ux[N], uy[N], a[N * 2], b[N * 2];
+ for (size_t i = 0; i < N; i++) {
+ ux[i] = -i * i + 5;
+ uy[i] = -i * i + 9;
+ }
+ MulPreCore<N, Gtag>::f(a, ux, uy);
+ MulPreCore<N, Ltag>::f(b, ux, uy);
+ for (size_t i = 0; i < N * 2; i++) {
+ if (a[i] != b[i]) {
+ printf("ERR %016llx %016llx\n", (long long)a[i], (long long)b[i]);
+ }
+ }
+ puts("end testMul");
+ CYBOZU_BENCH("gmp ", (MulPreCore<N, Gtag>::f), ux, ux, uy);
+ CYBOZU_BENCH("kara", (MulPre<N, Gtag>::karatsuba), ux, ux, uy);
+}
+
+void mulGmp(mpz_class& z, const mpz_class& x, const mpz_class& y, const mpz_class& p)
+{
+ z = (x * y) % p;
+}
+void compareGmp(const std::string& pStr)
+{
+ Fp::init(pStr);
+ std::string xStr = "2104871209348712947120947102843728";
+ std::string s1, s2;
+ {
+ Fp x(xStr);
+ CYBOZU_BENCH_C("mul by mcl", 1000, Fp::mul, x, x, x);
+ std::ostringstream os;
+ os << x;
+ s1 = os.str();
+ }
+ {
+ const mpz_class p(pStr);
+ mpz_class x(xStr);
+ CYBOZU_BENCH_C("mul by GMP", 1000, mulGmp, x, x, x, p);
+ std::ostringstream os;
+ os << x;
+ s2 = os.str();
+ }
+ if (s1 != s2) {
+ puts("ERR");
+ }
+}
+
+void test(const std::string& pStr, mcl::fp::Mode mode)
+{
+ printf("test %s\n", mcl::fp::ModeToStr(mode));
+ Fp::init(pStr, mode);
+ const mcl::fp::Op& op = Fp::getOp();
+ printf("bitSize=%d\n", (int)Fp::getBitSize());
+ mpz_class p(pStr);
+ Fp x = 123456;
+ Fp y;
+ Fp::pow(y, x, p);
+ std::cout << y << std::endl;
+ if (x != y) {
+ std::cout << "err:pow:" << y << std::endl;
+ return;
+ }
+ const size_t N = 24;
+ mcl::fp::Unit ux[N], uy[N];
+ for (size_t i = 0; i < N; i++) {
+ ux[i] = -i * i + 5;
+ uy[i] = -i * i + 9;
+ }
+ CYBOZU_BENCH("mulPre", op.fpDbl_mulPre, ux, ux, uy);
+ CYBOZU_BENCH("sqrPre", op.fpDbl_sqrPre, ux, ux);
+ CYBOZU_BENCH("add", op.fpDbl_add, ux, ux, ux, op.p);
+ CYBOZU_BENCH("sub", op.fpDbl_sub, ux, ux, ux, op.p);
+ if (op.fpDbl_addPre) {
+ CYBOZU_BENCH("addPre", op.fpDbl_addPre, ux, ux, ux);
+ CYBOZU_BENCH("subPre", op.fpDbl_subPre, ux, ux, ux);
+ }
+ CYBOZU_BENCH("mont", op.fpDbl_mod, ux, ux, op.p);
+ CYBOZU_BENCH("mul", Fp::mul, x, x, x);
+ compareGmp(pStr);
+}
+
+void testAll(const std::string& pStr)
+{
+ test(pStr, mcl::fp::FP_GMP);
+ test(pStr, mcl::fp::FP_GMP_MONT);
+#ifdef MCL_USE_LLVM
+ test(pStr, mcl::fp::FP_LLVM);
+ test(pStr, mcl::fp::FP_LLVM_MONT);
+#endif
+ compareGmp(pStr);
+}
+int main()
+ try
+{
+ const char *pTbl[] = {
+ "40347654345107946713373737062547060536401653012956617387979052445947619094013143666088208645002153616185987062074179207",
+ "13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006083527",
+ "776259046150354467574489744231251277628443008558348305569526019013025476343188443165439204414323238975243865348565536603085790022057407195722143637520590569602227488010424952775132642815799222412631499596858234375446423426908029627",
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(pTbl); i++) {
+ testAll(pTbl[i]);
+ }
+ testMul();
+} catch (std::exception& e) {
+ printf("err %s\n", e.what());
+ puts("make clean");
+ puts("make -DMCL_MAX_BIT_SIZE=768");
+ return 1;
+}
+
diff --git a/vendor/github.com/tangerine-network/mcl/sample/pairing.cpp b/vendor/github.com/tangerine-network/mcl/sample/pairing.cpp
new file mode 100644
index 000000000..230583b6e
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/pairing.cpp
@@ -0,0 +1,56 @@
+#include <mcl/bn256.hpp>
+
+using namespace mcl::bn256;
+
+void minimum_sample(const G1& P, const G2& Q)
+{
+ const mpz_class a = 123;
+ const mpz_class b = 456;
+ Fp12 e1, e2;
+ pairing(e1, P, Q);
+ G2 aQ;
+ G1 bP;
+ G2::mul(aQ, Q, a);
+ G1::mul(bP, P, b);
+ pairing(e2, bP, aQ);
+ Fp12::pow(e1, e1, a * b);
+ printf("%s\n", e1 == e2 ? "ok" : "ng");
+}
+
+void miller_and_finel_exp(const G1& P, const G2& Q)
+{
+ Fp12 e1, e2;
+ pairing(e1, P, Q);
+
+ millerLoop(e2, P, Q);
+ finalExp(e2, e2);
+ printf("%s\n", e1 == e2 ? "ok" : "ng");
+}
+
+void precomputed(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);
+ printf("%s\n", e1 == e2 ? "ok" : "ng");
+}
+
+int main()
+{
+ const char *aa = "12723517038133731887338407189719511622662176727675373276651903807414909099441";
+ const char *ab = "4168783608814932154536427934509895782246573715297911553964171371032945126671";
+ const char *ba = "13891744915211034074451795021214165905772212241412891944830863846330766296736";
+ const char *bb = "7937318970632701341203597196594272556916396164729705624521405069090520231616";
+
+ initPairing();
+ G2 Q(Fp2(aa, ab), Fp2(ba, bb));
+ G1 P(-1, 1);
+
+ minimum_sample(P, Q);
+ miller_and_finel_exp(P, Q);
+ precomputed(P, Q);
+}
+
diff --git a/vendor/github.com/tangerine-network/mcl/sample/pairing_c.c b/vendor/github.com/tangerine-network/mcl/sample/pairing_c.c
new file mode 100644
index 000000000..5c2cd222a
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/pairing_c.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <string.h>
+#define MCLBN_FP_UNIT_SIZE 4
+#include <mcl/bn.h>
+
+int g_err = 0;
+#define ASSERT(x) { if (!(x)) { printf("err %s:%d\n", __FILE__, __LINE__); g_err++; } }
+
+int main()
+{
+ char buf[1024];
+ const char *aStr = "123";
+ const char *bStr = "456";
+ mclBn_init(MCL_BN254, MCLBN_FP_UNIT_SIZE);
+ mclBnFr a, b, ab;
+ mclBnG1 P, aP;
+ mclBnG2 Q, bQ;
+ mclBnGT e, e1, e2;
+ mclBnFr_setStr(&a, aStr, strlen(aStr), 10);
+ mclBnFr_setStr(&b, bStr, strlen(bStr), 10);
+ mclBnFr_mul(&ab, &a, &b);
+ mclBnFr_getStr(buf, sizeof(buf), &ab, 10);
+ printf("%s x %s = %s\n", aStr, bStr, buf);
+
+ ASSERT(!mclBnG1_hashAndMapTo(&P, "this", 4));
+ ASSERT(!mclBnG2_hashAndMapTo(&Q, "that", 4));
+ mclBnG1_getStr(buf, sizeof(buf), &P, 16);
+ printf("P = %s\n", buf);
+ mclBnG2_getStr(buf, sizeof(buf), &Q, 16);
+ printf("Q = %s\n", buf);
+
+ mclBnG1_mul(&aP, &P, &a);
+ mclBnG2_mul(&bQ, &Q, &b);
+
+ mclBn_pairing(&e, &P, &Q);
+ mclBnGT_getStr(buf, sizeof(buf), &e, 16);
+ printf("e = %s\n", buf);
+ mclBnGT_pow(&e1, &e, &a);
+ mclBn_pairing(&e2, &aP, &Q);
+ ASSERT(mclBnGT_isEqual(&e1, &e2));
+
+ mclBnGT_pow(&e1, &e, &b);
+ mclBn_pairing(&e2, &P, &bQ);
+ ASSERT(mclBnGT_isEqual(&e1, &e2));
+ if (g_err) {
+ printf("err %d\n", g_err);
+ return 1;
+ } else {
+ printf("no err\n");
+ return 0;
+ }
+}
diff --git a/vendor/github.com/tangerine-network/mcl/sample/random.cpp b/vendor/github.com/tangerine-network/mcl/sample/random.cpp
new file mode 100644
index 000000000..a2a3619ad
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/random.cpp
@@ -0,0 +1,29 @@
+#include <mcl/fp.hpp>
+#include <mcl/gmp_util.hpp>
+#include <mcl/ecparam.hpp>
+#include <cybozu/random_generator.hpp>
+#include <map>
+#include <mcl/fp.hpp>
+typedef mcl::FpT<> Fp;
+
+typedef std::map<std::string, int> Map;
+
+int main(int argc, char *argv[])
+{
+ cybozu::RandomGenerator rg;
+ const char *p = mcl::ecparam::secp192k1.p;
+ if (argc == 2) {
+ p = argv[1];
+ }
+ Fp::init(p);
+ Fp x;
+ printf("p=%s\n", p);
+ Map m;
+ for (int i = 0; i < 10000; i++) {
+ x.setRand(rg);
+ m[x.getStr(16)]++;
+ }
+ for (Map::const_iterator i = m.begin(), ie = m.end(); i != ie; ++i) {
+ printf("%s %d\n", i->first.c_str(), i->second);
+ }
+}
diff --git a/vendor/github.com/tangerine-network/mcl/sample/rawbench.cpp b/vendor/github.com/tangerine-network/mcl/sample/rawbench.cpp
new file mode 100644
index 000000000..4d7506ef5
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/rawbench.cpp
@@ -0,0 +1,180 @@
+#define PUT(x) std::cout << #x "=" << (x) << std::endl
+#include <cybozu/benchmark.hpp>
+#include <cybozu/option.hpp>
+#include <cybozu/xorshift.hpp>
+#include <mcl/fp.hpp>
+#include <mcl/fp_tower.hpp>
+
+typedef mcl::FpT<mcl::FpTag> Fp;
+typedef mcl::Fp2T<Fp> Fp2;
+typedef mcl::FpDblT<Fp> FpDbl;
+typedef mcl::Fp6T<Fp> Fp6;
+typedef mcl::Fp12T<Fp> Fp12;
+
+typedef mcl::fp::Unit Unit;
+
+void mul9(const mcl::fp::Op& op, Unit *y, const Unit *x, const Unit *p)
+{
+ const size_t maxN = sizeof(Fp) / sizeof(Unit);
+ Unit tmp[maxN];
+ op.fp_add(tmp, x, x, p); // 2x
+ op.fp_add(tmp, tmp, tmp, p); // 4x
+ op.fp_add(tmp, tmp, tmp, p); // 8x
+ op.fp_add(y, tmp, x, p); // 9x
+}
+
+void benchRaw(const char *p, mcl::fp::Mode mode)
+{
+ Fp::init(1, p, mode);
+ Fp2::init();
+ const size_t maxN = sizeof(Fp) / sizeof(Unit);
+ const mcl::fp::Op& op = Fp::getOp();
+ cybozu::XorShift rg;
+ Fp fx, fy;
+ fx.setRand(rg);
+ fy.setRand(rg);
+ Unit ux[maxN * 2] = {};
+ Unit uy[maxN * 2] = {};
+ Unit uz[maxN * 2] = {};
+ memcpy(ux, fx.getUnit(), sizeof(Unit) * op.N);
+ memcpy(ux + op.N, fx.getUnit(), sizeof(Unit) * op.N);
+ memcpy(uy, fy.getUnit(), sizeof(Unit) * op.N);
+ memcpy(ux + op.N, fx.getUnit(), sizeof(Unit) * op.N);
+ double fp_addT, fp_subT;
+ double fp_addPreT, fp_subPreT;
+ double fp_sqrT, fp_mulT;
+ double fp_mulUnitT;
+ double mul9T;
+ double fp_mulUnitPreT;
+ double fpN1_modT;
+ double fpDbl_addT, fpDbl_subT;
+ double fpDbl_sqrPreT, fpDbl_mulPreT, fpDbl_modT;
+ double fp2_sqrT, fp2_mulT;
+ CYBOZU_BENCH_T(fp_addT, op.fp_add, uz, ux, uy, op.p);
+ CYBOZU_BENCH_T(fp_subT, op.fp_sub, uz, uy, ux, op.p);
+ CYBOZU_BENCH_T(fp_addPreT, op.fp_addPre, uz, ux, uy);
+ CYBOZU_BENCH_T(fp_subPreT, op.fp_subPre, uz, uy, ux);
+ CYBOZU_BENCH_T(fp_sqrT, op.fp_sqr, uz, ux, op.p);
+ CYBOZU_BENCH_T(fp_mulT, op.fp_mul, uz, ux, uy, op.p);
+ CYBOZU_BENCH_T(fp_mulUnitT, op.fp_mulUnit, uz, ux, 9, op.p);
+ CYBOZU_BENCH_T(mul9T, mul9, op, uz, ux, op.p);
+ CYBOZU_BENCH_T(fp_mulUnitPreT, op.fp_mulUnitPre, ux, ux, 9);
+ CYBOZU_BENCH_T(fpN1_modT, op.fpN1_mod, ux, uy, op.p);
+ CYBOZU_BENCH_T(fpDbl_addT, op.fpDbl_add, uz, ux, uy, op.p);
+ CYBOZU_BENCH_T(fpDbl_subT, op.fpDbl_sub, uz, uy, ux, op.p);
+ CYBOZU_BENCH_T(fpDbl_sqrPreT, op.fpDbl_sqrPre, uz, ux);
+ CYBOZU_BENCH_T(fpDbl_mulPreT, op.fpDbl_mulPre, uz, ux, uy);
+ CYBOZU_BENCH_T(fpDbl_modT, op.fpDbl_mod, uz, ux, op.p);
+ Fp2 f2x, f2y;
+ f2x.a = fx;
+ f2x.b = fy;
+ f2y = f2x;
+ CYBOZU_BENCH_T(fp2_sqrT, Fp2::sqr, f2x, f2x);
+ CYBOZU_BENCH_T(fp2_mulT, Fp2::mul, f2x, f2x, f2y);
+ printf("%s\n", mcl::fp::ModeToStr(mode));
+ const char *tStrTbl[] = {
+ "fp_add", "fp_sub",
+ "addPre", "subPre",
+ "fp_sqr", "fp_mul",
+ "mulUnit",
+ "mul9",
+ "mulUnitP",
+ "fpN1_mod",
+ "D_add", "D_sub",
+ "D_sqrPre", "D_mulPre", "D_mod",
+ "fp2_sqr", "fp2_mul",
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tStrTbl); i++) {
+ printf(" %8s", tStrTbl[i]);
+ }
+ printf("\n");
+ const double tTbl[] = {
+ fp_addT, fp_subT,
+ fp_addPreT, fp_subPreT,
+ fp_sqrT, fp_mulT,
+ fp_mulUnitT,
+ mul9T,
+ fp_mulUnitPreT,
+ fpN1_modT,
+ fpDbl_addT, fpDbl_subT,
+ fpDbl_sqrPreT, fpDbl_mulPreT, fpDbl_modT,
+ fp2_sqrT, fp2_mulT,
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tTbl); i++) {
+ printf(" %8.2f", tTbl[i]);
+ }
+ printf("\n");
+}
+
+int main(int argc, char *argv[])
+ try
+{
+ cybozu::Option opt;
+ size_t bitSize;
+ opt.appendOpt(&bitSize, 0, "s", ": bitSize");
+ opt.appendHelp("h", ": show this message");
+ if (!opt.parse(argc, argv)) {
+ opt.usage();
+ return 1;
+ }
+ const char *tbl[] = {
+ // N = 2
+ "0x0000000000000001000000000000000d",
+ "0x7fffffffffffffffffffffffffffffff",
+ "0x8000000000000000000000000000001d",
+ "0xffffffffffffffffffffffffffffff61",
+
+ // N = 3
+ "0x000000000000000100000000000000000000000000000033", // min prime
+ "0x70000000000000000000000000000000000000000000001f",
+ "0x800000000000000000000000000000000000000000000005",
+ "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d",
+ "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
+ "0xffffffffffffffffffffffffffffffffffffffffffffff13", // max prime
+
+ // N = 4
+ "0x0000000000000001000000000000000000000000000000000000000000000085", // min prime
+ "0x2523648240000001ba344d80000000086121000000000013a700000000000013", // BN254
+ "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47", // Snark
+ "0x7523648240000001ba344d80000000086121000000000013a700000000000017",
+ "0x800000000000000000000000000000000000000000000000000000000000005f",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff43", // max prime
+ // N = 5
+ "0x80000000000000000000000000000000000000000000000000000000000000000000000000000009",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3b",
+ // N = 6
+ "0x800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000171",
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec3",
+ // N = 7
+ "0x8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff35",
+ // N = 8
+ "0x8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006f",
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7",
+#if MCL_MAX_BIT_SIZE == 1024
+ "0xc70b1ddda9b96e3965e5855942aa5852d8f8e052c760ac32cdfec16a2ed3d56981e1a475e20a70144ed2f5061ba64900f69451492803f815d446ee133d0668f7a7f3276d6301c95ce231f0e4b0d0f3882f10014fca04454cff55d2e2d4cfc1aad33b8d38397e2fc8b623177e63d0b783269c40a85b8f105654783b8ed2e737df",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff97",
+#endif
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ const char *p = tbl[i];
+ if (bitSize > 0 && (strlen(p) - 2) * 4 != bitSize) {
+ continue;
+ }
+ printf("prime=%s\n", p);
+ benchRaw(tbl[i], mcl::fp::FP_GMP);
+ benchRaw(tbl[i], mcl::fp::FP_GMP_MONT);
+#ifdef MCL_USE_LLVM
+ benchRaw(tbl[i], mcl::fp::FP_LLVM);
+ benchRaw(tbl[i], mcl::fp::FP_LLVM_MONT);
+#endif
+#ifdef MCL_USE_XBYAK
+ if (bitSize <= 384) {
+ benchRaw(tbl[i], mcl::fp::FP_XBYAK);
+ }
+#endif
+ }
+} catch (std::exception& e) {
+ printf("ERR %s\n", e.what());
+ return 1;
+}
diff --git a/vendor/github.com/tangerine-network/mcl/sample/she_make_dlp_table.cpp b/vendor/github.com/tangerine-network/mcl/sample/she_make_dlp_table.cpp
new file mode 100644
index 000000000..41f18e225
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/she_make_dlp_table.cpp
@@ -0,0 +1,69 @@
+/*
+ make she DLP table
+*/
+#include <mcl/she.hpp>
+#include <cybozu/option.hpp>
+#include <fstream>
+
+using namespace mcl::she;
+
+struct Param {
+ int curveType;
+ int hashBitSize;
+ int group;
+ std::string path;
+};
+
+template<class HashTable, class G>
+void makeTable(const Param& param, const char *groupStr, HashTable& hashTbl, const G& P)
+{
+ char baseName[32];
+ CYBOZU_SNPRINTF(baseName, sizeof(baseName), "she-dlp-%d-%d-%s.bin", param.curveType, param.hashBitSize, groupStr);
+ const std::string fileName = param.path + baseName;
+ printf("file=%s\n", fileName.c_str());
+ std::ofstream ofs(fileName.c_str(), std::ios::binary);
+
+ const size_t hashSize = 1u << param.hashBitSize;
+ hashTbl.init(P, hashSize);
+ hashTbl.save(ofs);
+}
+
+void run(const Param& param)
+{
+ SHE::init(mcl::getCurveParam(param.curveType));
+
+ switch (param.group) {
+ case 1:
+ makeTable(param, "g1", getHashTableG1(), SHE::P_);
+ break;
+ case 2:
+ makeTable(param, "g2", getHashTableG2(), SHE::Q_);
+ break;
+ case 3:
+ makeTable(param, "gt", getHashTableGT(), SHE::ePQ_);
+ break;
+ default:
+ throw cybozu::Exception("bad group") << param.group;
+ }
+}
+
+int main(int argc, char *argv[])
+ try
+{
+ cybozu::Option opt;
+ Param param;
+ opt.appendOpt(&param.curveType, 0, "ct", ": curveType(0:BN254, 1:BN381_1, 5:BLS12_381)");
+ opt.appendOpt(&param.hashBitSize, 20, "hb", ": hash bit size");
+ opt.appendOpt(&param.group, 3, "g", ": group(1:G1, 2:G2, 3:GT");
+ opt.appendOpt(&param.path, "./", "path", ": path to table");
+ opt.appendHelp("h");
+ if (opt.parse(argc, argv)) {
+ run(param);
+ } else {
+ opt.usage();
+ return 1;
+ }
+} catch (std::exception& e) {
+ printf("err %s\n", e.what());
+ return 1;
+}
diff --git a/vendor/github.com/tangerine-network/mcl/sample/she_smpl.cpp b/vendor/github.com/tangerine-network/mcl/sample/she_smpl.cpp
new file mode 100644
index 000000000..e01b9c130
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/she_smpl.cpp
@@ -0,0 +1,125 @@
+/*
+ sample of somewhat homomorphic encryption(SHE)
+*/
+#define PUT(x) std::cout << #x << "=" << (x) << std::endl;
+#include <cybozu/benchmark.hpp>
+#include <mcl/she.hpp>
+
+using namespace mcl::she;
+
+void miniSample()
+{
+ // init library
+ SHE::init();
+
+ SecretKey sec;
+
+ // init secret key by random_device
+ sec.setByCSPRNG();
+
+ // set range to decode GT DLP
+ SHE::setRangeForDLP(1000);
+
+ PublicKey pub;
+ // get public key
+ sec.getPublicKey(pub);
+
+ const int N = 5;
+ int a[] = { 1, 5, -3, 4, 6 };
+ int b[] = { 4, 2, 1, 9, -2 };
+ // compute correct value
+ int sum = 0;
+ for (size_t i = 0; i < N; i++) {
+ sum += a[i] * b[i];
+ }
+
+ std::vector<CipherText> ca(N), cb(N);
+
+ // encrypt each a[] and b[]
+ for (size_t i = 0; i < N; i++) {
+ pub.enc(ca[i], a[i]);
+ pub.enc(cb[i], b[i]);
+ }
+ CipherText c;
+ c.clearAsMultiplied(); // clear as multiplied before using c.add()
+ // inner product of encrypted vector
+ for (size_t i = 0; i < N; i++) {
+ CipherText t;
+ CipherText::mul(t, ca[i], cb[i]); // t = ca[i] * cb[i]
+ c.add(t); // c += t
+ }
+ // decode it
+ int m = (int)sec.dec(c);
+ // verify the value
+ if (m == sum) {
+ puts("ok");
+ } else {
+ printf("err correct %d err %d\n", sum, m);
+ }
+}
+
+void usePrimitiveCipherText()
+{
+ // init library
+ SHE::init();
+
+ SecretKey sec;
+
+ // init secret key by random_device
+ sec.setByCSPRNG();
+
+ // set range to decode GT DLP
+ SHE::setRangeForGTDLP(100);
+
+ PublicKey pub;
+ // get public key
+ sec.getPublicKey(pub);
+
+ int a1 = 1, a2 = 2;
+ int b1 = 5, b2 = -4;
+ CipherTextG1 c1, c2; // size of CipherTextG1 = N * 2 ; N = 256-bit for CurveFp254BNb
+ CipherTextG2 d1, d2; // size of CipherTextG2 = N * 4
+ pub.enc(c1, a1);
+ pub.enc(c2, a2);
+ pub.enc(d1, b1);
+ pub.enc(d2, b2);
+ c1.add(c2); // CipherTextG1 is additive HE
+ d1.add(d2); // CipherTextG2 is additive HE
+ CipherTextGT cm; // size of CipherTextGT = N * 12 * 4
+ CipherTextGT::mul(cm, c1, d1); // cm = c1 * d1
+ cm.add(cm); // 2cm
+ int m = (int)sec.dec(cm);
+ int ok = (a1 + a2) * (b1 + b2) * 2;
+ if (m == ok) {
+ puts("ok");
+ } else {
+ printf("err m=%d ok=%d\n", m, ok);
+ }
+ std::string s;
+ s = c1.getStr(mcl::IoSerialize); // serialize
+ printf("c1 data size %d byte\n", (int)s.size());
+
+ c2.setStr(s, mcl::IoSerialize);
+ printf("deserialize %s\n", c1 == c2 ? "ok" : "ng");
+
+ s = d1.getStr(mcl::IoSerialize); // serialize
+ printf("d1 data size %d byte\n", (int)s.size());
+ d2.setStr(s, mcl::IoSerialize);
+ printf("deserialize %s\n", d1 == d2 ? "ok" : "ng");
+
+ s = cm.getStr(mcl::IoSerialize); // serialize
+ printf("cm data size %d byte\n", (int)s.size());
+ CipherTextGT cm2;
+ cm2.setStr(s, mcl::IoSerialize);
+ printf("deserialize %s\n", cm == cm2 ? "ok" : "ng");
+}
+
+int main()
+ try
+{
+ miniSample();
+ usePrimitiveCipherText();
+} catch (std::exception& e) {
+ printf("err %s\n", e.what());
+ return 1;
+}
diff --git a/vendor/github.com/tangerine-network/mcl/sample/tri-dh.cpp b/vendor/github.com/tangerine-network/mcl/sample/tri-dh.cpp
new file mode 100644
index 000000000..8b720edbf
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/tri-dh.cpp
@@ -0,0 +1,97 @@
+/*
+ tripartie Diffie-Hellman
+*/
+#include <iostream>
+#include <fstream>
+#include <cybozu/random_generator.hpp>
+#include <mcl/bn256.hpp>
+#include <cybozu/option.hpp>
+
+static cybozu::RandomGenerator rg;
+
+const std::string skSuf = ".sk.txt";
+const std::string pkSuf = ".pk.txt";
+
+using namespace mcl::bn256;
+
+void keygen(const std::string& user)
+{
+ if (user.empty()) {
+ throw cybozu::Exception("keygen:user is empty");
+ }
+ const char *aa = "12723517038133731887338407189719511622662176727675373276651903807414909099441";
+ const char *ab = "4168783608814932154536427934509895782246573715297911553964171371032945126671";
+ const char *ba = "13891744915211034074451795021214165905772212241412891944830863846330766296736";
+ const char *bb = "7937318970632701341203597196594272556916396164729705624521405069090520231616";
+
+
+ initPairing();
+ G2 Q(Fp2(aa, ab), Fp2(ba, bb));
+ G1 P(-1, 1);
+
+ Fr s;
+ s.setRand(rg);
+ G1::mul(P, P, s);
+ G2::mul(Q, Q, s);
+ {
+ std::string name = user + skSuf;
+ std::ofstream ofs(name.c_str(), std::ios::binary);
+ ofs << s << std::endl;
+ }
+ {
+ std::string name = user + pkSuf;
+ std::ofstream ofs(name.c_str(), std::ios::binary);
+ ofs << P << std::endl;
+ ofs << Q << std::endl;
+ }
+}
+
+void load(G1& P, G2& Q, const std::string& fileName)
+{
+ std::ifstream ifs(fileName.c_str(), std::ios::binary);
+ ifs >> P >> Q;
+}
+
+void share(const std::string& skFile, const std::string& pk1File, const std::string& pk2File)
+{
+ initPairing();
+ Fr s;
+ G1 P1, P2;
+ G2 Q1, Q2;
+ {
+ std::ifstream ifs(skFile.c_str(), std::ios::binary);
+ ifs >> s;
+ }
+ load(P1, Q1, pk1File);
+ load(P2, Q2, pk2File);
+ Fp12 e;
+ pairing(e, P1, Q2);
+ {
+ // verify(not necessary)
+ Fp12 e2;
+ pairing(e2, P2, Q1);
+ if (e != e2) {
+ throw cybozu::Exception("share:bad public key file") << e << e2;
+ }
+ }
+ Fp12::pow(e, e, s);
+ std::cout << "share key:\n" << e << std::endl;
+}
+
+int main(int argc, char *argv[])
+ try
+{
+ if (argc == 3 && strcmp(argv[1], "keygen") == 0) {
+ keygen(argv[2]);
+ } else if (argc == 5 && strcmp(argv[1], "share") == 0) {
+ share(argv[2], argv[3], argv[4]);
+ } else {
+ fprintf(stderr, "tri-dh.exe keygen <user name>\n");
+ fprintf(stderr, "tri-dh.exe share <secret key file> <public key1 file> <public key2 file>\n");
+ return 1;
+ }
+} catch (std::exception& e) {
+ printf("ERR %s\n", e.what());
+ return 1;
+}
+
diff --git a/vendor/github.com/tangerine-network/mcl/sample/vote.cpp b/vendor/github.com/tangerine-network/mcl/sample/vote.cpp
new file mode 100644
index 000000000..88137187c
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/sample/vote.cpp
@@ -0,0 +1,206 @@
+/*
+ vote sample tool
+ Copyright (c) 2014, National Institute of Advanced Industrial
+ Science and Technology All rights reserved.
+ This source file is subject to BSD 3-Clause license.
+
+ modifyed for mcl by herumi
+*/
+#include <iostream>
+#include <fstream>
+#include <cybozu/random_generator.hpp>
+#include <cybozu/option.hpp>
+#include <cybozu/itoa.hpp>
+#include <mcl/fp.hpp>
+#include <mcl/ec.hpp>
+#include <mcl/elgamal.hpp>
+#include <mcl/ecparam.hpp>
+
+typedef mcl::FpT<> Fp;
+typedef mcl::FpT<mcl::ZnTag> Zn; // use ZnTag because Zn is different class with Fp
+typedef mcl::EcT<Fp> Ec;
+typedef mcl::ElgamalT<Ec, Zn> Elgamal;
+
+cybozu::RandomGenerator rg;
+
+const std::string pubFile = "vote_pub.txt";
+const std::string prvFile = "vote_prv.txt";
+const std::string resultFile = "vote_ret.txt";
+
+std::string GetSheetName(size_t n)
+{
+ return std::string("vote_") + cybozu::itoa(n) + ".txt";
+}
+
+struct Param {
+ std::string mode;
+ std::string voteList;
+ Param(int argc, const char *const argv[])
+ {
+ cybozu::Option opt;
+ opt.appendOpt(&voteList, "11001100", "l", ": list of voters for vote mode(eg. 11001100)");
+ opt.appendHelp("h", ": put this message");
+ opt.appendParam(&mode, "mode", ": init/vote/count/open");
+ if (!opt.parse(argc, argv)) {
+ opt.usage();
+ exit(1);
+ }
+ printf("mode=%s\n", mode.c_str());
+ if (mode == "vote") {
+ printf("voters=%s\n", voteList.c_str());
+ size_t pos = voteList.find_first_not_of("01");
+ if (pos != std::string::npos) {
+ printf("bad char %c\n", voteList[pos]);
+ exit(1);
+ }
+ }
+ }
+};
+
+void SysInit()
+{
+ const mcl::EcParam& para = mcl::ecparam::secp192k1;
+ Zn::init(para.n);
+ Fp::init(para.p);
+ Ec::init(para.a, para.b);
+}
+
+template<class T>
+bool Load(T& t, const std::string& name, bool doThrow = true)
+{
+ std::ifstream ifs(name.c_str(), std::ios::binary);
+ if (!ifs) {
+ if (doThrow) throw cybozu::Exception("Load:can't read") << name;
+ return false;
+ }
+ if (ifs >> t) return true;
+ if (doThrow) throw cybozu::Exception("Load:bad data") << name;
+ return false;
+}
+
+template<class T>
+void Save(const std::string& name, const T& t)
+{
+ std::ofstream ofs(name.c_str(), std::ios::binary);
+ ofs << t;
+}
+
+void Init()
+{
+ const mcl::EcParam& para = mcl::ecparam::secp192k1;
+ const Fp x0(para.gx);
+ const Fp y0(para.gy);
+ const Ec P(x0, y0);
+ const size_t bitSize = para.bitSize;
+
+ Elgamal::PrivateKey prv;
+ prv.init(P, bitSize, rg);
+ const Elgamal::PublicKey& pub = prv.getPublicKey();
+ printf("make privateKey=%s, publicKey=%s\n", prvFile.c_str(), pubFile.c_str());
+ Save(prvFile, prv);
+ Save(pubFile, pub);
+}
+
+struct CipherWithZkp {
+ Elgamal::CipherText c;
+ Elgamal::Zkp zkp;
+ bool verify(const Elgamal::PublicKey& pub) const
+ {
+ return pub.verify(c, zkp);
+ }
+};
+
+inline std::ostream& operator<<(std::ostream& os, const CipherWithZkp& self)
+{
+ return os << self.c << std::endl << self.zkp;
+}
+inline std::istream& operator>>(std::istream& is, CipherWithZkp& self)
+{
+ return is >> self.c >> self.zkp;
+}
+
+void Vote(const std::string& voteList)
+{
+ Elgamal::PublicKey pub;
+ Load(pub, pubFile);
+ puts("shuffle");
+ std::vector<size_t> idxTbl(voteList.size());
+ for (size_t i = 0; i < idxTbl.size(); i++) {
+ idxTbl[i] = i;
+ }
+ cybozu::shuffle(idxTbl, rg);
+ puts("each voter votes");
+ for (size_t i = 0; i < voteList.size(); i++) {
+ CipherWithZkp c;
+ pub.encWithZkp(c.c, c.zkp, voteList[i] - '0', rg);
+ const std::string sheetName = GetSheetName(idxTbl[i]);
+ printf("make %s\n", sheetName.c_str());
+ Save(sheetName, c);
+ }
+}
+
+void Count()
+{
+ Elgamal::PublicKey pub;
+ Load(pub, pubFile);
+ Elgamal::CipherText result;
+ puts("aggregate votes");
+ for (size_t i = 0; ; i++) {
+ const std::string sheetName = GetSheetName(i);
+ CipherWithZkp c;
+ if (!Load(c, sheetName, false)) break;
+ if (!c.verify(pub)) throw cybozu::Exception("bad cipher text") << i;
+ printf("add %s\n", sheetName.c_str());
+ result.add(c.c);
+ }
+ printf("create result file : %s\n", resultFile.c_str());
+ Save(resultFile, result);
+}
+
+void Open()
+{
+ Elgamal::PrivateKey prv;
+ Load(prv, prvFile);
+ Elgamal::CipherText c;
+ Load(c, resultFile);
+ Zn n;
+ prv.dec(n, c);
+ std::cout << "result of vote count " << n << std::endl;
+#if 0
+ puts("open real value");
+ for (size_t i = 0; ; i++) {
+ Elgamal::CipherText c;
+ const std::string sheetName = GetSheetName(i);
+ if (!Load(c, sheetName, false)) break;
+ Zn n;
+ prv.dec(n, c);
+ std::cout << sheetName << " " << n << std::endl;
+ }
+#endif
+}
+
+int main(int argc, char *argv[])
+ try
+{
+ const Param p(argc, argv);
+ SysInit();
+ if (p.mode == "init") {
+ Init();
+ } else
+ if (p.mode == "vote") {
+ Vote(p.voteList);
+ } else
+ if (p.mode == "count") {
+ Count();
+ } else
+ if (p.mode == "open") {
+ Open();
+ } else
+ {
+ printf("bad mode=%s\n", p.mode.c_str());
+ return 1;
+ }
+} catch (std::exception& e) {
+ printf("ERR %s\n", e.what());
+}
+