diff options
Diffstat (limited to 'vendor/github.com/tangerine-network/mcl/sample')
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(¶m.curveType, 0, "ct", ": curveType(0:BN254, 1:BN381_1, 5:BLS12_381)"); + opt.appendOpt(¶m.hashBitSize, 20, "hb", ": hash bit size"); + opt.appendOpt(¶m.group, 3, "g", ": group(1:G1, 2:G2, 3:GT"); + opt.appendOpt(¶m.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()); +} + |