aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/tangerine-network/mcl/misc
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tangerine-network/mcl/misc')
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/bench.txt21
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/karatsuba.cpp75
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/mul.cpp58
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/precompute.cpp30
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/she/bench.sh6
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/she/bench4.txt99
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/she/bench6.txt99
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/she/bench8.txt99
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/she/nizkp.pdfbin0 -> 28787 bytes
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/she/she-api-ja.md314
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/she/she-api.md322
-rw-r--r--vendor/github.com/tangerine-network/mcl/misc/she/she.pdfbin0 -> 25716 bytes
12 files changed, 1123 insertions, 0 deletions
diff --git a/vendor/github.com/tangerine-network/mcl/misc/bench.txt b/vendor/github.com/tangerine-network/mcl/misc/bench.txt
new file mode 100644
index 000000000..3e18e6b44
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/bench.txt
@@ -0,0 +1,21 @@
+Core i7-7700 @ 3.6GHz
+ BN254 BLS12_381
+G1::mul 185.863Kclk 360.723Kclk
+G1::add 812.01 clk 1.540Kclk
+G1::dbl 837.24 clk 1.977Kclk
+G2::mul 340.125Kclk 642.457Kclk
+G2::add 2.233Kclk 4.368Kclk
+G2::dbl 2.134Kclk 4.088Kclk
+GT::pow 615.052Kclk 1.055Mclk
+G1::setStr chk 1.546Kclk 534.376Kclk
+G1::setStr 1.592Kclk 4.000Kclk
+G2::setStr chk 609.195Kclk 1.402Mclk
+G2::setStr 5.444Kclk 8.282Kclk
+hashAndMapToG1 26.997Kclk 336.207Kclk
+hashAndMapToG2 212.800Kclk 775.072Kclk
+pairing 909.076Kclk 2.367Mclk
+millerLoop 549.957Kclk 983.935Kclk
+finalExp 375.203Kclk 1.404Mclk
+precomputeG2 126.000Kclk 236.912Kclk
+precomputedML 427.272Kclk 729.234Kclk
+
diff --git a/vendor/github.com/tangerine-network/mcl/misc/karatsuba.cpp b/vendor/github.com/tangerine-network/mcl/misc/karatsuba.cpp
new file mode 100644
index 000000000..7c150c6e3
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/karatsuba.cpp
@@ -0,0 +1,75 @@
+/*
+ sudo cpufreq-set -c 0 -g performance
+ mycl karatsuba.cpp -DMCL_USE_LLVM=1 ../lib/libmcl.a && ./a.out
+*/
+#include <stdio.h>
+#include <mcl/fp.hpp>
+#include <cybozu/xorshift.hpp>
+#include "../src/proto.hpp"
+#include "../src/low_func.hpp"
+#ifdef MCL_USE_LLVM
+#include "../src/low_func_llvm.hpp"
+#endif
+#include <cybozu/test.hpp>
+#include <cybozu/benchmark.hpp>
+
+typedef mcl::FpT<> Fp;
+
+using namespace mcl::fp;
+
+void dump(const Unit *x, size_t N)
+{
+ for (size_t i = 0; i < N; i++) {
+ printf("%016llx ", (long long)x[N - 1 - i]);
+ }
+ printf("\n");
+}
+
+void gggKara(uint64_t *z, const uint64_t *x, const uint64_t *)
+{
+ SqrPre<8, Gtag>::f(z, x);
+}
+void gggLLVM(uint64_t *z, const uint64_t *x, const uint64_t *y)
+{
+ MulPre<8, Ltag>::f(z, x, y);
+}
+
+template<size_t N>
+void benchKaratsuba()
+{
+ cybozu::XorShift rg;
+ printf("N=%d\n", (int)N);
+ Unit z[N * 2];
+ rg.read(z, N);
+ CYBOZU_BENCH("g:mulPre ", (MulPreCore<N, Gtag>::f), z, z, z);
+// CYBOZU_BENCH("g:mulKara", (MulPre<N, Gtag>::karatsuba), z, z, z);
+ CYBOZU_BENCH("g:sqrPre ", (SqrPreCore<N, Gtag>::f), z, z);
+// CYBOZU_BENCH("g:sqrKara", (SqrPre<N, Gtag>::karatsuba), z, z);
+
+#ifdef MCL_USE_LLVM
+ CYBOZU_BENCH("l:mulPre ", (MulPreCore<N, Ltag>::f), z, z, z);
+ CYBOZU_BENCH("l:sqrPre ", (SqrPreCore<N, Ltag>::f), z, z);
+ CYBOZU_BENCH("l:mulKara", (MulPre<N, Ltag>::karatsuba), z, z, z);
+ CYBOZU_BENCH("l:sqrKara", (SqrPre<N, Ltag>::karatsuba), z, z);
+#endif
+}
+
+CYBOZU_TEST_AUTO(karatsuba)
+{
+ benchKaratsuba<4>();
+ benchKaratsuba<6>();
+ benchKaratsuba<8>();
+#if MCL_MAX_BIT_SIZE >= 640
+ benchKaratsuba<10>();
+#endif
+#if MCL_MAX_BIT_SIZE >= 768
+ benchKaratsuba<12>();
+#endif
+#if MCL_MAX_BIT_SIZE >= 896
+ benchKaratsuba<14>();
+#endif
+#if MCL_MAX_BIT_SIZE >= 1024
+ benchKaratsuba<16>();
+#endif
+}
+
diff --git a/vendor/github.com/tangerine-network/mcl/misc/mul.cpp b/vendor/github.com/tangerine-network/mcl/misc/mul.cpp
new file mode 100644
index 000000000..146ac33a9
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/mul.cpp
@@ -0,0 +1,58 @@
+/*
+ sudo cpufreq-set -c 0 -g performance
+ mycl mul.cpp -DMCL_USE_LLVM=1 ../lib/libmcl.a && ./a.out
+*/
+#include <stdio.h>
+#include <mcl/fp.hpp>
+#include <cybozu/xorshift.hpp>
+#include <cybozu/test.hpp>
+#include <cybozu/benchmark.hpp>
+
+typedef mcl::FpT<> Fp;
+
+using namespace mcl::fp;
+
+void dump(const Unit *x, size_t N)
+{
+ for (size_t i = 0; i < N; i++) {
+ printf("%016llx ", (long long)x[N - 1 - i]);
+ }
+ printf("\n");
+}
+
+CYBOZU_TEST_AUTO(mulPre)
+{
+ cybozu::XorShift rg;
+ const char *pTbl[] = {
+ "0x2523648240000001ba344d80000000086121000000000013a700000000000013",
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
+ "6701817056313037086248947066310538444882082605308124576230408038843357549886356779857393369967010764802541005796711440355753503701056323603", // 462 bit
+ "4562440617622195218641171605700291324893228507248559930579192517899275167208677386505912811317371399778642309573594407310688704721375437998252661319722214188251994674360264950082874192246603471", // 640 bit
+ "1552518092300708935148979488462502555256886017116696611139052038026050952686376886330878408828646477950487730697131073206171580044114814391444287275041181139204454976020849905550265285631598444825262999193716468750892846853816057031", // 768 bit
+ };
+ const size_t N = 16;
+ const Mode modeTbl[] = {
+ FP_GMP_MONT,
+#ifdef MCL_USE_LLVM
+ FP_LLVM_MONT,
+#endif
+ };
+ for (size_t j = 0; j < CYBOZU_NUM_OF_ARRAY(modeTbl); j++) {
+ Mode mode = modeTbl[j];
+ printf("%s\n", ModeToStr(mode));
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(pTbl); i++) {
+ const char *p = pTbl[i];
+ Fp::init(p, mode);
+ printf("bitSize=%d\n", (int)Fp::getBitSize());
+ const Op& op = Fp::getOp();
+ Unit x[N], y[N * 2];
+ rg.read(x, N);
+ rg.read(y, N * 2);
+ CYBOZU_BENCH("mul ", op.fp_mul, y, y, x, op.p);
+ CYBOZU_BENCH("sqr ", op.fp_sqr, y, y, op.p);
+ CYBOZU_BENCH("mulPre", op.fpDbl_mulPre, y, y, y);
+ CYBOZU_BENCH("sqrPre", op.fpDbl_sqrPre, y, y);
+ CYBOZU_BENCH("mod ", op.fpDbl_mod, y, y, op.p);
+ }
+ }
+}
diff --git a/vendor/github.com/tangerine-network/mcl/misc/precompute.cpp b/vendor/github.com/tangerine-network/mcl/misc/precompute.cpp
new file mode 100644
index 000000000..63cdd663b
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/precompute.cpp
@@ -0,0 +1,30 @@
+#include <mcl/bn256.hpp>
+#include <iostream>
+
+using namespace mcl::bn;
+
+int main()
+{
+ initPairing(mcl::BN254);
+ G2 Q;
+ mapToG2(Q, 1);
+ std::vector<Fp6> Qcoeff;
+ precomputeG2(Qcoeff, Q);
+ puts("#if MCL_SIZEOF_UNIT == 8");
+ puts("static const uint64_t QcoeffTblBN254[][6][4] = {");
+ for (size_t i = 0; i < Qcoeff.size(); i++) {
+ const Fp6& x6 = Qcoeff[i];
+ puts("\t{");
+ for (size_t j = 0; j < 6; j++) {
+ printf("\t\t{");
+ const Fp& x = x6.getFp0()[j];
+ for (size_t k = 0; k < 4; k++) {
+ printf("0x%016llxull,", (unsigned long long)x.getUnit()[k]);
+ }
+ puts("},");
+ }
+ puts("\t},");
+ }
+ puts("};");
+ puts("#endif");
+}
diff --git a/vendor/github.com/tangerine-network/mcl/misc/she/bench.sh b/vendor/github.com/tangerine-network/mcl/misc/she/bench.sh
new file mode 100644
index 000000000..ced87b4db
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/she/bench.sh
@@ -0,0 +1,6 @@
+for i in 4 6 8
+do echo $i
+touch test/she_test.cpp
+make bin/she_test.exe CFLAGS_USER=-DMCLBN_FP_UNIT_SIZE=$i
+bin/she_test.exe > misc/she/bench$i.txt
+done
diff --git a/vendor/github.com/tangerine-network/mcl/misc/she/bench4.txt b/vendor/github.com/tangerine-network/mcl/misc/she/bench4.txt
new file mode 100644
index 000000000..99b2593c4
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/she/bench4.txt
@@ -0,0 +1,99 @@
+ctest:module=log
+CurveFp254BNb
+ctest:module=HashTable
+ctest:module=GTHashTable
+ctest:module=enc_dec
+ctest:module=add_sub_mul
+ctest:module=add_mul_add_sub
+ctest:module=innerProduct
+ctest:module=io
+ctest:module=bench
+enc 673.772Kclk
+add 8.021Kclk
+mul 4.042Mclk
+dec 2.194Mclk
+add after mul 20.693Kclk
+ctest:module=saveHash
+ctest:module=hashBench
+Kclk
+m=000fffff decG1 1.83e+02
+m=001fffff decG1 1.83e+02
+m=003fffff decG1 1.83e+02
+m=007fffff decG1 1.90e+02
+m=00ffffff decG1 2.04e+02
+m=01ffffff decG1 2.66e+02
+m=03ffffff decG1 4.17e+02
+m=07ffffff decG1 7.15e+02
+m=0fffffff decG1 1.29e+03
+m=1fffffff decG1 2.43e+03
+m=3fffffff decG1 4.70e+03
+m=7fffffff decG1 9.28e+03
+
+m=000fffff decG2 4.09e+02
+m=001fffff decG2 4.11e+02
+m=003fffff decG2 4.09e+02
+m=007fffff decG2 4.23e+02
+m=00ffffff decG2 4.48e+02
+m=01ffffff decG2 5.21e+02
+m=03ffffff decG2 7.25e+02
+m=07ffffff decG2 1.11e+03
+m=0fffffff decG2 1.87e+03
+m=1fffffff decG2 3.36e+03
+m=3fffffff decG2 6.38e+03
+m=7fffffff decG2 1.24e+04
+
+m=000fffff decGT 2.20e+03
+m=001fffff decGT 2.21e+03
+m=003fffff decGT 2.20e+03
+m=007fffff decGT 2.21e+03
+m=00ffffff decGT 2.23e+03
+m=01ffffff decGT 2.28e+03
+m=03ffffff decGT 2.37e+03
+m=07ffffff decGT 2.56e+03
+m=0fffffff decGT 2.94e+03
+m=1fffffff decGT 3.78e+03
+m=3fffffff decGT 5.41e+03
+m=7fffffff decGT 8.69e+03
+large m
+G1::add 7.36e-01
+G1::mul 1.92e+02
+G2::add 3.51e+00
+G2::mul 4.03e+02
+GT::mul 5.47e+00
+GT::pow 7.27e+02
+G1window 1.92e+01
+G2window 6.15e+01
+GTwindow 1.35e+02
+miller 6.69e+02
+finalExp 4.23e+02
+precomML 5.16e+02
+small m = 2097151
+G1::mul 4.52e+01
+G2::mul 1.01e+02
+GT::pow 1.33e+02
+G1window 1.55e+00
+G2window 5.02e+00
+GTwindow 1.55e+01
+encG1 2.10e+02
+encG2 4.82e+02
+encGT 2.47e+03
+encG1pre 5.31e+01
+encG2pre 1.47e+02
+encGTpre 6.01e+02
+decG1 1.84e+02
+decG2 3.96e+02
+degGT 2.20e+03
+mul 4.07e+03
+addG1 1.56e+00
+addG2 4.72e+00
+addGT 2.12e+01
+reRandG1 2.10e+02
+reRandG2 4.71e+02
+reRandGT 2.49e+03
+reRandG1pre 5.16e+01
+reRandG2pre 1.44e+02
+reRandGTpre 6.10e+02
+mulG1 9.03e+01
+mulG2 2.03e+02
+mulGT 5.34e+02
+ctest:name=she_test, module=11, total=2879, ok=2879, ng=0, exception=0
diff --git a/vendor/github.com/tangerine-network/mcl/misc/she/bench6.txt b/vendor/github.com/tangerine-network/mcl/misc/she/bench6.txt
new file mode 100644
index 000000000..863f7129a
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/she/bench6.txt
@@ -0,0 +1,99 @@
+ctest:module=log
+CurveFp382_1
+ctest:module=HashTable
+ctest:module=GTHashTable
+ctest:module=enc_dec
+ctest:module=add_sub_mul
+ctest:module=add_mul_add_sub
+ctest:module=innerProduct
+ctest:module=io
+ctest:module=bench
+enc 2.077Mclk
+add 17.694Kclk
+mul 13.408Mclk
+dec 5.854Mclk
+add after mul 41.570Kclk
+ctest:module=saveHash
+ctest:module=hashBench
+Kclk
+m=000fffff decG1 5.34e+02
+m=001fffff decG1 5.36e+02
+m=003fffff decG1 5.34e+02
+m=007fffff decG1 5.48e+02
+m=00ffffff decG1 5.87e+02
+m=01ffffff decG1 7.11e+02
+m=03ffffff decG1 9.53e+02
+m=07ffffff decG1 1.41e+03
+m=0fffffff decG1 2.30e+03
+m=1fffffff decG1 4.11e+03
+m=3fffffff decG1 7.71e+03
+m=7fffffff decG1 1.50e+04
+
+m=000fffff decG2 1.27e+03
+m=001fffff decG2 1.27e+03
+m=003fffff decG2 1.27e+03
+m=007fffff decG2 1.30e+03
+m=00ffffff decG2 1.35e+03
+m=01ffffff decG2 1.53e+03
+m=03ffffff decG2 1.88e+03
+m=07ffffff decG2 2.55e+03
+m=0fffffff decG2 3.87e+03
+m=1fffffff decG2 6.53e+03
+m=3fffffff decG2 1.18e+04
+m=7fffffff decG2 2.25e+04
+
+m=000fffff decGT 6.01e+03
+m=001fffff decGT 6.03e+03
+m=003fffff decGT 6.01e+03
+m=007fffff decGT 6.04e+03
+m=00ffffff decGT 6.08e+03
+m=01ffffff decGT 6.17e+03
+m=03ffffff decGT 6.39e+03
+m=07ffffff decGT 6.71e+03
+m=0fffffff decGT 7.44e+03
+m=1fffffff decGT 8.95e+03
+m=3fffffff decGT 1.20e+04
+m=7fffffff decGT 1.80e+04
+large m
+G1::add 1.48e+00
+G1::mul 5.44e+02
+G2::add 6.91e+00
+G2::mul 1.28e+03
+GT::mul 1.04e+01
+GT::pow 2.04e+03
+G1window 5.57e+01
+G2window 2.04e+02
+GTwindow 4.03e+02
+miller 2.09e+03
+finalExp 1.50e+03
+precomML 1.63e+03
+small m = 2097151
+G1::mul 8.29e+01
+G2::mul 2.05e+02
+GT::pow 2.66e+02
+G1window 3.18e+00
+G2window 1.14e+01
+GTwindow 3.19e+01
+encG1 6.01e+02
+encG2 1.49e+03
+encGT 7.66e+03
+encG1pre 1.41e+02
+encG2pre 4.71e+02
+encGTpre 1.76e+03
+decG1 5.37e+02
+decG2 1.27e+03
+degGT 6.02e+03
+mul 1.34e+04
+addG1 3.07e+00
+addG2 1.02e+01
+addGT 4.18e+01
+reRandG1 5.99e+02
+reRandG2 1.49e+03
+reRandGT 7.69e+03
+reRandG1pre 1.40e+02
+reRandG2pre 4.68e+02
+reRandGTpre 1.75e+03
+mulG1 1.65e+02
+mulG2 4.14e+02
+mulGT 1.06e+03
+ctest:name=she_test, module=11, total=2879, ok=2879, ng=0, exception=0
diff --git a/vendor/github.com/tangerine-network/mcl/misc/she/bench8.txt b/vendor/github.com/tangerine-network/mcl/misc/she/bench8.txt
new file mode 100644
index 000000000..f8fe8fd75
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/she/bench8.txt
@@ -0,0 +1,99 @@
+ctest:module=log
+CurveFp462
+ctest:module=HashTable
+ctest:module=GTHashTable
+ctest:module=enc_dec
+ctest:module=add_sub_mul
+ctest:module=add_mul_add_sub
+ctest:module=innerProduct
+ctest:module=io
+ctest:module=bench
+enc 5.095Mclk
+add 36.280Kclk
+mul 30.163Mclk
+dec 12.974Mclk
+add after mul 76.646Kclk
+ctest:module=saveHash
+ctest:module=hashBench
+Kclk
+m=000fffff decG1 1.44e+03
+m=001fffff decG1 1.45e+03
+m=003fffff decG1 1.45e+03
+m=007fffff decG1 1.47e+03
+m=00ffffff decG1 1.54e+03
+m=01ffffff decG1 1.70e+03
+m=03ffffff decG1 2.03e+03
+m=07ffffff decG1 2.64e+03
+m=0fffffff decG1 3.88e+03
+m=1fffffff decG1 6.32e+03
+m=3fffffff decG1 1.12e+04
+m=7fffffff decG1 2.11e+04
+
+m=000fffff decG2 2.99e+03
+m=001fffff decG2 3.01e+03
+m=003fffff decG2 2.99e+03
+m=007fffff decG2 3.05e+03
+m=00ffffff decG2 3.15e+03
+m=01ffffff decG2 3.41e+03
+m=03ffffff decG2 3.93e+03
+m=07ffffff decG2 4.95e+03
+m=0fffffff decG2 6.97e+03
+m=1fffffff decG2 1.10e+04
+m=3fffffff decG2 1.91e+04
+m=7fffffff decG2 3.54e+04
+
+m=000fffff decGT 1.31e+04
+m=001fffff decGT 1.31e+04
+m=003fffff decGT 1.31e+04
+m=007fffff decGT 1.31e+04
+m=00ffffff decGT 1.32e+04
+m=01ffffff decGT 1.33e+04
+m=03ffffff decGT 1.36e+04
+m=07ffffff decGT 1.43e+04
+m=0fffffff decGT 1.56e+04
+m=1fffffff decGT 1.82e+04
+m=3fffffff decGT 2.34e+04
+m=7fffffff decGT 3.39e+04
+large m
+G1::add 3.40e+00
+G1::mul 1.41e+03
+G2::add 1.38e+01
+G2::mul 2.93e+03
+GT::mul 1.94e+01
+GT::pow 4.30e+03
+G1window 1.59e+02
+G2window 4.89e+02
+GTwindow 8.96e+02
+miller 4.99e+03
+finalExp 3.26e+03
+precomML 3.71e+03
+small m = 2097151
+G1::mul 1.53e+02
+G2::mul 3.85e+02
+GT::pow 4.88e+02
+G1window 6.96e+00
+G2window 2.17e+01
+GTwindow 5.83e+01
+encG1 1.62e+03
+encG2 3.48e+03
+encGT 1.79e+04
+encG1pre 3.67e+02
+encG2pre 1.09e+03
+encGTpre 3.88e+03
+decG1 1.45e+03
+decG2 3.02e+03
+degGT 1.31e+04
+mul 3.02e+04
+addG1 7.08e+00
+addG2 2.03e+01
+addGT 7.68e+01
+reRandG1 1.63e+03
+reRandG2 3.48e+03
+reRandGT 1.79e+04
+reRandG1pre 3.65e+02
+reRandG2pre 1.08e+03
+reRandGTpre 3.79e+03
+mulG1 3.08e+02
+mulG2 7.65e+02
+mulGT 1.95e+03
+ctest:name=she_test, module=11, total=2879, ok=2879, ng=0, exception=0
diff --git a/vendor/github.com/tangerine-network/mcl/misc/she/nizkp.pdf b/vendor/github.com/tangerine-network/mcl/misc/she/nizkp.pdf
new file mode 100644
index 000000000..7e61b5a64
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/she/nizkp.pdf
Binary files differ
diff --git a/vendor/github.com/tangerine-network/mcl/misc/she/she-api-ja.md b/vendor/github.com/tangerine-network/mcl/misc/she/she-api-ja.md
new file mode 100644
index 000000000..850f11ff3
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/she/she-api-ja.md
@@ -0,0 +1,314 @@
+# L2準同型暗号ライブラリshe
+
+# 概要
+she(somewhat homomorphic encryption)はペアリングベースのL2準同型暗号と呼ばれる公開鍵暗号ライブラリである。
+L2準同型暗号とは暗号文同士の加算を複数回、乗算を一度だけできる性質を表す。
+
+特に2個の整数値ベクトルx = (x_i), y = (y_i)の各要素が暗号化された状態で、その2個のベクトルの内積を暗号化したまま計算できる。
+
+ΣEnc(x_i) Enc(y_i) = Enc(Σx_i y_i).
+
+# 特長
+* ペアリングベースの最新アルゴリズムを実装
+ * [Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and A Fast Implementation in WebAssembly : ASIA CCS2018](http://asiaccs2018.org/?page_id=632)
+* C++版はWindows(x64), Linux(x64, ARM64), OSX(x64)に対応
+* JavaScript(WebAssembly 以降JSと記す)版はChrome, Firefox, Edge, Safari(Android, iPhone含む), Node.jsに対応
+
+# クラスと主な機能
+
+## 主なクラス
+* 秘密鍵クラス SecretKey
+* 公開鍵クラス PublicKey
+* 暗号文クラス CipherTextG1, CipherTextG2, CipherTextGT
+* ゼロ知識証明クラス ZkpBin, ZkpEq, ZkpBinEq
+
+## 暗号化と復号方法
+* 秘密鍵から公開鍵を作成する
+* 公開鍵を用いて整数から暗号文を作る
+* 秘密鍵を用いて暗号文を復号する
+
+## 暗号文同士の計算
+* 同じ暗号文クラス同士は加算・減算できる
+* CipherTextG1とCipherTextG2を乗算するとCipherTextGTになる
+
+## 復号の重要な注意点
+* このsheは復号時に小さな離散対数問題(DLP)を解く必要がある
+* DLPのテーブルサイズをs、暗号文をEnc(m)とすると復号時間はm/sに比例する
+* テーブルサイズの設定は`setRangeForDLP(s)`を使う
+ * `m/s`の最大値は`setTryNum(tryNum)`で行う
+
+## ゼロ知識証明クラス
+* mを暗号するときに同時にゼロ知識証明を生成する
+* 暗号文と生成されたゼロ知識証明と公開鍵でmに関する制約条件を検証できる
+
+# JS版
+
+## Node.jsでの読み込み
+
+```
+>npm install she-wasm
+>node
+>const she = require('she-wasm')
+```
+
+## ブラウザでの読み込み
+[she-wasm](https://github.com/herumi/she-wasm/)のshe.js, she\_c.js, she\_c.wasmファイルを同じディレクトリに置いてshe.jsを読み込む
+```
+// HTML
+<script src="she.js"></script>
+```
+
+## JS版サンプル
+
+```
+// システムの初期化
+she.init().then(() => {
+ const sec = new she.SecretKey()
+ // 秘密鍵の初期化
+ sec.setByCSPRNG()
+
+ // 秘密鍵secから公開鍵pubを作成
+ const pub = sec.getPublicKey()
+
+ const m1 = 1
+ const m2 = 2
+ const m3 = 3
+ const m4 = -1
+
+ // 平文m1とm2をCipherTextG1として暗号化
+ const c11 = pub.encG1(m1)
+ const c12 = pub.encG1(m2)
+
+ // 平文m3とm4をCipherTextG2として暗号化
+ const c21 = pub.encG2(m3)
+ const c22 = pub.encG2(m4)
+
+ // c11とc12, c21とc22をそれぞれ加算
+ const c1 = she.add(c11, c12)
+ const c2 = she.add(c21, c22)
+
+ // c1とc2を乗算するとCipherTextGT型になる
+ const ct = she.mul(c1, c2)
+
+ // 暗号文ctを復号する
+ console.log(`(${m1} + ${m2}) * (${m3} + ${m4}) = ${sec.dec(ct)}`)
+})
+```
+
+# C++版サンプル
+ライブラリのビルドは[mcl](https://github.com/herumi/mcl/#installation-requirements)を参照
+```
+#include <mcl/she.hpp>
+int main()
+ try
+{
+ using namespace mcl::she;
+ // システのム初期化
+ init();
+
+ SecretKey sec;
+
+ // 秘密鍵の初期化
+ sec.setByCSPRNG();
+
+ // 秘密鍵secから公開鍵pubを作成
+ PublicKey pub;
+ sec.getPublicKey(pub);
+
+ int m1 = 1;
+ int m2 = 2;
+ int m3 = 3;
+ int m4 = -1;
+
+ // 平文m1とm2をCipherTextG1として暗号化
+ CipherTextG1 c11, c12;
+ pub.enc(c11, m1);
+ pub.enc(c12, m2);
+
+ // 平文m3とm4をCipherTextG2として暗号化
+ CipherTextG2 c21, c22;
+ pub.enc(c21, m3);
+ pub.enc(c22, m4);
+
+ // c11とc12, c21とc22をそれぞれ加算
+ CipherTextG1 c1;
+ CipherTextG2 c2;
+ CipherTextG1::add(c1, c11, c12);
+ CipherTextG2::add(c2, c21, c22);
+
+ // c1とc2を乗算するとCipherTextGT型になる
+ CipherTextGT ct;
+ CipherTextGT::mul(ct, c1, c2);
+
+ // 暗号文ctを復号する
+ printf("(%d + %d) * (%d + %d) = %d\n", m1, m2, m3, m4, (int)sec.dec(ct));
+} catch (std::exception& e) {
+ printf("ERR %s\n", e.what());
+ return 1;
+}
+
+```
+
+# クラス共通メソッド
+
+## シリアライズ(C++)
+
+* `setStr(const std::string& str, int ioMode = 0)`
+ * ioModeに従ってstrで設定する
+
+* `getStr(std::string& str, int ioMode = 0) const`
+* `std::string getStr(int ioMode = 0) const`
+ * ioModeに従ってstrを取得する
+* `size_t serialize(void *buf, size_t maxBufSize) const`
+ * maxBufSize確保されたbufにシリアライズする
+ * bufに書き込まれたbyte長が返る
+ * エラーの場合は0が返る
+* `size_t deserialize(const void *buf, size_t bufSize)`
+ * bufから最大bufSizeまで値を読み込みデリシアライズする
+ * 読み込まれたbyte長が返る
+ * エラーの場合は0が返る
+
+## シリアライズ(JS)
+
+* `deserialize(s)`
+ * Uint8Array型sでデシリアライズ
+* `serialize()`
+ * シリアライズしてUint8Arrayの値を返す
+* `deserializeHexStr(s)`
+ * 16進数文字列sでデシリアライズ
+* `serializeToHexStr()`
+ * 16進数文字列sでシリアライズ
+
+## ioMode
+
+* 2 ; 2進数
+* 10 ; 10進数
+* 16 ; 16進数
+* IoPrefix ; 2または16とorの値を設定すると0bまたは0xがつく
+* IoEcAffine ; (G1, G2のみ)アフィン座標
+* IoEcProj ; (G1, G2のみ)射影座標
+* IoSerialize ; serialize()/deserialize()と同じ
+
+## 注意
+* C++の名前空間は`mcl::she`
+* 以下CTはCipherTextG1, CipherTextG2, CipherTextGTのいずれかを表す
+* JS版の平文は32ビット整数の範囲に制限される
+
+## SecretKeyクラス
+
+* `void setByCSPRNG()`(C++)
+* `void setByCSPRNG()`(JS)
+ * 疑似乱数で秘密鍵を初期化する
+
+* `int64_t dec(const CT& c) const`(C++)
+* `int dec(CT c)`(JS)
+ * 暗号文cを復号する
+* `int64_t decViaGT(const CipherTextG1& c) const`(C++)
+* `int64_t decViaGT(const CipherTextG2& c) const`(C++)
+* `int decViaGT(CT c)`(JS)
+ * 暗号文をGT経由で復号する
+* `bool isZero(const CT& c) const`(C++)
+* `bool isZero(CT c)`(JS)
+ * cの復号結果が0ならばtrue
+ * decしてから0と比較するよりも高速
+
+## PublicKey, PrecomputedPublicKeyクラス
+PrecomputedPublicKeyはPublicKeyの高速版
+
+* `void PrecomputedPublicKey::init(const PublicKey& pub)`(C++)
+* `void PrecomputedPublicKey::init(pub)`(JS)
+ * 公開鍵pubでPrecomputedPublicKeyを初期化する
+
+
+* `PrecomputedPublicKey::destroy()`(JS)
+ * JavaScriptではPrecomputedPublicKeyが不要になったらこのメソッドを呼ぶ必要がある
+ * そうしないとメモリリークする
+
+以下はPK = PublicKey or PrecomputedPublicKey
+
+* `void PK::enc(CT& c, int64_t m) const`(C++)
+* `CipherTextG1 PK::encG1(m)`(JS)
+* `CipherTextG2 PK::encG2(m)`(JS)
+* `CipherTextGT PK::encGT(m)`(JS)
+ * mを暗号化してcにセットする(またはその値を返す)
+
+* `void PK::reRand(CT& c) const`(C++)
+* `CT PK::reRand(CT c)`(JS)
+ * cを再ランダム化する
+ * 再ランダム化された暗号文と元の暗号文は同じ平文を暗号化したものかどうか判定できない
+
+* `void convert(CipherTextGT& cm, const CT& ca) const`
+* `CipherTextGT convert(CT ca)`
+ * 暗号文ca(CipherTextG1かCipherTextG2)をCipherTextGTに変換する
+
+## CipherTextクラス
+
+* `void CT::add(CT& z, const CT& x const CT& y)`(C++)
+* `CT she.add(CT x, CT y)`(JS)
+ * 暗号文xと暗号文yを足してzにセットする(またはその値を返す)
+* `void CT::sub(CT& z, const CT& x const CT& y)`(C++)
+* `CT she.sub(CT x, CT y)`(JS)
+ * 暗号文xから暗号文yを引いてzにセットする(またはその値を返す)
+* `void CT::neg(CT& y, const CT& x)`(C++)
+* `void she.neg(CT x)`(JS)
+ * 暗号文xの符号反転をyにセットする(またはその値を返す)
+* `void CT::mul(CT& z, const CT& x, int y)`(C++)
+* `CT she.mulInt(CT x, int y)`(JS)
+ * 暗号文xを整数倍yしてzにセットする(またはその値を返す)
+
+* `void CipherTextGT::mul(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y)`(C++)
+* `CipherTextGT she.mul(CipherTextG1 x, CipherTextG2 y)`(JS)
+ * 暗号文xと暗号文yを掛けてzにセットする(またはその値を返す)
+
+* `void CipherTextGT::mulML(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y)`(C++)
+ * 暗号文xと暗号文yを掛けて(Millerループだけして)zにセットする(またはその値を返す)
+* `CipherTextGT::finalExp(CipherText& , const CipherTextG1& x, const CipherTextG2& y)`(C++)
+ * mul(a, b) = finalExp(mulML(a, b))
+ * add(mul(a, b), mul(c, d)) = finalExp(add(mulML(a, b), mulML(c, d)))
+ * すなわち積和演算はmulMLしたものを足してから最後に一度finalExpするのがよい
+
+## ゼロ知識証明クラス
+
+### 概要
+* ZkpBin 暗号文encGi(m)(i = 1, 2, T)についてm = 0または1であることを復号せずに検証できる
+* ZkpEq 暗号文encG1(m1), encG2(m2)についてm1 = m2であることを検証できる
+* ZkpBinEq 暗号文encG1(m1), encG2(m2)についてm1 = m2 = 0または1であることを検証できる
+
+### API
+PK = PublicKey or PrecomputedPublicKey
+
+* `void PK::encWithZkpBin(CipherTextG1& c, Zkp& zkp, int m) const`(C++)
+* `void PK::encWithZkpBin(CipherTextG2& c, Zkp& zkp, int m) const`(C++)
+* `[CipherTextG1, ZkpBin] PK::encWithZkpBinG1(m)`(JS)
+* `[CipherTextG2, ZkpBin] PK::encWithZkpBinG2(m)`(JS)
+ * m(=0 or 1)を暗号化して暗号文cとゼロ知識証明zkpをセットする(または[c, zkp]を返す)
+ * mが0でも1でもなければ例外
+* `void PK::encWithZkpEq(CipherTextG1& c1, CipherTextG2& c2, ZkpEq& zkp, const INT& m) const`(C++)
+* `[CipherTextG1, CipherTextG2, ZkpEq] PK::encWithZkpEq(m)`(JS)
+ * mを暗号化して暗号文c1, c2とゼロ知識証明zkpをセットする(または[c1, c2, zkp]を返す)
+* `void PK::encWithZkpBinEq(CipherTextG1& c1, CipherTextG2& c2, ZkpBinEq& zkp, int m) const`(C++)
+* `[CipherTextG1, CipherTextG2, ZkpEqBin] PK::encWithZkpBinEq(m)`(JS)
+ * m(=0 or 1)を暗号化して暗号文c1, c2とゼロ知識証明zkpをセットする(または[c1, c2, zkp]を返す)
+ * mが0でも1でもなければ例外
+
+## グローバル関数
+
+* `void init(const CurveParam& cp, size_t hashSize = 1024, size_t tryNum = 2048)`(C++)
+* `void init(curveType = she.BN254, hashSize = 1024, tryNum = 2048)`(JS)
+ * hashSizeの大きさの復号用テーブルとtryNumを元に初期化する
+ * 復号可能な平文mの範囲は|m| <= hashSize * tryNum
+* `she.loadTableForGTDLP(Uint8Array a)`(JS)
+ * 復号用テーブルを読み込む
+ * 現在は`https://herumi.github.io/she-dlp-table/she-dlp-0-20-gt.bin`のみがある
+* `void useDecG1ViaGT(bool use)`(C++/JS)
+* `void useDecG2ViaGT(bool use)`(C++/JS)
+ * CipherTextG1, CipherTextG2の復号をCipherTextGT経由で行う
+ * 大きな値を復号するときはDLP用の巨大なテーブルをそれぞれに持つよりもGTに集約した方が効率がよい
+
+# ライセンス
+
+このライブラリは[修正BSDライセンス](https://github.com/herumi/mcl/blob/master/COPYRIGHT)で提供されます
+
+# 開発者
+
+光成滋生 MITSUNARI Shigeo(herumi@nifty.com)
diff --git a/vendor/github.com/tangerine-network/mcl/misc/she/she-api.md b/vendor/github.com/tangerine-network/mcl/misc/she/she-api.md
new file mode 100644
index 000000000..af54311e9
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/she/she-api.md
@@ -0,0 +1,322 @@
+# she ; Two-level homomorphic encryption library for browser/Node.js by WebAssembly
+
+# Abstruct
+she is a somewhat(two-level) homomorphic encryption library,
+which is based on pairings.
+This library supports polynomially many homomorphic additions and
+one multiplication over encrypted data.
+
+Especially, the inner products of two encrypted integer vectors such as Enc(x) = (Enc(x_i)), Enc(y) = (Enc(y_i))
+can be computed.
+
+Sum_i Enc(x_i) Enc(y_i) = Enc(Sum_i x_i y_i).
+
+# Features
+* supports the latest pairing based algorithm
+ * [Efficient Two-level Homomorphic Encryption in Prime-order Bilinear Groups and A Fast Implementation in WebAssembly : ASIA CCS2018](http://asiaccs2018.org/?page_id=632)
+* supports Windows(x64), Linux(x64, ARM64), OSX(x64)
+* supports JavaScript(WebAssembly), Chrome, Firefox, Safari(contains Android, iPhone), Node.js
+
+# Classes
+
+## Main classes
+* secret key class ; SecretKey
+* public key class ; PublicKey
+* ciphertext class ; CipherTextG1, CipherTextG2, CipherTextGT
+* zero-knowledge proof class ; ZkpBin, ZkpEq, ZkpBinEq
+
+## Encryption and decryption
+* create the corresponding public key from a secret key
+* encrypt an integer(plaintext) with a public key
+* decrypt a ciphertext with a secret key
+
+## Homomorphic operations
+* homomorphic addtion/substraction over ciphertexts of the same ciphertext class
+* homomprphic multiplication over ciphertext of CipherTextG1 and CipherTextG2
+ * The class of the result is CipherTextGT.
+
+## Important notation of decryption
+* This library requires to solve a small DLP to decrypt a ciphertext.
+* The decryption timing is O(m/s), where s is the size of table to solve DLP, and m is the size fo a plaintext.
+* call `setRangeForDLP(s)` to set the table size.
+ * The maximun `m/s` is set by `setTryNum(tryNum)`.
+
+## Zero-knowledge proof class
+* A zero-knowledge proof is simultaneously created when encrypting a plaintext `m`.
+* The restriction according to `m` can be verified with a created zero-knowledge proof and a public key.
+
+# Setup for JavaScript(JS)
+
+## for Node.js
+
+```
+>npm install she-wasm
+>node
+>const she = require('she-wasm')
+```
+
+## for a browser
+
+Copy `she.js`, `she\_c.js`, `she\_c.wasm` to your directory from [she-wasm](https://github.com/herumi/she-wasm/),
+and read `she.js`.
+```
+// HTML
+<script src="she.js"></script>
+```
+
+## A sample for JS
+
+```
+// initialize a library
+she.init().then(() => {
+ const sec = new she.SecretKey()
+ // initialize a secret key by CSPRNG(cryptographically secure pseudo random number generator)
+ sec.setByCSPRNG()
+
+ // create a public key from a secret key
+ const pub = sec.getPublicKey()
+
+ const m1 = 1
+ const m2 = 2
+ const m3 = 3
+ const m4 = -1
+
+ // encrypt m1 and m2 as CipherTextG1 class
+ const c11 = pub.encG1(m1)
+ const c12 = pub.encG1(m2)
+
+ // encrypt m3 and m4 as CipherTextG2 class
+ const c21 = pub.encG2(m3)
+ const c22 = pub.encG2(m4)
+
+ // add c11 and c12, c21 and c22 respectively
+ const c1 = she.add(c11, c12)
+ const c2 = she.add(c21, c22)
+
+ // get ct as a CipherTextGT class by multiplying c1 with c2
+ const ct = she.mul(c1, c2)
+
+ // decrypt ct
+ console.log(`(${m1} + ${m2}) * (${m3} + ${m4}) = ${sec.dec(ct)}`)
+})
+```
+
+# A sample for C++
+How to build the library, see [mcl](https://github.com/herumi/mcl/#installation-requirements).
+```
+#include <mcl/she.hpp>
+int main()
+ try
+{
+ using namespace mcl::she;
+ // initialize a library
+ init();
+
+ SecretKey sec;
+
+ // initialize a secret key by CSPRNG
+ sec.setByCSPRNG();
+
+ // create a public key from a secret key
+ PublicKey pub;
+ sec.getPublicKey(pub);
+
+ int m1 = 1;
+ int m2 = 2;
+ int m3 = 3;
+ int m4 = -1;
+
+ // encrypt m1 and m2 as CipherTextG1 class
+ CipherTextG1 c11, c12;
+ pub.enc(c11, m1);
+ pub.enc(c12, m2);
+
+ // encrypt m3 and m4 as CipherTextG2 class
+ CipherTextG2 c21, c22;
+ pub.enc(c21, m3);
+ pub.enc(c22, m4);
+
+ // add c11 and c12, c21 and c22 respectively
+ CipherTextG1 c1;
+ CipherTextG2 c2;
+ CipherTextG1::add(c1, c11, c12);
+ CipherTextG2::add(c2, c21, c22);
+
+ // get ct as a CipherTextGT class by multiplying c1 with c2
+ CipherTextGT ct;
+ CipherTextGT::mul(ct, c1, c2);
+
+ // decrypt ct
+ printf("(%d + %d) * (%d + %d) = %d\n", m1, m2, m3, m4, (int)sec.dec(ct));
+} catch (std::exception& e) {
+ printf("ERR %s\n", e.what());
+ return 1;
+}
+
+```
+# Class method
+
+## Serialization(C++)
+
+* `setStr(const std::string& str, int ioMode = 0)`
+ * set a value by `str` according to `ioMode`
+
+* `getStr(std::string& str, int ioMode = 0) const`
+* `std::string getStr(int ioMode = 0) const`
+ * get a string `str` according to `ioMode`
+* `size_t serialize(void *buf, size_t maxBufSize) const`
+ * serialize a value to buf which has maxBufSize byte size
+ * return the byte size to be written in `buf`
+ * return zero if error
+* `size_t deserialize(const void *buf, size_t bufSize)`
+ * deserialize a value from buf which has bufSize byte size
+ * return the byte size to be read from `buf`
+ * return zero if error
+
+## Serialization(JS)
+
+* `deserialize(s)`
+ * deserialize from `s` as Uint8Array type
+* `serialize()`
+ * serialize a value and return Uint8Array value
+* `deserializeHexStr(s)`
+ * deserialize as a hexadecimal string
+* `serializeToHexStr()`
+ * serialize as a hexadecimal string
+
+## ioMode
+
+* 2 ; binary number
+* 10 ; decimal number
+* 16 ; hexadecimal number
+* IoPrefix ; append a prefix 0b(resp. 2) or 0x(resp. 16)
+* IoEcAffine ; affine coordinate (for only G1, G2)
+* IoEcProj ; projective coordinate (for only G1, G2)
+* IoSerialize ; same as serialize()/deserialize()
+
+## Notation
+* the namespace of C++ is `mcl::she`
+* CT means one of CipherTextG1, CipherTextG2, CipherTextGT
+* The range of plaintext is rectricted as a 32-bit integer for JS
+
+## SecretKey class
+
+* `void setByCSPRNG()`(C++)
+* `void setByCSPRNG()`(JS)
+ * set a secret key by CSPRNG(cryptographically secure pseudo random number generator)
+
+* `int64_t dec(const CT& c) const`(C++)
+* `int dec(CT c)`(JS)
+ * decrypt `c`
+* `int64_t decViaGT(const CipherTextG1& c) const`(C++)
+* `int64_t decViaGT(const CipherTextG2& c) const`(C++)
+* `int decViaGT(CT c)`(JS)
+ * decrypt `c` through CipherTextGT
+* `bool isZero(const CT& c) const`(C++)
+* `bool isZero(CT c)`(JS)
+ * return true if decryption of `c` is zero
+ * it is faster than the timing of comparision with zero after decrypting `c`
+
+## PublicKey, PrecomputedPublicKey class
+`PrecomputedPublicKey` is a faster version of `PublicKey`
+
+* `void PrecomputedPublicKey::init(const PublicKey& pub)`(C++)
+* `void PrecomputedPublicKey::init(pub)`(JS)
+ * initialize `PrecomputedPublicKey` by a public key `pub`
+
+* `PrecomputedPublicKey::destroy()`(JS)
+ * It is necessary to call this method if this instance becomes unnecessary
+ * otherwise a memory leak will be caused
+
+PK means PublicKey or PrecomputedPublicKey
+
+* `void PK::enc(CT& c, int64_t m) const`(C++)
+* `CipherTextG1 PK::encG1(m)`(JS)
+* `CipherTextG2 PK::encG2(m)`(JS)
+* `CipherTextGT PK::encGT(m)`(JS)
+ * encrypt `m` and set `c`(or return the value)
+
+* `void PK::reRand(CT& c) const`(C++)
+* `CT PK::reRand(CT c)`(JS)
+ * rerandomize `c`
+ * For `c = Enc(m)`, the rerandomized ciphertext is hard to detect if it is generated by the rerandomization
+ or an encrypted `m` freshly again.
+
+* `void convert(CipherTextGT& cm, const CT& ca) const`
+* `CipherTextGT convert(CT ca)`
+ * convert `ca`(CipherTextG1 or CipherTextG2) to `CipherTextGT` class
+
+## CipherText class
+
+* `void CT::add(CT& z, const CT& x const CT& y)`(C++)
+* `CT she.add(CT x, CT y)`(JS)
+ * add `x` and `y` and set the value to `z`(or return the value)
+* `void CT::sub(CT& z, const CT& x const CT& y)`(C++)
+* `CT she.sub(CT x, CT y)`(JS)
+ * subtract `x` and `y` and set the value to `z`(or return the value)
+* `void CT::neg(CT& y, const CT& x)`(C++)
+* `void she.neg(CT x)`(JS)
+ * negate `x` and set the value to `y`(or return the value)
+* `void CT::mul(CT& z, const CT& x, int y)`(C++)
+* `CT she.mulInt(CT x, int y)`(JS)
+ * multiple `x` and `y` and set the value `y`(or return the value)
+
+* `void CipherTextGT::mul(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y)`(C++)
+* `CipherTextGT she.mul(CipherTextG1 x, CipherTextG2 y)`(JS)
+ * multiple `x` and `y` and set the value `y`(or return the value)
+
+* `void CipherTextGT::mulML(CipherTextGT& z, const CipherTextG1& x, const CipherTextG2& y)`(C++)
+ * multiple(only Miller Loop) `x` and `y` and set the value `y`(or return the value)
+
+* `CipherTextGT::finalExp(CipherText& , const CipherTextG1& x, const CipherTextG2& y)`(C++)
+ * mul(a, b) = finalExp(mulML(a, b))
+ * add(mul(a, b), mul(c, d)) = finalExp(add(mulML(a, b), mulML(c, d)))
+ * i.e., innor product can be computed as once calling `finalExp` after computing `mulML` for each elements of two vectors and adding all
+
+## Zero knowledge proof class
+
+### Abstract
+* ZkpBin ; verify whether `m = 0` or `1` for ciphertexts `encGi(m)(i = 1, 2, T)`
+* ZkpEq ; verify whether `m1 = m2` for ciphertexts `encG1(m1)` and `encG2(m2)`
+* ZkpBinEq ; verify whether `m1 = m2 = 0` or `1` for ciphertexts `encG1(m1)` and `encG2(m2)`
+
+### API
+PK = PublicKey or PrecomputedPublicKey
+
+* `void PK::encWithZkpBin(CipherTextG1& c, Zkp& zkp, int m) const`(C++)
+* `void PK::encWithZkpBin(CipherTextG2& c, Zkp& zkp, int m) const`(C++)
+* `[CipherTextG1, ZkpBin] PK::encWithZkpBinG1(m)`(JS)
+* `[CipherTextG2, ZkpBin] PK::encWithZkpBinG2(m)`(JS)
+ * encrypt `m`(=0 or 1) and set the ciphertext `c` and zero-knowledge proof `zkp`(or returns [c, zkp])
+ * throw exception if m != 0 and m != 1
+* `void PK::encWithZkpEq(CipherTextG1& c1, CipherTextG2& c2, ZkpEq& zkp, const INT& m) const`(C++)
+* `[CipherTextG1, CipherTextG2, ZkpEq] PK::encWithZkpEq(m)`(JS)
+ * encrypt `m` and set the ciphertext `c1`, `c2` and zero-knowledge proof `zk`(or returns [c1, c2, zkp])
+* `void PK::encWithZkpBinEq(CipherTextG1& c1, CipherTextG2& c2, ZkpBinEq& zkp, int m) const`(C++)
+* `[CipherTextG1, CipherTextG2, ZkpEqBin] PK::encWithZkpBinEq(m)`(JS)
+ * encrypt `m`(=0 or 1) and set ciphertexts `c1`, `c2` and zero-knowledge proof `zkp`(or returns [c1, c2, zkp])
+ * throw exception if m != 0 and m != 1
+
+## Global functions
+
+* `void init(const CurveParam& cp, size_t hashSize = 1024, size_t tryNum = 2048)`(C++)
+* `void init(curveType = she.BN254, hashSize = 1024, tryNum = 2048)`(JS)
+ * initialize a table to solve a DLP with `hashSize` size and set maximum trying count `tryNum`.
+ * the range `m` to be solvable is |m| <= hashSize * tryNum
+* `getHashTableGT().load(InputStream& is)`(C++)
+* `she.loadTableForGTDLP(Uint8Array a)`(JS)
+ * load a DLP table for CipherTextGT
+ * reset the value of `hashSize` used in `init()`
+ * `https://herumi.github.io/she-dlp-table/she-dlp-0-20-gt.bin` is a precomputed table
+* `void useDecG1ViaGT(bool use)`(C++/JS)
+* `void useDecG2ViaGT(bool use)`(C++/JS)
+ * decrypt a ciphertext of CipherTextG1 and CipherTextG2 through CipherTextGT
+ * it is better when decrypt a big value
+
+# License
+
+[modified new BSD License](https://github.com/herumi/mcl/blob/master/COPYRIGHT)
+
+# Author
+
+光成滋生 MITSUNARI Shigeo(herumi@nifty.com)
diff --git a/vendor/github.com/tangerine-network/mcl/misc/she/she.pdf b/vendor/github.com/tangerine-network/mcl/misc/she/she.pdf
new file mode 100644
index 000000000..355a308b3
--- /dev/null
+++ b/vendor/github.com/tangerine-network/mcl/misc/she/she.pdf
Binary files differ