aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/dexon-foundation/mcl/include/cybozu
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2018-10-23 15:17:52 +0800
committerWei-Ning Huang <w@dexon.org>2019-04-09 21:32:51 +0800
commit0f4b7dd20e5b4390bb868460faa8d6c2d296af7b (patch)
tree0cb8cb2d11616eb58d7e5f0fe2e2e313dc02f0f2 /vendor/github.com/dexon-foundation/mcl/include/cybozu
parent30c2100b2ce5179f1421f6c37f0397f2c2333284 (diff)
downloaddexon-0f4b7dd20e5b4390bb868460faa8d6c2d296af7b.tar.gz
dexon-0f4b7dd20e5b4390bb868460faa8d6c2d296af7b.tar.zst
dexon-0f4b7dd20e5b4390bb868460faa8d6c2d296af7b.zip
vendor: use govendor to import dexon-consensus-core
Diffstat (limited to 'vendor/github.com/dexon-foundation/mcl/include/cybozu')
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/array.hpp197
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/atoi.hpp239
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/benchmark.hpp212
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/bit_operation.hpp139
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/critical_section.hpp60
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/crypto.hpp321
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/endian.hpp224
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/exception.hpp252
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/hash.hpp67
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/inttype.hpp163
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/itoa.hpp337
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/link_libeay32.hpp21
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/link_mpir.hpp18
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/link_ssleay32.hpp19
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/mutex.hpp141
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/option.hpp723
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp139
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/serializer.hpp363
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp438
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/stream.hpp267
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/test.hpp373
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/unordered_map.hpp13
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp172
23 files changed, 4898 insertions, 0 deletions
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/array.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/array.hpp
new file mode 100644
index 000000000..30df3667d
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/array.hpp
@@ -0,0 +1,197 @@
+#pragma once
+
+/**
+ @file
+ @brief scoped array and aligned array
+
+ @author MITSUNARI Shigeo(@herumi)
+*/
+#include <new>
+#include <utility>
+#ifdef _WIN32
+ #include <malloc.h>
+#else
+ #include <stdlib.h>
+#endif
+#include <cybozu/inttype.hpp>
+
+namespace cybozu {
+
+inline void *AlignedMalloc(size_t size, size_t alignment)
+{
+#ifdef _WIN32
+ return _aligned_malloc(size, alignment);
+#else
+ void *p;
+ int ret = posix_memalign(&p, alignment, size);
+ return (ret == 0) ? p : 0;
+#endif
+}
+
+inline void AlignedFree(void *p)
+{
+#ifdef _WIN32
+ if (p == 0) return;
+ _aligned_free(p);
+#else
+ free(p);
+#endif
+}
+
+template<class T>
+class ScopedArray {
+ T *p_;
+ size_t size_;
+ ScopedArray(const ScopedArray&);
+ void operator=(const ScopedArray&);
+public:
+ explicit ScopedArray(size_t size)
+ : p_(new T[size])
+ , size_(size)
+ {
+ }
+ ~ScopedArray()
+ {
+ delete[] p_;
+ }
+ T& operator[](size_t idx) CYBOZU_NOEXCEPT { return p_[idx]; }
+ const T& operator[](size_t idx) const CYBOZU_NOEXCEPT { return p_[idx]; }
+ size_t size() const CYBOZU_NOEXCEPT { return size_; }
+ bool empty() const CYBOZU_NOEXCEPT { return size_ == 0; }
+ T* begin() CYBOZU_NOEXCEPT { return p_; }
+ T* end() CYBOZU_NOEXCEPT { return p_ + size_; }
+ const T* begin() const CYBOZU_NOEXCEPT { return p_; }
+ const T* end() const CYBOZU_NOEXCEPT { return p_ + size_; }
+ T* data() CYBOZU_NOEXCEPT { return p_; }
+ const T* data() const CYBOZU_NOEXCEPT { return p_; }
+};
+
+/**
+ T must be POD type
+ 16byte aligment array
+*/
+template<class T, size_t N = 16, bool defaultDoClear = true>
+class AlignedArray {
+ T *p_;
+ size_t size_;
+ size_t allocSize_;
+ T *alloc(size_t size) const
+ {
+ T *p = static_cast<T*>(AlignedMalloc(size * sizeof(T), N));
+ if (p == 0) throw std::bad_alloc();
+ return p;
+ }
+ void copy(T *dst, const T *src, size_t n) const
+ {
+ for (size_t i = 0; i < n; i++) dst[i] = src[i];
+ }
+ void setZero(T *p, size_t n) const
+ {
+ for (size_t i = 0; i < n; i++) p[i] = 0;
+ }
+ /*
+ alloc allocN and copy [p, p + copyN) to new p_
+ don't modify size_
+ */
+ void allocCopy(size_t allocN, const T *p, size_t copyN)
+ {
+ T *q = alloc(allocN);
+ copy(q, p, copyN);
+ AlignedFree(p_);
+ p_ = q;
+ allocSize_ = allocN;
+ }
+public:
+ /*
+ don't clear buffer with zero if doClear is false
+ */
+ explicit AlignedArray(size_t size = 0, bool doClear = defaultDoClear)
+ : p_(0)
+ , size_(0)
+ , allocSize_(0)
+ {
+ resize(size, doClear);
+ }
+ AlignedArray(const AlignedArray& rhs)
+ : p_(0)
+ , size_(0)
+ , allocSize_(0)
+ {
+ *this = rhs;
+ }
+ AlignedArray& operator=(const AlignedArray& rhs)
+ {
+ if (allocSize_ < rhs.size_) {
+ allocCopy(rhs.size_, rhs.p_, rhs.size_);
+ } else {
+ copy(p_, rhs.p_, rhs.size_);
+ }
+ size_ = rhs.size_;
+ return *this;
+ }
+#if (CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11)
+ AlignedArray(AlignedArray&& rhs) CYBOZU_NOEXCEPT
+ : p_(rhs.p_)
+ , size_(rhs.size_)
+ , allocSize_(rhs.allocSize_)
+ {
+ rhs.p_ = 0;
+ rhs.size_ = 0;
+ rhs.allocSize_ = 0;
+ }
+ AlignedArray& operator=(AlignedArray&& rhs) CYBOZU_NOEXCEPT
+ {
+ swap(rhs);
+ rhs.clear();
+ return *this;
+ }
+#endif
+ /*
+ don't clear buffer with zero if doClear is false
+ @note don't free if shrinked
+ */
+ void resize(size_t size, bool doClear = defaultDoClear)
+ {
+ // shrink
+ if (size <= size_) {
+ size_ = size;
+ return;
+ }
+ // realloc if necessary
+ if (size > allocSize_) {
+ allocCopy(size, p_, size_);
+ }
+ if (doClear) setZero(p_ + size_, size - size_);
+ size_ = size;
+ }
+ void clear() // not free
+ {
+ size_ = 0;
+ }
+ ~AlignedArray()
+ {
+ AlignedFree(p_);
+ }
+ void swap(AlignedArray& rhs) CYBOZU_NOEXCEPT
+ {
+ std::swap(p_, rhs.p_);
+ std::swap(size_, rhs.size_);
+ std::swap(allocSize_, rhs.allocSize_);
+ }
+ T& operator[](size_t idx) CYBOZU_NOEXCEPT { return p_[idx]; }
+ const T& operator[](size_t idx) const CYBOZU_NOEXCEPT { return p_[idx]; }
+ size_t size() const CYBOZU_NOEXCEPT { return size_; }
+ bool empty() const CYBOZU_NOEXCEPT { return size_ == 0; }
+ T* begin() CYBOZU_NOEXCEPT { return p_; }
+ T* end() CYBOZU_NOEXCEPT { return p_ + size_; }
+ const T* begin() const CYBOZU_NOEXCEPT { return p_; }
+ const T* end() const CYBOZU_NOEXCEPT { return p_ + size_; }
+ T* data() CYBOZU_NOEXCEPT { return p_; }
+ const T* data() const CYBOZU_NOEXCEPT { return p_; }
+#if (CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11)
+ const T* cbegin() const CYBOZU_NOEXCEPT { return p_; }
+ const T* cend() const CYBOZU_NOEXCEPT { return p_ + size_; }
+#endif
+};
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/atoi.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/atoi.hpp
new file mode 100644
index 000000000..a22853a17
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/atoi.hpp
@@ -0,0 +1,239 @@
+#pragma once
+/**
+ @file
+ @brief converter between integer and string
+
+ @author MITSUNARI Shigeo(@herumi)
+*/
+
+#include <memory.h>
+#include <limits.h>
+#include <limits>
+#include <cybozu/exception.hpp>
+
+namespace cybozu {
+
+namespace atoi_local {
+
+template<typename T, size_t n>
+T convertToInt(bool *b, const char *p, size_t size, const char (&max)[n], T min, T overflow1, char overflow2)
+{
+ if (size > 0 && *p) {
+ bool isMinus = false;
+ size_t i = 0;
+ if (*p == '-') {
+ isMinus = true;
+ i++;
+ }
+ if (i < size && p[i]) {
+ // skip leading zero
+ while (i < size && p[i] == '0') i++;
+ // check minimum
+ if (isMinus && size - i >= n - 1 && memcmp(max, &p[i], n - 1) == 0) {
+ if (b) *b = true;
+ return min;
+ }
+ T x = 0;
+ for (;;) {
+ unsigned char c;
+ if (i == size || (c = static_cast<unsigned char>(p[i])) == '\0') {
+ if (b) *b = true;
+ return isMinus ? -x : x;
+ }
+ unsigned int y = c - '0';
+ if (y > 9 || x > overflow1 || (x == overflow1 && c >= overflow2)) {
+ break;
+ }
+ x = x * 10 + T(y);
+ i++;
+ }
+ }
+ }
+ if (b) {
+ *b = false;
+ return 0;
+ } else {
+ throw cybozu::Exception("atoi::convertToInt") << cybozu::exception::makeString(p, size);
+ }
+}
+
+template<typename T>
+T convertToUint(bool *b, const char *p, size_t size, T overflow1, char overflow2)
+{
+ if (size > 0 && *p) {
+ size_t i = 0;
+ // skip leading zero
+ while (i < size && p[i] == '0') i++;
+ T x = 0;
+ for (;;) {
+ unsigned char c;
+ if (i == size || (c = static_cast<unsigned char>(p[i])) == '\0') {
+ if (b) *b = true;
+ return x;
+ }
+ unsigned int y = c - '0';
+ if (y > 9 || x > overflow1 || (x == overflow1 && c >= overflow2)) {
+ break;
+ }
+ x = x * 10 + T(y);
+ i++;
+ }
+ }
+ if (b) {
+ *b = false;
+ return 0;
+ } else {
+ throw cybozu::Exception("atoi::convertToUint") << cybozu::exception::makeString(p, size);
+ }
+}
+
+template<typename T>
+T convertHexToInt(bool *b, const char *p, size_t size)
+{
+ if (size > 0 && *p) {
+ size_t i = 0;
+ T x = 0;
+ for (;;) {
+ unsigned int c;
+ if (i == size || (c = static_cast<unsigned char>(p[i])) == '\0') {
+ if (b) *b = true;
+ return x;
+ }
+ if (c - 'A' <= 'F' - 'A') {
+ c = (c - 'A') + 10;
+ } else if (c - 'a' <= 'f' - 'a') {
+ c = (c - 'a') + 10;
+ } else if (c - '0' <= '9' - '0') {
+ c = c - '0';
+ } else {
+ break;
+ }
+ // avoid overflow
+ if (x > (std::numeric_limits<T>::max)() / 16) break;
+ x = x * 16 + T(c);
+ i++;
+ }
+ }
+ if (b) {
+ *b = false;
+ return 0;
+ } else {
+ throw cybozu::Exception("atoi::convertHexToInt") << cybozu::exception::makeString(p, size);
+ }
+}
+
+} // atoi_local
+
+/**
+ auto detect return value class
+ @note if you set bool pointer p then throw nothing and set *p = false if bad string
+*/
+class atoi {
+ const char *p_;
+ size_t size_;
+ bool *b_;
+ void set(bool *b, const char *p, size_t size)
+ {
+ b_ = b;
+ p_ = p;
+ size_ = size;
+ }
+public:
+ atoi(const char *p, size_t size = -1)
+ {
+ set(0, p, size);
+ }
+ atoi(bool *b, const char *p, size_t size = -1)
+ {
+ set(b, p, size);
+ }
+ atoi(const std::string& str)
+ {
+ set(0, str.c_str(), str.size());
+ }
+ atoi(bool *b, const std::string& str)
+ {
+ set(b, str.c_str(), str.size());
+ }
+ inline operator signed char() const
+ {
+ return atoi_local::convertToInt<signed char>(b_, p_, size_, "128", -128, 12, '8');
+ }
+ inline operator unsigned char() const
+ {
+ return atoi_local::convertToUint<unsigned char>(b_, p_, size_, 25, '6');
+ }
+ inline operator short() const
+ {
+ return atoi_local::convertToInt<short>(b_, p_, size_, "32768", -32768, 3276, '8');
+ }
+ inline operator unsigned short() const
+ {
+ return atoi_local::convertToUint<unsigned short>(b_, p_, size_, 6553, '6');
+ }
+ inline operator int() const
+ {
+ return atoi_local::convertToInt<int>(b_, p_, size_, "2147483648", INT_MIN, 214748364, '8');
+ }
+ inline operator unsigned int() const
+ {
+ return atoi_local::convertToUint<unsigned int>(b_, p_, size_, 429496729, '6');
+ }
+ inline operator long long() const
+ {
+ return atoi_local::convertToInt<long long>(b_, p_, size_, "9223372036854775808", LLONG_MIN, 922337203685477580LL, '8');
+ }
+ inline operator unsigned long long() const
+ {
+ return atoi_local::convertToUint<unsigned long long>(b_, p_, size_, 1844674407370955161ULL, '6');
+ }
+#if defined(__SIZEOF_LONG__) && (__SIZEOF_LONG__ == 8)
+ inline operator long() const { return static_cast<long>(static_cast<long long>(*this)); }
+ inline operator unsigned long() const { return static_cast<unsigned long>(static_cast<unsigned long long>(*this)); }
+#else
+ inline operator long() const { return static_cast<long>(static_cast<int>(*this)); }
+ inline operator unsigned long() const { return static_cast<unsigned long>(static_cast<unsigned int>(*this)); }
+#endif
+};
+
+class hextoi {
+ const char *p_;
+ size_t size_;
+ bool *b_;
+ void set(bool *b, const char *p, size_t size)
+ {
+ b_ = b;
+ p_ = p;
+ size_ = size;
+ }
+public:
+ hextoi(const char *p, size_t size = -1)
+ {
+ set(0, p, size);
+ }
+ hextoi(bool *b, const char *p, size_t size = -1)
+ {
+ set(b, p, size);
+ }
+ hextoi(const std::string& str)
+ {
+ set(0, str.c_str(), str.size());
+ }
+ hextoi(bool *b, const std::string& str)
+ {
+ set(b, str.c_str(), str.size());
+ }
+ operator unsigned char() const { return atoi_local::convertHexToInt<unsigned char>(b_, p_, size_); }
+ operator unsigned short() const { return atoi_local::convertHexToInt<unsigned short>(b_, p_, size_); }
+ operator unsigned int() const { return atoi_local::convertHexToInt<unsigned int>(b_, p_, size_); }
+ operator unsigned long() const { return atoi_local::convertHexToInt<unsigned long>(b_, p_, size_); }
+ operator unsigned long long() const { return atoi_local::convertHexToInt<unsigned long long>(b_, p_, size_); }
+ operator char() const { return atoi_local::convertHexToInt<char>(b_, p_, size_); }
+ operator signed char() const { return atoi_local::convertHexToInt<signed char>(b_, p_, size_); }
+ operator short() const { return atoi_local::convertHexToInt<short>(b_, p_, size_); }
+ operator int() const { return atoi_local::convertHexToInt<int>(b_, p_, size_); }
+ operator long() const { return atoi_local::convertHexToInt<long>(b_, p_, size_); }
+ operator long long() const { return atoi_local::convertHexToInt<long long>(b_, p_, size_); }
+};
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/benchmark.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/benchmark.hpp
new file mode 100644
index 000000000..4c02f1869
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/benchmark.hpp
@@ -0,0 +1,212 @@
+#pragma once
+/**
+ @file
+ @brief measure exec time of function
+ @author MITSUNARI Shigeo
+*/
+#if defined(_MSC_VER) && (MSC_VER <= 1500)
+ #include <cybozu/inttype.hpp>
+#else
+ #include <stdint.h>
+#endif
+#include <stdio.h>
+
+#ifdef __EMSCRIPTEN__
+ #define CYBOZU_BENCH_USE_GETTIMEOFDAY
+#endif
+
+#ifdef CYBOZU_BENCH_USE_GETTIMEOFDAY
+ #include <sys/time.h>
+#elif !defined(CYBOZU_BENCH_DONT_USE_RDTSC)
+ #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__)
+ #define CYBOZU_BENCH_USE_RDTSC
+ #define CYBOZU_BENCH_USE_CPU_TIMER
+ #endif
+ #if defined(__GNUC__) && defined(__ARM_ARCH_7A__)
+// #define CYBOZU_BENCH_USE_MRC
+// #define CYBOZU_BENCH_USE_CPU_TIMER
+ #endif
+#endif
+
+
+#include <assert.h>
+#include <time.h>
+#ifdef _MSC_VER
+ #include <intrin.h>
+ #include <sys/timeb.h>
+#else
+#endif
+
+#ifndef CYBOZU_UNUSED
+ #ifdef __GNUC__
+ #define CYBOZU_UNUSED __attribute__((unused))
+ #else
+ #define CYBOZU_UNUSED
+ #endif
+#endif
+
+namespace cybozu {
+
+namespace bench {
+
+static void (*g_putCallback)(double);
+
+static inline void setPutCallback(void (*f)(double))
+{
+ g_putCallback = f;
+}
+
+} // cybozu::bench
+
+class CpuClock {
+public:
+ static inline uint64_t getCpuClk()
+ {
+#ifdef CYBOZU_BENCH_USE_RDTSC
+#ifdef _MSC_VER
+ return __rdtsc();
+#else
+ unsigned int eax, edx;
+ __asm__ volatile("rdtsc" : "=a"(eax), "=d"(edx));
+ return ((uint64_t)edx << 32) | eax;
+#endif
+#elif defined(CYBOZU_BENCH_USE_MRC)
+ uint32_t clk;
+ __asm__ volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(clk));
+ return clk;
+#else
+#ifdef _MSC_VER
+ struct _timeb timeb;
+ _ftime_s(&timeb);
+ return uint64_t(timeb.time) * 1000000000 + timeb.millitm * 1000000;
+#elif defined(CYBOZU_BENCH_USE_GETTIMEOFDAY)
+ struct timeval tv;
+ int ret CYBOZU_UNUSED = gettimeofday(&tv, 0);
+ assert(ret == 0);
+ return uint64_t(tv.tv_sec) * 1000000000 + tv.tv_usec * 1000;
+#else
+ struct timespec tp;
+ int ret CYBOZU_UNUSED = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
+ assert(ret == 0);
+ return uint64_t(tp.tv_sec) * 1000000000 + tp.tv_nsec;
+#endif
+#endif
+ }
+ CpuClock()
+ : clock_(0)
+ , count_(0)
+ {
+ }
+ void begin()
+ {
+ clock_ -= getCpuClk();
+ }
+ void end()
+ {
+ clock_ += getCpuClk();
+ count_++;
+ }
+ int getCount() const { return count_; }
+ uint64_t getClock() const { return clock_; }
+ void clear() { count_ = 0; clock_ = 0; }
+ void put(const char *msg = 0, int N = 1) const
+ {
+ double t = getClock() / double(getCount()) / N;
+ if (msg && *msg) printf("%s ", msg);
+ if (bench::g_putCallback) {
+ bench::g_putCallback(t);
+ return;
+ }
+#ifdef CYBOZU_BENCH_USE_CPU_TIMER
+ if (t > 1e6) {
+ printf("%7.3fMclk", t * 1e-6);
+ } else if (t > 1e3) {
+ printf("%7.3fKclk", t * 1e-3);
+ } else {
+ printf("%6.2f clk", t);
+ }
+#else
+ if (t > 1e6) {
+ printf("%7.3fmsec", t * 1e-6);
+ } else if (t > 1e3) {
+ printf("%7.3fusec", t * 1e-3);
+ } else {
+ printf("%6.2fnsec", t);
+ }
+#endif
+ if (msg && *msg) printf("\n");
+ }
+ // adhoc constatns for CYBOZU_BENCH
+#ifdef CYBOZU_BENCH_USE_CPU_TIMER
+ static const int loopN1 = 1000;
+ static const int loopN2 = 100;
+ static const uint64_t maxClk = (uint64_t)1e8;
+#else
+ static const int loopN1 = 100;
+ static const int loopN2 = 100;
+ static const uint64_t maxClk = (uint64_t)1e8;
+#endif
+private:
+ uint64_t clock_;
+ int count_;
+};
+
+namespace bench {
+
+static CpuClock g_clk;
+static int CYBOZU_UNUSED g_loopNum;
+
+} // cybozu::bench
+/*
+ loop counter is automatically determined
+ CYBOZU_BENCH(<msg>, <func>, <param1>, <param2>, ...);
+ if msg == "" then only set g_clk, g_loopNum
+*/
+#define CYBOZU_BENCH(msg, func, ...) \
+{ \
+ const uint64_t _cybozu_maxClk = cybozu::CpuClock::maxClk; \
+ cybozu::CpuClock _cybozu_clk; \
+ for (int _cybozu_i = 0; _cybozu_i < cybozu::CpuClock::loopN2; _cybozu_i++) { \
+ _cybozu_clk.begin(); \
+ for (int _cybozu_j = 0; _cybozu_j < cybozu::CpuClock::loopN1; _cybozu_j++) { func(__VA_ARGS__); } \
+ _cybozu_clk.end(); \
+ if (_cybozu_clk.getClock() > _cybozu_maxClk) break; \
+ } \
+ if (msg && *msg) _cybozu_clk.put(msg, cybozu::CpuClock::loopN1); \
+ cybozu::bench::g_clk = _cybozu_clk; cybozu::bench::g_loopNum = cybozu::CpuClock::loopN1; \
+}
+
+/*
+ double clk;
+ CYBOZU_BENCH_T(clk, <func>, <param1>, <param2>, ...);
+ clk is set by CYBOZU_BENCH_T
+*/
+#define CYBOZU_BENCH_T(clk, func, ...) \
+{ \
+ const uint64_t _cybozu_maxClk = cybozu::CpuClock::maxClk; \
+ cybozu::CpuClock _cybozu_clk; \
+ for (int _cybozu_i = 0; _cybozu_i < cybozu::CpuClock::loopN2; _cybozu_i++) { \
+ _cybozu_clk.begin(); \
+ for (int _cybozu_j = 0; _cybozu_j < cybozu::CpuClock::loopN1; _cybozu_j++) { func(__VA_ARGS__); } \
+ _cybozu_clk.end(); \
+ if (_cybozu_clk.getClock() > _cybozu_maxClk) break; \
+ } \
+ clk = _cybozu_clk.getClock() / (double)_cybozu_clk.getCount() / cybozu::CpuClock::loopN1; \
+}
+
+/*
+ loop counter N is given
+ CYBOZU_BENCH_C(<msg>, <counter>, <func>, <param1>, <param2>, ...);
+ if msg == "" then only set g_clk, g_loopNum
+*/
+#define CYBOZU_BENCH_C(msg, _N, func, ...) \
+{ \
+ cybozu::CpuClock _cybozu_clk; \
+ _cybozu_clk.begin(); \
+ for (int _cybozu_j = 0; _cybozu_j < _N; _cybozu_j++) { func(__VA_ARGS__); } \
+ _cybozu_clk.end(); \
+ if (msg && *msg) _cybozu_clk.put(msg, _N); \
+ cybozu::bench::g_clk = _cybozu_clk; cybozu::bench::g_loopNum = _N; \
+}
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/bit_operation.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/bit_operation.hpp
new file mode 100644
index 000000000..865c1e47d
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/bit_operation.hpp
@@ -0,0 +1,139 @@
+#pragma once
+/**
+ @file
+ @brief bit operation
+*/
+#include <assert.h>
+#include <cybozu/inttype.hpp>
+
+#if (CYBOZU_HOST == CYBOZU_HOST_INTEL)
+ #if defined(_WIN32)
+ #include <intrin.h>
+ #elif defined(__linux__) || defined(__CYGWIN__) || defined(__clang__)
+ #include <x86intrin.h>
+ #elif defined(__GNUC__)
+ #include <emmintrin.h>
+ #endif
+#endif
+
+namespace cybozu {
+
+namespace bit_op_local {
+
+template<bool equalTo8>
+struct Tag {};
+
+// sizeof(T) < 8
+template<>
+struct Tag<false> {
+ template<class T>
+ static inline int bsf(T x)
+ {
+#if defined(_MSC_VER)
+ unsigned long out;
+ _BitScanForward(&out, x);
+#pragma warning(suppress: 6102)
+ return out;
+#else
+ return __builtin_ctz(x);
+#endif
+ }
+ template<class T>
+ static inline int bsr(T x)
+ {
+#if defined(_MSC_VER)
+ unsigned long out;
+ _BitScanReverse(&out, x);
+#pragma warning(suppress: 6102)
+ return out;
+#else
+ return __builtin_clz(x) ^ 0x1f;
+#endif
+ }
+};
+
+// sizeof(T) == 8
+template<>
+struct Tag<true> {
+ template<class T>
+ static inline int bsf(T x)
+ {
+#if defined(_MSC_VER) && defined(_WIN64)
+ unsigned long out;
+ _BitScanForward64(&out, x);
+#pragma warning(suppress: 6102)
+ return out;
+#elif defined(__x86_64__)
+ return __builtin_ctzll(x);
+#else
+ const uint32_t L = uint32_t(x);
+ if (L) return Tag<false>::bsf(L);
+ const uint32_t H = uint32_t(x >> 32);
+ return Tag<false>::bsf(H) + 32;
+#endif
+ }
+ template<class T>
+ static inline int bsr(T x)
+ {
+#if defined(_MSC_VER) && defined(_WIN64)
+ unsigned long out;
+ _BitScanReverse64(&out, x);
+#pragma warning(suppress: 6102)
+ return out;
+#elif defined(__x86_64__)
+ return __builtin_clzll(x) ^ 0x3f;
+#else
+ const uint32_t H = uint32_t(x >> 32);
+ if (H) return Tag<false>::bsr(H) + 32;
+ const uint32_t L = uint32_t(x);
+ return Tag<false>::bsr(L);
+#endif
+ }
+};
+
+} // bit_op_local
+
+template<class T>
+int bsf(T x)
+{
+ return bit_op_local::Tag<sizeof(T) == 8>::bsf(x);
+}
+template<class T>
+int bsr(T x)
+{
+ return bit_op_local::Tag<sizeof(T) == 8>::bsr(x);
+}
+
+template<class T>
+uint64_t makeBitMask64(T x)
+{
+ assert(x < 64);
+ return (uint64_t(1) << x) - 1;
+}
+
+template<class T>
+uint32_t popcnt(T x);
+
+template<>
+inline uint32_t popcnt<uint32_t>(uint32_t x)
+{
+#if defined(_MSC_VER)
+ return static_cast<uint32_t>(_mm_popcnt_u32(x));
+#else
+ return static_cast<uint32_t>(__builtin_popcount(x));
+#endif
+}
+
+template<>
+inline uint32_t popcnt<uint64_t>(uint64_t x)
+{
+#if defined(__x86_64__)
+ return static_cast<uint32_t>(__builtin_popcountll(x));
+#elif defined(_WIN64)
+ return static_cast<uint32_t>(_mm_popcnt_u64(x));
+#else
+ return popcnt<uint32_t>(static_cast<uint32_t>(x)) + popcnt<uint32_t>(static_cast<uint32_t>(x >> 32));
+#endif
+}
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/critical_section.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/critical_section.hpp
new file mode 100644
index 000000000..13d7f3a0e
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/critical_section.hpp
@@ -0,0 +1,60 @@
+#pragma once
+/**
+ @file
+ @brief critical section
+
+ @author MITSUNARI Shigeo(@herumi)
+ @author MITSUNARI Shigeo
+*/
+#include <cybozu/mutex.hpp>
+
+namespace cybozu {
+
+class ConditionVariableCs;
+
+namespace thread {
+
+#ifdef _WIN32
+typedef CRITICAL_SECTION CsHandle;
+inline void CsInit(CsHandle& cs) { InitializeCriticalSection(&cs); }
+inline void CsLock(CsHandle& cs) { EnterCriticalSection(&cs); }
+inline void CsUnlock(CsHandle& cs) { LeaveCriticalSection(&cs); }
+inline void CsTerm(CsHandle& cs) { DeleteCriticalSection(&cs); }
+#else
+typedef pthread_mutex_t CsHandle;
+inline void CsInit(CsHandle& cs) { pthread_mutex_init(&cs, NULL); }
+inline void CsLock(CsHandle& cs) { pthread_mutex_lock(&cs); }
+inline void CsUnlock(CsHandle& cs) { pthread_mutex_unlock(&cs); }
+inline void CsTerm(CsHandle& cs) { pthread_mutex_destroy(&cs); }
+#endif
+
+} // cybozu::thread
+
+class CriticalSection {
+ friend class cybozu::ConditionVariableCs;
+public:
+ CriticalSection()
+ {
+ thread::CsInit(hdl_);
+ }
+ ~CriticalSection()
+ {
+ thread::CsTerm(hdl_);
+ }
+ inline void lock()
+ {
+ thread::CsLock(hdl_);
+ }
+ inline void unlock()
+ {
+ thread::CsUnlock(hdl_);
+ }
+private:
+ CriticalSection(const CriticalSection&);
+ CriticalSection& operator=(const CriticalSection&);
+ thread::CsHandle hdl_;
+};
+
+typedef cybozu::thread::AutoLockT<cybozu::CriticalSection> AutoLockCs; //!< auto lock critical section
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/crypto.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/crypto.hpp
new file mode 100644
index 000000000..d427179d9
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/crypto.hpp
@@ -0,0 +1,321 @@
+#pragma once
+/**
+ @file
+ @brief wrap openssl
+ @author MITSUNARI Shigeo(@herumi)
+*/
+
+#include <cybozu/exception.hpp>
+#ifdef __APPLE__
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#endif
+#if 0 //#ifdef __APPLE__
+ #define COMMON_DIGEST_FOR_OPENSSL
+ #include <CommonCrypto/CommonDigest.h>
+ #include <CommonCrypto/CommonHMAC.h>
+ #define SHA1 CC_SHA1
+ #define SHA224 CC_SHA224
+ #define SHA256 CC_SHA256
+ #define SHA384 CC_SHA384
+ #define SHA512 CC_SHA512
+#else
+#include <openssl/hmac.h>
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+#endif
+#ifdef _MSC_VER
+ #include <cybozu/link_libeay32.hpp>
+#endif
+
+namespace cybozu {
+
+namespace crypto {
+
+class Hash {
+public:
+ enum Name {
+ N_SHA1,
+ N_SHA224,
+ N_SHA256,
+ N_SHA384,
+ N_SHA512
+ };
+private:
+ Name name_;
+ size_t hashSize_;
+ union {
+ SHA_CTX sha1;
+ SHA256_CTX sha256;
+ SHA512_CTX sha512;
+ } ctx_;
+public:
+ static inline size_t getSize(Name name)
+ {
+ switch (name) {
+ case N_SHA1: return SHA_DIGEST_LENGTH;
+ case N_SHA224: return SHA224_DIGEST_LENGTH;
+ case N_SHA256: return SHA256_DIGEST_LENGTH;
+ case N_SHA384: return SHA384_DIGEST_LENGTH;
+ case N_SHA512: return SHA512_DIGEST_LENGTH;
+ default:
+ throw cybozu::Exception("crypto:Hash:getSize") << name;
+ }
+ }
+ static inline const char *getName(Name name)
+ {
+ switch (name) {
+ case N_SHA1: return "sha1";
+ case N_SHA224: return "sha224";
+ case N_SHA256: return "sha256";
+ case N_SHA384: return "sha384";
+ case N_SHA512: return "sha512";
+ default:
+ throw cybozu::Exception("crypto:Hash:getName") << name;
+ }
+ }
+ static inline Name getName(const std::string& nameStr)
+ {
+ static const struct {
+ const char *nameStr;
+ Name name;
+ } tbl[] = {
+ { "sha1", N_SHA1 },
+ { "sha224", N_SHA224 },
+ { "sha256", N_SHA256 },
+ { "sha384", N_SHA384 },
+ { "sha512", N_SHA512 },
+ };
+ for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) {
+ if (nameStr == tbl[i].nameStr) return tbl[i].name;
+ }
+ throw cybozu::Exception("crypto:Hash:getName") << nameStr;
+ }
+ explicit Hash(Name name = N_SHA1)
+ : name_(name)
+ , hashSize_(getSize(name))
+ {
+ reset();
+ }
+ void update(const void *buf, size_t bufSize)
+ {
+ switch (name_) {
+ case N_SHA1: SHA1_Update(&ctx_.sha1, buf, bufSize); break;
+ case N_SHA224: SHA224_Update(&ctx_.sha256, buf, bufSize); break;
+ case N_SHA256: SHA256_Update(&ctx_.sha256, buf, bufSize); break;
+ case N_SHA384: SHA384_Update(&ctx_.sha512, buf, bufSize); break;
+ case N_SHA512: SHA512_Update(&ctx_.sha512, buf, bufSize); break;
+ }
+ }
+ void update(const std::string& buf)
+ {
+ update(buf.c_str(), buf.size());
+ }
+ void reset()
+ {
+ switch (name_) {
+ case N_SHA1: SHA1_Init(&ctx_.sha1); break;
+ case N_SHA224: SHA224_Init(&ctx_.sha256); break;
+ case N_SHA256: SHA256_Init(&ctx_.sha256); break;
+ case N_SHA384: SHA384_Init(&ctx_.sha512); break;
+ case N_SHA512: SHA512_Init(&ctx_.sha512); break;
+ default:
+ throw cybozu::Exception("crypto:Hash:rset") << name_;
+ }
+ }
+ /*
+ md must have hashSize byte
+ @note clear inner buffer after calling digest
+ */
+ void digest(void *out, const void *buf, size_t bufSize)
+ {
+ update(buf, bufSize);
+ unsigned char *md = reinterpret_cast<unsigned char*>(out);
+ switch (name_) {
+ case N_SHA1: SHA1_Final(md, &ctx_.sha1); break;
+ case N_SHA224: SHA224_Final(md, &ctx_.sha256); break;
+ case N_SHA256: SHA256_Final(md, &ctx_.sha256); break;
+ case N_SHA384: SHA384_Final(md, &ctx_.sha512); break;
+ case N_SHA512: SHA512_Final(md, &ctx_.sha512); break;
+ default:
+ throw cybozu::Exception("crypto:Hash:digest") << name_;
+ }
+ reset();
+ }
+ std::string digest(const void *buf, size_t bufSize)
+ {
+ std::string ret;
+ ret.resize(hashSize_);
+ digest(&ret[0], buf, bufSize);
+ return ret;
+ }
+ std::string digest(const std::string& buf = "")
+ {
+ return digest(buf.c_str(), buf.size());
+ }
+ /*
+ out must have necessary size
+ @note return written size
+ */
+ static inline size_t digest(void *out, Name name, const void *buf, size_t bufSize)
+ {
+ unsigned char *md = (unsigned char*)out;
+ const unsigned char *src = cybozu::cast<const unsigned char *>(buf);
+ switch (name) {
+ case N_SHA1: SHA1(src, bufSize, md); return 160 / 8;
+ case N_SHA224: SHA224(src, bufSize, md); return 224 / 8;
+ case N_SHA256: SHA256(src, bufSize, md); return 256 / 8;
+ case N_SHA384: SHA384(src, bufSize, md); return 384 / 8;
+ case N_SHA512: SHA512(src, bufSize, md); return 512 / 8;
+ default:
+ return 0;
+ }
+ }
+ static inline std::string digest(Name name, const void *buf, size_t bufSize)
+ {
+ char md[128];
+ size_t size = digest(md, name, buf, bufSize);
+ if (size == 0) throw cybozu::Exception("crypt:Hash:digest") << name;
+ return std::string(md, size);
+ }
+ static inline std::string digest(Name name, const std::string& buf)
+ {
+ return digest(name, buf.c_str(), buf.size());
+ }
+};
+
+class Hmac {
+ const EVP_MD *evp_;
+public:
+ explicit Hmac(Hash::Name name = Hash::N_SHA1)
+ {
+ switch (name) {
+ case Hash::N_SHA1: evp_ = EVP_sha1(); break;
+ case Hash::N_SHA224: evp_ = EVP_sha224(); break;
+ case Hash::N_SHA256: evp_ = EVP_sha256(); break;
+ case Hash::N_SHA384: evp_ = EVP_sha384(); break;
+ case Hash::N_SHA512: evp_ = EVP_sha512(); break;
+ default:
+ throw cybozu::Exception("crypto:Hmac:") << name;
+ }
+ }
+ std::string eval(const std::string& key, const std::string& data)
+ {
+ std::string out(EVP_MD_size(evp_) + 1, 0);
+ unsigned int outLen = 0;
+ if (HMAC(evp_, key.c_str(), static_cast<int>(key.size()),
+ cybozu::cast<const uint8_t *>(data.c_str()), data.size(), cybozu::cast<uint8_t *>(&out[0]), &outLen)) {
+ out.resize(outLen);
+ return out;
+ }
+ throw cybozu::Exception("crypto::Hamc::eval");
+ }
+};
+
+class Cipher {
+ const EVP_CIPHER *cipher_;
+ EVP_CIPHER_CTX *ctx_;
+public:
+ enum Name {
+ N_AES128_CBC,
+ N_AES192_CBC,
+ N_AES256_CBC,
+ N_AES128_ECB, // be carefull to use
+ N_AES192_ECB, // be carefull to use
+ N_AES256_ECB, // be carefull to use
+ };
+ static inline size_t getSize(Name name)
+ {
+ switch (name) {
+ case N_AES128_CBC: return 128;
+ case N_AES192_CBC: return 192;
+ case N_AES256_CBC: return 256;
+ case N_AES128_ECB: return 128;
+ case N_AES192_ECB: return 192;
+ case N_AES256_ECB: return 256;
+ default:
+ throw cybozu::Exception("crypto:Cipher:getSize") << name;
+ }
+ }
+ enum Mode {
+ Decoding,
+ Encoding
+ };
+ explicit Cipher(Name name = N_AES128_CBC)
+ : cipher_(0)
+ , ctx_(0)
+ {
+ ctx_ = EVP_CIPHER_CTX_new();
+ if (ctx_ == 0) throw cybozu::Exception("crypto:Cipher:EVP_CIPHER_CTX_new");
+ switch (name) {
+ case N_AES128_CBC: cipher_ = EVP_aes_128_cbc(); break;
+ case N_AES192_CBC: cipher_ = EVP_aes_192_cbc(); break;
+ case N_AES256_CBC: cipher_ = EVP_aes_256_cbc(); break;
+ case N_AES128_ECB: cipher_ = EVP_aes_128_ecb(); break;
+ case N_AES192_ECB: cipher_ = EVP_aes_192_ecb(); break;
+ case N_AES256_ECB: cipher_ = EVP_aes_256_ecb(); break;
+ default:
+ throw cybozu::Exception("crypto:Cipher:Cipher:name") << (int)name;
+ }
+ }
+ ~Cipher()
+ {
+ if (ctx_) EVP_CIPHER_CTX_free(ctx_);
+ }
+ /*
+ @note don't use padding = true
+ */
+ void setup(Mode mode, const std::string& key, const std::string& iv, bool padding = false)
+ {
+ const int keyLen = static_cast<int>(key.size());
+ const int expectedKeyLen = EVP_CIPHER_key_length(cipher_);
+ if (keyLen != expectedKeyLen) {
+ throw cybozu::Exception("crypto:Cipher:setup:keyLen") << keyLen << expectedKeyLen;
+ }
+
+ int ret = EVP_CipherInit_ex(ctx_, cipher_, NULL, cybozu::cast<const uint8_t*>(key.c_str()), cybozu::cast<const uint8_t*>(iv.c_str()), mode == Encoding ? 1 : 0);
+ if (ret != 1) {
+ throw cybozu::Exception("crypto:Cipher:setup:EVP_CipherInit_ex") << ret;
+ }
+ ret = EVP_CIPHER_CTX_set_padding(ctx_, padding ? 1 : 0);
+ if (ret != 1) {
+ throw cybozu::Exception("crypto:Cipher:setup:EVP_CIPHER_CTX_set_padding") << ret;
+ }
+/*
+ const int ivLen = static_cast<int>(iv.size());
+ const int expectedIvLen = EVP_CIPHER_CTX_iv_length(&ctx_);
+ if (ivLen != expectedIvLen) {
+ throw cybozu::Exception("crypto:Cipher:setup:ivLen") << ivLen << expectedIvLen;
+ }
+*/
+ }
+ /*
+ the size of outBuf must be larger than inBufSize + blockSize
+ @retval positive or 0 : writeSize(+blockSize)
+ @retval -1 : error
+ */
+ int update(char *outBuf, const char *inBuf, int inBufSize)
+ {
+ int outLen = 0;
+ int ret = EVP_CipherUpdate(ctx_, cybozu::cast<uint8_t*>(outBuf), &outLen, cybozu::cast<const uint8_t*>(inBuf), inBufSize);
+ if (ret != 1) return -1;
+ return outLen;
+ }
+ /*
+ return -1 if padding
+ @note don't use
+ */
+ int finalize(char *outBuf)
+ {
+ int outLen = 0;
+ int ret = EVP_CipherFinal_ex(ctx_, cybozu::cast<uint8_t*>(outBuf), &outLen);
+ if (ret != 1) return -1;
+ return outLen;
+ }
+};
+
+} } // cybozu::crypto
+
+#ifdef __APPLE__
+ #pragma GCC diagnostic pop
+#endif
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/endian.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/endian.hpp
new file mode 100644
index 000000000..3f1575c46
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/endian.hpp
@@ -0,0 +1,224 @@
+#pragma once
+
+/**
+ @file
+ @brief deal with big and little endian
+
+ @author MITSUNARI Shigeo(@herumi)
+*/
+#include <cybozu/inttype.hpp>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+namespace cybozu {
+
+#ifdef _MSC_VER
+inline uint16_t byteSwap(uint16_t x) { return _byteswap_ushort(x); }
+inline uint32_t byteSwap(uint32_t x) { return _byteswap_ulong(x); }
+inline uint64_t byteSwap(uint64_t x) { return _byteswap_uint64(x); }
+#else
+#if (((__GNUC__) << 16) + (__GNUC_MINOR__)) >= ((4 << 16) + 8)
+inline uint16_t byteSwap(uint16_t x) { return __builtin_bswap16(x); }
+#else
+inline uint16_t byteSwap(uint16_t x) { return (x >> 8) | (x << 8); }
+#endif
+inline uint32_t byteSwap(uint32_t x) { return __builtin_bswap32(x); }
+inline uint64_t byteSwap(uint64_t x) { return __builtin_bswap64(x); }
+#endif
+
+/**
+ get 16bit integer as little endian
+ @param src [in] pointer
+*/
+inline uint16_t Get16bitAsLE(const void *src)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ uint16_t x;
+ memcpy(&x, src, sizeof(x));
+ return x;
+#else
+ const uint8_t *p = static_cast<const uint8_t *>(src);
+ return p[0] | (p[1] << 8);
+#endif
+}
+
+/**
+ get 32bit integer as little endian
+ @param src [in] pointer
+*/
+inline uint32_t Get32bitAsLE(const void *src)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ uint32_t x;
+ memcpy(&x, src, sizeof(x));
+ return x;
+#else
+ const uint8_t *p = static_cast<const uint8_t *>(src);
+ return Get16bitAsLE(p) | (static_cast<uint32_t>(Get16bitAsLE(p + 2)) << 16);
+#endif
+}
+
+/**
+ get 64bit integer as little endian
+ @param src [in] pointer
+*/
+inline uint64_t Get64bitAsLE(const void *src)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ uint64_t x;
+ memcpy(&x, src, sizeof(x));
+ return x;
+#else
+ const uint8_t *p = static_cast<const uint8_t *>(src);
+ return Get32bitAsLE(p) | (static_cast<uint64_t>(Get32bitAsLE(p + 4)) << 32);
+#endif
+}
+
+/**
+ get 16bit integer as bit endian
+ @param src [in] pointer
+*/
+inline uint16_t Get16bitAsBE(const void *src)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ uint16_t x;
+ memcpy(&x, src, sizeof(x));
+ return byteSwap(x);
+#else
+ const uint8_t *p = static_cast<const uint8_t *>(src);
+ return p[1] | (p[0] << 8);
+#endif
+}
+
+/**
+ get 32bit integer as bit endian
+ @param src [in] pointer
+*/
+inline uint32_t Get32bitAsBE(const void *src)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ uint32_t x;
+ memcpy(&x, src, sizeof(x));
+ return byteSwap(x);
+#else
+ const uint8_t *p = static_cast<const uint8_t *>(src);
+ return Get16bitAsBE(p + 2) | (static_cast<uint32_t>(Get16bitAsBE(p)) << 16);
+#endif
+}
+
+/**
+ get 64bit integer as big endian
+ @param src [in] pointer
+*/
+inline uint64_t Get64bitAsBE(const void *src)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ uint64_t x;
+ memcpy(&x, src, sizeof(x));
+ return byteSwap(x);
+#else
+ const uint8_t *p = static_cast<const uint8_t *>(src);
+ return Get32bitAsBE(p + 4) | (static_cast<uint64_t>(Get32bitAsBE(p)) << 32);
+#endif
+}
+
+/**
+ set 16bit integer as little endian
+ @param src [out] pointer
+ @param x [in] integer
+*/
+inline void Set16bitAsLE(void *src, uint16_t x)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ memcpy(src, &x, sizeof(x));
+#else
+ uint8_t *p = static_cast<uint8_t *>(src);
+ p[0] = static_cast<uint8_t>(x);
+ p[1] = static_cast<uint8_t>(x >> 8);
+#endif
+}
+/**
+ set 32bit integer as little endian
+ @param src [out] pointer
+ @param x [in] integer
+*/
+inline void Set32bitAsLE(void *src, uint32_t x)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ memcpy(src, &x, sizeof(x));
+#else
+ uint8_t *p = static_cast<uint8_t *>(src);
+ p[0] = static_cast<uint8_t>(x);
+ p[1] = static_cast<uint8_t>(x >> 8);
+ p[2] = static_cast<uint8_t>(x >> 16);
+ p[3] = static_cast<uint8_t>(x >> 24);
+#endif
+}
+/**
+ set 64bit integer as little endian
+ @param src [out] pointer
+ @param x [in] integer
+*/
+inline void Set64bitAsLE(void *src, uint64_t x)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ memcpy(src, &x, sizeof(x));
+#else
+ uint8_t *p = static_cast<uint8_t *>(src);
+ Set32bitAsLE(p, static_cast<uint32_t>(x));
+ Set32bitAsLE(p + 4, static_cast<uint32_t>(x >> 32));
+#endif
+}
+/**
+ set 16bit integer as big endian
+ @param src [out] pointer
+ @param x [in] integer
+*/
+inline void Set16bitAsBE(void *src, uint16_t x)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ x = byteSwap(x);
+ memcpy(src, &x, sizeof(x));
+#else
+ uint8_t *p = static_cast<uint8_t *>(src);
+ p[0] = static_cast<uint8_t>(x >> 8);
+ p[1] = static_cast<uint8_t>(x);
+#endif
+}
+/**
+ set 32bit integer as big endian
+ @param src [out] pointer
+ @param x [in] integer
+*/
+inline void Set32bitAsBE(void *src, uint32_t x)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ x = byteSwap(x);
+ memcpy(src, &x, sizeof(x));
+#else
+ uint8_t *p = static_cast<uint8_t *>(src);
+ p[0] = static_cast<uint8_t>(x >> 24);
+ p[1] = static_cast<uint8_t>(x >> 16);
+ p[2] = static_cast<uint8_t>(x >> 8);
+ p[3] = static_cast<uint8_t>(x);
+#endif
+}
+/**
+ set 64bit integer as big endian
+ @param src [out] pointer
+ @param x [in] integer
+*/
+inline void Set64bitAsBE(void *src, uint64_t x)
+{
+#if CYBOZU_ENDIAN == CYBOZU_ENDIAN_LITTLE
+ x = byteSwap(x);
+ memcpy(src, &x, sizeof(x));
+#else
+ uint8_t *p = static_cast<uint8_t *>(src);
+ Set32bitAsBE(p, static_cast<uint32_t>(x >> 32));
+ Set32bitAsBE(p + 4, static_cast<uint32_t>(x));
+#endif
+}
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/exception.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/exception.hpp
new file mode 100644
index 000000000..247ba4de0
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/exception.hpp
@@ -0,0 +1,252 @@
+#pragma once
+/**
+ @file
+ @brief definition of abstruct exception class
+ @author MITSUNARI Shigeo(@herumi)
+*/
+#ifdef CYBOZU_MINIMUM_EXCEPTION
+
+#include <cybozu/inttype.hpp>
+
+namespace cybozu {
+
+namespace exception {
+inline const char *makeString(const char *, size_t)
+{
+ return "";
+}
+
+} // cybozu::exception
+
+class Exception {
+public:
+ explicit Exception(const char* = 0, bool = true)
+ {
+ }
+ ~Exception() CYBOZU_NOEXCEPT {}
+ const char *what() const CYBOZU_NOEXCEPT { return "cybozu:Exception"; }
+ template<class T>
+ Exception& operator<<(const T&)
+ {
+ return *this;
+ }
+};
+
+} // cybozu
+
+#else
+
+#include <string>
+#include <algorithm>
+#include <sstream>
+#include <errno.h>
+#include <stdio.h>
+#ifdef _WIN32
+ #include <winsock2.h>
+ #include <windows.h>
+#else
+ #include <string.h> // for strerror_r
+#endif
+#include <cybozu/inttype.hpp>
+#ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE
+ #include <cybozu/stacktrace.hpp>
+#endif
+
+namespace cybozu {
+
+const bool DontThrow = true;
+
+namespace exception {
+
+/* get max 16 characters to avoid buffer overrun */
+inline std::string makeString(const char *str, size_t size)
+{
+ return std::string(str, std::min<size_t>(size, 16));
+}
+
+#ifdef _WIN32
+inline std::string wstr2str(const std::wstring& wstr)
+{
+ std::string str;
+ for (size_t i = 0; i < wstr.size(); i++) {
+ uint16_t c = wstr[i];
+ if (c < 0x80) {
+ str += char(c);
+ } else {
+ char buf[16];
+ CYBOZU_SNPRINTF(buf, sizeof(buf), "\\u%04x", c);
+ str += buf;
+ }
+ }
+ return str;
+}
+#endif
+
+} // cybozu::exception
+
+/**
+ convert errno to string
+ @param err [in] errno
+ @note for both windows and linux
+*/
+inline std::string ConvertErrorNoToString(int err)
+{
+ char errBuf[256];
+ std::string ret;
+#ifdef _WIN32
+ if (strerror_s(errBuf, sizeof(errBuf), err) == 0) {
+ ret = errBuf;
+ } else {
+ ret = "err";
+ }
+#elif defined(_GNU_SOURCE)
+ ret = ::strerror_r(err, errBuf, sizeof(errBuf));
+#else
+ if (strerror_r(err, errBuf, sizeof(errBuf)) == 0) {
+ ret = errBuf;
+ } else {
+ ret = "err";
+ }
+#endif
+ char buf2[64];
+ CYBOZU_SNPRINTF(buf2, sizeof(buf2), "(%d)", err);
+ ret += buf2;
+ return ret;
+}
+
+class Exception : public std::exception {
+ mutable std::string str_;
+#ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE
+ mutable std::string stackTrace_;
+#endif
+public:
+ explicit Exception(const std::string& name = "", bool enableStackTrace = true)
+ : str_(name)
+ {
+#ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE
+ if (enableStackTrace) stackTrace_ = cybozu::StackTrace().toString();
+#else
+ cybozu::disable_warning_unused_variable(enableStackTrace);
+#endif
+ }
+ ~Exception() CYBOZU_NOEXCEPT {}
+ const char *what() const CYBOZU_NOEXCEPT { return toString().c_str(); }
+ const std::string& toString() const CYBOZU_NOEXCEPT
+ {
+#ifdef CYBOZU_EXCEPTION_WITH_STACKTRACE
+ try {
+ if (!stackTrace_.empty()) {
+#ifdef CYBOZU_STACKTRACE_ONELINE
+ str_ += "\n<<<STACKTRACE>>> ";
+ str_ += stackTrace_;
+#else
+ str_ += "\n<<<STACKTRACE\n";
+ str_ += stackTrace_;
+ str_ += "\n>>>STACKTRACE";
+#endif
+ }
+ } catch (...) {
+ }
+ stackTrace_.clear();
+#endif
+ return str_;
+ }
+ Exception& operator<<(const char *s)
+ {
+ str_ += ':';
+ str_ += s;
+ return *this;
+ }
+ Exception& operator<<(const std::string& s)
+ {
+ return operator<<(s.c_str());
+ }
+#ifdef _WIN32
+ Exception& operator<<(const std::wstring& s)
+ {
+ return operator<<(cybozu::exception::wstr2str(s));
+ }
+#endif
+ template<class T>
+ Exception& operator<<(const T& x)
+ {
+ std::ostringstream os;
+ os << x;
+ return operator<<(os.str());
+ }
+};
+
+class ErrorNo {
+public:
+#ifdef _WIN32
+ typedef unsigned int NativeErrorNo;
+#else
+ typedef int NativeErrorNo;
+#endif
+ explicit ErrorNo(NativeErrorNo err)
+ : err_(err)
+ {
+ }
+ ErrorNo()
+ : err_(getLatestNativeErrorNo())
+ {
+ }
+ NativeErrorNo getLatestNativeErrorNo() const
+ {
+#ifdef _WIN32
+ return ::GetLastError();
+#else
+ return errno;
+#endif
+ }
+ /**
+ convert NativeErrNo to string(maybe UTF8)
+ @param err [in] errno
+ @note Linux : same as ConvertErrorNoToString
+ Windows : for Win32 API(use en-us)
+ */
+ std::string toString() const
+ {
+#ifdef _WIN32
+ const int msgSize = 256;
+ wchar_t msg[msgSize];
+ int size = FormatMessageW(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ 0,
+ err_,
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+ msg,
+ msgSize,
+ NULL
+ );
+ if (size <= 0) return "";
+ // remove last "\r\n"
+ if (size > 2 && msg[size - 2] == '\r') {
+ msg[size - 2] = 0;
+ size -= 2;
+ }
+ std::string ret;
+ ret.resize(size);
+ // assume ascii only
+ for (int i = 0; i < size; i++) {
+ ret[i] = (char)msg[i];
+ }
+ char buf2[64];
+ CYBOZU_SNPRINTF(buf2, sizeof(buf2), "(%u)", err_);
+ ret += buf2;
+ return ret;
+#else
+ return ConvertErrorNoToString(err_);
+#endif
+ }
+private:
+ NativeErrorNo err_;
+};
+
+inline std::ostream& operator<<(std::ostream& os, const cybozu::ErrorNo& self)
+{
+ return os << self.toString();
+}
+
+} // cybozu
+#endif
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/hash.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/hash.hpp
new file mode 100644
index 000000000..3fd246fa1
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/hash.hpp
@@ -0,0 +1,67 @@
+#pragma once
+#include <cybozu/inttype.hpp>
+
+namespace cybozu {
+
+template<class Iter>
+uint32_t hash32(Iter begin, Iter end, uint32_t v = 0)
+{
+ if (v == 0) v = 2166136261U;
+ while (begin != end) {
+ v ^= *begin++;
+ v *= 16777619;
+ }
+ return v;
+}
+template<class Iter>
+uint64_t hash64(Iter begin, Iter end, uint64_t v = 0)
+{
+ if (v == 0) v = 14695981039346656037ULL;
+ while (begin != end) {
+ v ^= *begin++;
+ v *= 1099511628211ULL;
+ }
+ v ^= v >> 32;
+ return v;
+}
+template<class T>
+uint32_t hash32(const T *x, size_t n, uint32_t v = 0)
+{
+ return hash32(x, x + n, v);
+}
+template<class T>
+uint64_t hash64(const T *x, size_t n, uint64_t v = 0)
+{
+ return hash64(x, x + n, v);
+}
+
+} // cybozu
+
+namespace boost {
+
+template<class T>
+struct hash;
+
+} // boost
+
+#if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
+#include <functional>
+#else
+
+namespace std { CYBOZU_NAMESPACE_TR1_BEGIN
+
+#ifdef _MSC_VER
+ #pragma warning(push)
+ #pragma warning(disable : 4099) // missmatch class and struct
+#endif
+#ifndef __APPLE__
+template<class T>
+struct hash;
+#endif
+#ifdef _MSC_VER
+ #pragma warning(pop)
+#endif
+
+CYBOZU_NAMESPACE_TR1_END } // std
+
+#endif
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/inttype.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/inttype.hpp
new file mode 100644
index 000000000..62856bdb3
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/inttype.hpp
@@ -0,0 +1,163 @@
+#pragma once
+/**
+ @file
+ @brief int type definition and macros
+ @author MITSUNARI Shigeo(@herumi)
+*/
+
+#if defined(_MSC_VER) && (MSC_VER <= 1500) && !defined(CYBOZU_DEFINED_INTXX)
+ #define CYBOZU_DEFINED_INTXX
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+ typedef unsigned int uint32_t;
+ typedef int int32_t;
+ typedef unsigned short uint16_t;
+ typedef short int16_t;
+ typedef unsigned char uint8_t;
+ typedef signed char int8_t;
+#else
+ #include <stdint.h>
+#endif
+
+#ifdef _MSC_VER
+ #ifndef CYBOZU_DEFINED_SSIZE_T
+ #define CYBOZU_DEFINED_SSIZE_T
+ #ifdef _WIN64
+ typedef int64_t ssize_t;
+ #else
+ typedef int32_t ssize_t;
+ #endif
+ #endif
+#else
+ #include <unistd.h> // for ssize_t
+#endif
+
+#ifndef CYBOZU_ALIGN
+ #ifdef _MSC_VER
+ #define CYBOZU_ALIGN(x) __declspec(align(x))
+ #else
+ #define CYBOZU_ALIGN(x) __attribute__((aligned(x)))
+ #endif
+#endif
+#ifndef CYBOZU_FORCE_INLINE
+ #ifdef _MSC_VER
+ #define CYBOZU_FORCE_INLINE __forceinline
+ #else
+ #define CYBOZU_FORCE_INLINE __attribute__((always_inline))
+ #endif
+#endif
+#ifndef CYBOZU_UNUSED
+ #ifdef __GNUC__
+ #define CYBOZU_UNUSED __attribute__((unused))
+ #else
+ #define CYBOZU_UNUSED
+ #endif
+#endif
+#ifndef CYBOZU_ALLOCA
+ #ifdef _MSC_VER
+ #include <malloc.h>
+ #define CYBOZU_ALLOCA(x) _malloca(x)
+ #else
+ #define CYBOZU_ALLOCA(x) __builtin_alloca(x)
+ #endif
+#endif
+#ifndef CYBOZU_NUM_OF_ARRAY
+ #define CYBOZU_NUM_OF_ARRAY(x) (sizeof(x) / sizeof(*x))
+#endif
+#ifndef CYBOZU_SNPRINTF
+ #if defined(_MSC_VER) && (_MSC_VER < 1900)
+ #define CYBOZU_SNPRINTF(x, len, ...) (void)_snprintf_s(x, len, len - 1, __VA_ARGS__)
+ #else
+ #define CYBOZU_SNPRINTF(x, len, ...) (void)snprintf(x, len, __VA_ARGS__)
+ #endif
+#endif
+
+#define CYBOZU_CPP_VERSION_CPP03 0
+#define CYBOZU_CPP_VERSION_TR1 1
+#define CYBOZU_CPP_VERSION_CPP11 2
+#define CYBOZU_CPP_VERSION_CPP14 3
+#define CYBOZU_CPP_VERSION_CPP17 4
+
+#ifdef __GNUC__
+ #define CYBOZU_GNUC_PREREQ(major, minor) ((__GNUC__) * 100 + (__GNUC_MINOR__) >= (major) * 100 + (minor))
+#else
+ #define CYBOZU_GNUC_PREREQ(major, minor) 0
+#endif
+
+#if (__cplusplus >= 201703)
+ #define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_CPP17
+#elif (__cplusplus >= 201402)
+ #define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_CPP14
+#elif (__cplusplus >= 201103) || (_MSC_VER >= 1500) || defined(__GXX_EXPERIMENTAL_CXX0X__)
+ #if defined(_MSC_VER) && (_MSC_VER <= 1600)
+ #define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_TR1
+ #else
+ #define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_CPP11
+ #endif
+#elif CYBOZU_GNUC_PREREQ(4, 5) || (CYBOZU_GNUC_PREREQ(4, 2) && __GLIBCXX__ >= 20070719) || defined(__INTEL_COMPILER) || (__clang_major__ >= 3)
+ #define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_TR1
+#else
+ #define CYBOZU_CPP_VERSION CYBOZU_CPP_VERSION_CPP03
+#endif
+
+#ifdef CYBOZU_USE_BOOST
+ #define CYBOZU_NAMESPACE_STD boost
+ #define CYBOZU_NAMESPACE_TR1_BEGIN
+ #define CYBOZU_NAMESPACE_TR1_END
+#elif (CYBOZU_CPP_VERSION == CYBOZU_CPP_VERSION_TR1) && !defined(__APPLE__)
+ #define CYBOZU_NAMESPACE_STD std::tr1
+ #define CYBOZU_NAMESPACE_TR1_BEGIN namespace tr1 {
+ #define CYBOZU_NAMESPACE_TR1_END }
+#else
+ #define CYBOZU_NAMESPACE_STD std
+ #define CYBOZU_NAMESPACE_TR1_BEGIN
+ #define CYBOZU_NAMESPACE_TR1_END
+#endif
+
+#ifndef CYBOZU_OS_BIT
+ #if defined(_WIN64) || defined(__x86_64__) || defined(__AARCH64EL__) || defined(__EMSCRIPTEN__)
+ #define CYBOZU_OS_BIT 64
+ #else
+ #define CYBOZU_OS_BIT 32
+ #endif
+#endif
+
+#ifndef CYBOZU_HOST
+ #define CYBOZU_HOST_UNKNOWN 0
+ #define CYBOZU_HOST_INTEL 1
+ #define CYBOZU_HOST_ARM 2
+ #if defined(_M_IX86) || defined(_M_AMD64) || defined(__x86_64__) || defined(__i386__)
+ #define CYBOZU_HOST CYBOZU_HOST_INTEL
+ #elif defined(__arm__) || defined(__AARCH64EL__)
+ #define CYBOZU_HOST CYBOZU_HOST_ARM
+ #else
+ #define CYBOZU_HOST CYBOZU_HOST_UNKNOWN
+ #endif
+#endif
+
+#ifndef CYBOZU_ENDIAN
+ #define CYBOZU_ENDIAN_UNKNOWN 0
+ #define CYBOZU_ENDIAN_LITTLE 1
+ #define CYBOZU_ENDIAN_BIG 2
+ #if (CYBOZU_HOST == CYBOZU_HOST_INTEL)
+ #define CYBOZU_ENDIAN CYBOZU_ENDIAN_LITTLE
+ #elif (CYBOZU_HOST == CYBOZU_HOST_ARM) && (defined(__ARM_EABI__) || defined(__AARCH64EL__))
+ #define CYBOZU_ENDIAN CYBOZU_ENDIAN_LITTLE
+ #else
+ #define CYBOZU_ENDIAN CYBOZU_ENDIAN_UNKNOWN
+ #endif
+#endif
+
+#if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
+ #define CYBOZU_NOEXCEPT noexcept
+#else
+ #define CYBOZU_NOEXCEPT throw()
+#endif
+namespace cybozu {
+template<class T>
+void disable_warning_unused_variable(const T&) { }
+template<class T, class S>
+T cast(const S* ptr) { return static_cast<T>(static_cast<const void*>(ptr)); }
+template<class T, class S>
+T cast(S* ptr) { return static_cast<T>(static_cast<void*>(ptr)); }
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/itoa.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/itoa.hpp
new file mode 100644
index 000000000..072e5b8b4
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/itoa.hpp
@@ -0,0 +1,337 @@
+#pragma once
+/**
+ @file
+ @brief convert integer to string(ascii)
+
+ @author MITSUNARI Shigeo(@herumi)
+*/
+#include <limits.h>
+#ifndef CYBOZU_DONT_USE_STRING
+#include <string>
+#endif
+#include <memory.h>
+#include <cybozu/inttype.hpp>
+#include <cybozu/bit_operation.hpp>
+
+namespace cybozu {
+
+template<class T>
+size_t getHexLength(T x)
+{
+ return x == 0 ? 1 : cybozu::bsr(x) / 4 + 1;
+}
+
+template<class T>
+size_t getBinLength(T x)
+{
+ return x == 0 ? 1 : cybozu::bsr(x) + 1;
+}
+/*
+ convert x to hex string with len
+ @note out should have getHexLength(x) size
+ out is not NUL terminated
+*/
+template<class T>
+void itohex(char *out, size_t len, T x, bool upCase = true)
+{
+ static const char *hexTbl[] = {
+ "0123456789abcdef",
+ "0123456789ABCDEF"
+ };
+ const char *tbl = hexTbl[upCase];
+ for (size_t i = 0; i < len; i++) {
+ out[len - i - 1] = tbl[x % 16];
+ x /= 16;
+ }
+}
+/*
+ convert x to bin string with len
+ @note out should have getBinLength(x) size
+ out is not NUL terminated
+*/
+template<class T>
+void itobin(char *out, size_t len, T x)
+{
+ for (size_t i = 0; i < len; i++) {
+ out[len - i - 1] = '0' + (x & 1);
+ x >>= 1;
+ }
+}
+
+namespace itoa_local {
+
+/*
+ convert x to dec
+ use buf[0, bufSize)
+ return 0 if false
+ return writtenSize which is not terminated
+ @REMARK the top of string is buf + bufSize - writtenSize
+*/
+template<class UT>
+size_t uintToDec(char *buf, size_t bufSize, UT x)
+{
+ for (size_t i = 0; i < bufSize; i++) {
+ buf[bufSize - 1 - i] = '0' + static_cast<int>(x % 10);
+ x /= 10;
+ if (x == 0) return i + 1;
+ }
+ return 0;
+}
+
+/*
+ convert x to hex
+ use buf[0, bufSize)
+ return 0 if false
+ return writtenSize which is not terminated
+ @REMARK the top of string is buf + bufSize - writtenSize
+*/
+template<class UT>
+size_t uintToHex(char *buf, size_t bufSize, UT x, bool upCase = true)
+{
+ static const char *hexTbl[] = {
+ "0123456789abcdef",
+ "0123456789ABCDEF"
+ };
+ const char *tbl = hexTbl[upCase];
+ for (size_t i = 0; i < bufSize; i++) {
+ buf[bufSize - 1 - i] = tbl[x % 16];
+ x /= 16;
+ if (x == 0) return i + 1;
+ }
+ return 0;
+}
+
+/*
+ convert x to bin
+ use buf[0, bufSize)
+ return 0 if false
+ return writtenSize which is not terminated
+ @REMARK the top of string is buf + bufSize - writtenSize
+*/
+template<class UT>
+size_t uintToBin(char *buf, size_t bufSize, UT x)
+{
+ for (size_t i = 0; i < bufSize; i++) {
+ buf[bufSize - 1 - i] = '0' + (x & 1);
+ x >>= 1;
+ if (x == 0) return i + 1;
+ }
+ return 0;
+}
+
+template<class T>
+size_t intToDec(char *buf, size_t bufSize, T x)
+{
+ if (x == LLONG_MIN) {
+ const char minStr[] = "-9223372036854775808";
+ const size_t minStrLen = sizeof(minStr) - 1;
+ if (bufSize < minStrLen) {
+ return 0;
+ } else {
+ memcpy(buf + bufSize - minStrLen, minStr, minStrLen);
+ return minStrLen;
+ }
+ }
+ bool negative = x < 0;
+ uint64_t absX = negative ? -x : x;
+ size_t n = uintToDec(buf, bufSize, absX);
+ if (n == 0) return 0;
+ if (negative) {
+ if (bufSize == n) return 0;
+ n++;
+ buf[bufSize - n] = '-';
+ }
+ return n;
+}
+
+#ifndef CYBOZU_DONT_USE_STRING
+template<typename T>
+void convertFromUint(std::string& out, T x)
+{
+ char buf[40];
+ size_t n = uintToDec(buf, sizeof(buf), x);
+ assert(n > 0);
+ out.assign(buf + sizeof(buf) - n, n);
+}
+
+inline void convertFromInt(std::string& out, long long x)
+{
+ char buf[40];
+ size_t n = intToDec(buf, sizeof(buf), x);
+ assert(n > 0);
+ out.assign(buf + sizeof(buf) - n, n);
+}
+
+template<typename T>
+void itohexLocal(std::string& out, T x, bool upCase, bool withZero)
+{
+ const size_t size = withZero ? sizeof(T) * 2 : getHexLength(x);
+ out.resize(size);
+ itohex(&out[0], size, x, upCase);
+}
+
+template<class T>
+void itobinLocal(std::string& out, T x, bool withZero)
+{
+ const size_t size = withZero ? sizeof(T) * 8 : getBinLength(x);
+ out.resize(size);
+ itobin(&out[0], size, x);
+}
+#endif
+
+} // itoa_local
+
+#ifndef CYBOZU_DONT_USE_STRING
+/**
+ convert int to string
+ @param out [out] string
+ @param x [in] int
+*/
+inline void itoa(std::string& out, int x)
+{
+ itoa_local::convertFromInt(out, x);
+}
+
+/**
+ convert long long to string
+ @param out [out] string
+ @param x [in] long long
+*/
+inline void itoa(std::string& out, long long x)
+{
+ itoa_local::convertFromInt(out, x);
+}
+
+/**
+ convert unsigned int to string
+ @param out [out] string
+ @param x [in] unsigned int
+*/
+inline void itoa(std::string& out, unsigned int x)
+{
+ itoa_local::convertFromUint(out, x);
+}
+
+/**
+ convert unsigned long long to string
+ @param out [out] string
+ @param x [in] unsigned long long
+*/
+inline void itoa(std::string& out, unsigned long long x)
+{
+ itoa_local::convertFromUint(out, x);
+}
+
+#if defined(__SIZEOF_LONG__) && (__SIZEOF_LONG__ == 8)
+inline void itoa(std::string& out, long x) { itoa(out, static_cast<long long>(x)); }
+inline void itoa(std::string& out, unsigned long x) { itoa(out, static_cast<unsigned long long>(x)); }
+#else
+inline void itoa(std::string& out, long x) { itoa(out, static_cast<int>(x)); }
+inline void itoa(std::string& out, unsigned long x) { itoa(out, static_cast<int>(x)); }
+#endif
+/**
+ convert integer to string
+ @param x [in] int
+*/
+template<typename T>
+inline std::string itoa(T x)
+{
+ std::string ret;
+ itoa(ret, x);
+ return ret;
+}
+
+inline void itohex(std::string& out, unsigned char x, bool upCase = true, bool withZero = true)
+{
+ itoa_local::itohexLocal(out, x, upCase, withZero);
+}
+
+inline void itohex(std::string& out, unsigned short x, bool upCase = true, bool withZero = true)
+{
+ itoa_local::itohexLocal(out, x, upCase, withZero);
+}
+
+inline void itohex(std::string& out, unsigned int x, bool upCase = true, bool withZero = true)
+{
+ itoa_local::itohexLocal(out, x, upCase, withZero);
+}
+
+inline void itohex(std::string& out, unsigned long x, bool upCase = true, bool withZero = true)
+{
+ itoa_local::itohexLocal(out, x, upCase, withZero);
+}
+
+inline void itohex(std::string& out, unsigned long long x, bool upCase = true, bool withZero = true)
+{
+ itoa_local::itohexLocal(out, x, upCase, withZero);
+}
+
+template<typename T>
+inline std::string itobin(T x, bool withZero = true)
+{
+ std::string out;
+ itoa_local::itobinLocal(out, x, withZero);
+ return out;
+}
+
+inline void itobin(std::string& out, unsigned char x, bool withZero = true)
+{
+ itoa_local::itobinLocal(out, x, withZero);
+}
+
+inline void itobin(std::string& out, unsigned short x, bool withZero = true)
+{
+ itoa_local::itobinLocal(out, x, withZero);
+}
+
+inline void itobin(std::string& out, unsigned int x, bool withZero = true)
+{
+ itoa_local::itobinLocal(out, x, withZero);
+}
+
+inline void itobin(std::string& out, unsigned long x, bool withZero = true)
+{
+ itoa_local::itobinLocal(out, x, withZero);
+}
+
+inline void itobin(std::string& out, unsigned long long x, bool withZero = true)
+{
+ itoa_local::itobinLocal(out, x, withZero);
+}
+
+template<typename T>
+inline std::string itohex(T x, bool upCase = true, bool withZero = true)
+{
+ std::string out;
+ itohex(out, x, upCase, withZero);
+ return out;
+}
+/**
+ convert integer to string with zero padding
+ @param x [in] int
+ @param len [in] minimum lengh of string
+ @param c [in] padding character
+ @note
+ itoa(12, 4) == "0012"
+ itoa(1234, 4) == "1234"
+ itoa(12345, 4) == "12345"
+ itoa(-12, 4) == "-012"
+*/
+template<typename T>
+inline std::string itoaWithZero(T x, size_t len, char c = '0')
+{
+ std::string ret;
+ itoa(ret, x);
+ if (ret.size() < len) {
+ std::string zero(len - ret.size(), c);
+ if (x >= 0) {
+ ret = zero + ret;
+ } else {
+ ret = "-" + zero + ret.substr(1);
+ }
+ }
+ return ret;
+}
+#endif
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/link_libeay32.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/link_libeay32.hpp
new file mode 100644
index 000000000..d83f1b6ea
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/link_libeay32.hpp
@@ -0,0 +1,21 @@
+#pragma once
+/**
+ @file
+ @brief link libeay32.lib of openssl
+ @author MITSUNARI Shigeo(@herumi)
+*/
+#if defined(_WIN32) && defined(_MT)
+ #if _MSC_VER >= 1900 // VC2015
+ #ifdef _WIN64
+ #pragma comment(lib, "mt/14/libeay32.lib")
+ #else
+ #pragma comment(lib, "mt/14/32/libeay32.lib")
+ #endif
+// #elif _MSC_VER == 1800 // VC2013
+ #else
+ #pragma comment(lib, "mt/12/libeay32.lib")
+ #endif
+ #pragma comment(lib, "advapi32.lib")
+ #pragma comment(lib, "gdi32.lib")
+ #pragma comment(lib, "user32.lib")
+#endif
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/link_mpir.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/link_mpir.hpp
new file mode 100644
index 000000000..d20d7b1a9
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/link_mpir.hpp
@@ -0,0 +1,18 @@
+#pragma once
+/**
+ @file
+ @brief link mpir/mpirxx of mpir
+ @author MITSUNARI Shigeo(@herumi)
+*/
+#if defined(_WIN32) && defined(_MT)
+ #if _MSC_VER >= 1900 // VC2015, VC2017(1910)
+ #pragma comment(lib, "mt/14/mpir.lib")
+ #pragma comment(lib, "mt/14/mpirxx.lib")
+ #elif _MSC_VER == 1800 // VC2013
+ #pragma comment(lib, "mt/12/mpir.lib")
+ #pragma comment(lib, "mt/12/mpirxx.lib")
+ #elif _MSC_VER == 1700 // VC2012
+ #pragma comment(lib, "mt/11/mpir.lib")
+ #pragma comment(lib, "mt/11/mpirxx.lib")
+ #endif
+#endif
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/link_ssleay32.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/link_ssleay32.hpp
new file mode 100644
index 000000000..60c2361ae
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/link_ssleay32.hpp
@@ -0,0 +1,19 @@
+#pragma once
+/**
+ @file
+ @brief link ssleay32.lib of openssl
+ @author MITSUNARI Shigeo(@herumi)
+*/
+#if defined(_WIN32) && defined(_MT)
+ #if _MSC_VER >= 1900 // VC2015
+ #ifdef _WIN64
+ #pragma comment(lib, "mt/14/ssleay32.lib")
+ #else
+ #pragma comment(lib, "mt/14/32/ssleay32.lib")
+ #endif
+// #elif _MSC_VER == 1800 // VC2013
+ #else
+ #pragma comment(lib, "mt/12/ssleay32.lib")
+ #endif
+ #pragma comment(lib, "user32.lib")
+#endif
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/mutex.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/mutex.hpp
new file mode 100644
index 000000000..acde6bcbf
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/mutex.hpp
@@ -0,0 +1,141 @@
+#pragma once
+/**
+ @file
+ @brief mutex
+
+ @author MITSUNARI Shigeo(@herumi)
+ @author MITSUNARI Shigeo
+*/
+
+#ifdef _WIN32
+ #include <windows.h>
+#else
+ #include <pthread.h>
+ #include <time.h>
+#endif
+#include <assert.h>
+#include <stdlib.h>
+
+namespace cybozu {
+
+class ConditionVariable;
+
+namespace thread {
+
+#ifdef _WIN32
+ typedef HANDLE MutexHandle;
+ inline void MutexInit(MutexHandle& mutex)
+ {
+// mutex = CreateSemaphore(NULL /* no security */, 1 /* init */, 0x7FFFFFFF /* max */, NULL /* no name */);
+ mutex = CreateMutex(NULL /* no security */, FALSE /* no owner */, NULL /* no name */);
+ }
+ inline void MutexLock(MutexHandle& mutex) { WaitForSingleObject(mutex, INFINITE); }
+ /*
+ return false if timeout
+ @param msec [in] msec
+ */
+ inline bool MutexLockTimeout(MutexHandle& mutex, int msec)
+ {
+ DWORD ret = WaitForSingleObject(mutex, msec);
+ if (ret == WAIT_OBJECT_0) {
+ return true;
+ }
+ if (ret == WAIT_TIMEOUT) {
+ return false;
+ }
+ /* ret == WAIT_ABANDONED */
+ assert(0);
+ return false;
+ }
+ inline void MutexUnlock(MutexHandle& mutex)
+ {
+// ReleaseSemaphore(mutex, 1, NULL);
+ ReleaseMutex(mutex);
+ }
+ inline void MutexTerm(MutexHandle& mutex) { CloseHandle(mutex); }
+#else
+ typedef pthread_mutex_t MutexHandle;
+ inline void MutexInit(MutexHandle& mutex)
+ {
+#if 1
+ pthread_mutex_init(&mutex, NULL);
+#else
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_TIMED_NP)) {
+ perror("pthread_mutexattr_settype");
+ exit(1);
+ }
+ pthread_mutex_init(&mutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+#endif
+ }
+ inline void MutexLock(MutexHandle& mutex) { pthread_mutex_lock(&mutex); }
+#if 0
+ inline bool MutexLockTimeout(MutexHandle& mutex, int msec)
+ {
+ timespec absTime;
+ clock_gettime(CLOCK_REALTIME, &absTime);
+ absTime.tv_sec += msec / 1000;
+ absTime.tv_nsec += msec % 1000;
+ bool ret = pthread_mutex_timedlock(&mutex, &absTime) == 0;
+ return ret;
+ }
+#endif
+ inline void MutexUnlock(MutexHandle& mutex) { pthread_mutex_unlock(&mutex); }
+ inline void MutexTerm(MutexHandle& mutex) { pthread_mutex_destroy(&mutex); }
+#endif
+
+template<class T>
+class AutoLockT {
+public:
+ explicit AutoLockT(T &t)
+ : t_(t)
+ {
+ t_.lock();
+ }
+ ~AutoLockT()
+ {
+ t_.unlock();
+ }
+private:
+ T& t_;
+ AutoLockT& operator=(const AutoLockT&);
+};
+
+} // cybozu::thread
+
+class Mutex {
+ friend class cybozu::ConditionVariable;
+public:
+ Mutex()
+ {
+ thread::MutexInit(hdl_);
+ }
+ ~Mutex()
+ {
+ thread::MutexTerm(hdl_);
+ }
+ void lock()
+ {
+ thread::MutexLock(hdl_);
+ }
+#if 0
+ bool lockTimeout(int msec)
+ {
+ return thread::MutexLockTimeout(hdl_, msec);
+ }
+#endif
+ void unlock()
+ {
+ thread::MutexUnlock(hdl_);
+ }
+private:
+ Mutex(const Mutex&);
+ Mutex& operator=(const Mutex&);
+ thread::MutexHandle hdl_;
+};
+
+typedef cybozu::thread::AutoLockT<cybozu::Mutex> AutoLock;
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/option.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/option.hpp
new file mode 100644
index 000000000..a5dfd137d
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/option.hpp
@@ -0,0 +1,723 @@
+#pragma once
+/**
+ @file
+ @brief command line parser
+
+ @author MITSUNARI Shigeo(@herumi)
+*/
+#include <string>
+#include <vector>
+#include <map>
+#include <sstream>
+#include <iostream>
+#include <limits>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <cybozu/exception.hpp>
+#include <cybozu/atoi.hpp>
+
+/*
+ Option parser
+
+ progName (opt1-name|opt2-name|...) param1 param2 ...
+ param1:param1-help
+ param2:param2-help
+ -op1-name:opt1-help
+ ...
+
+ How to setup
+ int num;
+ -n num ; (optional) option => appendOpt(&x, <defaultValue>, "num", "num-help");
+ -n num ; must option => appendMust(&x, "num", "num-help");
+
+ std::vector<int> v;
+ -v s1 s2 s3 ... => appendVec(&v, "v");
+
+ Remark1: terminate parsing of v if argv begins with '-[^0-9]'
+ Remark2: the begining character of opt-name is not a number ('0'...'9')
+ because avoid conflict with minus number
+
+ std::string file1;
+ file1 is param => appendParam(&file1, "input-file");
+ file2 is optional param => appendParamOpt(&file2, "output-file");
+
+ How to use
+ opt.parse(argc, argv);
+
+ see sample/option_smpl.cpp
+*/
+
+namespace cybozu {
+
+struct OptionError : public cybozu::Exception {
+ enum Type {
+ NoError = 0,
+ BAD_OPT = 1,
+ BAD_VALUE,
+ NO_VALUE,
+ OPT_IS_NECESSARY,
+ PARAM_IS_NECESSARY,
+ REDUNDANT_VAL,
+ BAD_ARGC
+ };
+ Type type;
+ int argPos;
+ OptionError()
+ : cybozu::Exception("OptionError", false)
+ , type(NoError)
+ , argPos(0)
+ {
+ }
+ cybozu::Exception& set(Type _type, int _argPos = 0)
+ {
+ this->type = _type;
+ this->argPos = _argPos;
+ switch (_type) {
+ case BAD_OPT:
+ (*this) << "bad opt";
+ break;
+ case BAD_VALUE:
+ (*this) << "bad value";
+ break;
+ case NO_VALUE:
+ (*this) << "no value";
+ break;
+ case OPT_IS_NECESSARY:
+ (*this) << "opt is necessary";
+ break;
+ case PARAM_IS_NECESSARY:
+ (*this) << "param is necessary";
+ break;
+ case REDUNDANT_VAL:
+ (*this) << "redundant argVal";
+ break;
+ case BAD_ARGC:
+ (*this) << "bad argc";
+ default:
+ break;
+ }
+ return *this;
+ }
+};
+
+namespace option_local {
+
+template<class T>
+bool convert(T* x, const char *str)
+{
+ std::istringstream is(str);
+ is >> *x;
+ return !!is;
+}
+
+template<>
+inline bool convert(std::string* x, const char *str)
+{
+ *x = str;
+ return true;
+}
+
+template<class T>
+bool convertInt(T* x, const char *str)
+{
+ if (str[0] == '0' && str[1] == 'x') {
+ bool b;
+ *x = cybozu::hextoi(&b, str + 2);
+ return b;
+ }
+ size_t len = strlen(str);
+ int factor = 1;
+ if (len > 1) {
+ switch (str[len - 1]) {
+ case 'k': factor = 1000; len--; break;
+ case 'm': factor = 1000 * 1000; len--; break;
+ case 'g': factor = 1000 * 1000 * 1000; len--; break;
+ case 'K': factor = 1024; len--; break;
+ case 'M': factor = 1024 * 1024; len--; break;
+ case 'G': factor = 1024 * 1024 * 1024; len--; break;
+ default: break;
+ }
+ }
+ bool b;
+ T y = cybozu::atoi(&b, str, len);
+ if (!b) return false;
+ if (factor > 1) {
+ if ((std::numeric_limits<T>::min)() / factor <= y
+ && y <= (std::numeric_limits<T>::max)() / factor) {
+ *x = y * factor;
+ } else {
+ return false;
+ }
+ } else {
+ *x = y;
+ }
+ return true;
+}
+
+#define CYBOZU_OPTION_DEFINE_CONVERT_INT(type) \
+template<>inline bool convert(type* x, const char *str) { return convertInt(x, str); }
+
+CYBOZU_OPTION_DEFINE_CONVERT_INT(int)
+CYBOZU_OPTION_DEFINE_CONVERT_INT(long)
+CYBOZU_OPTION_DEFINE_CONVERT_INT(long long)
+
+CYBOZU_OPTION_DEFINE_CONVERT_INT(unsigned int)
+CYBOZU_OPTION_DEFINE_CONVERT_INT(unsigned long)
+CYBOZU_OPTION_DEFINE_CONVERT_INT(unsigned long long)
+
+#undef CYBOZU_OPTION_DEFINE_CONVERT_INT
+
+struct HolderBase {
+ virtual ~HolderBase(){}
+ virtual bool set(const char*) = 0;
+ virtual HolderBase *clone() const = 0;
+ virtual std::string toStr() const = 0;
+ virtual const void *get() const = 0;
+};
+
+template<class T>
+struct Holder : public HolderBase {
+ T *p_;
+ Holder(T *p) : p_(p) {}
+ HolderBase *clone() const { return new Holder(p_); }
+ bool set(const char *str) { return option_local::convert(p_, str); }
+ std::string toStr() const
+ {
+ std::ostringstream os;
+ os << *p_;
+ return os.str();
+ }
+ const void *get() const { return (void*)p_; }
+};
+
+/*
+ for gcc 7 with -fnew-ttp-matching
+ this specialization is not necessary under -fno-new-ttp-matching
+*/
+template struct Holder<std::string>;
+
+template<class T, class Alloc, template<class T_, class Alloc_>class Container>
+struct Holder<Container<T, Alloc> > : public HolderBase {
+ typedef Container<T, Alloc> Vec;
+ Vec *p_;
+ Holder(Vec *p) : p_(p) {}
+ HolderBase *clone() const { return new Holder<Vec>(p_); }
+ bool set(const char *str)
+ {
+ T t;
+ bool b = option_local::convert(&t, str);
+ if (b) p_->push_back(t);
+ return b;
+ }
+ std::string toStr() const
+ {
+ std::ostringstream os;
+ bool isFirst = true;
+ for (typename Vec::const_iterator i = p_->begin(), ie = p_->end(); i != ie; ++i) {
+ if (isFirst) {
+ isFirst = false;
+ } else {
+ os << ' ';
+ }
+ os << *i;
+ }
+ return os.str();
+ }
+ const void *get() const { return (void*)p_; }
+};
+
+class Var {
+ HolderBase *p_;
+ bool isSet_;
+public:
+ Var() : p_(0), isSet_(false) { }
+ Var(const Var& rhs) : p_(rhs.p_->clone()), isSet_(false) { }
+ template<class T>
+ explicit Var(T *x) : p_(new Holder<T>(x)), isSet_(false) { }
+
+ ~Var() { delete p_; }
+
+ void swap(Var& rhs) CYBOZU_NOEXCEPT
+ {
+ std::swap(p_, rhs.p_);
+ std::swap(isSet_, rhs.isSet_);
+ }
+ void operator=(const Var& rhs)
+ {
+ Var v(rhs);
+ swap(v);
+ }
+ bool set(const char *str)
+ {
+ isSet_ = true;
+ return p_->set(str);
+ }
+ std::string toStr() const { return p_ ? p_->toStr() : ""; }
+ bool isSet() const { return isSet_; }
+ const void *get() const { return p_ ? p_->get() : 0; }
+};
+
+} // option_local
+
+class Option {
+ enum Mode { // for opt
+ N_is0 = 0, // for bool by appendBoolOpt()
+ N_is1 = 1,
+ N_any = 2
+ };
+ enum ParamMode {
+ P_exact = 0, // one
+ P_optional = 1, // zero or one
+ P_variable = 2 // zero or greater
+ };
+ struct Info {
+ option_local::Var var;
+ Mode mode; // 0 or 1 or any ; for opt, not used for Param
+ bool isMust; // this option is must
+ std::string opt; // option param name without '-'
+ std::string help; // description of option
+
+ Info() : mode(N_is0), isMust(false) {}
+ template<class T>
+ Info(T* pvar, Mode mode, bool isMust, const char *opt, const std::string& help)
+ : var(pvar)
+ , mode(mode)
+ , isMust(isMust)
+ , opt(opt)
+ , help(help)
+ {
+ }
+ friend inline std::ostream& operator<<(std::ostream& os, const Info& self)
+ {
+ os << self.opt << '=' << self.var.toStr();
+ if (self.var.isSet()) {
+ os << " (set)";
+ } else {
+ os << " (default)";
+ }
+ return os;
+ }
+ void put() const
+ {
+ std::cout << *this;
+ }
+ void usage() const
+ {
+ printf(" -%s %s%s\n", opt.c_str(), help.c_str(), isMust ? " (must)" : "");
+ }
+ void shortUsage() const
+ {
+ printf(" -%s %s", opt.c_str(), mode == N_is0 ? "" : mode == N_is1 ? "para" : "para...");
+ }
+ bool isSet() const { return var.isSet(); }
+ const void *get() const { return var.get(); }
+ };
+ typedef std::vector<Info> InfoVec;
+ typedef std::vector<std::string> StrVec;
+ typedef std::map<std::string, size_t> OptMap;
+ InfoVec infoVec_;
+ InfoVec paramVec_;
+ Info remains_;
+ OptMap optMap_;
+ bool showOptUsage_;
+ ParamMode paramMode_;
+ std::string progName_;
+ std::string desc_;
+ std::string helpOpt_;
+ std::string help_;
+ std::string usage_;
+ StrVec delimiters_;
+ StrVec *remainsAfterDelimiter_;
+ int nextDelimiter_;
+ template<class T>
+ void appendSub(T *pvar, Mode mode, bool isMust, const char *opt, const std::string& help)
+ {
+ const char c = opt[0];
+ if ('0' <= c && c <= '9') throw cybozu::Exception("Option::appendSub:opt must begin with not number") << opt;
+ if (optMap_.find(opt) != optMap_.end()) {
+ throw cybozu::Exception("Option::append:duplicate option") << opt;
+ }
+ optMap_[opt] = infoVec_.size();
+ infoVec_.push_back(Info(pvar, mode, isMust, opt, help));
+ }
+
+ template<class T, class U>
+ void append(T *pvar, const U& defaultVal, bool isMust, const char *opt, const std::string& help = "")
+ {
+ *pvar = defaultVal;
+ appendSub(pvar, N_is1, isMust, opt, help);
+ }
+ /*
+ don't deal with negative number as option
+ */
+ bool isOpt(const char *str) const
+ {
+ if (str[0] != '-') return false;
+ const char c = str[1];
+ if ('0' <= c && c <= '9') return false;
+ return true;
+ }
+ void verifyParamMode()
+ {
+ if (paramMode_ != P_exact) throw cybozu::Exception("Option:appendParamVec:appendParam is forbidden after appendParamOpt/appendParamVec");
+ }
+ std::string getBaseName(const std::string& name) const
+ {
+ size_t pos = name.find_last_of("/\\");
+ if (pos == std::string::npos) return name;
+ return name.substr(pos + 1);
+ }
+ bool inDelimiters(const std::string& str) const
+ {
+ return std::find(delimiters_.begin(), delimiters_.end(), str) != delimiters_.end();
+ }
+public:
+ Option()
+ : showOptUsage_(true)
+ , paramMode_(P_exact)
+ , remainsAfterDelimiter_(0)
+ , nextDelimiter_(-1)
+ {
+ }
+ virtual ~Option() {}
+ /*
+ append optional option with default value
+ @param pvar [in] pointer to option variable
+ @param defaultVal [in] default value
+ @param opt [in] option name
+ @param help [in] option help
+ @note you can use 123k, 56M if T is int/long/long long
+ k : *1000
+ m : *1000000
+ g : *1000000000
+ K : *1024
+ M : *1024*1024
+ G : *1024*1024*1024
+ */
+ template<class T, class U>
+ void appendOpt(T *pvar, const U& defaultVal, const char *opt, const std::string& help = "")
+ {
+ append(pvar, defaultVal, false, opt, help);
+ }
+ /*
+ default value of *pvar is false
+ */
+ void appendBoolOpt(bool *pvar, const char *opt, const std::string& help = "")
+ {
+ *pvar = false;
+ appendSub(pvar, N_is0, false, opt, help);
+ }
+ /*
+ append necessary option
+ @param pvar [in] pointer to option variable
+ @param opt [in] option name
+ @param help [in] option help
+ */
+ template<class T>
+ void appendMust(T *pvar, const char *opt, const std::string& help = "")
+ {
+ append(pvar, T(), true, opt, help);
+ }
+ /*
+ append vector option
+ @param pvar [in] pointer to option variable
+ @param opt [in] option name
+ @param help [in] option help
+ */
+ template<class T, class Alloc, template<class T_, class Alloc_>class Container>
+ void appendVec(Container<T, Alloc> *pvar, const char *opt, const std::string& help = "")
+ {
+ appendSub(pvar, N_any, false, opt, help);
+ }
+ /*
+ append parameter
+ @param pvar [in] pointer to parameter
+ @param opt [in] option name
+ @param help [in] option help
+ */
+ template<class T>
+ void appendParam(T *pvar, const char *opt, const std::string& help = "")
+ {
+ verifyParamMode();
+ paramVec_.push_back(Info(pvar, N_is1, true, opt, help));
+ }
+ /*
+ append optional parameter
+ @param pvar [in] pointer to parameter
+ @param defaultVal [in] default value
+ @param opt [in] option name
+ @param help [in] option help
+ @note you can call appendParamOpt once after appendParam
+ */
+ template<class T, class U>
+ void appendParamOpt(T *pvar, const U& defaultVal, const char *opt, const std::string& help = "")
+ {
+ verifyParamMode();
+ *pvar = defaultVal;
+ paramMode_ = P_optional;
+ paramVec_.push_back(Info(pvar, N_is1, false, opt, help));
+ }
+ /*
+ append remain parameter
+ @param pvar [in] pointer to vector of parameter
+ @param opt [in] option name
+ @param help [in] option help
+ @note you can call appendParamVec once after appendParam
+ */
+ template<class T, class Alloc, template<class T_, class Alloc_>class Container>
+ void appendParamVec(Container<T, Alloc> *pvar, const char *name, const std::string& help = "")
+ {
+ verifyParamMode();
+ paramMode_ = P_variable;
+ remains_.var = option_local::Var(pvar);
+ remains_.mode = N_any;
+ remains_.isMust = false;
+ remains_.opt = name;
+ remains_.help = help;
+ }
+ void appendHelp(const char *opt, const std::string& help = ": show this message")
+ {
+ helpOpt_ = opt;
+ help_ = help;
+ }
+ /*
+ stop parsing after delimiter is found
+ @param delimiter [in] string to stop
+ @param remain [out] set remaining strings if remain
+ */
+ void setDelimiter(const std::string& delimiter, std::vector<std::string> *remain = 0)
+ {
+ delimiters_.push_back(delimiter);
+ remainsAfterDelimiter_ = remain;
+ }
+ /*
+ stop parsing after delimiter is found
+ @param delimiter [in] string to stop to append list of delimiters
+ */
+ void appendDelimiter(const std::string& delimiter)
+ {
+ delimiters_.push_back(delimiter);
+ }
+ /*
+ clear list of delimiters
+ */
+ void clearDelimiterList() { delimiters_.clear(); }
+ /*
+ return the next position of delimiter between [0, argc]
+ @note return argc if delimiter is not set nor found
+ */
+ int getNextPositionOfDelimiter() const { return nextDelimiter_; }
+ /*
+ parse (argc, argv)
+ @param argc [in] argc of main
+ @param argv [in] argv of main
+ @param startPos [in] start position of argc
+ @param progName [in] used instead of argv[0]
+ */
+ bool parse(int argc, const char *const argv[], int startPos = 1, const char *progName = 0)
+ {
+ if (argc < 1 || startPos > argc) return false;
+ progName_ = getBaseName(progName ? progName : argv[startPos - 1]);
+ nextDelimiter_ = argc;
+ OptionError err;
+ for (int pos = startPos; pos < argc; pos++) {
+ if (inDelimiters(argv[pos])) {
+ nextDelimiter_ = pos + 1;
+ if (remainsAfterDelimiter_) {
+ for (int i = nextDelimiter_; i < argc; i++) {
+ remainsAfterDelimiter_->push_back(argv[i]);
+ }
+ }
+ break;
+ }
+ if (isOpt(argv[pos])) {
+ const std::string str = argv[pos] + 1;
+ if (helpOpt_ == str) {
+ usage();
+ exit(0);
+ }
+ OptMap::const_iterator i = optMap_.find(str);
+ if (i == optMap_.end()) {
+ err.set(OptionError::BAD_OPT, pos);
+ goto ERR;
+ }
+
+ Info& info = infoVec_[i->second];
+ switch (info.mode) {
+ case N_is0:
+ if (!info.var.set("1")) {
+ err.set(OptionError::BAD_VALUE, pos);
+ goto ERR;
+ }
+ break;
+ case N_is1:
+ pos++;
+ if (pos == argc) {
+ err.set(OptionError::BAD_VALUE, pos) << (std::string("no value for -") + info.opt);
+ goto ERR;
+ }
+ if (!info.var.set(argv[pos])) {
+ err.set(OptionError::BAD_VALUE, pos) << (std::string(argv[pos]) + " for -" + info.opt);
+ goto ERR;
+ }
+ break;
+ case N_any:
+ default:
+ {
+ pos++;
+ int j = 0;
+ while (pos < argc && !isOpt(argv[pos])) {
+ if (!info.var.set(argv[pos])) {
+ err.set(OptionError::BAD_VALUE, pos) << (std::string(argv[pos]) + " for -" + info.opt) << j;
+ goto ERR;
+ }
+ pos++;
+ j++;
+ }
+ if (j > 0) {
+ pos--;
+ } else {
+ err.set(OptionError::NO_VALUE, pos) << (std::string("for -") + info.opt);
+ goto ERR;
+ }
+ }
+ break;
+ }
+ } else {
+ bool used = false;
+ for (size_t i = 0; i < paramVec_.size(); i++) {
+ Info& param = paramVec_[i];
+ if (!param.var.isSet()) {
+ if (!param.var.set(argv[pos])) {
+ err.set(OptionError::BAD_VALUE, pos) << (std::string(argv[pos]) + " for " + param.opt);
+ goto ERR;
+ }
+ used = true;
+ break;
+ }
+ }
+ if (!used) {
+ if (paramMode_ == P_variable) {
+ remains_.var.set(argv[pos]);
+ } else {
+ err.set(OptionError::REDUNDANT_VAL, pos) << argv[pos];
+ goto ERR;
+ }
+ }
+ }
+ }
+ // check whether must-opt is set
+ for (size_t i = 0; i < infoVec_.size(); i++) {
+ const Info& info = infoVec_[i];
+ if (info.isMust && !info.var.isSet()) {
+ err.set(OptionError::OPT_IS_NECESSARY) << info.opt;
+ goto ERR;
+ }
+ }
+ // check whether param is set
+ for (size_t i = 0; i < paramVec_.size(); i++) {
+ const Info& param = paramVec_[i];
+ if (param.isMust && !param.var.isSet()) {
+ err.set(OptionError::PARAM_IS_NECESSARY) << param.opt;
+ goto ERR;
+ }
+ }
+ // check whether remains is set
+ if (paramMode_ == P_variable && remains_.isMust && !remains_.var.isSet()) {
+ err.set(OptionError::PARAM_IS_NECESSARY) << remains_.opt;
+ goto ERR;
+ }
+ return true;
+ ERR:
+ assert(err.type);
+ printf("%s\n", err.what());
+ return false;
+ }
+ /*
+ show desc at first in usage()
+ */
+ void setDescription(const std::string& desc)
+ {
+ desc_ = desc;
+ }
+ /*
+ show command line after desc
+ don't put option message if not showOptUsage
+ */
+ void setUsage(const std::string& usage, bool showOptUsage = false)
+ {
+ usage_ = usage;
+ showOptUsage_ = showOptUsage;
+ }
+ void usage() const
+ {
+ if (!desc_.empty()) printf("%s\n", desc_.c_str());
+ if (usage_.empty()) {
+ printf("usage:%s", progName_.c_str());
+ if (!infoVec_.empty()) printf(" [opt]");
+ for (size_t i = 0; i < infoVec_.size(); i++) {
+ if (infoVec_[i].isMust) infoVec_[i].shortUsage();
+ }
+ for (size_t i = 0; i < paramVec_.size(); i++) {
+ printf(" %s", paramVec_[i].opt.c_str());
+ }
+ if (paramMode_ == P_variable) {
+ printf(" %s", remains_.opt.c_str());
+ }
+ printf("\n");
+ } else {
+ printf("%s\n", usage_.c_str());
+ if (!showOptUsage_) return;
+ }
+ for (size_t i = 0; i < paramVec_.size(); i++) {
+ const Info& param = paramVec_[i];
+ if (!param.help.empty()) printf(" %s %s\n", paramVec_[i].opt.c_str(), paramVec_[i].help.c_str());
+ }
+ if (!remains_.help.empty()) printf(" %s %s\n", remains_.opt.c_str(), remains_.help.c_str());
+ if (!helpOpt_.empty()) {
+ printf(" -%s %s\n", helpOpt_.c_str(), help_.c_str());
+ }
+ for (size_t i = 0; i < infoVec_.size(); i++) {
+ infoVec_[i].usage();
+ }
+ }
+ friend inline std::ostream& operator<<(std::ostream& os, const Option& self)
+ {
+ for (size_t i = 0; i < self.paramVec_.size(); i++) {
+ const Info& param = self.paramVec_[i];
+ os << param.opt << '=' << param.var.toStr() << std::endl;
+ }
+ if (self.paramMode_ == P_variable) {
+ os << "remains=" << self.remains_.var.toStr() << std::endl;
+ }
+ for (size_t i = 0; i < self.infoVec_.size(); i++) {
+ os << self.infoVec_[i] << std::endl;
+ }
+ return os;
+ }
+ void put() const
+ {
+ std::cout << *this;
+ }
+ /*
+ whether pvar is set or not
+ */
+ template<class T>
+ bool isSet(const T* pvar) const
+ {
+ const void *p = static_cast<const void*>(pvar);
+ for (size_t i = 0; i < paramVec_.size(); i++) {
+ const Info& v = paramVec_[i];
+ if (v.get() == p) return v.isSet();
+ }
+ if (remains_.get() == p) return remains_.isSet();
+ for (size_t i = 0; i < infoVec_.size(); i++) {
+ const Info& v = infoVec_[i];
+ if (v.get() == p) return v.isSet();
+ }
+ throw cybozu::Exception("Option:isSet:no assigned var") << pvar;
+ }
+};
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp
new file mode 100644
index 000000000..23096989d
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp
@@ -0,0 +1,139 @@
+#pragma once
+/**
+ @file
+ @brief pseudrandom generator
+ @author MITSUNARI Shigeo(@herumi)
+ @license modified new BSD license
+ http://opensource.org/licenses/BSD-3-Clause
+*/
+
+#include <cybozu/exception.hpp>
+#ifdef _WIN32
+#include <winsock2.h>
+#include <windows.h>
+#include <wincrypt.h>
+#ifdef _MSC_VER
+#pragma comment (lib, "advapi32.lib")
+#endif
+#include <cybozu/critical_section.hpp>
+#else
+#include <sys/types.h>
+#include <fcntl.h>
+#endif
+
+namespace cybozu {
+
+class RandomGenerator {
+ RandomGenerator(const RandomGenerator&);
+ void operator=(const RandomGenerator&);
+public:
+ uint32_t operator()()
+ {
+ return get32();
+ }
+ uint32_t get32()
+ {
+ uint32_t ret;
+ read(&ret, 1);
+ return ret;
+ }
+ uint64_t get64()
+ {
+ uint64_t ret;
+ read(&ret, 1);
+ return ret;
+ }
+#ifdef _WIN32
+ RandomGenerator()
+ : prov_(0)
+ , pos_(bufSize)
+ {
+ DWORD flagTbl[] = { 0, CRYPT_NEWKEYSET };
+ for (int i = 0; i < 2; i++) {
+ if (CryptAcquireContext(&prov_, NULL, NULL, PROV_RSA_FULL, flagTbl[i]) != 0) return;
+ }
+ throw cybozu::Exception("randomgenerator");
+ }
+ void read_inner(void *buf, size_t byteSize)
+ {
+ if (CryptGenRandom(prov_, static_cast<DWORD>(byteSize), static_cast<BYTE*>(buf)) == 0) {
+ throw cybozu::Exception("randomgenerator:read") << byteSize;
+ }
+ }
+ ~RandomGenerator()
+ {
+ if (prov_) {
+ CryptReleaseContext(prov_, 0);
+ }
+ }
+ /*
+ fill buf[0..bufNum-1] with random data
+ @note bufNum is not byte size
+ */
+ template<class T>
+ void read(T *buf, size_t bufNum)
+ {
+ cybozu::AutoLockCs al(cs_);
+ const size_t byteSize = sizeof(T) * bufNum;
+ if (byteSize > bufSize) {
+ read_inner(buf, byteSize);
+ } else {
+ if (pos_ + byteSize > bufSize) {
+ read_inner(buf_, bufSize);
+ pos_ = 0;
+ }
+ memcpy(buf, buf_ + pos_, byteSize);
+ pos_ += byteSize;
+ }
+ }
+private:
+ HCRYPTPROV prov_;
+ static const size_t bufSize = 1024;
+ char buf_[bufSize];
+ size_t pos_;
+ cybozu::CriticalSection cs_;
+#else
+ RandomGenerator()
+ : fp_(::fopen("/dev/urandom", "rb"))
+ {
+ if (!fp_) throw cybozu::Exception("randomgenerator");
+ }
+ ~RandomGenerator()
+ {
+ if (fp_) ::fclose(fp_);
+ }
+ /*
+ fill buf[0..bufNum-1] with random data
+ @note bufNum is not byte size
+ */
+ template<class T>
+ void read(T *buf, size_t bufNum)
+ {
+ const size_t byteSize = sizeof(T) * bufNum;
+ if (::fread(buf, 1, (int)byteSize, fp_) != byteSize) {
+ throw cybozu::Exception("randomgenerator:read") << byteSize;
+ }
+ }
+#endif
+private:
+ FILE *fp_;
+};
+
+template<class T, class RG>
+void shuffle(T* v, size_t n, RG& rg)
+{
+ if (n <= 1) return;
+ for (size_t i = 0; i < n - 1; i++) {
+ size_t r = i + size_t(rg.get64() % (n - i));
+ using namespace std;
+ swap(v[i], v[r]);
+ }
+}
+
+template<class V, class RG>
+void shuffle(V& v, RG& rg)
+{
+ shuffle(v.data(), v.size(), rg);
+}
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/serializer.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/serializer.hpp
new file mode 100644
index 000000000..1e23c8f42
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/serializer.hpp
@@ -0,0 +1,363 @@
+#pragma once
+/**
+ @file
+ @brief serializer for vector, list, map and so on
+
+ @author MITSUNARI Shigeo(@herumi)
+*/
+#include <assert.h>
+#include <cybozu/stream.hpp>
+
+#ifdef _MSC_VER
+ #pragma warning(push)
+ #pragma warning(disable : 4127)
+#endif
+
+//#define CYBOZU_SERIALIZER_FIXED_SIZE_INTEGER
+
+namespace cybozu {
+
+namespace serializer_local {
+
+template<class T>
+union ci {
+ T i;
+ uint8_t c[sizeof(T)];
+};
+
+template<class S, void (S::*)(size_t)>
+struct HasMemFunc { };
+
+template<class T>
+void dispatch_reserve(T& t, size_t size, int, HasMemFunc<T, &T::reserve>* = 0)
+{
+ t.reserve(size);
+}
+
+template<class T>
+void dispatch_reserve(T&, size_t, int*)
+{
+}
+
+template<class T>
+void reserve_if_exists(T& t, size_t size)
+{
+ dispatch_reserve(t, size, 0);
+}
+
+} // serializer_local
+
+template<class InputStream, class T>
+void loadRange(T *p, size_t num, InputStream& is)
+{
+ cybozu::read(p, num * sizeof(T), is);
+}
+
+template<class OutputStream, class T>
+void saveRange(OutputStream& os, const T *p, size_t num)
+{
+ cybozu::write(os, p, num * sizeof(T));
+}
+
+template<class InputStream, class T>
+void loadPod(T& x, InputStream& is)
+{
+ serializer_local::ci<T> ci;
+ loadRange(ci.c, sizeof(ci.c), is);
+ x = ci.i;
+}
+
+template<class OutputStream, class T>
+void savePod(OutputStream& os, const T& x)
+{
+ serializer_local::ci<T> ci;
+ ci.i = x;
+ saveRange(os, ci.c, sizeof(ci.c));
+}
+
+template<class InputStream, class T>
+void load(T& x, InputStream& is)
+{
+ x.load(is);
+}
+
+template<class OutputStream, class T>
+void save(OutputStream& os, const T& x)
+{
+ x.save(os);
+}
+
+#define CYBOZU_SERIALIZER_MAKE_SERIALIZER_F(type) \
+template<class InputStream>void load(type& x, InputStream& is) { loadPod(x, is); } \
+template<class OutputStream>void save(OutputStream& os, type x) { savePod(os, x); }
+
+CYBOZU_SERIALIZER_MAKE_SERIALIZER_F(bool)
+CYBOZU_SERIALIZER_MAKE_SERIALIZER_F(char)
+CYBOZU_SERIALIZER_MAKE_SERIALIZER_F(short)
+CYBOZU_SERIALIZER_MAKE_SERIALIZER_F(unsigned char)
+CYBOZU_SERIALIZER_MAKE_SERIALIZER_F(unsigned short)
+CYBOZU_SERIALIZER_MAKE_SERIALIZER_F(wchar_t)
+
+CYBOZU_SERIALIZER_MAKE_SERIALIZER_F(float)
+CYBOZU_SERIALIZER_MAKE_SERIALIZER_F(double)
+
+#ifdef CYBOZU_SERIALIZER_FIXED_SIZE_INTEGER
+
+#define CYBOZU_SERIALIZER_MAKE_INT_SERIALIZER(type) CYBOZU_SERIALIZER_MAKE_SERIALIZER_F(type)
+
+#else
+
+namespace serializer_local {
+
+template<class S, class T>
+bool isRecoverable(T x)
+{
+ return T(S(x)) == x;
+}
+/*
+ data structure H:D of integer x
+ H:header(1byte)
+ 0x80 ; D = 1 byte zero ext
+ 0x81 ; D = 2 byte zero ext
+ 0x82 ; D = 4 byte zero ext
+ 0x83 ; D = 8 byte zero ext
+ 0x84 ; D = 1 byte signed ext
+ 0x85 ; D = 2 byte signed ext
+ 0x86 ; D = 4 byte signed ext
+ 0x87 ; D = 8 byte signed ext
+ other; x = signed H, D = none
+*/
+template<class OutputStream, class T>
+void saveVariableInt(OutputStream& os, const T& x)
+{
+ if (isRecoverable<int8_t>(x)) {
+ uint8_t u8 = uint8_t(x);
+ if (unsigned(u8 - 0x80) <= 7) {
+ savePod(os, uint8_t(0x84));
+ }
+ savePod(os, u8);
+ } else if (isRecoverable<uint8_t>(x)) {
+ savePod(os, uint8_t(0x80));
+ savePod(os, uint8_t(x));
+ } else if (isRecoverable<uint16_t>(x) || isRecoverable<int16_t>(x)) {
+ savePod(os, uint8_t(isRecoverable<uint16_t>(x) ? 0x81 : 0x85));
+ savePod(os, uint16_t(x));
+ } else if (isRecoverable<uint32_t>(x) || isRecoverable<int32_t>(x)) {
+ savePod(os, uint8_t(isRecoverable<uint32_t>(x) ? 0x82 : 0x86));
+ savePod(os, uint32_t(x));
+ } else {
+ assert(sizeof(T) == 8);
+ savePod(os, uint8_t(0x83));
+ savePod(os, uint64_t(x));
+ }
+}
+
+template<class InputStream, class T>
+void loadVariableInt(T& x, InputStream& is)
+{
+ uint8_t h;
+ loadPod(h, is);
+ if (h == 0x80) {
+ uint8_t v;
+ loadPod(v, is);
+ x = v;
+ } else if (h == 0x81) {
+ uint16_t v;
+ loadPod(v, is);
+ x = v;
+ } else if (h == 0x82) {
+ uint32_t v;
+ loadPod(v, is);
+ x = v;
+ } else if (h == 0x83) {
+ if (sizeof(T) == 4) throw cybozu::Exception("loadVariableInt:bad header") << h;
+ uint64_t v;
+ loadPod(v, is);
+ x = static_cast<T>(v);
+ } else if (h == 0x84) {
+ int8_t v;
+ loadPod(v, is);
+ x = v;
+ } else if (h == 0x85) {
+ int16_t v;
+ loadPod(v, is);
+ x = v;
+ } else if (h == 0x86) {
+ int32_t v;
+ loadPod(v, is);
+ x = v;
+ } else if (h == 0x87) {
+ if (sizeof(T) == 4) throw cybozu::Exception("loadVariableInt:bad header") << h;
+ int64_t v;
+ loadPod(v, is);
+ x = static_cast<T>(v);
+ } else {
+ x = static_cast<int8_t>(h);
+ }
+}
+
+} // serializer_local
+
+#define CYBOZU_SERIALIZER_MAKE_INT_SERIALIZER(type) \
+template<class InputStream>void load(type& x, InputStream& is) { serializer_local::loadVariableInt(x, is); } \
+template<class OutputStream>void save(OutputStream& os, type x) { serializer_local::saveVariableInt(os, x); }
+
+#endif
+
+CYBOZU_SERIALIZER_MAKE_INT_SERIALIZER(int)
+CYBOZU_SERIALIZER_MAKE_INT_SERIALIZER(long)
+CYBOZU_SERIALIZER_MAKE_INT_SERIALIZER(long long)
+CYBOZU_SERIALIZER_MAKE_INT_SERIALIZER(unsigned int)
+CYBOZU_SERIALIZER_MAKE_INT_SERIALIZER(unsigned long)
+CYBOZU_SERIALIZER_MAKE_INT_SERIALIZER(unsigned long long)
+
+#undef CYBOZU_SERIALIZER_MAKE_INT_SERIALIZER
+#undef CYBOZU_SERIALIZER_MAKE_UNT_SERIALIZER
+#undef CYBOZU_SERIALIZER_MAKE_SERIALIZER_F
+#undef CYBOZU_SERIALIZER_MAKE_SERIALIZER_V
+
+// only for std::vector<POD>
+template<class V, class InputStream>
+void loadPodVec(V& v, InputStream& is)
+{
+ size_t size;
+ load(size, is);
+ v.resize(size);
+ if (size > 0) loadRange(&v[0], size, is);
+}
+
+// only for std::vector<POD>
+template<class V, class OutputStream>
+void savePodVec(OutputStream& os, const V& v)
+{
+ save(os, v.size());
+ if (!v.empty()) saveRange(os, &v[0], v.size());
+}
+
+template<class InputStream>
+void load(std::string& str, InputStream& is)
+{
+ loadPodVec(str, is);
+}
+
+template<class OutputStream>
+void save(OutputStream& os, const std::string& str)
+{
+ savePodVec(os, str);
+}
+
+template<class OutputStream>
+void save(OutputStream& os, const char *x)
+{
+ const size_t len = strlen(x);
+ save(os, len);
+ if (len > 0) saveRange(os, x, len);
+}
+
+
+// for vector, list
+template<class InputStream, class T, class Alloc, template<class T_, class Alloc_>class Container>
+void load(Container<T, Alloc>& x, InputStream& is)
+{
+ size_t size;
+ load(size, is);
+ serializer_local::reserve_if_exists(x, size);
+ for (size_t i = 0; i < size; i++) {
+ x.push_back(T());
+ T& t = x.back();
+ load(t, is);
+ }
+}
+
+template<class OutputStream, class T, class Alloc, template<class T_, class Alloc_>class Container>
+void save(OutputStream& os, const Container<T, Alloc>& x)
+{
+ typedef Container<T, Alloc> V;
+ save(os, x.size());
+ for (typename V::const_iterator i = x.begin(), end = x.end(); i != end; ++i) {
+ save(os, *i);
+ }
+}
+
+// for set
+template<class InputStream, class K, class Pred, class Alloc, template<class K_, class Pred_, class Alloc_>class Container>
+void load(Container<K, Pred, Alloc>& x, InputStream& is)
+{
+ size_t size;
+ load(size, is);
+ for (size_t i = 0; i < size; i++) {
+ K t;
+ load(t, is);
+ x.insert(t);
+ }
+}
+
+template<class OutputStream, class K, class Pred, class Alloc, template<class K_, class Pred_, class Alloc_>class Container>
+void save(OutputStream& os, const Container<K, Pred, Alloc>& x)
+{
+ typedef Container<K, Pred, Alloc> Set;
+ save(os, x.size());
+ for (typename Set::const_iterator i = x.begin(), end = x.end(); i != end; ++i) {
+ save(os, *i);
+ }
+}
+
+// for map
+template<class InputStream, class K, class V, class Pred, class Alloc, template<class K_, class V_, class Pred_, class Alloc_>class Container>
+void load(Container<K, V, Pred, Alloc>& x, InputStream& is)
+{
+ typedef Container<K, V, Pred, Alloc> Map;
+ size_t size;
+ load(size, is);
+ for (size_t i = 0; i < size; i++) {
+ std::pair<typename Map::key_type, typename Map::mapped_type> vt;
+ load(vt.first, is);
+ load(vt.second, is);
+ x.insert(vt);
+ }
+}
+
+template<class OutputStream, class K, class V, class Pred, class Alloc, template<class K_, class V_, class Pred_, class Alloc_>class Container>
+void save(OutputStream& os, const Container<K, V, Pred, Alloc>& x)
+{
+ typedef Container<K, V, Pred, Alloc> Map;
+ save(os, x.size());
+ for (typename Map::const_iterator i = x.begin(), end = x.end(); i != end; ++i) {
+ save(os, i->first);
+ save(os, i->second);
+ }
+}
+
+// unordered_map
+template<class InputStream, class K, class V, class Hash, class Pred, class Alloc, template<class K_, class V_, class Hash_, class Pred_, class Alloc_>class Container>
+void load(Container<K, V, Hash, Pred, Alloc>& x, InputStream& is)
+{
+ typedef Container<K, V, Hash, Pred, Alloc> Map;
+ size_t size;
+ load(size, is);
+// x.reserve(size); // tr1::unordered_map may not have reserve
+ cybozu::serializer_local::reserve_if_exists(x, size);
+ for (size_t i = 0; i < size; i++) {
+ std::pair<typename Map::key_type, typename Map::mapped_type> vt;
+ load(vt.first, is);
+ load(vt.second, is);
+ x.insert(vt);
+ }
+}
+
+template<class OutputStream, class K, class V, class Hash, class Pred, class Alloc, template<class K_, class V_, class Hash_, class Pred_, class Alloc_>class Container>
+void save(OutputStream& os, const Container<K, V, Hash, Pred, Alloc>& x)
+{
+ typedef Container<K, V, Hash, Pred, Alloc> Map;
+ save(os, x.size());
+ for (typename Map::const_iterator i = x.begin(), end = x.end(); i != end; ++i) {
+ save(os, i->first);
+ save(os, i->second);
+ }
+}
+
+} // cybozu
+
+#ifdef _MSC_VER
+ #pragma warning(pop)
+#endif
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp
new file mode 100644
index 000000000..97193849b
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp
@@ -0,0 +1,438 @@
+#pragma once
+/**
+ @file
+ @brief SHA-256, SHA-512 class
+ @author MITSUNARI Shigeo(@herumi)
+ @license modified new BSD license
+ http://opensource.org/licenses/BSD-3-Clause
+*/
+#include <cybozu/endian.hpp>
+#ifndef CYBOZU_DONT_USE_STRING
+#include <cybozu/itoa.hpp>
+#include <string>
+#endif
+#include <memory.h>
+#include <assert.h>
+
+namespace cybozu {
+
+namespace sha2_local {
+
+template<class T>
+T min_(T x, T y) { return x < y ? x : y;; }
+
+#ifndef CYBOZU_DONT_USE_STRING
+inline void uint32toHexStr(char *buf, const uint32_t *x, size_t n)
+{
+ for (size_t i = 0; i < n; i++) {
+ cybozu::itohex(buf + i * 8, 8, x[i], false);
+ }
+}
+
+inline void uint64toHexStr(char *buf, const uint64_t *x, size_t n)
+{
+ for (size_t i = 0; i < n; i++) {
+ cybozu::itohex(buf + i * 16, 16, x[i], false);
+ }
+}
+#endif
+
+inline uint32_t rot32(uint32_t x, int s)
+{
+#ifdef _MSC_VER
+ return _rotr(x, s);
+#else
+ return (x >> s) | (x << (32 - s));
+#endif
+}
+
+inline uint64_t rot64(uint64_t x, int s)
+{
+#ifdef _MSC_VER
+ return _rotr64(x, s);
+#else
+ return (x >> s) | (x << (64 - s));
+#endif
+}
+
+} // cybozu::sha2_local
+
+class Sha256 {
+private:
+ static const size_t blockSize_ = 64;
+ static const size_t hSize_ = 8;
+ uint64_t totalSize_;
+ size_t roundBufSize_;
+ char roundBuf_[blockSize_];
+ uint32_t h_[hSize_];
+ static const size_t outByteSize_ = hSize_ * sizeof(uint32_t);
+ const uint32_t *k_;
+
+ /**
+ @param buf [in] buffer(64byte)
+ */
+ void round(const char *buf)
+ {
+ using namespace sha2_local;
+ uint32_t w[64];
+ for (int i = 0; i < 16; i++) {
+ w[i] = cybozu::Get32bitAsBE(&buf[i * 4]);
+ }
+ for (int i = 16 ; i < 64; i++) {
+ uint32_t t = w[i - 15];
+ uint32_t s0 = rot32(t, 7) ^ rot32(t, 18) ^ (t >> 3);
+ t = w[i - 2];
+ uint32_t s1 = rot32(t, 17) ^ rot32(t, 19) ^ (t >> 10);
+ w[i] = w[i - 16] + s0 + w[i - 7] + s1;
+ }
+ uint32_t a = h_[0];
+ uint32_t b = h_[1];
+ uint32_t c = h_[2];
+ uint32_t d = h_[3];
+ uint32_t e = h_[4];
+ uint32_t f = h_[5];
+ uint32_t g = h_[6];
+ uint32_t h = h_[7];
+ for (int i = 0; i < 64; i++) {
+ uint32_t s1 = rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
+ uint32_t ch = g ^ (e & (f ^ g));
+ uint32_t t1 = h + s1 + ch + k_[i] + w[i];
+ uint32_t s0 = rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
+ uint32_t maj = ((a | b) & c) | (a & b);
+ uint32_t t2 = s0 + maj;
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ }
+ h_[0] += a;
+ h_[1] += b;
+ h_[2] += c;
+ h_[3] += d;
+ h_[4] += e;
+ h_[5] += f;
+ h_[6] += g;
+ h_[7] += h;
+ totalSize_ += 64;
+ }
+ /*
+ final phase
+ */
+ void term(const char *buf, size_t bufSize)
+ {
+ assert(bufSize < blockSize_);
+ const uint64_t totalSize = totalSize_ + bufSize;
+
+ uint8_t last[blockSize_];
+ memcpy(last, buf, bufSize);
+ memset(&last[bufSize], 0, blockSize_ - bufSize);
+ last[bufSize] = uint8_t(0x80); /* top bit = 1 */
+ if (bufSize >= blockSize_ - 8) {
+ round(reinterpret_cast<const char*>(last));
+ memset(last, 0, sizeof(last)); // clear stack
+ }
+ cybozu::Set32bitAsBE(&last[56], uint32_t(totalSize >> 29));
+ cybozu::Set32bitAsBE(&last[60], uint32_t(totalSize * 8));
+ round(reinterpret_cast<const char*>(last));
+ }
+public:
+ Sha256()
+ {
+ clear();
+ }
+ Sha256(const void *buf, size_t bufSize)
+ {
+ clear();
+ digest(buf, bufSize);
+ }
+ void clear()
+ {
+ static const uint32_t kTbl[] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+ k_ = kTbl;
+ totalSize_ = 0;
+ roundBufSize_ = 0;
+ h_[0] = 0x6a09e667;
+ h_[1] = 0xbb67ae85;
+ h_[2] = 0x3c6ef372;
+ h_[3] = 0xa54ff53a;
+ h_[4] = 0x510e527f;
+ h_[5] = 0x9b05688c;
+ h_[6] = 0x1f83d9ab;
+ h_[7] = 0x5be0cd19;
+ }
+ void update(const void *buf_, size_t bufSize)
+ {
+ const char *buf = reinterpret_cast<const char*>(buf_);
+ if (bufSize == 0) return;
+ if (roundBufSize_ > 0) {
+ size_t size = sha2_local::min_(blockSize_ - roundBufSize_, bufSize);
+ memcpy(roundBuf_ + roundBufSize_, buf, size);
+ roundBufSize_ += size;
+ buf += size;
+ bufSize -= size;
+ }
+ if (roundBufSize_ == blockSize_) {
+ round(roundBuf_);
+ roundBufSize_ = 0;
+ }
+ while (bufSize >= blockSize_) {
+ assert(roundBufSize_ == 0);
+ round(buf);
+ buf += blockSize_;
+ bufSize -= blockSize_;
+ }
+ if (bufSize > 0) {
+ assert(bufSize < blockSize_);
+ assert(roundBufSize_ == 0);
+ memcpy(roundBuf_, buf, bufSize);
+ roundBufSize_ = bufSize;
+ }
+ assert(roundBufSize_ < blockSize_);
+ }
+ void digest(const void *buf, size_t bufSize)
+ {
+ update(buf, bufSize);
+ term(roundBuf_, roundBufSize_);
+ }
+ size_t get(void *out) const
+ {
+ char *p = reinterpret_cast<char*>(out);
+ for (size_t i = 0; i < hSize_; i++) {
+ cybozu::Set32bitAsBE(&p[i * sizeof(h_[0])], h_[i]);
+ }
+ return outByteSize_;
+ }
+#ifndef CYBOZU_DONT_USE_STRING
+ void update(const std::string& buf)
+ {
+ update(buf.c_str(), buf.size());
+ }
+ void digest(const std::string& str = "")
+ {
+ digest(str.c_str(), str.size());
+ }
+ std::string get() const
+ {
+ char out[outByteSize_];
+ get(out);
+ return std::string(out, sizeof(out));
+ }
+ std::string toHexStr() const
+ {
+ char buf[outByteSize_ * 2];
+ sha2_local::uint32toHexStr(buf, h_, hSize_);
+ return std::string(buf, sizeof(buf));
+ }
+#endif
+};
+
+class Sha512 {
+private:
+ static const size_t blockSize_ = 128;
+ static const size_t hSize_ = 8;
+ uint64_t totalSize_;
+ size_t roundBufSize_;
+ char roundBuf_[blockSize_];
+ uint64_t h_[hSize_];
+ static const size_t outByteSize_ = hSize_ * sizeof(uint64_t);
+ const uint64_t *k_;
+
+ template<size_t i0, size_t i1, size_t i2, size_t i3, size_t i4, size_t i5, size_t i6, size_t i7>
+ void round1(uint64_t *S, const uint64_t *w, size_t i)
+ {
+ using namespace sha2_local;
+ uint64_t& a = S[i0];
+ uint64_t& b = S[i1];
+ uint64_t& c = S[i2];
+ uint64_t& d = S[i3];
+ uint64_t& e = S[i4];
+ uint64_t& f = S[i5];
+ uint64_t& g = S[i6];
+ uint64_t& h = S[i7];
+
+ uint64_t s1 = rot64(e, 14) ^ rot64(e, 18) ^ rot64(e, 41);
+ uint64_t ch = g ^ (e & (f ^ g));
+ uint64_t t0 = h + s1 + ch + k_[i] + w[i];
+ uint64_t s0 = rot64(a, 28) ^ rot64(a, 34) ^ rot64(a, 39);
+ uint64_t maj = ((a | b) & c) | (a & b);
+ uint64_t t1 = s0 + maj;
+ d += t0;
+ h = t0 + t1;
+ }
+ /**
+ @param buf [in] buffer(64byte)
+ */
+ void round(const char *buf)
+ {
+ using namespace sha2_local;
+ uint64_t w[80];
+ for (int i = 0; i < 16; i++) {
+ w[i] = cybozu::Get64bitAsBE(&buf[i * 8]);
+ }
+ for (int i = 16 ; i < 80; i++) {
+ uint64_t t = w[i - 15];
+ uint64_t s0 = rot64(t, 1) ^ rot64(t, 8) ^ (t >> 7);
+ t = w[i - 2];
+ uint64_t s1 = rot64(t, 19) ^ rot64(t, 61) ^ (t >> 6);
+ w[i] = w[i - 16] + s0 + w[i - 7] + s1;
+ }
+ uint64_t s[8];
+ for (int i = 0; i < 8; i++) {
+ s[i] = h_[i];
+ }
+ for (int i = 0; i < 80; i += 8) {
+ round1<0, 1, 2, 3, 4, 5, 6, 7>(s, w, i + 0);
+ round1<7, 0, 1, 2, 3, 4, 5, 6>(s, w, i + 1);
+ round1<6, 7, 0, 1, 2, 3, 4, 5>(s, w, i + 2);
+ round1<5, 6, 7, 0, 1, 2, 3, 4>(s, w, i + 3);
+ round1<4, 5, 6, 7, 0, 1, 2, 3>(s, w, i + 4);
+ round1<3, 4, 5, 6, 7, 0, 1, 2>(s, w, i + 5);
+ round1<2, 3, 4, 5, 6, 7, 0, 1>(s, w, i + 6);
+ round1<1, 2, 3, 4, 5, 6, 7, 0>(s, w, i + 7);
+ }
+ for (int i = 0; i < 8; i++) {
+ h_[i] += s[i];
+ }
+ totalSize_ += blockSize_;
+ }
+ /*
+ final phase
+ */
+ void term(const char *buf, size_t bufSize)
+ {
+ assert(bufSize < blockSize_);
+ const uint64_t totalSize = totalSize_ + bufSize;
+
+ uint8_t last[blockSize_];
+ memcpy(last, buf, bufSize);
+ memset(&last[bufSize], 0, blockSize_ - bufSize);
+ last[bufSize] = uint8_t(0x80); /* top bit = 1 */
+ if (bufSize >= blockSize_ - 16) {
+ round(reinterpret_cast<const char*>(last));
+ memset(last, 0, sizeof(last)); // clear stack
+ }
+ cybozu::Set64bitAsBE(&last[blockSize_ - 8], totalSize * 8);
+ round(reinterpret_cast<const char*>(last));
+ }
+public:
+ Sha512()
+ {
+ clear();
+ }
+ Sha512(const void *buf, size_t bufSize)
+ {
+ clear();
+ digest(buf, bufSize);
+ }
+ void clear()
+ {
+ static const uint64_t kTbl[] = {
+ 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL,
+ 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
+ 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
+ 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
+ 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL,
+ 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
+ 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL,
+ 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
+ 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
+ 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
+ 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL,
+ 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
+ 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL,
+ 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
+ 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
+ 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
+ };
+ k_ = kTbl;
+ totalSize_ = 0;
+ roundBufSize_ = 0;
+ h_[0] = 0x6a09e667f3bcc908ull;
+ h_[1] = 0xbb67ae8584caa73bull;
+ h_[2] = 0x3c6ef372fe94f82bull;
+ h_[3] = 0xa54ff53a5f1d36f1ull;
+ h_[4] = 0x510e527fade682d1ull;
+ h_[5] = 0x9b05688c2b3e6c1full;
+ h_[6] = 0x1f83d9abfb41bd6bull;
+ h_[7] = 0x5be0cd19137e2179ull;
+ }
+ void update(const void *buf_, size_t bufSize)
+ {
+ const char *buf = reinterpret_cast<const char*>(buf_);
+ if (bufSize == 0) return;
+ if (roundBufSize_ > 0) {
+ size_t size = sha2_local::min_(blockSize_ - roundBufSize_, bufSize);
+ memcpy(roundBuf_ + roundBufSize_, buf, size);
+ roundBufSize_ += size;
+ buf += size;
+ bufSize -= size;
+ }
+ if (roundBufSize_ == blockSize_) {
+ round(roundBuf_);
+ roundBufSize_ = 0;
+ }
+ while (bufSize >= blockSize_) {
+ assert(roundBufSize_ == 0);
+ round(buf);
+ buf += blockSize_;
+ bufSize -= blockSize_;
+ }
+ if (bufSize > 0) {
+ assert(bufSize < blockSize_);
+ assert(roundBufSize_ == 0);
+ memcpy(roundBuf_, buf, bufSize);
+ roundBufSize_ = bufSize;
+ }
+ assert(roundBufSize_ < blockSize_);
+ }
+ void digest(const void *buf, size_t bufSize)
+ {
+ update(buf, bufSize);
+ term(roundBuf_, roundBufSize_);
+ }
+ size_t get(void *out) const
+ {
+ char *p = reinterpret_cast<char*>(out);
+ for (size_t i = 0; i < hSize_; i++) {
+ cybozu::Set64bitAsBE(&p[i * sizeof(h_[0])], h_[i]);
+ }
+ return outByteSize_;
+ }
+#ifndef CYBOZU_DONT_USE_STRING
+ void digest(const std::string& str = "")
+ {
+ digest(str.c_str(), str.size());
+ }
+ void update(const std::string& buf)
+ {
+ update(buf.c_str(), buf.size());
+ }
+ std::string get() const
+ {
+ char out[outByteSize_];
+ get(out);
+ return std::string(out, sizeof(out));
+ }
+ std::string toHexStr() const
+ {
+ char buf[outByteSize_ * 2];
+ sha2_local::uint64toHexStr(buf, h_, hSize_);
+ return std::string(buf, sizeof(buf));
+ }
+#endif
+};
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/stream.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/stream.hpp
new file mode 100644
index 000000000..bc110bdb0
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/stream.hpp
@@ -0,0 +1,267 @@
+#pragma once
+/**
+ @file
+ @brief stream and line stream class
+
+ @author MITSUNARI Shigeo(@herumi)
+*/
+#ifndef CYBOZU_DONT_USE_STRING
+#include <string>
+#include <iosfwd>
+#endif
+#include <cybozu/exception.hpp>
+#include <memory.h>
+
+namespace cybozu {
+
+namespace stream_local {
+
+template <typename From, typename To>
+struct is_convertible {
+ typedef char yes;
+ typedef int no;
+
+ static no test(...);
+ static yes test(const To*);
+ static const bool value = sizeof(test(static_cast<const From*>(0))) == sizeof(yes);
+};
+
+template <bool b, class T = void>
+struct enable_if { typedef T type; };
+
+template <class T>
+struct enable_if<false, T> {};
+
+#ifndef CYBOZU_DONT_USE_STRING
+/* specialization for istream */
+template<class InputStream>
+size_t readSome_inner(void *buf, size_t size, InputStream& is, typename enable_if<is_convertible<InputStream, std::istream>::value>::type* = 0)
+{
+ if (size > 0x7fffffff) size = 0x7fffffff;
+ is.read(static_cast<char *>(buf), size);
+ const int64_t readSize = is.gcount();
+ if (readSize < 0) return 0;
+ if (size == 1 && readSize == 0) is.clear();
+ return static_cast<size_t>(readSize);
+}
+
+/* generic version for size_t readSome(void *, size_t) */
+template<class InputStream>
+size_t readSome_inner(void *buf, size_t size, InputStream& is, typename enable_if<!is_convertible<InputStream, std::istream>::value>::type* = 0)
+{
+ return is.readSome(buf, size);
+}
+#else
+template<class InputStream>
+size_t readSome_inner(void *buf, size_t size, InputStream& is)
+{
+ return is.readSome(buf, size);
+}
+#endif
+
+#ifndef CYBOZU_DONT_USE_EXCEPTION
+/* specialization for ostream */
+template<class OutputStream>
+void writeSub(OutputStream& os, const void *buf, size_t size, typename enable_if<is_convertible<OutputStream, std::ostream>::value>::type* = 0)
+{
+ if (!os.write(static_cast<const char *>(buf), size)) throw cybozu::Exception("stream:writeSub") << size;
+}
+#endif
+
+#ifndef CYBOZU_DONT_USE_STRING
+/* generic version for void write(const void*, size_t), which writes all data */
+template<class OutputStream>
+void writeSub(OutputStream& os, const void *buf, size_t size, typename enable_if<!is_convertible<OutputStream, std::ostream>::value>::type* = 0)
+{
+ os.write(buf, size);
+}
+
+template<class OutputStream>
+void writeSub(bool *pb, OutputStream& os, const void *buf, size_t size, typename enable_if<is_convertible<OutputStream, std::ostream>::value>::type* = 0)
+{
+ *pb = !!os.write(static_cast<const char *>(buf), size);
+}
+
+/* generic version for void write(const void*, size_t), which writes all data */
+template<class OutputStream>
+void writeSub(bool *pb, OutputStream& os, const void *buf, size_t size, typename enable_if<!is_convertible<OutputStream, std::ostream>::value>::type* = 0)
+{
+ os.write(pb, buf, size);
+}
+#else
+template<class OutputStream>
+void writeSub(bool *pb, OutputStream& os, const void *buf, size_t size)
+{
+ os.write(pb, buf, size);
+}
+#endif
+
+} // stream_local
+
+/*
+ make a specializaiton of class to use new InputStream, OutputStream
+*/
+template<class InputStream>
+struct InputStreamTag {
+ static size_t readSome(void *buf, size_t size, InputStream& is)
+ {
+ return stream_local::readSome_inner<InputStream>(buf, size, is);
+ }
+ static bool readChar(char *c, InputStream& is)
+ {
+ return readSome(c, 1, is) == 1;
+ }
+};
+
+template<class OutputStream>
+struct OutputStreamTag {
+ static void write(OutputStream& os, const void *buf, size_t size)
+ {
+ stream_local::writeSub<OutputStream>(os, buf, size);
+ }
+};
+
+class MemoryInputStream {
+ const char *p_;
+ size_t size_;
+ size_t pos;
+public:
+ MemoryInputStream(const void *p, size_t size) : p_(static_cast<const char *>(p)), size_(size), pos(0) {}
+ size_t readSome(void *buf, size_t size)
+ {
+ if (size > size_ - pos) size = size_ - pos;
+ memcpy(buf, p_ + pos, size);
+ pos += size;
+ return size;
+ }
+ size_t getPos() const { return pos; }
+};
+
+class MemoryOutputStream {
+ char *p_;
+ size_t size_;
+ size_t pos;
+public:
+ MemoryOutputStream(void *p, size_t size) : p_(static_cast<char *>(p)), size_(size), pos(0) {}
+ void write(bool *pb, const void *buf, size_t size)
+ {
+ if (size > size_ - pos) {
+ *pb = false;
+ return;
+ }
+ memcpy(p_ + pos, buf, size);
+ pos += size;
+ *pb = true;
+ }
+#ifndef CYBOZU_DONT_USE_EXCEPTION
+ void write(const void *buf, size_t size)
+ {
+ bool b;
+ write(&b, buf, size);
+ if (!b) throw cybozu::Exception("MemoryOutputStream:write") << size << size_ << pos;
+ }
+#endif
+ size_t getPos() const { return pos; }
+};
+
+#ifndef CYBOZU_DONT_USE_STRING
+class StringInputStream {
+ const std::string& str_;
+ size_t pos;
+ StringInputStream(const StringInputStream&);
+ void operator=(const StringInputStream&);
+public:
+ explicit StringInputStream(const std::string& str) : str_(str), pos(0) {}
+ size_t readSome(void *buf, size_t size)
+ {
+ const size_t remainSize = str_.size() - pos;
+ if (size > remainSize) size = remainSize;
+ memcpy(buf, &str_[pos], size);
+ pos += size;
+ return size;
+ }
+ size_t getPos() const { return pos; }
+};
+
+class StringOutputStream {
+ std::string& str_;
+ StringOutputStream(const StringOutputStream&);
+ void operator=(const StringOutputStream&);
+public:
+ explicit StringOutputStream(std::string& str) : str_(str) {}
+ void write(bool *pb, const void *buf, size_t size)
+ {
+ str_.append(static_cast<const char *>(buf), size);
+ *pb = true;
+ }
+ void write(const void *buf, size_t size)
+ {
+ str_.append(static_cast<const char *>(buf), size);
+ }
+ size_t getPos() const { return str_.size(); }
+};
+#endif
+
+template<class InputStream>
+size_t readSome(void *buf, size_t size, InputStream& is)
+{
+ return stream_local::readSome_inner(buf, size, is);
+}
+
+template<class OutputStream>
+void write(OutputStream& os, const void *buf, size_t size)
+{
+ stream_local::writeSub(os, buf, size);
+}
+
+template<class OutputStream>
+void write(bool *pb, OutputStream& os, const void *buf, size_t size)
+{
+ stream_local::writeSub(pb, os, buf, size);
+}
+
+template<typename InputStream>
+void read(bool *pb, void *buf, size_t size, InputStream& is)
+{
+ char *p = static_cast<char*>(buf);
+ while (size > 0) {
+ size_t readSize = cybozu::readSome(p, size, is);
+ if (readSize == 0) {
+ *pb = false;
+ return;
+ }
+ p += readSize;
+ size -= readSize;
+ }
+ *pb = true;
+}
+
+#ifndef CYBOZU_DONT_USE_EXCEPTION
+template<typename InputStream>
+void read(void *buf, size_t size, InputStream& is)
+{
+ bool b;
+ read(&b, buf, size, is);
+ if (!b) throw cybozu::Exception("stream:read");
+}
+#endif
+
+template<class InputStream>
+bool readChar(char *c, InputStream& is)
+{
+ return readSome(c, 1, is) == 1;
+}
+
+template<class OutputStream>
+void writeChar(OutputStream& os, char c)
+{
+ cybozu::write(os, &c, 1);
+}
+
+template<class OutputStream>
+void writeChar(bool *pb, OutputStream& os, char c)
+{
+ cybozu::write(pb, os, &c, 1);
+}
+
+} // cybozu
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/test.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/test.hpp
new file mode 100644
index 000000000..7dfffab96
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/test.hpp
@@ -0,0 +1,373 @@
+#pragma once
+/**
+ @file
+ @brief unit test class
+
+ @author MITSUNARI Shigeo(@herumi)
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <string>
+#include <list>
+#include <iostream>
+#include <utility>
+#if defined(_MSC_VER) && (MSC_VER <= 1500)
+ #include <cybozu/inttype.hpp>
+#else
+ #include <stdint.h>
+#endif
+
+namespace cybozu { namespace test {
+
+class AutoRun {
+ typedef void (*Func)();
+ typedef std::list<std::pair<const char*, Func> > UnitTestList;
+public:
+ AutoRun()
+ : init_(0)
+ , term_(0)
+ , okCount_(0)
+ , ngCount_(0)
+ , exceptionCount_(0)
+ {
+ }
+ void setup(Func init, Func term)
+ {
+ init_ = init;
+ term_ = term;
+ }
+ void append(const char *name, Func func)
+ {
+ list_.push_back(std::make_pair(name, func));
+ }
+ void set(bool isOK)
+ {
+ if (isOK) {
+ okCount_++;
+ } else {
+ ngCount_++;
+ }
+ }
+ std::string getBaseName(const std::string& name) const
+ {
+#ifdef _WIN32
+ const char sep = '\\';
+#else
+ const char sep = '/';
+#endif
+ size_t pos = name.find_last_of(sep);
+ std::string ret = name.substr(pos + 1);
+ pos = ret.find('.');
+ return ret.substr(0, pos);
+ }
+ int run(int, char *argv[])
+ {
+ std::string msg;
+ try {
+ if (init_) init_();
+ for (UnitTestList::const_iterator i = list_.begin(), ie = list_.end(); i != ie; ++i) {
+ std::cout << "ctest:module=" << i->first << std::endl;
+ try {
+ (i->second)();
+ } catch (std::exception& e) {
+ exceptionCount_++;
+ std::cout << "ctest: " << i->first << " is stopped by exception " << e.what() << std::endl;
+ } catch (...) {
+ exceptionCount_++;
+ std::cout << "ctest: " << i->first << " is stopped by unknown exception" << std::endl;
+ }
+ }
+ if (term_) term_();
+ } catch (std::exception& e) {
+ msg = std::string("ctest:err:") + e.what();
+ } catch (...) {
+ msg = "ctest:err: catch unknown exception";
+ }
+ fflush(stdout);
+ if (msg.empty()) {
+ int err = ngCount_ + exceptionCount_;
+ int total = okCount_ + err;
+ std::cout << "ctest:name=" << getBaseName(*argv)
+ << ", module=" << list_.size()
+ << ", total=" << total
+ << ", ok=" << okCount_
+ << ", ng=" << ngCount_
+ << ", exception=" << exceptionCount_ << std::endl;
+ return err > 0 ? 1 : 0;
+ } else {
+ std::cout << msg << std::endl;
+ return 1;
+ }
+ }
+ static inline AutoRun& getInstance()
+ {
+ static AutoRun instance;
+ return instance;
+ }
+private:
+ Func init_;
+ Func term_;
+ int okCount_;
+ int ngCount_;
+ int exceptionCount_;
+ UnitTestList list_;
+};
+
+static AutoRun& autoRun = AutoRun::getInstance();
+
+inline void test(bool ret, const std::string& msg, const std::string& param, const char *file, int line)
+{
+ autoRun.set(ret);
+ if (!ret) {
+ printf("%s(%d):ctest:%s(%s);\n", file, line, msg.c_str(), param.c_str());
+ }
+}
+
+template<typename T, typename U>
+bool isEqual(const T& lhs, const U& rhs)
+{
+ return lhs == rhs;
+}
+
+// avoid warning of comparision of integers of different signs
+inline bool isEqual(size_t lhs, int rhs)
+{
+ return lhs == size_t(rhs);
+}
+inline bool isEqual(int lhs, size_t rhs)
+{
+ return size_t(lhs) == rhs;
+}
+inline bool isEqual(const char *lhs, const char *rhs)
+{
+ return strcmp(lhs, rhs) == 0;
+}
+inline bool isEqual(char *lhs, const char *rhs)
+{
+ return strcmp(lhs, rhs) == 0;
+}
+inline bool isEqual(const char *lhs, char *rhs)
+{
+ return strcmp(lhs, rhs) == 0;
+}
+inline bool isEqual(char *lhs, char *rhs)
+{
+ return strcmp(lhs, rhs) == 0;
+}
+// avoid to compare float directly
+inline bool isEqual(float lhs, float rhs)
+{
+ union fi {
+ float f;
+ uint32_t i;
+ } lfi, rfi;
+ lfi.f = lhs;
+ rfi.f = rhs;
+ return lfi.i == rfi.i;
+}
+// avoid to compare double directly
+inline bool isEqual(double lhs, double rhs)
+{
+ union di {
+ double d;
+ uint64_t i;
+ } ldi, rdi;
+ ldi.d = lhs;
+ rdi.d = rhs;
+ return ldi.i == rdi.i;
+}
+
+} } // cybozu::test
+
+#ifndef CYBOZU_TEST_DISABLE_AUTO_RUN
+int main(int argc, char *argv[])
+{
+ return cybozu::test::autoRun.run(argc, argv);
+}
+#endif
+
+/**
+ alert if !x
+ @param x [in]
+*/
+#define CYBOZU_TEST_ASSERT(x) cybozu::test::test(!!(x), "CYBOZU_TEST_ASSERT", #x, __FILE__, __LINE__)
+
+/**
+ alert if x != y
+ @param x [in]
+ @param y [in]
+*/
+#define CYBOZU_TEST_EQUAL(x, y) { \
+ bool _cybozu_eq = cybozu::test::isEqual(x, y); \
+ cybozu::test::test(_cybozu_eq, "CYBOZU_TEST_EQUAL", #x ", " #y, __FILE__, __LINE__); \
+ if (!_cybozu_eq) { \
+ std::cout << "ctest: lhs=" << (x) << std::endl; \
+ std::cout << "ctest: rhs=" << (y) << std::endl; \
+ } \
+}
+/**
+ alert if fabs(x, y) >= eps
+ @param x [in]
+ @param y [in]
+*/
+#define CYBOZU_TEST_NEAR(x, y, eps) { \
+ bool _cybozu_isNear = fabs((x) - (y)) < eps; \
+ cybozu::test::test(_cybozu_isNear, "CYBOZU_TEST_NEAR", #x ", " #y, __FILE__, __LINE__); \
+ if (!_cybozu_isNear) { \
+ std::cout << "ctest: lhs=" << (x) << std::endl; \
+ std::cout << "ctest: rhs=" << (y) << std::endl; \
+ } \
+}
+
+#define CYBOZU_TEST_EQUAL_POINTER(x, y) { \
+ bool _cybozu_eq = x == y; \
+ cybozu::test::test(_cybozu_eq, "CYBOZU_TEST_EQUAL_POINTER", #x ", " #y, __FILE__, __LINE__); \
+ if (!_cybozu_eq) { \
+ std::cout << "ctest: lhs=" << static_cast<const void*>(x) << std::endl; \
+ std::cout << "ctest: rhs=" << static_cast<const void*>(y) << std::endl; \
+ } \
+}
+/**
+ alert if x[] != y[]
+ @param x [in]
+ @param y [in]
+ @param n [in]
+*/
+#define CYBOZU_TEST_EQUAL_ARRAY(x, y, n) { \
+ for (size_t _cybozu_test_i = 0, _cybozu_ie = (size_t)(n); _cybozu_test_i < _cybozu_ie; _cybozu_test_i++) { \
+ bool _cybozu_eq = cybozu::test::isEqual((x)[_cybozu_test_i], (y)[_cybozu_test_i]); \
+ cybozu::test::test(_cybozu_eq, "CYBOZU_TEST_EQUAL_ARRAY", #x ", " #y ", " #n, __FILE__, __LINE__); \
+ if (!_cybozu_eq) { \
+ std::cout << "ctest: i=" << _cybozu_test_i << std::endl; \
+ std::cout << "ctest: lhs=" << (x)[_cybozu_test_i] << std::endl; \
+ std::cout << "ctest: rhs=" << (y)[_cybozu_test_i] << std::endl; \
+ } \
+ } \
+}
+
+/**
+ always alert
+ @param msg [in]
+*/
+#define CYBOZU_TEST_FAIL(msg) cybozu::test::test(false, "CYBOZU_TEST_FAIL", msg, __FILE__, __LINE__)
+
+/**
+ verify message in exception
+*/
+#define CYBOZU_TEST_EXCEPTION_MESSAGE(statement, Exception, msg) \
+{ \
+ int _cybozu_ret = 0; \
+ std::string _cybozu_errMsg; \
+ try { \
+ statement; \
+ _cybozu_ret = 1; \
+ } catch (const Exception& _cybozu_e) { \
+ _cybozu_errMsg = _cybozu_e.what(); \
+ if (_cybozu_errMsg.find(msg) == std::string::npos) { \
+ _cybozu_ret = 2; \
+ } \
+ } catch (...) { \
+ _cybozu_ret = 3; \
+ } \
+ if (_cybozu_ret) { \
+ cybozu::test::test(false, "CYBOZU_TEST_EXCEPTION_MESSAGE", #statement ", " #Exception ", " #msg, __FILE__, __LINE__); \
+ if (_cybozu_ret == 1) { \
+ std::cout << "ctest: no exception" << std::endl; \
+ } else if (_cybozu_ret == 2) { \
+ std::cout << "ctest: bad exception msg:" << _cybozu_errMsg << std::endl; \
+ } else { \
+ std::cout << "ctest: unexpected exception" << std::endl; \
+ } \
+ } else { \
+ cybozu::test::autoRun.set(true); \
+ } \
+}
+
+#define CYBOZU_TEST_EXCEPTION(statement, Exception) \
+{ \
+ int _cybozu_ret = 0; \
+ try { \
+ statement; \
+ _cybozu_ret = 1; \
+ } catch (const Exception&) { \
+ } catch (...) { \
+ _cybozu_ret = 2; \
+ } \
+ if (_cybozu_ret) { \
+ cybozu::test::test(false, "CYBOZU_TEST_EXCEPTION", #statement ", " #Exception, __FILE__, __LINE__); \
+ if (_cybozu_ret == 1) { \
+ std::cout << "ctest: no exception" << std::endl; \
+ } else { \
+ std::cout << "ctest: unexpected exception" << std::endl; \
+ } \
+ } else { \
+ cybozu::test::autoRun.set(true); \
+ } \
+}
+
+/**
+ verify statement does not throw
+*/
+#define CYBOZU_TEST_NO_EXCEPTION(statement) \
+try { \
+ statement; \
+ cybozu::test::autoRun.set(true); \
+} catch (...) { \
+ cybozu::test::test(false, "CYBOZU_TEST_NO_EXCEPTION", #statement, __FILE__, __LINE__); \
+}
+
+/**
+ append auto unit test
+ @param name [in] module name
+*/
+#define CYBOZU_TEST_AUTO(name) \
+void cybozu_test_ ## name(); \
+struct cybozu_test_local_ ## name { \
+ cybozu_test_local_ ## name() \
+ { \
+ cybozu::test::autoRun.append(#name, cybozu_test_ ## name); \
+ } \
+} cybozu_test_local_instance_ ## name; \
+void cybozu_test_ ## name()
+
+/**
+ append auto unit test with fixture
+ @param name [in] module name
+*/
+#define CYBOZU_TEST_AUTO_WITH_FIXTURE(name, Fixture) \
+void cybozu_test_ ## name(); \
+void cybozu_test_real_ ## name() \
+{ \
+ Fixture f; \
+ cybozu_test_ ## name(); \
+} \
+struct cybozu_test_local_ ## name { \
+ cybozu_test_local_ ## name() \
+ { \
+ cybozu::test::autoRun.append(#name, cybozu_test_real_ ## name); \
+ } \
+} cybozu_test_local_instance_ ## name; \
+void cybozu_test_ ## name()
+
+/**
+ setup fixture
+ @param Fixture [in] class name of fixture
+ @note cstr of Fixture is called before test and dstr of Fixture is called after test
+*/
+#define CYBOZU_TEST_SETUP_FIXTURE(Fixture) \
+Fixture *cybozu_test_local_fixture; \
+void cybozu_test_local_init() \
+{ \
+ cybozu_test_local_fixture = new Fixture(); \
+} \
+void cybozu_test_local_term() \
+{ \
+ delete cybozu_test_local_fixture; \
+} \
+struct cybozu_test_local_fixture_setup_ { \
+ cybozu_test_local_fixture_setup_() \
+ { \
+ cybozu::test::autoRun.setup(cybozu_test_local_init, cybozu_test_local_term); \
+ } \
+} cybozu_test_local_fixture_setup_instance_;
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/unordered_map.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/unordered_map.hpp
new file mode 100644
index 000000000..89f8f8774
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/unordered_map.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include <cybozu/inttype.hpp>
+
+#ifdef CYBOZU_USE_BOOST
+ #include <boost/unordered_map.hpp>
+#elif (CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11) || (defined __APPLE__)
+ #include <unordered_map>
+#elif (CYBOZU_CPP_VERSION == CYBOZU_CPP_VERSION_TR1)
+ #include <list>
+ #include <tr1/unordered_map>
+#endif
+
diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp
new file mode 100644
index 000000000..69edaa939
--- /dev/null
+++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp
@@ -0,0 +1,172 @@
+#pragma once
+/**
+ @file
+ @brief XorShift
+
+ @author MITSUNARI Shigeo(@herumi)
+ @author MITSUNARI Shigeo
+*/
+#include <cybozu/inttype.hpp>
+
+namespace cybozu {
+
+class XorShift {
+ uint32_t x_, y_, z_, w_;
+public:
+ explicit XorShift(uint32_t x = 0, uint32_t y = 0, uint32_t z = 0, uint32_t w = 0)
+ {
+ init(x, y, z, w);
+ }
+ void init(uint32_t x = 0, uint32_t y = 0, uint32_t z = 0, uint32_t w = 0)
+ {
+ x_ = x ? x : 123456789;
+ y_ = y ? y : 362436069;
+ z_ = z ? z : 521288629;
+ w_ = w ? w : 88675123;
+ }
+ uint32_t get32()
+ {
+ unsigned int t = x_ ^ (x_ << 11);
+ x_ = y_; y_ = z_; z_ = w_;
+ return w_ = (w_ ^ (w_ >> 19)) ^ (t ^ (t >> 8));
+ }
+ uint32_t operator()() { return get32(); }
+ uint64_t get64()
+ {
+ uint32_t a = get32();
+ uint32_t b = get32();
+ return (uint64_t(a) << 32) | b;
+ }
+ template<class T>
+ void read(T *x, size_t n)
+ {
+ const size_t size = sizeof(T) * n;
+ uint8_t *p8 = static_cast<uint8_t*>(x);
+ for (size_t i = 0; i < size; i++) {
+ p8[i] = static_cast<uint8_t>(get32());
+ }
+ }
+ void read(uint32_t *x, size_t n)
+ {
+ for (size_t i = 0; i < n; i++) {
+ x[i] = get32();
+ }
+ }
+ void read(uint64_t *x, size_t n)
+ {
+ for (size_t i = 0; i < n; i++) {
+ x[i] = get64();
+ }
+ }
+};
+
+// see http://xorshift.di.unimi.it/xorshift128plus.c
+class XorShift128Plus {
+ uint64_t s_[2];
+ static const uint64_t seed0 = 123456789;
+ static const uint64_t seed1 = 987654321;
+public:
+ explicit XorShift128Plus(uint64_t s0 = seed0, uint64_t s1 = seed1)
+ {
+ init(s0, s1);
+ }
+ void init(uint64_t s0 = seed0, uint64_t s1 = seed1)
+ {
+ s_[0] = s0;
+ s_[1] = s1;
+ }
+ uint32_t get32()
+ {
+ return static_cast<uint32_t>(get64());
+ }
+ uint64_t operator()() { return get64(); }
+ uint64_t get64()
+ {
+ uint64_t s1 = s_[0];
+ const uint64_t s0 = s_[1];
+ s_[0] = s0;
+ s1 ^= s1 << 23;
+ s_[1] = s1 ^ s0 ^ (s1 >> 18) ^ (s0 >> 5);
+ return s_[1] + s0;
+ }
+ template<class T>
+ void read(T *x, size_t n)
+ {
+ const size_t size = sizeof(T) * n;
+ uint8_t *p8 = static_cast<uint8_t*>(x);
+ for (size_t i = 0; i < size; i++) {
+ p8[i] = static_cast<uint8_t>(get32());
+ }
+ }
+ void read(uint32_t *x, size_t n)
+ {
+ for (size_t i = 0; i < n; i++) {
+ x[i] = get32();
+ }
+ }
+ void read(uint64_t *x, size_t n)
+ {
+ for (size_t i = 0; i < n; i++) {
+ x[i] = get64();
+ }
+ }
+};
+
+// see http://xoroshiro.di.unimi.it/xoroshiro128plus.c
+class Xoroshiro128Plus {
+ uint64_t s_[2];
+ static const uint64_t seed0 = 123456789;
+ static const uint64_t seed1 = 987654321;
+ uint64_t rotl(uint64_t x, unsigned int k) const
+ {
+ return (x << k) | (x >> (64 - k));
+ }
+public:
+ explicit Xoroshiro128Plus(uint64_t s0 = seed0, uint64_t s1 = seed1)
+ {
+ init(s0, s1);
+ }
+ void init(uint64_t s0 = seed0, uint64_t s1 = seed1)
+ {
+ s_[0] = s0;
+ s_[1] = s1;
+ }
+ uint32_t get32()
+ {
+ return static_cast<uint32_t>(get64());
+ }
+ uint64_t operator()() { return get64(); }
+ uint64_t get64()
+ {
+ uint64_t s0 = s_[0];
+ uint64_t s1 = s_[1];
+ uint64_t result = s0 + s1;
+ s1 ^= s0;
+ s_[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14);
+ s_[1] = rotl(s1, 36);
+ return result;
+ }
+ template<class T>
+ void read(T *x, size_t n)
+ {
+ const size_t size = sizeof(T) * n;
+ uint8_t *p8 = static_cast<uint8_t*>(x);
+ for (size_t i = 0; i < size; i++) {
+ p8[i] = static_cast<uint8_t>(get32());
+ }
+ }
+ void read(uint32_t *x, size_t n)
+ {
+ for (size_t i = 0; i < n; i++) {
+ x[i] = get32();
+ }
+ }
+ void read(uint64_t *x, size_t n)
+ {
+ for (size_t i = 0; i < n; i++) {
+ x[i] = get64();
+ }
+ }
+};
+
+} // cybozu