diff options
Diffstat (limited to 'vendor/github.com/dexon-foundation/mcl/include')
18 files changed, 1681 insertions, 518 deletions
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 index 23096989d..ff4a78da5 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp @@ -54,11 +54,9 @@ public: } throw cybozu::Exception("randomgenerator"); } - void read_inner(void *buf, size_t byteSize) + bool 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; - } + return CryptGenRandom(prov_, static_cast<DWORD>(byteSize), static_cast<BYTE*>(buf)) != 0; } ~RandomGenerator() { @@ -71,12 +69,15 @@ public: @note bufNum is not byte size */ template<class T> - void read(T *buf, size_t bufNum) + void read(bool *pb, T *buf, size_t bufNum) { cybozu::AutoLockCs al(cs_); const size_t byteSize = sizeof(T) * bufNum; if (byteSize > bufSize) { - read_inner(buf, byteSize); + if (!read_inner(buf, byteSize)) { + *pb = false; + return; + } } else { if (pos_ + byteSize > bufSize) { read_inner(buf_, bufSize); @@ -85,6 +86,14 @@ public: memcpy(buf, buf_ + pos_, byteSize); pos_ += byteSize; } + *pb = true; + } + template<class T> + void read(T *buf, size_t bufNum) + { + bool b; + read(&b, buf, bufNum); + if (!b) throw cybozu::Exception("RandomGenerator:read") << bufNum; } private: HCRYPTPROV prov_; @@ -107,12 +116,17 @@ private: @note bufNum is not byte size */ template<class T> - void read(T *buf, size_t bufNum) + void read(bool *pb, 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; - } + *pb = ::fread(buf, 1, (int)byteSize, fp_) == byteSize; + } + template<class T> + void read(T *buf, size_t bufNum) + { + bool b; + read(&b, buf, bufNum); + if (!b) throw cybozu::Exception("RandomGenerator:read") << bufNum; } #endif private: diff --git a/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp b/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp index 97193849b..1830936f0 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp @@ -6,36 +6,124 @@ @license modified new BSD license http://opensource.org/licenses/BSD-3-Clause */ -#include <cybozu/endian.hpp> +#if !defined(CYBOZU_DONT_USE_OPENSSL) && !defined(MCL_DONT_USE_OPENSSL) + #define CYBOZU_USE_OPENSSL_SHA +#endif + #ifndef CYBOZU_DONT_USE_STRING -#include <cybozu/itoa.hpp> #include <string> #endif -#include <memory.h> -#include <assert.h> -namespace cybozu { +#ifdef CYBOZU_USE_OPENSSL_SHA +#ifdef __APPLE__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif +#include <openssl/sha.h> +#ifdef _MSC_VER + #include <cybozu/link_libeay32.hpp> +#endif -namespace sha2_local { +#ifdef __APPLE__ + #pragma GCC diagnostic pop +#endif -template<class T> -T min_(T x, T y) { return x < y ? x : y;; } +namespace cybozu { +class Sha256 { + SHA256_CTX ctx_; +public: + Sha256() + { + clear(); + } + void clear() + { + SHA256_Init(&ctx_); + } + void update(const void *buf, size_t bufSize) + { + SHA256_Update(&ctx_, buf, bufSize); + } + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) + { + if (mdSize < SHA256_DIGEST_LENGTH) return 0; + update(buf, bufSize); + SHA256_Final(reinterpret_cast<uint8_t*>(md), &ctx_); + return SHA256_DIGEST_LENGTH; + } #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); + void update(const std::string& buf) + { + update(buf.c_str(), buf.size()); } -} + std::string digest(const std::string& buf) + { + return digest(buf.c_str(), buf.size()); + } + std::string digest(const void *buf, size_t bufSize) + { + std::string md(SHA256_DIGEST_LENGTH, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; + } +#endif +}; -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); +class Sha512 { + SHA512_CTX ctx_; +public: + Sha512() + { + clear(); + } + void clear() + { + SHA512_Init(&ctx_); + } + void update(const void *buf, size_t bufSize) + { + SHA512_Update(&ctx_, buf, bufSize); + } + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) + { + if (mdSize < SHA512_DIGEST_LENGTH) return 0; + update(buf, bufSize); + SHA512_Final(reinterpret_cast<uint8_t*>(md), &ctx_); + return SHA512_DIGEST_LENGTH; + } +#ifndef CYBOZU_DONT_USE_STRING + void update(const std::string& buf) + { + update(buf.c_str(), buf.size()); + } + std::string digest(const std::string& buf) + { + return digest(buf.c_str(), buf.size()); + } + std::string digest(const void *buf, size_t bufSize) + { + std::string md(SHA512_DIGEST_LENGTH, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; } -} #endif +}; + +} // cybozu + +#else + +#include <cybozu/endian.hpp> +#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;; } inline uint32_t rot32(uint32_t x, int s) { @@ -55,12 +143,64 @@ inline uint64_t rot64(uint64_t x, int s) #endif } +template<class T> +struct Common { + void term(const char *buf, size_t bufSize) + { + assert(bufSize < T::blockSize_); + T& self = static_cast<T&>(*this); + const uint64_t totalSize = self.totalSize_ + bufSize; + + uint8_t last[T::blockSize_]; + memcpy(last, buf, bufSize); + last[bufSize] = uint8_t(0x80); /* top bit = 1 */ + memset(&last[bufSize + 1], 0, T::blockSize_ - bufSize - 1); + if (bufSize >= T::blockSize_ - T::msgLenByte_) { + self.round(reinterpret_cast<const char*>(last)); + memset(last, 0, sizeof(last)); // clear stack + } + cybozu::Set64bitAsBE(&last[T::blockSize_ - 8], totalSize * 8); + self.round(reinterpret_cast<const char*>(last)); + } + void inner_update(const char *buf, size_t bufSize) + { + T& self = static_cast<T&>(*this); + if (bufSize == 0) return; + if (self.roundBufSize_ > 0) { + size_t size = sha2_local::min_(T::blockSize_ - self.roundBufSize_, bufSize); + memcpy(self.roundBuf_ + self.roundBufSize_, buf, size); + self.roundBufSize_ += size; + buf += size; + bufSize -= size; + } + if (self.roundBufSize_ == T::blockSize_) { + self.round(self.roundBuf_); + self.roundBufSize_ = 0; + } + while (bufSize >= T::blockSize_) { + assert(self.roundBufSize_ == 0); + self.round(buf); + buf += T::blockSize_; + bufSize -= T::blockSize_; + } + if (bufSize > 0) { + assert(bufSize < T::blockSize_); + assert(self.roundBufSize_ == 0); + memcpy(self.roundBuf_, buf, bufSize); + self.roundBufSize_ = bufSize; + } + assert(self.roundBufSize_ < T::blockSize_); + } +}; + } // cybozu::sha2_local -class Sha256 { +class Sha256 : public sha2_local::Common<Sha256> { + friend struct sha2_local::Common<Sha256>; private: static const size_t blockSize_ = 64; static const size_t hSize_ = 8; + static const size_t msgLenByte_ = 8; uint64_t totalSize_; size_t roundBufSize_; char roundBuf_[blockSize_]; @@ -117,38 +257,13 @@ private: 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)); + totalSize_ += blockSize_; } public: Sha256() { clear(); } - Sha256(const void *buf, size_t bufSize) - { - clear(); - digest(buf, bufSize); - } void clear() { static const uint32_t kTbl[] = { @@ -173,43 +288,16 @@ public: h_[6] = 0x1f83d9ab; h_[7] = 0x5be0cd19; } - void update(const void *buf_, size_t bufSize) + 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_); + inner_update(reinterpret_cast<const char*>(buf), bufSize); } - void digest(const void *buf, size_t bufSize) + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) { + if (mdSize < outByteSize_) return 0; update(buf, bufSize); term(roundBuf_, roundBufSize_); - } - size_t get(void *out) const - { - char *p = reinterpret_cast<char*>(out); + char *p = reinterpret_cast<char*>(md); for (size_t i = 0; i < hSize_; i++) { cybozu::Set32bitAsBE(&p[i * sizeof(h_[0])], h_[i]); } @@ -220,29 +308,25 @@ public: { update(buf.c_str(), buf.size()); } - void digest(const std::string& str = "") + std::string digest(const std::string& buf) { - digest(str.c_str(), str.size()); + return digest(buf.c_str(), buf.size()); } - std::string get() const + std::string digest(const void *buf, size_t bufSize) { - 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)); + std::string md(outByteSize_, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; } #endif }; -class Sha512 { +class Sha512 : public sha2_local::Common<Sha512> { + friend struct sha2_local::Common<Sha512>; private: static const size_t blockSize_ = 128; static const size_t hSize_ = 8; + static const size_t msgLenByte_ = 16; uint64_t totalSize_; size_t roundBufSize_; char roundBuf_[blockSize_]; @@ -308,35 +392,11 @@ private: } 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[] = { @@ -369,70 +429,39 @@ public: h_[6] = 0x1f83d9abfb41bd6bull; h_[7] = 0x5be0cd19137e2179ull; } - void update(const void *buf_, size_t bufSize) + 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_); + inner_update(reinterpret_cast<const char*>(buf), bufSize); } - void digest(const void *buf, size_t bufSize) + size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize) { + if (mdSize < outByteSize_) return 0; update(buf, bufSize); term(roundBuf_, roundBufSize_); - } - size_t get(void *out) const - { - char *p = reinterpret_cast<char*>(out); + char *p = reinterpret_cast<char*>(md); 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 + std::string digest(const std::string& buf) { - char out[outByteSize_]; - get(out); - return std::string(out, sizeof(out)); + return digest(buf.c_str(), buf.size()); } - std::string toHexStr() const + std::string digest(const void *buf, size_t bufSize) { - char buf[outByteSize_ * 2]; - sha2_local::uint64toHexStr(buf, h_, hSize_); - return std::string(buf, sizeof(buf)); + std::string md(outByteSize_, 0); + digest(&md[0], md.size(), buf, bufSize); + return md; } #endif }; } // cybozu + +#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 index 69edaa939..08c6a04f9 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp @@ -7,9 +7,47 @@ @author MITSUNARI Shigeo */ #include <cybozu/inttype.hpp> +#include <assert.h> namespace cybozu { +namespace xorshift_local { + +/* + U is uint32_t or uint64_t +*/ +template<class U, class Gen> +void read_local(void *p, size_t n, Gen& gen, U (Gen::*f)()) +{ + uint8_t *dst = static_cast<uint8_t*>(p); + const size_t uSize = sizeof(U); + assert(uSize == 4 || uSize == 8); + union ua { + U u; + uint8_t a[uSize]; + }; + + while (n >= uSize) { + ua ua; + ua.u = (gen.*f)(); + for (size_t i = 0; i < uSize; i++) { + dst[i] = ua.a[i]; + } + dst += uSize; + n -= uSize; + } + assert(n < uSize); + if (n > 0) { + ua ua; + ua.u = (gen.*f)(); + for (size_t i = 0; i < n; i++) { + dst[i] = ua.a[i]; + } + } +} + +} // xorshift_local + class XorShift { uint32_t x_, y_, z_, w_; public: @@ -38,25 +76,18 @@ public: 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) + void read(bool *pb, T *p, size_t n) { - for (size_t i = 0; i < n; i++) { - x[i] = get32(); - } + xorshift_local::read_local(p, n * sizeof(T), *this, &XorShift::get32); + *pb = true; } - void read(uint64_t *x, size_t n) + template<class T> + size_t read(T *p, size_t n) { - for (size_t i = 0; i < n; i++) { - x[i] = get64(); - } + bool b; + read(&b, p, n); + (void)b; + return n; } }; @@ -90,25 +121,18 @@ public: return s_[1] + s0; } template<class T> - void read(T *x, size_t n) + void read(bool *pb, T *p, 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()); - } + xorshift_local::read_local(p, n * sizeof(T), *this, &XorShift128Plus::get64); + *pb = true; } - 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) + template<class T> + size_t read(T *p, size_t n) { - for (size_t i = 0; i < n; i++) { - x[i] = get64(); - } + bool b; + read(&b, p, n); + (void)b; + return n; } }; @@ -147,25 +171,18 @@ public: return result; } template<class T> - void read(T *x, size_t n) + void read(bool *pb, T *p, 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(); - } + xorshift_local::read_local(p, n * sizeof(T), *this, &Xoroshiro128Plus::get64); + *pb = true; } - void read(uint64_t *x, size_t n) + template<class T> + size_t read(T *p, size_t n) { - for (size_t i = 0; i < n; i++) { - x[i] = get64(); - } + bool b; + read(&b, p, n); + (void)b; + return n; } }; diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/array.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/array.hpp index 84c5f3765..a6d2a8fa3 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/array.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/array.hpp @@ -8,6 +8,9 @@ */ #include <stdlib.h> #include <stddef.h> +#ifndef CYBOZU_DONT_USE_EXCEPTION +#include <new> +#endif namespace mcl { @@ -15,8 +18,6 @@ template<class T> class Array { T *p_; size_t n_; - Array(const Array&); - void operator=(const Array&); template<class U> void swap_(U& x, U& y) const { @@ -31,6 +32,26 @@ public: { free(p_); } +#ifndef CYBOZU_DONT_USE_EXCEPTION + Array(const Array& rhs) + : p_(0) + , n_(0) + { + if (rhs.n_ == 0) return; + p_ = (T*)malloc(sizeof(T) * rhs.n_); + if (p_ == 0) throw std::bad_alloc(); + n_ = rhs.n_; + for (size_t i = 0; i < n_; i++) { + p_[i] = rhs.p_[i]; + } + } + Array& operator=(const Array& rhs) + { + Array tmp(rhs); + tmp.swap(*this); + return *this; + } +#endif bool resize(size_t n) { if (n <= n_) { diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.h b/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.h index 9c78f92f1..0a31d5501 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.h +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.h @@ -68,6 +68,8 @@ typedef struct mclBnFr mclBnFr; typedef struct mclBnG1 mclBnG1; typedef struct mclBnG2 mclBnG2; typedef struct mclBnGT mclBnGT; +typedef struct mclBnFp mclBnFp; +typedef struct mclBnFp2 mclBnFp2; #else @@ -87,6 +89,14 @@ typedef struct { uint64_t d[MCLBN_FP_UNIT_SIZE * 12]; } mclBnGT; +typedef struct { + uint64_t d[MCLBN_FP_UNIT_SIZE]; +} mclBnFp; + +typedef struct { + mclBnFp d[2]; +} mclBnFp2; + #endif #include <mcl/curve_type.h> @@ -102,6 +112,8 @@ enum { mclBls12_CurveFp381 = 5 }; +// return 0xABC which means A.BC +MCLBN_DLL_API int mclBn_getVersion(); /* init library @param curve [in] type of bn curve @@ -146,6 +158,10 @@ MCLBN_DLL_API int mclBn_getG1ByteSize(void); return bytes for serialized Fr */ MCLBN_DLL_API int mclBn_getFrByteSize(void); +/* + return bytes for serialized Fp +*/ +MCLBN_DLL_API int mclBn_getFpByteSize(void); /* return decimal string of the order of the curve(=the characteristic of Fr) @@ -168,6 +184,8 @@ MCLBN_DLL_API mclSize mclBnFr_deserialize(mclBnFr *x, const void *buf, mclSize b MCLBN_DLL_API mclSize mclBnG1_deserialize(mclBnG1 *x, const void *buf, mclSize bufSize); MCLBN_DLL_API mclSize mclBnG2_deserialize(mclBnG2 *x, const void *buf, mclSize bufSize); MCLBN_DLL_API mclSize mclBnGT_deserialize(mclBnGT *x, const void *buf, mclSize bufSize); +MCLBN_DLL_API mclSize mclBnFp_deserialize(mclBnFp *x, const void *buf, mclSize bufSize); +MCLBN_DLL_API mclSize mclBnFp2_deserialize(mclBnFp2 *x, const void *buf, mclSize bufSize); /* serialize @@ -177,6 +195,8 @@ MCLBN_DLL_API mclSize mclBnFr_serialize(void *buf, mclSize maxBufSize, const mcl MCLBN_DLL_API mclSize mclBnG1_serialize(void *buf, mclSize maxBufSize, const mclBnG1 *x); MCLBN_DLL_API mclSize mclBnG2_serialize(void *buf, mclSize maxBufSize, const mclBnG2 *x); MCLBN_DLL_API mclSize mclBnGT_serialize(void *buf, mclSize maxBufSize, const mclBnGT *x); +MCLBN_DLL_API mclSize mclBnFp_serialize(void *buf, mclSize maxBufSize, const mclBnFp *x); +MCLBN_DLL_API mclSize mclBnFp2_serialize(void *buf, mclSize maxBufSize, const mclBnFp2 *x); /* set string @@ -190,6 +210,7 @@ MCLBN_DLL_API int mclBnFr_setStr(mclBnFr *x, const char *buf, mclSize bufSize, i MCLBN_DLL_API int mclBnG1_setStr(mclBnG1 *x, const char *buf, mclSize bufSize, int ioMode); MCLBN_DLL_API int mclBnG2_setStr(mclBnG2 *x, const char *buf, mclSize bufSize, int ioMode); MCLBN_DLL_API int mclBnGT_setStr(mclBnGT *x, const char *buf, mclSize bufSize, int ioMode); +MCLBN_DLL_API int mclBnFp_setStr(mclBnFp *x, const char *buf, mclSize bufSize, int ioMode); /* buf is terminated by '\0' @@ -199,16 +220,29 @@ MCLBN_DLL_API mclSize mclBnFr_getStr(char *buf, mclSize maxBufSize, const mclBnF MCLBN_DLL_API mclSize mclBnG1_getStr(char *buf, mclSize maxBufSize, const mclBnG1 *x, int ioMode); MCLBN_DLL_API mclSize mclBnG2_getStr(char *buf, mclSize maxBufSize, const mclBnG2 *x, int ioMode); MCLBN_DLL_API mclSize mclBnGT_getStr(char *buf, mclSize maxBufSize, const mclBnGT *x, int ioMode); +MCLBN_DLL_API mclSize mclBnFp_getStr(char *buf, mclSize maxBufSize, const mclBnFp *x, int ioMode); // set zero MCLBN_DLL_API void mclBnFr_clear(mclBnFr *x); +MCLBN_DLL_API void mclBnFp_clear(mclBnFp *x); +MCLBN_DLL_API void mclBnFp2_clear(mclBnFp2 *x); // set x to y MCLBN_DLL_API void mclBnFr_setInt(mclBnFr *y, mclInt x); MCLBN_DLL_API void mclBnFr_setInt32(mclBnFr *y, int x); -// mask buf with (1 << (bitLen(r) - 1)) - 1 if buf >= r +// x = buf & (1 << bitLen(r)) - 1 +// if (x >= r) x &= (1 << (bitLen(r) - 1)) - 1 +// always return 0 MCLBN_DLL_API int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize); +MCLBN_DLL_API int mclBnFp_setLittleEndian(mclBnFp *x, const void *buf, mclSize bufSize); + +// set (buf mod r) to x +// return 0 if bufSize <= (byte size of Fr * 2) else -1 +MCLBN_DLL_API int mclBnFr_setLittleEndianMod(mclBnFr *x, const void *buf, mclSize bufSize); +// set (buf mod p) to x +// return 0 if bufSize <= (byte size of Fp * 2) else -1 +MCLBN_DLL_API int mclBnFp_setLittleEndianMod(mclBnFp *x, const void *buf, mclSize bufSize); // return 1 if true and 0 otherwise MCLBN_DLL_API int mclBnFr_isValid(const mclBnFr *x); @@ -216,15 +250,33 @@ MCLBN_DLL_API int mclBnFr_isEqual(const mclBnFr *x, const mclBnFr *y); MCLBN_DLL_API int mclBnFr_isZero(const mclBnFr *x); MCLBN_DLL_API int mclBnFr_isOne(const mclBnFr *x); +MCLBN_DLL_API int mclBnFp_isEqual(const mclBnFp *x, const mclBnFp *y); +MCLBN_DLL_API int mclBnFp2_isEqual(const mclBnFp2 *x, const mclBnFp2 *y); + #ifndef MCL_DONT_USE_CSRPNG // return 0 if success MCLBN_DLL_API int mclBnFr_setByCSPRNG(mclBnFr *x); + +/* + set user-defined random function for setByCSPRNG + @param self [in] user-defined pointer + @param readFunc [in] user-defined function, + which writes random bufSize bytes to buf and returns bufSize if success else returns 0 + @note if self == 0 and readFunc == 0 then set default random function + @note not threadsafe +*/ +MCLBN_DLL_API void mclBn_setRandFunc(void *self, unsigned int (*readFunc)(void *self, void *buf, unsigned int bufSize)); #endif // hash(s) and set x // return 0 if success MCLBN_DLL_API int mclBnFr_setHashOf(mclBnFr *x, const void *buf, mclSize bufSize); +MCLBN_DLL_API int mclBnFp_setHashOf(mclBnFp *x, const void *buf, mclSize bufSize); +// map x to y +// return 0 if success else -1 +MCLBN_DLL_API int mclBnFp_mapToG1(mclBnG1 *y, const mclBnFp *x); +MCLBN_DLL_API int mclBnFp2_mapToG2(mclBnG2 *y, const mclBnFp2 *x); MCLBN_DLL_API void mclBnFr_neg(mclBnFr *y, const mclBnFr *x); MCLBN_DLL_API void mclBnFr_inv(mclBnFr *y, const mclBnFr *x); @@ -340,6 +392,7 @@ MCLBN_DLL_API void mclBn_precomputedMillerLoop2mixed(mclBnGT *f, const mclBnG1 * Lagrange interpolation recover out = y(0) by { (xVec[i], yVec[i]) } return 0 if success else -1 + @note *out = yVec[0] if k = 1 @note k >= 2, xVec[i] != 0, xVec[i] != xVec[j] for i != j */ MCLBN_DLL_API int mclBn_FrLagrangeInterpolation(mclBnFr *out, const mclBnFr *xVec, const mclBnFr *yVec, mclSize k); @@ -363,6 +416,13 @@ MCLBN_DLL_API int mclBn_G2EvaluatePolynomial(mclBnG2 *out, const mclBnG2 *cVec, MCLBN_DLL_API void mclBn_verifyOrderG1(int doVerify); MCLBN_DLL_API void mclBn_verifyOrderG2(int doVerify); +/* + EXPERIMENTAL + only for curve = MCL_SECP* or MCL_NIST* + return standard base point of the current elliptic curve +*/ +MCLBN_DLL_API int mclBnG1_getBasePoint(mclBnG1 *x); + #ifdef __cplusplus } #endif diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.hpp index 8e9a9c652..5ebe5d956 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/bn.hpp @@ -315,11 +315,18 @@ public: }; struct MapTo { + enum { + BNtype, + BLS12type, + STD_ECtype + }; Fp c1_; // sqrt(-3) Fp c2_; // (-1 + sqrt(-3)) / 2 mpz_class z_; mpz_class cofactor_; - bool isBN_; + int type_; + bool useNaiveMapTo_; + int legendre(bool *pb, const Fp& x) const { mpz_class xx; @@ -488,27 +495,44 @@ struct MapTo { (void)b; c2_ = (c1_ - 1) / 2; } - void init(const mpz_class& cofactor, const mpz_class &z, bool isBN, int curveType = -1) + /* + if type == STD_ECtype, then cofactor, z are not used. + */ + void init(const mpz_class& cofactor, const mpz_class &z, int curveType) { - isBN_ = isBN; - if (isBN_) { - initBN(cofactor, z, curveType); + if (0 <= curveType && curveType < MCL_EC_BEGIN) { + type_ = curveType == MCL_BLS12_381 ? BLS12type : BNtype; + } else { + type_ = STD_ECtype; + } + if (type_ == STD_ECtype) { + useNaiveMapTo_ = true; } else { + useNaiveMapTo_ = false; + } +#ifdef MCL_USE_OLD_MAPTO_FOR_BLS12 + if (type == BLS12type) useNaiveMapTo_ = true; +#endif + if (type_ == BNtype) { + initBN(cofactor, z, curveType); + } else if (type_ == BLS12type) { initBLS12(z); } } bool calcG1(G1& P, const Fp& t) const { - if (isBN_) { - if (!calcBN<G1, Fp>(P, t)) return false; - // no subgroup - } else { -#ifdef MCL_USE_OLD_MAPTO_FOR_BLS12 + if (useNaiveMapTo_) { naiveMapTo<G1, Fp>(P, t); -#else + } else { if (!calcBN<G1, Fp>(P, t)) return false; -#endif + } + switch (type_) { + case BNtype: + // no subgroup + break; + case BLS12type: mulByCofactorBLS12(P, P); + break; } assert(P.isValid()); return true; @@ -518,16 +542,18 @@ struct MapTo { */ bool calcG2(G2& P, const Fp2& t) const { - if (isBN_) { - if (!calcBN<G2, Fp2>(P, t)) return false; - mulByCofactorBN(P, P); + if (useNaiveMapTo_) { + naiveMapTo<G2, Fp2>(P, t); } else { -#ifdef MCL_USE_OLD_MAPTO_FOR_BLS12 - naiveMapTo<G1, Fp>(P, t); -#else if (!calcBN<G2, Fp2>(P, t)) return false; -#endif + } + switch(type_) { + case BNtype: + mulByCofactorBN(P, P); + break; + case BLS12type: mulByCofactorBLS12(P, P); + break; } assert(P.isValid()); return true; @@ -1018,6 +1044,9 @@ struct Param { bool useNAF; local::SignVec zReplTbl; + // for initG1only + G1 basePoint; + void init(bool *pb, const mcl::CurveParam& cp, fp::Mode mode) { this->cp = cp; @@ -1043,12 +1072,12 @@ struct Param { assert((p % 6) == 1); r = local::evalPoly(z, rCoff); } - Fp::init(pb, p, mode); - if (!*pb) return; Fr::init(pb, r, mode); if (!*pb) return; - Fp2::init(cp.xi_a); - Fp2 xi(cp.xi_a, 1); + Fp::init(pb, cp.xi_a, p, mode); + if (!*pb) return; + Fp2::init(); + const Fp2 xi(cp.xi_a, 1); g2 = Fp2::get_gTbl()[0]; g3 = Fp2::get_gTbl()[3]; if (cp.isMtype) { @@ -1099,14 +1128,31 @@ struct Param { } */ if (isBLS12) { - mapTo.init(0, z, false); + mapTo.init(0, z, cp.curveType); } else { - mapTo.init(2 * p - r, z, true, cp.curveType); + mapTo.init(2 * p - r, z, cp.curveType); } glv1.init(r, z, isBLS12, cp.curveType); glv2.init(r, z, isBLS12); + basePoint.clear(); *pb = true; } + void initG1only(bool *pb, const mcl::EcParam& para) + { + Fp::init(pb, para.p); + if (!*pb) return; + Fr::init(pb, para.n); + if (!*pb) return; + G1::init(pb, para.a, para.b); + if (!*pb) return; + G1::setOrder(Fr::getOp().mp); + mapTo.init(0, 0, para.curveType); + Fp x0, y0; + x0.setStr(pb, para.gx); + if (!*pb) return; + y0.setStr(pb, para.gy); + basePoint.set(pb, x0, y0); + } #ifndef CYBOZU_DONT_USE_EXCEPTION void init(const mcl::CurveParam& cp, fp::Mode mode) { @@ -1564,17 +1610,22 @@ inline void mulSparse(Fp12& z, const Fp6& x) } inline void convertFp6toFp12(Fp12& y, const Fp6& x) { - y.clear(); if (BN::param.cp.isMtype) { // (a, b, c) -> (a, c, 0, 0, b, 0) y.a.a = x.a; y.b.b = x.b; y.a.b = x.c; + y.a.c.clear(); + y.b.a.clear(); + y.b.c.clear(); } else { // (a, b, c) -> (b, 0, 0, c, a, 0) y.b.b = x.a; y.a.a = x.b; y.b.a = x.c; + y.a.b.clear(); + y.a.c.clear(); + y.b.c.clear(); } } inline void mulSparse2(Fp12& z, const Fp6& x, const Fp6& y) @@ -2190,5 +2241,21 @@ inline void initPairing(const mcl::CurveParam& cp = mcl::BN254, fp::Mode mode = } #endif +inline void initG1only(bool *pb, const mcl::EcParam& para) +{ + local::StaticVar<>::param.initG1only(pb, para); + if (!*pb) return; + G1::setMulArrayGLV(0); + G2::setMulArrayGLV(0); + Fp12::setPowArrayGLV(0); + G1::setCompressedExpression(); + G2::setCompressedExpression(); +} + +inline const G1& getG1basePoint() +{ + return local::StaticVar<>::param.basePoint; +} + } } // mcl::bn diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/curve_type.h b/vendor/github.com/dexon-foundation/mcl/include/mcl/curve_type.h index 5957d1ae8..9e4a941a0 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/curve_type.h +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/curve_type.h @@ -14,5 +14,22 @@ enum { MCL_BN462 = 3, MCL_BN_SNARK1 = 4, MCL_BLS12_381 = 5, - MCL_BN160 = 6 + MCL_BN160 = 6, + + /* + for only G1 + the size of curve must be less or equal to MCLBN_FP_UNIT_SIZE + */ + MCL_EC_BEGIN = 100, + MCL_SECP192K1 = MCL_EC_BEGIN, + MCL_SECP224K1 = 101, + MCL_SECP256K1 = 102, + MCL_SECP384R1 = 103, + MCL_SECP521R1 = 104, + MCL_NIST_P192 = 105, + MCL_NIST_P224 = 106, + MCL_NIST_P256 = 107, + MCL_EC_END = MCL_NIST_P256 + 1, + MCL_NIST_P384 = MCL_SECP384R1, + MCL_NIST_P521 = MCL_SECP521R1 }; diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/ec.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/ec.hpp index 8ebf7e757..b8eb10be3 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/ec.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/ec.hpp @@ -23,11 +23,11 @@ namespace mcl { namespace ec { enum Mode { - Jacobi, - Proj + Jacobi = 0, + Proj = 1 }; -} // mcl::ecl +} // mcl::ec /* elliptic curve @@ -423,27 +423,41 @@ public: dblNoVerifyInf(R, P); } #ifndef MCL_EC_USE_AFFINE - static inline void addJacobi(EcT& R, const EcT& P, const EcT& Q) + static inline void addJacobi(EcT& R, const EcT& P, const EcT& Q, bool isPzOne, bool isQzOne) { - const bool isQzOne = Q.z.isOne(); Fp r, U1, S1, H, H3; - Fp::sqr(r, P.z); + if (isPzOne) { + // r = 1; + } else { + Fp::sqr(r, P.z); + } if (isQzOne) { U1 = P.x; - Fp::mul(H, Q.x, r); + if (isPzOne) { + H = Q.x; + } else { + Fp::mul(H, Q.x, r); + } H -= U1; - r *= P.z; S1 = P.y; } else { Fp::sqr(S1, Q.z); Fp::mul(U1, P.x, S1); - Fp::mul(H, Q.x, r); + if (isPzOne) { + H = Q.x; + } else { + Fp::mul(H, Q.x, r); + } H -= U1; - r *= P.z; S1 *= Q.z; S1 *= P.y; } - r *= Q.y; + if (isPzOne) { + r = Q.y; + } else { + r *= P.z; + r *= Q.y; + } r -= S1; if (H.isZero()) { if (r.isZero()) { @@ -453,11 +467,13 @@ public: } return; } - if (isQzOne) { - Fp::mul(R.z, P.z, H); + if (isPzOne) { + R.z = H; } else { - Fp::mul(R.z, P.z, Q.z); - R.z *= H; + Fp::mul(R.z, P.z, H); + } + if (!isQzOne) { + R.z *= Q.z; } Fp::sqr(H3, H); // H^2 Fp::sqr(R.y, r); // r^2 @@ -471,9 +487,8 @@ public: H3 *= S1; Fp::sub(R.y, U1, H3); } - static inline void addProj(EcT& R, const EcT& P, const EcT& Q) + static inline void addProj(EcT& R, const EcT& P, const EcT& Q, bool isPzOne, bool isQzOne) { - const bool isQzOne = Q.z.isOne(); Fp r, PyQz, v, A, vv; if (isQzOne) { r = P.x; @@ -482,8 +497,13 @@ public: Fp::mul(r, P.x, Q.z); Fp::mul(PyQz, P.y, Q.z); } - Fp::mul(A, Q.y, P.z); - Fp::mul(v, Q.x, P.z); + if (isPzOne) { + A = Q.y; + v = Q.x; + } else { + Fp::mul(A, Q.y, P.z); + Fp::mul(v, Q.x, P.z); + } v -= r; if (v.isZero()) { if (A == PyQz) { @@ -501,10 +521,19 @@ public: if (isQzOne) { R.z = P.z; } else { - Fp::mul(R.z, P.z, Q.z); + if (isPzOne) { + R.z = Q.z; + } else { + Fp::mul(R.z, P.z, Q.z); + } + } + // R.z = 1 if isPzOne && isQzOne + if (isPzOne && isQzOne) { + R.z = vv; + } else { + A *= R.z; + R.z *= vv; } - A *= R.z; - R.z *= vv; A -= vv; vv *= PyQz; A -= r; @@ -515,17 +544,14 @@ public: R.y -= vv; } #endif - static inline void add(EcT& R, const EcT& P0, const EcT& Q0) - { - if (P0.isZero()) { R = Q0; return; } - if (Q0.isZero()) { R = P0; return; } - if (&P0 == &Q0) { - dblNoVerifyInf(R, P0); + static inline void add(EcT& R, const EcT& P, const EcT& Q) { + if (P.isZero()) { R = Q; return; } + if (Q.isZero()) { R = P; return; } + if (&P == &Q) { + dblNoVerifyInf(R, P); return; } #ifdef MCL_EC_USE_AFFINE - const EcT& P(P0); - const EcT& Q(Q0); Fp t; Fp::neg(t, Q.y); if (P.y == t) { R.clear(); return; } @@ -547,19 +573,14 @@ public: Fp::sub(R.y, s, P.y); R.x = x3; #else - const EcT *pP = &P0; - const EcT *pQ = &Q0; - if (pP->z.isOne()) { - fp::swap_(pP, pQ); - } - const EcT& P(*pP); - const EcT& Q(*pQ); + bool isPzOne = P.z.isOne(); + bool isQzOne = Q.z.isOne(); switch (mode_) { case ec::Jacobi: - addJacobi(R, P, Q); + addJacobi(R, P, Q, isPzOne, isQzOne); break; case ec::Proj: - addProj(R, P, Q); + addProj(R, P, Q, isPzOne, isQzOne); break; } #endif @@ -889,6 +910,10 @@ public: bool operator<=(const EcT& rhs) const { return !operator>(rhs); } static inline void mulArray(EcT& z, const EcT& x, const fp::Unit *y, size_t yn, bool isNegative, bool constTime = false) { + if (!constTime && x.isZero()) { + z.clear(); + return; + } if (mulArrayGLV && (constTime || yn > 1)) { mulArrayGLV(z, x, y, yn, isNegative, constTime); return; @@ -983,6 +1008,7 @@ struct EcParam { const char *gy; const char *n; size_t bitSize; // bit length of p + int curveType; }; } // mcl diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/ecparam.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/ecparam.hpp index 19b76bf55..087bf8b6c 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/ecparam.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/ecparam.hpp @@ -7,6 +7,7 @@ http://opensource.org/licenses/BSD-3-Clause */ #include <mcl/ec.hpp> +#include <mcl/curve_type.h> namespace mcl { namespace ecparam { @@ -18,7 +19,8 @@ const struct mcl::EcParam secp160k1 = { "0x3b4c382ce37aa192a4019e763036f4f5dd4d7ebb", "0x938cf935318fdced6bc28286531733c3f03c4fee", "0x100000000000000000001b8fa16dfab9aca16b6b3", - 160 + 160, + -1 }; // p=2^160 + 7 const struct mcl::EcParam p160_1 = { @@ -29,7 +31,8 @@ const struct mcl::EcParam p160_1 = { "1", "1236612389951462151661156731535316138439983579284", "1461501637330902918203683518218126812711137002561", - 161 + 161, + -1 }; const struct mcl::EcParam secp192k1 = { "secp192k1", @@ -39,7 +42,8 @@ const struct mcl::EcParam secp192k1 = { "0xdb4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d", "0x9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d", "0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d", - 192 + 192, + MCL_SECP192K1 }; const struct mcl::EcParam secp224k1 = { "secp224k1", @@ -49,7 +53,8 @@ const struct mcl::EcParam secp224k1 = { "0xa1455b334df099df30fc28a169a467e9e47075a90f7e650eb6b7a45c", "0x7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5", "0x10000000000000000000000000001dce8d2ec6184caf0a971769fb1f7", - 224 + 224, + MCL_SECP224K1 }; const struct mcl::EcParam secp256k1 = { "secp256k1", @@ -59,7 +64,8 @@ const struct mcl::EcParam secp256k1 = { "0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8", "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - 256 + 256, + MCL_SECP256K1 }; const struct mcl::EcParam secp384r1 = { "secp384r1", @@ -69,7 +75,8 @@ const struct mcl::EcParam secp384r1 = { "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973", - 384 + 384, + MCL_SECP384R1 }; const struct mcl::EcParam secp521r1 = { "secp521r1", @@ -79,7 +86,8 @@ const struct mcl::EcParam secp521r1 = { "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - 521 + 521, + MCL_SECP521R1 }; const struct mcl::EcParam NIST_P192 = { "NIST_P192", @@ -89,7 +97,8 @@ const struct mcl::EcParam NIST_P192 = { "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", - 192 + 192, + MCL_NIST_P192 }; const struct mcl::EcParam NIST_P224 = { "NIST_P224", @@ -99,7 +108,8 @@ const struct mcl::EcParam NIST_P224 = { "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d", - 224 + 224, + MCL_NIST_P224 }; const struct mcl::EcParam NIST_P256 = { "NIST_P256", @@ -109,7 +119,8 @@ const struct mcl::EcParam NIST_P256 = { "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - 256 + 256, + MCL_NIST_P256 }; // same secp384r1 const struct mcl::EcParam NIST_P384 = { @@ -120,7 +131,8 @@ const struct mcl::EcParam NIST_P384 = { "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f", "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973", - 384 + 384, + MCL_NIST_P384 }; // same secp521r1 const struct mcl::EcParam NIST_P521 = { @@ -131,7 +143,8 @@ const struct mcl::EcParam NIST_P521 = { "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - 521 + 521, + MCL_NIST_P521 }; } // mcl::ecparam @@ -161,4 +174,18 @@ static inline const mcl::EcParam* getEcParam(const std::string& name) } #endif +inline const mcl::EcParam* getEcParam(int curve) +{ + switch (curve) { + case MCL_SECP192K1: return &ecparam::secp192k1; + case MCL_SECP224K1: return &ecparam::secp224k1; + case MCL_SECP256K1: return &ecparam::secp256k1; + case MCL_SECP384R1: return &ecparam::secp384r1; + case MCL_NIST_P192: return &ecparam::NIST_P192; + case MCL_NIST_P224: return &ecparam::NIST_P224; + case MCL_NIST_P256: return &ecparam::NIST_P256; + default: return 0; + } +} + } // mcl diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/elgamal.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/elgamal.hpp index 8bc3104b7..431148508 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/elgamal.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/elgamal.hpp @@ -244,8 +244,7 @@ struct ElgamalT { input : m = 0 or 1 output : c (c1, c2), zkp */ - template<class Hash> - void encWithZkp(CipherText& c, Zkp& zkp, int m, Hash& hash, fp::RandGen rg = fp::RandGen()) const + void encWithZkp(CipherText& c, Zkp& zkp, int m, fp::RandGen rg = fp::RandGen()) const { if (m != 0 && m != 1) { throw cybozu::Exception("elgamal:PublicKey:encWithZkp") << m; @@ -272,10 +271,8 @@ struct ElgamalT { mulH(R12, r1); std::ostringstream os; os << R01 << R02 << R11 << R12 << c.c1 << c.c2 << f << g << h; - hash.update(os.str()); - const std::string digest = hash.digest(); Zn cc; - cc.setArrayMask(digest.c_str(), digest.size()); + cc.setHashOf(os.str()); zkp.c1 = cc - zkp.c0; zkp.s1 = r1 + zkp.c1 * u; } else { @@ -296,10 +293,8 @@ struct ElgamalT { Ec::sub(R12, t1, t2); std::ostringstream os; os << R01 << R02 << R11 << R12 << c.c1 << c.c2 << f << g << h; - hash.update(os.str()); - const std::string digest = hash.digest(); Zn cc; - cc.setArrayMask(digest.c_str(), digest.size()); + cc.setHashOf(os.str()); zkp.c0 = cc - zkp.c1; zkp.s0 = r0 + zkp.c0 * u; } @@ -307,8 +302,7 @@ struct ElgamalT { /* verify cipher text with ZKP */ - template<class Hash> - bool verify(const CipherText& c, const Zkp& zkp, Hash& hash) const + bool verify(const CipherText& c, const Zkp& zkp) const { Ec R01, R02, R11, R12; Ec t1, t2; @@ -327,10 +321,8 @@ struct ElgamalT { Ec::sub(R12, t1, t2); std::ostringstream os; os << R01 << R02 << R11 << R12 << c.c1 << c.c2 << f << g << h; - hash.update(os.str()); - const std::string digest = hash.digest(); Zn cc; - cc.setArrayMask(digest.c_str(), digest.size()); + cc.setHashOf(os.str()); return cc == zkp.c0 + zkp.c1; } /* diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/fp.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/fp.hpp index 48500127e..2e69729dd 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/fp.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/fp.hpp @@ -70,8 +70,6 @@ inline void dumpUnit(Unit x) bool isEnableJIT(); // 1st call is not threadsafe -void getRandVal(Unit *out, RandGen& rg, const Unit *in, size_t bitSize); - uint32_t sha256(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize); uint32_t sha512(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize); @@ -112,10 +110,14 @@ public: } printf("\n"); } - static inline void init(bool *pb, const mpz_class& _p, fp::Mode mode = fp::FP_AUTO) + /* + xi_a is used for Fp2::mul_xi(), where xi = xi_a + i and i^2 = -1 + if xi_a = 0 then asm functions for Fp2 are not generated. + */ + static inline void init(bool *pb, int xi_a, const mpz_class& p, fp::Mode mode = fp::FP_AUTO) { assert(maxBitSize <= MCL_MAX_BIT_SIZE); - *pb = op_.init(_p, maxBitSize, mode); + *pb = op_.init(p, maxBitSize, xi_a, mode); if (!*pb) return; { // set oneRep FpT& one = *reinterpret_cast<FpT*>(op_.oneRep); @@ -130,19 +132,23 @@ public: } inv(inv2_, 2); #ifdef MCL_XBYAK_DIRECT_CALL - add = (void (*)(FpT& z, const FpT& x, const FpT& y))op_.fp_addA_; + add = fp::func_ptr_cast<void (*)(FpT& z, const FpT& x, const FpT& y)>(op_.fp_addA_); if (add == 0) add = addC; - sub = (void (*)(FpT& z, const FpT& x, const FpT& y))op_.fp_subA_; + sub = fp::func_ptr_cast<void (*)(FpT& z, const FpT& x, const FpT& y)>(op_.fp_subA_); if (sub == 0) sub = subC; - neg = (void (*)(FpT& y, const FpT& x))op_.fp_negA_; + neg = fp::func_ptr_cast<void (*)(FpT& y, const FpT& x)>(op_.fp_negA_); if (neg == 0) neg = negC; - mul = (void (*)(FpT& z, const FpT& x, const FpT& y))op_.fp_mulA_; + mul = fp::func_ptr_cast<void (*)(FpT& z, const FpT& x, const FpT& y)>(op_.fp_mulA_); if (mul == 0) mul = mulC; - sqr = (void (*)(FpT& y, const FpT& x))op_.fp_sqrA_; + sqr = fp::func_ptr_cast<void (*)(FpT& y, const FpT& x)>(op_.fp_sqrA_); if (sqr == 0) sqr = sqrC; #endif *pb = true; } + static inline void init(bool *pb, const mpz_class& p, fp::Mode mode = fp::FP_AUTO) + { + init(pb, 0, p, mode); + } static inline void init(bool *pb, const char *mstr, fp::Mode mode = fp::FP_AUTO) { mpz_class p; @@ -296,10 +302,13 @@ public: } cybozu::write(pb, os, buf + sizeof(buf) - len, len); } + /* + mode = Mod : set x mod p if sizeof(S) * n <= 64 else error + */ template<class S> - void setArray(bool *pb, const S *x, size_t n) + void setArray(bool *pb, const S *x, size_t n, mcl::fp::MaskMode mode = fp::NoMask) { - *pb = fp::copyAndMask(v_, x, sizeof(S) * n, op_, fp::NoMask); + *pb = fp::copyAndMask(v_, x, sizeof(S) * n, op_, mode); toMont(); } /* @@ -331,12 +340,21 @@ public: b.p = &v_[0]; } } - void setByCSPRNG(fp::RandGen rg = fp::RandGen()) + void setByCSPRNG(bool *pb, fp::RandGen rg = fp::RandGen()) { if (rg.isZero()) rg = fp::RandGen::get(); - fp::getRandVal(v_, rg, op_.p, op_.bitSize); - toMont(); + rg.read(pb, v_, op_.N * sizeof(Unit)); // byte size + if (!pb) return; + setArrayMask(v_, op_.N); + } +#ifndef CYBOZU_DONT_USE_EXCEPTION + void setByCSPRNG(fp::RandGen rg = fp::RandGen()) + { + bool b; + setByCSPRNG(&b, rg); + if (!b) throw cybozu::Exception("setByCSPRNG"); } +#endif void setRand(fp::RandGen rg = fp::RandGen()) // old api { setByCSPRNG(rg); @@ -522,17 +540,25 @@ public: } #endif #ifndef CYBOZU_DONT_USE_EXCEPTION - static inline void init(const mpz_class& _p, fp::Mode mode = fp::FP_AUTO) + static inline void init(int xi_a, const mpz_class& p, fp::Mode mode = fp::FP_AUTO) { bool b; - init(&b, _p, mode); + init(&b, xi_a, p, mode); if (!b) throw cybozu::Exception("Fp:init"); } + static inline void init(int xi_a, const std::string& mstr, fp::Mode mode = fp::FP_AUTO) + { + mpz_class p; + gmp::setStr(p, mstr); + init(xi_a, p, mode); + } + static inline void init(const mpz_class& p, fp::Mode mode = fp::FP_AUTO) + { + init(0, p, mode); + } static inline void init(const std::string& mstr, fp::Mode mode = fp::FP_AUTO) { - bool b; - init(&b, mstr.c_str(), mode); - if (!b) throw cybozu::Exception("Fp:init"); + init(0, mstr, mode); } template<class OutputStream> void save(OutputStream& os, int ioMode = IoSerialize) const @@ -562,7 +588,7 @@ public: { bool b; setMpz(&b, x); - if (!b) throw cybozu::Exception("Fp:setMpz:neg"); + if (!b) throw cybozu::Exception("Fp:setMpz"); } uint64_t getUint64() const { diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/fp_tower.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/fp_tower.hpp index 63738a3f5..95722e2d5 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/fp_tower.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/fp_tower.hpp @@ -121,20 +121,22 @@ public: static void (*add)(FpDblT& z, const FpDblT& x, const FpDblT& y); static void (*sub)(FpDblT& z, const FpDblT& x, const FpDblT& y); static void (*mod)(Fp& z, const FpDblT& xy); + static void (*addPre)(FpDblT& z, const FpDblT& x, const FpDblT& y); + static void (*subPre)(FpDblT& z, const FpDblT& x, const FpDblT& y); static void addC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_add(z.v_, x.v_, y.v_, Fp::op_.p); } static void subC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_sub(z.v_, x.v_, y.v_, Fp::op_.p); } static void modC(Fp& z, const FpDblT& xy) { Fp::op_.fpDbl_mod(z.v_, xy.v_, Fp::op_.p); } + static void addPreC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_addPre(z.v_, x.v_, y.v_); } + static void subPreC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_subPre(z.v_, x.v_, y.v_); } #else static void add(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_add(z.v_, x.v_, y.v_, Fp::op_.p); } static void sub(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_sub(z.v_, x.v_, y.v_, Fp::op_.p); } static void mod(Fp& z, const FpDblT& xy) { Fp::op_.fpDbl_mod(z.v_, xy.v_, Fp::op_.p); } + static void addPre(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_addPre(z.v_, x.v_, y.v_); } + static void subPre(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_subPre(z.v_, x.v_, y.v_); } #endif - static void addPreC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_addPre(z.v_, x.v_, y.v_); } - static void subPreC(FpDblT& z, const FpDblT& x, const FpDblT& y) { Fp::op_.fpDbl_subPre(z.v_, x.v_, y.v_); } static void mulPreC(FpDblT& xy, const Fp& x, const Fp& y) { Fp::op_.fpDbl_mulPre(xy.v_, x.v_, y.v_); } static void sqrPreC(FpDblT& xx, const Fp& x) { Fp::op_.fpDbl_sqrPre(xx.v_, x.v_); } - static void (*addPre)(FpDblT& z, const FpDblT& x, const FpDblT& y); - static void (*subPre)(FpDblT& z, const FpDblT& x, const FpDblT& y); /* mul(z, x, y) = mulPre(xy, x, y) + mod(z, xy) */ @@ -149,30 +151,24 @@ public: { const mcl::fp::Op& op = Fp::getOp(); #ifdef MCL_XBYAK_DIRECT_CALL - add = (void (*)(FpDblT&, const FpDblT&, const FpDblT&))op.fpDbl_addA_; + add = fp::func_ptr_cast<void (*)(FpDblT&, const FpDblT&, const FpDblT&)>(op.fpDbl_addA_); if (add == 0) add = addC; - sub = (void (*)(FpDblT&, const FpDblT&, const FpDblT&))op.fpDbl_subA_; + sub = fp::func_ptr_cast<void (*)(FpDblT&, const FpDblT&, const FpDblT&)>(op.fpDbl_subA_); if (sub == 0) sub = subC; - mod = (void (*)(Fp&, const FpDblT&))op.fpDbl_modA_; + mod = fp::func_ptr_cast<void (*)(Fp&, const FpDblT&)>(op.fpDbl_modA_); if (mod == 0) mod = modC; + addPre = fp::func_ptr_cast<void (*)(FpDblT&, const FpDblT&, const FpDblT&)>(op.fpDbl_addPre); + if (addPre == 0) addPre = addPreC; + subPre = fp::func_ptr_cast<void (*)(FpDblT&, const FpDblT&, const FpDblT&)>(op.fpDbl_subPre); + if (subPre == 0) subPre = subPreC; #endif - if (op.fpDbl_addPreA_) { - addPre = (void (*)(FpDblT&, const FpDblT&, const FpDblT&))op.fpDbl_addPreA_; - } else { - addPre = addPreC; - } - if (op.fpDbl_subPreA_) { - subPre = (void (*)(FpDblT&, const FpDblT&, const FpDblT&))op.fpDbl_subPreA_; - } else { - subPre = subPreC; - } if (op.fpDbl_mulPreA_) { - mulPre = (void (*)(FpDblT&, const Fp&, const Fp&))op.fpDbl_mulPreA_; + mulPre = fp::func_ptr_cast<void (*)(FpDblT&, const Fp&, const Fp&)>(op.fpDbl_mulPreA_); } else { mulPre = mulPreC; } if (op.fpDbl_sqrPreA_) { - sqrPre = (void (*)(FpDblT&, const Fp&))op.fpDbl_sqrPreA_; + sqrPre = fp::func_ptr_cast<void (*)(FpDblT&, const Fp&)>(op.fpDbl_sqrPreA_); } else { sqrPre = sqrPreC; } @@ -185,9 +181,9 @@ public: template<class Fp> void (*FpDblT<Fp>::add)(FpDblT&, const FpDblT&, const FpDblT&); template<class Fp> void (*FpDblT<Fp>::sub)(FpDblT&, const FpDblT&, const FpDblT&); template<class Fp> void (*FpDblT<Fp>::mod)(Fp&, const FpDblT&); -#endif template<class Fp> void (*FpDblT<Fp>::addPre)(FpDblT&, const FpDblT&, const FpDblT&); template<class Fp> void (*FpDblT<Fp>::subPre)(FpDblT&, const FpDblT&, const FpDblT&); +#endif template<class Fp> void (*FpDblT<Fp>::mulPre)(FpDblT&, const Fp&, const Fp&); template<class Fp> void (*FpDblT<Fp>::sqrPre)(FpDblT&, const Fp&); @@ -206,7 +202,6 @@ class Fp2T : public fp::Serializable<Fp2T<_Fp>, typedef fp::Unit Unit; typedef FpDblT<Fp> FpDbl; typedef Fp2DblT<Fp> Fp2Dbl; - static uint32_t xi_a_; static const size_t gN = 5; /* g = xi^((p - 1) / 6) @@ -245,11 +240,19 @@ public: a = a_; b = b_; } +#ifdef MCL_XBYAK_DIRECT_CALL static void (*add)(Fp2T& z, const Fp2T& x, const Fp2T& y); static void (*sub)(Fp2T& z, const Fp2T& x, const Fp2T& y); static void (*neg)(Fp2T& y, const Fp2T& x); static void (*mul)(Fp2T& z, const Fp2T& x, const Fp2T& y); static void (*sqr)(Fp2T& y, const Fp2T& x); +#else + static void add(Fp2T& z, const Fp2T& x, const Fp2T& y) { addC(z, x, y); } + static void sub(Fp2T& z, const Fp2T& x, const Fp2T& y) { subC(z, x, y); } + static void neg(Fp2T& y, const Fp2T& x) { negC(y, x); } + static void mul(Fp2T& z, const Fp2T& x, const Fp2T& y) { mulC(z, x, y); } + static void sqr(Fp2T& y, const Fp2T& x) { sqrC(y, x); } +#endif static void (*mul_xi)(Fp2T& y, const Fp2T& x); static void addPre(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::addPre(z.a, x.a, y.a); Fp::addPre(z.b, x.b, y.b); } static void inv(Fp2T& y, const Fp2T& x) { Fp::op_.fp2_inv(y.a.v_, x.a.v_); } @@ -377,51 +380,38 @@ public: } } - static uint32_t get_xi_a() { return xi_a_; } - static void init(uint32_t xi_a) + static uint32_t get_xi_a() { return Fp::getOp().xi_a; } + static void init() { // assert(Fp::maxSize <= 256); - xi_a_ = xi_a; mcl::fp::Op& op = Fp::op_; - add = (void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y))op.fp2_addA_; - if (add == 0) add = fp2_addC; - sub = (void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y))op.fp2_subA_; - if (sub == 0) sub = fp2_subC; - neg = (void (*)(Fp2T& y, const Fp2T& x))op.fp2_negA_; - if (neg == 0) neg = fp2_negC; - mul = (void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y))op.fp2_mulA_; - if (mul == 0) { - if (op.isFastMod) { - mul = fp2_mulC; - } else if (!op.isFullBit) { - if (0 && sizeof(Fp) * 8 == op.N * fp::UnitBitSize && op.fp2_mulNF) { - mul = fp2_mulNFW; - } else { - mul = fp2_mulC; - } - } else { - mul = fp2_mulC; - } - } - sqr = (void (*)(Fp2T& y, const Fp2T& x))op.fp2_sqrA_; - if (sqr == 0) sqr = fp2_sqrC; + assert(op.xi_a); + mul_xi = 0; +#ifdef MCL_XBYAK_DIRECT_CALL + add = fp::func_ptr_cast<void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y)>(op.fp2_addA_); + if (add == 0) add = addC; + sub = fp::func_ptr_cast<void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y)>(op.fp2_subA_); + if (sub == 0) sub = subC; + neg = fp::func_ptr_cast<void (*)(Fp2T& y, const Fp2T& x)>(op.fp2_negA_); + if (neg == 0) neg = negC; + mul = fp::func_ptr_cast<void (*)(Fp2T& z, const Fp2T& x, const Fp2T& y)>(op.fp2_mulA_); + if (mul == 0) mul = mulC; + sqr = fp::func_ptr_cast<void (*)(Fp2T& y, const Fp2T& x)>(op.fp2_sqrA_); + if (sqr == 0) sqr = sqrC; + mul_xi = fp::func_ptr_cast<void (*)(Fp2T&, const Fp2T&)>(op.fp2_mul_xiA_); +#endif op.fp2_inv = fp2_invW; - if (xi_a == 1) { - /* - current fp_generator.hpp generates mul_xi for xi_a = 1 - */ - if (op.fp2_mul_xiA_) { - mul_xi = (void (*)(Fp2T&, const Fp2T&))op.fp2_mul_xiA_; + if (mul_xi == 0) { + if (op.xi_a == 1) { + mul_xi = fp2_mul_xi_1_1iC; } else { - mul_xi = fp2_mul_xi_1_1i; + mul_xi = fp2_mul_xiC; } - } else { - mul_xi = fp2_mul_xiC; } FpDblT<Fp>::init(); Fp2DblT<Fp>::init(); // call init before Fp2::pow because FpDbl is used in Fp2T - const Fp2T xi(xi_a, 1); + const Fp2T xi(op.xi_a, 1); const mpz_class& p = Fp::getOp().mp; Fp2T::pow(g[0], xi, (p - 1) / 6); // g = xi^((p-1)/6) for (size_t i = 1; i < gN; i++) { @@ -490,17 +480,17 @@ private: default Fp2T operator Fp2T = Fp[i]/(i^2 + 1) */ - static void fp2_addC(Fp2T& z, const Fp2T& x, const Fp2T& y) + static void addC(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::add(z.a, x.a, y.a); Fp::add(z.b, x.b, y.b); } - static void fp2_subC(Fp2T& z, const Fp2T& x, const Fp2T& y) + static void subC(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp::sub(z.a, x.a, y.a); Fp::sub(z.b, x.b, y.b); } - static void fp2_negC(Fp2T& y, const Fp2T& x) + static void negC(Fp2T& y, const Fp2T& x) { Fp::neg(y.a, x.a); Fp::neg(y.b, x.b); @@ -531,13 +521,13 @@ private: Fp::sub(pz[1], t1, ac); pz[1] -= bd; } -#endif static void fp2_mulNFW(Fp2T& z, const Fp2T& x, const Fp2T& y) { const fp::Op& op = Fp::op_; op.fp2_mulNF((Unit*)&z, (const Unit*)&x, (const Unit*)&y, op.p); } - static void fp2_mulC(Fp2T& z, const Fp2T& x, const Fp2T& y) +#endif + static void mulC(Fp2T& z, const Fp2T& x, const Fp2T& y) { Fp2Dbl d; Fp2Dbl::mulPre(d, x, y); @@ -548,7 +538,7 @@ private: x = a + bi, i^2 = -1 y = x^2 = (a + bi)^2 = (a + b)(a - b) + 2abi */ - static void fp2_sqrC(Fp2T& y, const Fp2T& x) + static void sqrC(Fp2T& y, const Fp2T& x) { const Fp& a = x.a; const Fp& b = x.b; @@ -583,9 +573,9 @@ private: const Fp& a = x.a; const Fp& b = x.b; Fp t; - Fp::mulUnit(t, a, xi_a_); + Fp::mulUnit(t, a, Fp::getOp().xi_a); t -= b; - Fp::mulUnit(y.b, b, xi_a_); + Fp::mulUnit(y.b, b, Fp::getOp().xi_a); y.b += a; y.a = t; } @@ -593,7 +583,7 @@ private: xi = 1 + i ; xi_a = 1 y = (a + bi)xi = (a - b) + (a + b)i */ - static void fp2_mul_xi_1_1i(Fp2T& y, const Fp2T& x) + static void fp2_mul_xi_1_1iC(Fp2T& y, const Fp2T& x) { const Fp& a = x.a; const Fp& b = x.b; @@ -623,11 +613,13 @@ private: } }; +#ifdef MCL_XBYAK_DIRECT_CALL template<class Fp_> void (*Fp2T<Fp_>::add)(Fp2T& z, const Fp2T& x, const Fp2T& y); template<class Fp_> void (*Fp2T<Fp_>::sub)(Fp2T& z, const Fp2T& x, const Fp2T& y); template<class Fp_> void (*Fp2T<Fp_>::neg)(Fp2T& y, const Fp2T& x); template<class Fp_> void (*Fp2T<Fp_>::mul)(Fp2T& z, const Fp2T& x, const Fp2T& y); template<class Fp_> void (*Fp2T<Fp_>::sqr)(Fp2T& y, const Fp2T& x); +#endif template<class Fp_> void (*Fp2T<Fp_>::mul_xi)(Fp2T& y, const Fp2T& x); template<class Fp> @@ -697,7 +689,7 @@ struct Fp2DblT { { const mcl::fp::Op& op = Fp::getOp(); if (op.fp2Dbl_mulPreA_) { - mulPre = (void (*)(Fp2DblT&, const Fp2&, const Fp2&))op.fp2Dbl_mulPreA_; + mulPre = fp::func_ptr_cast<void (*)(Fp2DblT&, const Fp2&, const Fp2&)>(op.fp2Dbl_mulPreA_); } else { if (op.isFullBit) { mulPre = fp2Dbl_mulPreW<true>; @@ -706,7 +698,7 @@ struct Fp2DblT { } } if (op.fp2Dbl_sqrPreA_) { - sqrPre = (void (*)(Fp2DblT&, const Fp2&))op.fp2Dbl_sqrPreA_; + sqrPre = fp::func_ptr_cast<void (*)(Fp2DblT&, const Fp2&)>(op.fp2Dbl_sqrPreA_); } else { if (op.isFullBit) { sqrPre = fp2Dbl_sqrPreW<true>; @@ -769,11 +761,12 @@ struct Fp2DblT { template<class Fp> void (*Fp2DblT<Fp>::mulPre)(Fp2DblT&, const Fp2T<Fp>&, const Fp2T<Fp>&); template<class Fp> void (*Fp2DblT<Fp>::sqrPre)(Fp2DblT&, const Fp2T<Fp>&); -template<class Fp> uint32_t Fp2T<Fp>::xi_a_; template<class Fp> Fp2T<Fp> Fp2T<Fp>::g[Fp2T<Fp>::gN]; template<class Fp> Fp2T<Fp> Fp2T<Fp>::g2[Fp2T<Fp>::gN]; template<class Fp> Fp2T<Fp> Fp2T<Fp>::g3[Fp2T<Fp>::gN]; +template<class Fp> +struct Fp6DblT; /* Fp6T = Fp2[v] / (v^3 - xi) x = a + b v + c v^2 @@ -784,6 +777,7 @@ struct Fp6T : public fp::Serializable<Fp6T<_Fp>, typedef _Fp Fp; typedef Fp2T<Fp> Fp2; typedef Fp2DblT<Fp> Fp2Dbl; + typedef Fp6DblT<Fp> Fp6Dbl; typedef Fp BaseFp; Fp2 a, b, c; Fp6T() { } @@ -914,91 +908,7 @@ struct Fp6T : public fp::Serializable<Fp6T<_Fp>, y.b += t1; // c^2 xi + 2ab y.c -= t1; // b^2 + 2ac } - /* - x = a + bv + cv^2, y = d + ev + fv^2, v^3 = xi - xy = (ad + (bf + ce)xi) + ((ae + bd) + cf xi)v + ((af + cd) + be)v^2 - bf + ce = (b + c)(e + f) - be - cf - ae + bd = (a + b)(e + d) - ad - be - af + cd = (a + c)(d + f) - ad - cf - */ - static void mul(Fp6T& z, const Fp6T& x, const Fp6T& y) - { -//clk.begin(); - const Fp2& a = x.a; - const Fp2& b = x.b; - const Fp2& c = x.c; - const Fp2& d = y.a; - const Fp2& e = y.b; - const Fp2& f = y.c; -#if 1 - Fp2Dbl AD, BE, CF; - Fp2Dbl::mulPre(AD, a, d); - Fp2Dbl::mulPre(BE, b, e); - Fp2Dbl::mulPre(CF, c, f); - - Fp2 t1, t2, t3, t4; - Fp2::add(t1, b, c); - Fp2::add(t2, e, f); - Fp2Dbl T1; - Fp2Dbl::mulPre(T1, t1, t2); - Fp2Dbl::sub(T1, T1, BE); - Fp2Dbl::sub(T1, T1, CF); - Fp2Dbl::mul_xi(T1, T1); - - Fp2::add(t2, a, b); - Fp2::add(t3, e, d); - Fp2Dbl T2; - Fp2Dbl::mulPre(T2, t2, t3); - Fp2Dbl::sub(T2, T2, AD); - Fp2Dbl::sub(T2, T2, BE); - - Fp2::add(t3, a, c); - Fp2::add(t4, d, f); - Fp2Dbl T3; - Fp2Dbl::mulPre(T3, t3, t4); - Fp2Dbl::sub(T3, T3, AD); - Fp2Dbl::sub(T3, T3, CF); - - Fp2Dbl::add(AD, AD, T1); - Fp2Dbl::mod(z.a, AD); - Fp2Dbl::mul_xi(CF, CF); - Fp2Dbl::add(CF, CF, T2); - Fp2Dbl::mod(z.b, CF); - Fp2Dbl::add(T3, T3, BE); - Fp2Dbl::mod(z.c, T3); -#else - Fp2 ad, be, cf; - Fp2::mul(ad, a, d); - Fp2::mul(be, b, e); - Fp2::mul(cf, c, f); - - Fp2 t1, t2, t3, t4; - Fp2::add(t1, b, c); - Fp2::add(t2, e, f); - t1 *= t2; - t1 -= be; - t1 -= cf; - Fp2::mul_xi(t1, t1); - - Fp2::add(t2, a, b); - Fp2::add(t3, e, d); - t2 *= t3; - t2 -= ad; - t2 -= be; - - Fp2::add(t3, a, c); - Fp2::add(t4, d, f); - t3 *= t4; - t3 -= ad; - t3 -= cf; - - Fp2::add(z.a, ad, t1); - Fp2::mul_xi(z.b, cf); - z.b += t2; - Fp2::add(z.c, t3, be); -#endif -//clk.end(); - } + static inline void mul(Fp6T& z, const Fp6T& x, const Fp6T& y); /* x = a + bv + cv^2, v^3 = xi y = 1/x = p/q where @@ -1040,6 +950,94 @@ struct Fp6T : public fp::Serializable<Fp6T<_Fp>, } }; +template<class Fp> +struct Fp6DblT { + typedef Fp2T<Fp> Fp2; + typedef Fp6T<Fp> Fp6; + typedef Fp2DblT<Fp> Fp2Dbl; + typedef Fp6DblT<Fp> Fp6Dbl; + typedef fp::Unit Unit; + Fp2Dbl a, b, c; + static void add(Fp6Dbl& z, const Fp6Dbl& x, const Fp6Dbl& y) + { + Fp2Dbl::add(z.a, x.a, y.a); + Fp2Dbl::add(z.b, x.b, y.b); + Fp2Dbl::add(z.c, x.c, y.c); + } + static void sub(Fp6Dbl& z, const Fp6Dbl& x, const Fp6Dbl& y) + { + Fp2Dbl::sub(z.a, x.a, y.a); + Fp2Dbl::sub(z.b, x.b, y.b); + Fp2Dbl::sub(z.c, x.c, y.c); + } + /* + x = a + bv + cv^2, y = d + ev + fv^2, v^3 = xi + xy = (ad + (bf + ce)xi) + ((ae + bd) + cf xi)v + ((af + cd) + be)v^2 + bf + ce = (b + c)(e + f) - be - cf + ae + bd = (a + b)(e + d) - ad - be + af + cd = (a + c)(d + f) - ad - cf + */ + static void mulPre(Fp6DblT& z, const Fp6& x, const Fp6& y) + { +//clk.begin(); + const Fp2& a = x.a; + const Fp2& b = x.b; + const Fp2& c = x.c; + const Fp2& d = y.a; + const Fp2& e = y.b; + const Fp2& f = y.c; + Fp2Dbl& za = z.a; + Fp2Dbl& zb = z.b; + Fp2Dbl& zc = z.c; + Fp2Dbl BE; + Fp2Dbl::mulPre(za, a, d); + Fp2Dbl::mulPre(BE, b, e); + Fp2Dbl::mulPre(zb, c, f); + + Fp2 t1, t2, t3, t4; + Fp2::add(t1, b, c); + Fp2::add(t2, e, f); + Fp2Dbl T1; + Fp2Dbl::mulPre(T1, t1, t2); + Fp2Dbl::sub(T1, T1, BE); + Fp2Dbl::sub(T1, T1, zb); + Fp2Dbl::mul_xi(T1, T1); + + Fp2::add(t2, a, b); + Fp2::add(t3, e, d); + Fp2Dbl T2; + Fp2Dbl::mulPre(T2, t2, t3); + Fp2Dbl::sub(T2, T2, za); + Fp2Dbl::sub(T2, T2, BE); + + Fp2::add(t3, a, c); + Fp2::add(t4, d, f); + Fp2Dbl::mulPre(zc, t3, t4); + Fp2Dbl::sub(zc, zc, za); + Fp2Dbl::sub(zc, zc, zb); + + Fp2Dbl::add(za, za, T1); + Fp2Dbl::mul_xi(zb, zb); + Fp2Dbl::add(zb, zb, T2); + Fp2Dbl::add(zc, zc, BE); +//clk.end(); + } + static void mod(Fp6& y, const Fp6Dbl& x) + { + Fp2Dbl::mod(y.a, x.a); + Fp2Dbl::mod(y.b, x.b); + Fp2Dbl::mod(y.c, x.c); + } +}; + +template<class Fp> +inline void Fp6T<Fp>::mul(Fp6T<Fp>& z, const Fp6T<Fp>& x, const Fp6T<Fp>& y) +{ + Fp6DblT<Fp> Z; + Fp6DblT<Fp>::mulPre(Z, x, y); + Fp6DblT<Fp>::mod(z, Z); +} + /* Fp12T = Fp6[w] / (w^2 - v) x = a + b w @@ -1049,6 +1047,8 @@ struct Fp12T : public fp::Serializable<Fp12T<Fp>, fp::Operator<Fp12T<Fp> > > { typedef Fp2T<Fp> Fp2; typedef Fp6T<Fp> Fp6; + typedef Fp2DblT<Fp> Fp2Dbl; + typedef Fp6DblT<Fp> Fp6Dbl; typedef Fp BaseFp; Fp6 a, b; Fp12T() {} @@ -1115,6 +1115,14 @@ struct Fp12T : public fp::Serializable<Fp12T<Fp>, Fp2::add(z.b, x.a, y.b); Fp2::add(z.a, t, y.a); } + static void mulVadd(Fp6Dbl& z, const Fp6Dbl& x, const Fp6Dbl& y) + { + Fp2Dbl t; + Fp2Dbl::mul_xi(t, x.c); + Fp2Dbl::add(z.c, x.b, y.c); + Fp2Dbl::add(z.b, x.a, y.b); + Fp2Dbl::add(z.a, t, y.a); + } /* x = a + bw, y = c + dw, w^2 = v z = xy = (a + bw)(c + dw) = (ac + bdv) + (ad + bc)w @@ -1124,19 +1132,33 @@ struct Fp12T : public fp::Serializable<Fp12T<Fp>, */ static void mul(Fp12T& z, const Fp12T& x, const Fp12T& y) { + // 4.7Kclk -> 4.55Kclk const Fp6& a = x.a; const Fp6& b = x.b; const Fp6& c = y.a; const Fp6& d = y.b; - Fp6 t1, t2, ac, bd; + Fp6 t1, t2; Fp6::add(t1, a, b); Fp6::add(t2, c, d); +#if 1 + Fp6Dbl T, AC, BD; + Fp6Dbl::mulPre(AC, a, c); + Fp6Dbl::mulPre(BD, b, d); + mulVadd(T, BD, AC); + Fp6Dbl::mod(z.a, T); + Fp6Dbl::mulPre(T, t1, t2); // (a + b)(c + d) + Fp6Dbl::sub(T, T, AC); + Fp6Dbl::sub(T, T, BD); + Fp6Dbl::mod(z.b, T); +#else + Fp6 ac, bd; t1 *= t2; // (a + b)(c + d) Fp6::mul(ac, a, c); Fp6::mul(bd, b, d); mulVadd(z.a, bd, ac); t1 -= ac; Fp6::sub(z.b, t1, bd); +#endif } /* x = a + bw, w^2 = v diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/gmp_util.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/gmp_util.hpp index 2dd71eb50..bcbd91a1e 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/gmp_util.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/gmp_util.hpp @@ -450,7 +450,8 @@ inline void getRand(bool *pb, mpz_class& z, size_t bitSize, fp::RandGen rg = fp: *pb = false; return; } - rg.read(buf, n * sizeof(buf[0])); + rg.read(pb, buf, n * sizeof(buf[0])); + if (!*pb) return; uint32_t v = buf[n - 1]; if (rem == 0) { v |= 1U << 31; @@ -858,4 +859,96 @@ public: #endif }; +/* + Barrett Reduction + for non GMP version + mod of GMP is faster than Modp +*/ +struct Modp { + static const size_t unitBitSize = sizeof(mcl::fp::Unit) * 8; + mpz_class p_; + mpz_class u_; + mpz_class a_; + size_t pBitSize_; + size_t N_; + bool initU_; // Is u_ initialized? + Modp() + : pBitSize_(0) + , N_(0) + , initU_(false) + { + } + // x &= 1 << (unitBitSize * unitSize) + void shrinkSize(mpz_class &x, size_t unitSize) const + { + size_t u = gmp::getUnitSize(x); + if (u < unitSize) return; + bool b; + gmp::setArray(&b, x, gmp::getUnit(x), unitSize); + (void)b; + assert(b); + } + // p_ is set by p and compute (u_, a_) if possible + void init(const mpz_class& p) + { + p_ = p; + pBitSize_ = gmp::getBitSize(p); + N_ = (pBitSize_ + unitBitSize - 1) / unitBitSize; + initU_ = false; +#if 0 + u_ = (mpz_class(1) << (unitBitSize * 2 * N_)) / p_; +#else + /* + 1 << (unitBitSize * 2 * N_) may be overflow, + so use (1 << (unitBitSize * 2 * N_)) - 1 because u_ is same. + */ + uint8_t buf[48 * 2]; + const size_t byteSize = unitBitSize / 8 * 2 * N_; + if (byteSize > sizeof(buf)) return; + memset(buf, 0xff, byteSize); + bool b; + gmp::setArray(&b, u_, buf, byteSize); + if (!b) return; +#endif + u_ /= p_; + a_ = mpz_class(1) << (unitBitSize * (N_ + 1)); + initU_ = true; + } + void modp(mpz_class& r, const mpz_class& t) const + { + assert(p_ > 0); + const size_t tBitSize = gmp::getBitSize(t); + // use gmp::mod if init() fails or t is too large + if (tBitSize > unitBitSize * 2 * N_ || !initU_) { + gmp::mod(r, t, p_); + return; + } + if (tBitSize < pBitSize_) { + r = t; + return; + } + // mod is faster than modp if t is small + if (tBitSize <= unitBitSize * N_) { + gmp::mod(r, t, p_); + return; + } + mpz_class q; + q = t; + q >>= unitBitSize * (N_ - 1); + q *= u_; + q >>= unitBitSize * (N_ + 1); + q *= p_; + shrinkSize(q, N_ + 1); + r = t; + shrinkSize(r, N_ + 1); + r -= q; + if (r < 0) { + r += a_; + } + if (r >= p_) { + r -= p_; + } + } +}; + } // mcl diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/impl/bn_c_impl.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/impl/bn_c_impl.hpp new file mode 100644 index 000000000..bec2466dd --- /dev/null +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/impl/bn_c_impl.hpp @@ -0,0 +1,643 @@ +/* + This is an internal header + Do not include this +*/ +#define MCLBN_DLL_EXPORT +#include <mcl/bn.h> + +#if MCLBN_FP_UNIT_SIZE == 4 && MCLBN_FR_UNIT_SIZE == 4 +#include <mcl/bn256.hpp> +#elif MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE == 6 +#include <mcl/bn384.hpp> +#elif MCLBN_FP_UNIT_SIZE == 6 && MCLBN_FR_UNIT_SIZE == 4 +#include <mcl/bls12_381.hpp> +#elif MCLBN_FP_UNIT_SIZE == 8 && MCLBN_FR_UNIT_SIZE == 8 +#include <mcl/bn512.hpp> +#else + #error "not supported size" +#endif +#include <mcl/lagrange.hpp> +#include <mcl/ecparam.hpp> +using namespace mcl::bn; + +static Fr *cast(mclBnFr *p) { return reinterpret_cast<Fr*>(p); } +static const Fr *cast(const mclBnFr *p) { return reinterpret_cast<const Fr*>(p); } + +static G1 *cast(mclBnG1 *p) { return reinterpret_cast<G1*>(p); } +static const G1 *cast(const mclBnG1 *p) { return reinterpret_cast<const G1*>(p); } + +static G2 *cast(mclBnG2 *p) { return reinterpret_cast<G2*>(p); } +static const G2 *cast(const mclBnG2 *p) { return reinterpret_cast<const G2*>(p); } + +static Fp12 *cast(mclBnGT *p) { return reinterpret_cast<Fp12*>(p); } +static const Fp12 *cast(const mclBnGT *p) { return reinterpret_cast<const Fp12*>(p); } + +static Fp6 *cast(uint64_t *p) { return reinterpret_cast<Fp6*>(p); } +static const Fp6 *cast(const uint64_t *p) { return reinterpret_cast<const Fp6*>(p); } + +static Fp2 *cast(mclBnFp2 *p) { return reinterpret_cast<Fp2*>(p); } +static const Fp2 *cast(const mclBnFp2 *p) { return reinterpret_cast<const Fp2*>(p); } + +static Fp *cast(mclBnFp *p) { return reinterpret_cast<Fp*>(p); } +static const Fp *cast(const mclBnFp *p) { return reinterpret_cast<const Fp*>(p); } + +template<class T> +int setStr(T *x, const char *buf, mclSize bufSize, int ioMode) +{ + size_t n = cast(x)->deserialize(buf, bufSize, ioMode); + return n > 0 ? 0 : -1; +} + +#ifdef __EMSCRIPTEN__ +// use these functions forcibly +extern "C" MCLBN_DLL_API void *mclBnMalloc(size_t n) +{ + return malloc(n); +} +extern "C" MCLBN_DLL_API void mclBnFree(void *p) +{ + free(p); +} +#endif + +int mclBn_getVersion() +{ + return mcl::version; +} + +int mclBn_init(int curve, int compiledTimeVar) +{ + if (compiledTimeVar != MCLBN_COMPILED_TIME_VAR) { + return -(compiledTimeVar | (MCLBN_COMPILED_TIME_VAR * 100)); + } + if (MCL_EC_BEGIN <= curve && curve < MCL_EC_END) { + const mcl::EcParam *para = mcl::getEcParam(curve); + if (para == 0) return -2; + bool b; + initG1only(&b, *para); + return b ? 0 : -1; + } + const mcl::CurveParam& cp = mcl::getCurveParam(curve); + bool b; + initPairing(&b, cp); + return b ? 0 : -1; +} + +int mclBn_getOpUnitSize() +{ + return (int)Fp::getUnitSize() * sizeof(mcl::fp::Unit) / sizeof(uint64_t); +} + +int mclBn_getG1ByteSize() +{ + return mclBn_getFpByteSize(); +} + +int mclBn_getFrByteSize() +{ + return (int)Fr::getByteSize(); +} + +int mclBn_getFpByteSize() +{ + return (int)Fp::getByteSize(); +} + +mclSize mclBn_getCurveOrder(char *buf, mclSize maxBufSize) +{ + return Fr::getModulo(buf, maxBufSize); +} + +mclSize mclBn_getFieldOrder(char *buf, mclSize maxBufSize) +{ + return Fp::getModulo(buf, maxBufSize); +} + +//////////////////////////////////////////////// +// set zero +void mclBnFr_clear(mclBnFr *x) +{ + cast(x)->clear(); +} + +// set x to y +void mclBnFr_setInt(mclBnFr *y, mclInt x) +{ + *cast(y) = x; +} +void mclBnFr_setInt32(mclBnFr *y, int x) +{ + *cast(y) = x; +} + +int mclBnFr_setStr(mclBnFr *x, const char *buf, mclSize bufSize, int ioMode) +{ + return setStr(x, buf, bufSize, ioMode); +} +int mclBnFr_setLittleEndian(mclBnFr *x, const void *buf, mclSize bufSize) +{ + cast(x)->setArrayMask((const char *)buf, bufSize); + return 0; +} +int mclBnFr_setLittleEndianMod(mclBnFr *x, const void *buf, mclSize bufSize) +{ + bool b; + cast(x)->setArray(&b, (const char *)buf, bufSize, mcl::fp::Mod); + return b ? 0 : -1; +} +mclSize mclBnFr_deserialize(mclBnFr *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} +// return 1 if true +int mclBnFr_isValid(const mclBnFr *x) +{ + return cast(x)->isValid(); +} +int mclBnFr_isEqual(const mclBnFr *x, const mclBnFr *y) +{ + return *cast(x) == *cast(y); +} +int mclBnFr_isZero(const mclBnFr *x) +{ + return cast(x)->isZero(); +} +int mclBnFr_isOne(const mclBnFr *x) +{ + return cast(x)->isOne(); +} + +#ifndef MCL_DONT_USE_CSRPNG +int mclBnFr_setByCSPRNG(mclBnFr *x) +{ + bool b; + cast(x)->setByCSPRNG(&b); + return b ? 0 : -1; +} +void mclBn_setRandFunc(void *self, unsigned int (*readFunc)(void *self, void *buf, unsigned int bufSize)) +{ + mcl::fp::RandGen::setRandFunc(self, readFunc); +} +#endif + +// hash(buf) and set x +int mclBnFr_setHashOf(mclBnFr *x, const void *buf, mclSize bufSize) +{ + cast(x)->setHashOf(buf, bufSize); + return 0; +} + +mclSize mclBnFr_getStr(char *buf, mclSize maxBufSize, const mclBnFr *x, int ioMode) +{ + return cast(x)->getStr(buf, maxBufSize, ioMode); +} +mclSize mclBnFr_serialize(void *buf, mclSize maxBufSize, const mclBnFr *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnFr_neg(mclBnFr *y, const mclBnFr *x) +{ + Fr::neg(*cast(y), *cast(x)); +} +void mclBnFr_inv(mclBnFr *y, const mclBnFr *x) +{ + Fr::inv(*cast(y), *cast(x)); +} +void mclBnFr_sqr(mclBnFr *y, const mclBnFr *x) +{ + Fr::sqr(*cast(y), *cast(x)); +} +void mclBnFr_add(mclBnFr *z, const mclBnFr *x, const mclBnFr *y) +{ + Fr::add(*cast(z),*cast(x), *cast(y)); +} +void mclBnFr_sub(mclBnFr *z, const mclBnFr *x, const mclBnFr *y) +{ + Fr::sub(*cast(z),*cast(x), *cast(y)); +} +void mclBnFr_mul(mclBnFr *z, const mclBnFr *x, const mclBnFr *y) +{ + Fr::mul(*cast(z),*cast(x), *cast(y)); +} +void mclBnFr_div(mclBnFr *z, const mclBnFr *x, const mclBnFr *y) +{ + Fr::div(*cast(z),*cast(x), *cast(y)); +} + +//////////////////////////////////////////////// +// set zero +void mclBnG1_clear(mclBnG1 *x) +{ + cast(x)->clear(); +} + +int mclBnG1_setStr(mclBnG1 *x, const char *buf, mclSize bufSize, int ioMode) +{ + return setStr(x, buf, bufSize, ioMode); +} +mclSize mclBnG1_deserialize(mclBnG1 *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} + +// return 1 if true +int mclBnG1_isValid(const mclBnG1 *x) +{ + return cast(x)->isValid(); +} +int mclBnG1_isEqual(const mclBnG1 *x, const mclBnG1 *y) +{ + return *cast(x) == *cast(y); +} +int mclBnG1_isZero(const mclBnG1 *x) +{ + return cast(x)->isZero(); +} +int mclBnG1_isValidOrder(const mclBnG1 *x) +{ + return cast(x)->isValidOrder(); +} + +int mclBnG1_hashAndMapTo(mclBnG1 *x, const void *buf, mclSize bufSize) +{ + hashAndMapToG1(*cast(x), buf, bufSize); + return 0; +} + +mclSize mclBnG1_getStr(char *buf, mclSize maxBufSize, const mclBnG1 *x, int ioMode) +{ + return cast(x)->getStr(buf, maxBufSize, ioMode); +} + +mclSize mclBnG1_serialize(void *buf, mclSize maxBufSize, const mclBnG1 *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnG1_neg(mclBnG1 *y, const mclBnG1 *x) +{ + G1::neg(*cast(y), *cast(x)); +} +void mclBnG1_dbl(mclBnG1 *y, const mclBnG1 *x) +{ + G1::dbl(*cast(y), *cast(x)); +} +void mclBnG1_normalize(mclBnG1 *y, const mclBnG1 *x) +{ + G1::normalize(*cast(y), *cast(x)); +} +void mclBnG1_add(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y) +{ + G1::add(*cast(z),*cast(x), *cast(y)); +} +void mclBnG1_sub(mclBnG1 *z, const mclBnG1 *x, const mclBnG1 *y) +{ + G1::sub(*cast(z),*cast(x), *cast(y)); +} +void mclBnG1_mul(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y) +{ + G1::mul(*cast(z),*cast(x), *cast(y)); +} +void mclBnG1_mulCT(mclBnG1 *z, const mclBnG1 *x, const mclBnFr *y) +{ + G1::mulCT(*cast(z),*cast(x), *cast(y)); +} + +//////////////////////////////////////////////// +// set zero +void mclBnG2_clear(mclBnG2 *x) +{ + cast(x)->clear(); +} + +int mclBnG2_setStr(mclBnG2 *x, const char *buf, mclSize bufSize, int ioMode) +{ + return setStr(x, buf, bufSize, ioMode); +} +mclSize mclBnG2_deserialize(mclBnG2 *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} + +// return 1 if true +int mclBnG2_isValid(const mclBnG2 *x) +{ + return cast(x)->isValid(); +} +int mclBnG2_isEqual(const mclBnG2 *x, const mclBnG2 *y) +{ + return *cast(x) == *cast(y); +} +int mclBnG2_isZero(const mclBnG2 *x) +{ + return cast(x)->isZero(); +} +int mclBnG2_isValidOrder(const mclBnG2 *x) +{ + return cast(x)->isValidOrder(); +} + +int mclBnG2_hashAndMapTo(mclBnG2 *x, const void *buf, mclSize bufSize) +{ + hashAndMapToG2(*cast(x), buf, bufSize); + return 0; +} + +mclSize mclBnG2_getStr(char *buf, mclSize maxBufSize, const mclBnG2 *x, int ioMode) +{ + return cast(x)->getStr(buf, maxBufSize, ioMode); +} + +mclSize mclBnG2_serialize(void *buf, mclSize maxBufSize, const mclBnG2 *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnG2_neg(mclBnG2 *y, const mclBnG2 *x) +{ + G2::neg(*cast(y), *cast(x)); +} +void mclBnG2_dbl(mclBnG2 *y, const mclBnG2 *x) +{ + G2::dbl(*cast(y), *cast(x)); +} +void mclBnG2_normalize(mclBnG2 *y, const mclBnG2 *x) +{ + G2::normalize(*cast(y), *cast(x)); +} +void mclBnG2_add(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y) +{ + G2::add(*cast(z),*cast(x), *cast(y)); +} +void mclBnG2_sub(mclBnG2 *z, const mclBnG2 *x, const mclBnG2 *y) +{ + G2::sub(*cast(z),*cast(x), *cast(y)); +} +void mclBnG2_mul(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y) +{ + G2::mul(*cast(z),*cast(x), *cast(y)); +} +void mclBnG2_mulCT(mclBnG2 *z, const mclBnG2 *x, const mclBnFr *y) +{ + G2::mulCT(*cast(z),*cast(x), *cast(y)); +} + +//////////////////////////////////////////////// +// set zero +void mclBnGT_clear(mclBnGT *x) +{ + cast(x)->clear(); +} +void mclBnGT_setInt(mclBnGT *y, mclInt x) +{ + cast(y)->clear(); + *(cast(y)->getFp0()) = x; +} +void mclBnGT_setInt32(mclBnGT *y, int x) +{ + cast(y)->clear(); + *(cast(y)->getFp0()) = x; +} + +int mclBnGT_setStr(mclBnGT *x, const char *buf, mclSize bufSize, int ioMode) +{ + return setStr(x, buf, bufSize, ioMode); +} +mclSize mclBnGT_deserialize(mclBnGT *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} + +// return 1 if true +int mclBnGT_isEqual(const mclBnGT *x, const mclBnGT *y) +{ + return *cast(x) == *cast(y); +} +int mclBnGT_isZero(const mclBnGT *x) +{ + return cast(x)->isZero(); +} +int mclBnGT_isOne(const mclBnGT *x) +{ + return cast(x)->isOne(); +} + +mclSize mclBnGT_getStr(char *buf, mclSize maxBufSize, const mclBnGT *x, int ioMode) +{ + return cast(x)->getStr(buf, maxBufSize, ioMode); +} + +mclSize mclBnGT_serialize(void *buf, mclSize maxBufSize, const mclBnGT *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnGT_neg(mclBnGT *y, const mclBnGT *x) +{ + Fp12::neg(*cast(y), *cast(x)); +} +void mclBnGT_inv(mclBnGT *y, const mclBnGT *x) +{ + Fp12::inv(*cast(y), *cast(x)); +} +void mclBnGT_sqr(mclBnGT *y, const mclBnGT *x) +{ + Fp12::sqr(*cast(y), *cast(x)); +} +void mclBnGT_add(mclBnGT *z, const mclBnGT *x, const mclBnGT *y) +{ + Fp12::add(*cast(z),*cast(x), *cast(y)); +} +void mclBnGT_sub(mclBnGT *z, const mclBnGT *x, const mclBnGT *y) +{ + Fp12::sub(*cast(z),*cast(x), *cast(y)); +} +void mclBnGT_mul(mclBnGT *z, const mclBnGT *x, const mclBnGT *y) +{ + Fp12::mul(*cast(z),*cast(x), *cast(y)); +} +void mclBnGT_div(mclBnGT *z, const mclBnGT *x, const mclBnGT *y) +{ + Fp12::div(*cast(z),*cast(x), *cast(y)); +} + +void mclBnGT_pow(mclBnGT *z, const mclBnGT *x, const mclBnFr *y) +{ + Fp12::pow(*cast(z), *cast(x), *cast(y)); +} +void mclBnGT_powGeneric(mclBnGT *z, const mclBnGT *x, const mclBnFr *y) +{ + Fp12::powGeneric(*cast(z), *cast(x), *cast(y)); +} + +void mclBn_pairing(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y) +{ + pairing(*cast(z), *cast(x), *cast(y)); +} +void mclBn_finalExp(mclBnGT *y, const mclBnGT *x) +{ + finalExp(*cast(y), *cast(x)); +} +void mclBn_millerLoop(mclBnGT *z, const mclBnG1 *x, const mclBnG2 *y) +{ + millerLoop(*cast(z), *cast(x), *cast(y)); +} +int mclBn_getUint64NumToPrecompute(void) +{ + return int(BN::param.precomputedQcoeffSize * sizeof(Fp6) / sizeof(uint64_t)); +} + +void mclBn_precomputeG2(uint64_t *Qbuf, const mclBnG2 *Q) +{ + precomputeG2(cast(Qbuf), *cast(Q)); +} + +void mclBn_precomputedMillerLoop(mclBnGT *f, const mclBnG1 *P, const uint64_t *Qbuf) +{ + precomputedMillerLoop(*cast(f), *cast(P), cast(Qbuf)); +} + +void mclBn_precomputedMillerLoop2(mclBnGT *f, const mclBnG1 *P1, const uint64_t *Q1buf, const mclBnG1 *P2, const uint64_t *Q2buf) +{ + precomputedMillerLoop2(*cast(f), *cast(P1), cast(Q1buf), *cast(P2), cast(Q2buf)); +} + +void mclBn_precomputedMillerLoop2mixed(mclBnGT *f, const mclBnG1 *P1, const mclBnG2 *Q1, const mclBnG1 *P2, const uint64_t *Q2buf) +{ + precomputedMillerLoop2mixed(*cast(f), *cast(P1), *cast(Q1), *cast(P2), cast(Q2buf)); +} + +int mclBn_FrLagrangeInterpolation(mclBnFr *out, const mclBnFr *xVec, const mclBnFr *yVec, mclSize k) +{ + bool b; + mcl::LagrangeInterpolation(&b, *cast(out), cast(xVec), cast(yVec), k); + return b ? 0 : -1; +} +int mclBn_G1LagrangeInterpolation(mclBnG1 *out, const mclBnFr *xVec, const mclBnG1 *yVec, mclSize k) +{ + bool b; + mcl::LagrangeInterpolation(&b, *cast(out), cast(xVec), cast(yVec), k); + return b ? 0 : -1; +} +int mclBn_G2LagrangeInterpolation(mclBnG2 *out, const mclBnFr *xVec, const mclBnG2 *yVec, mclSize k) +{ + bool b; + mcl::LagrangeInterpolation(&b, *cast(out), cast(xVec), cast(yVec), k); + return b ? 0 : -1; +} +int mclBn_FrEvaluatePolynomial(mclBnFr *out, const mclBnFr *cVec, mclSize cSize, const mclBnFr *x) +{ + bool b; + mcl::evaluatePolynomial(&b, *cast(out), cast(cVec), cSize, *cast(x)); + return b ? 0 : -1; +} +int mclBn_G1EvaluatePolynomial(mclBnG1 *out, const mclBnG1 *cVec, mclSize cSize, const mclBnFr *x) +{ + bool b; + mcl::evaluatePolynomial(&b, *cast(out), cast(cVec), cSize, *cast(x)); + return b ? 0 : -1; +} +int mclBn_G2EvaluatePolynomial(mclBnG2 *out, const mclBnG2 *cVec, mclSize cSize, const mclBnFr *x) +{ + bool b; + mcl::evaluatePolynomial(&b, *cast(out), cast(cVec), cSize, *cast(x)); + return b ? 0 : -1; +} + +void mclBn_verifyOrderG1(int doVerify) +{ + verifyOrderG1(doVerify != 0); +} + +void mclBn_verifyOrderG2(int doVerify) +{ + verifyOrderG2(doVerify != 0); +} + +mclSize mclBnFp_getStr(char *buf, mclSize maxBufSize, const mclBnFp *x, int ioMode) +{ + return cast(x)->getStr(buf, maxBufSize, ioMode); +} +int mclBnFp_setStr(mclBnFp *x, const char *buf, mclSize bufSize, int ioMode) +{ + return setStr(x, buf, bufSize, ioMode); +} +mclSize mclBnFp_deserialize(mclBnFp *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} + +mclSize mclBnFp_serialize(void *buf, mclSize maxBufSize, const mclBnFp *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnFp_clear(mclBnFp *x) +{ + cast(x)->clear(); +} + +int mclBnFp_setLittleEndian(mclBnFp *x, const void *buf, mclSize bufSize) +{ + cast(x)->setArrayMask((const char *)buf, bufSize); + return 0; +} + +int mclBnFp_setLittleEndianMod(mclBnFp *x, const void *buf, mclSize bufSize) +{ + bool b; + cast(x)->setArray(&b, (const char *)buf, bufSize, mcl::fp::Mod); + return b ? 0 : -1; +} +int mclBnFp_isEqual(const mclBnFp *x, const mclBnFp *y) +{ + return *cast(x) == *cast(y); +} + +int mclBnFp_setHashOf(mclBnFp *x, const void *buf, mclSize bufSize) +{ + cast(x)->setHashOf(buf, bufSize); + return 0; +} + +int mclBnFp_mapToG1(mclBnG1 *y, const mclBnFp *x) +{ + bool b; + mapToG1(&b, *cast(y), *cast(x)); + return b ? 0 : -1; +} + +mclSize mclBnFp2_deserialize(mclBnFp2 *x, const void *buf, mclSize bufSize) +{ + return (mclSize)cast(x)->deserialize(buf, bufSize); +} + +mclSize mclBnFp2_serialize(void *buf, mclSize maxBufSize, const mclBnFp2 *x) +{ + return (mclSize)cast(x)->serialize(buf, maxBufSize); +} + +void mclBnFp2_clear(mclBnFp2 *x) +{ + cast(x)->clear(); +} + +int mclBnFp2_isEqual(const mclBnFp2 *x, const mclBnFp2 *y) +{ + return *cast(x) == *cast(y); +} + +int mclBnFp2_mapToG2(mclBnG2 *y, const mclBnFp2 *x) +{ + bool b; + mapToG2(&b, *cast(y), *cast(x)); + return b ? 0 : -1; +} + +int mclBnG1_getBasePoint(mclBnG1 *x) +{ + *cast(x) = mcl::bn::getG1basePoint(); + return 0; +} + diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/lagrange.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/lagrange.hpp index 7c0218896..18e0597ec 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/lagrange.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/lagrange.hpp @@ -15,14 +15,19 @@ namespace mcl { template<class G, class F> void LagrangeInterpolation(bool *pb, G& out, const F *S, const G *vec, size_t k) { + if (k == 0) { + *pb = false; + return; + } + if (k == 1) { + out = vec[0]; + *pb = true; + return; + } /* delta_{i,S}(0) = prod_{j != i} S[j] / (S[j] - S[i]) = a / b where a = prod S[j], b = S[i] * prod_{j != i} (S[j] - S[i]) */ - if (k < 2) { - *pb = false; - return; - } F a = S[0]; for (size_t i = 1; i < k; i++) { a *= S[i]; @@ -58,15 +63,20 @@ void LagrangeInterpolation(bool *pb, G& out, const F *S, const G *vec, size_t k) /* out = f(x) = c[0] + c[1] * x + c[2] * x^2 + ... + c[cSize - 1] * x^(cSize - 1) - @retval 0 if succeed else -1 + @retval 0 if succeed else -1 (if cSize == 0) */ template<class G, class T> void evaluatePolynomial(bool *pb, G& out, const G *c, size_t cSize, const T& x) { - if (cSize < 2) { + if (cSize == 0) { *pb = false; return; } + if (cSize == 1) { + out = c[0]; + *pb = true; + return; + } G y = c[cSize - 1]; for (int i = (int)cSize - 2; i >= 0; i--) { G::mul(y, y, x); diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/op.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/op.hpp index d108d1a55..36d37035e 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/op.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/op.hpp @@ -26,6 +26,8 @@ namespace mcl { +static const int version = 0x092; /* 0xABC = A.BC */ + /* specifies available string format mode for X::setIoMode() // for Fp, Fp2, Fp6, Fp12 @@ -59,7 +61,7 @@ namespace mcl { IoArray array of Unit(fixed size = Fp::getByteSize()) IoArrayRaw - array of Unit(fixed size = Fp::getByteSize()) without Montgomery convresion + array of Unit(fixed size = Fp::getByteSize()) without Montgomery conversion // for Ec::setIoMode() IoEcAffine(default) @@ -127,6 +129,15 @@ typedef int (*int2u)(Unit*, const Unit*); typedef Unit (*u1uII)(Unit*, Unit, Unit); typedef Unit (*u3u)(Unit*, const Unit*, const Unit*); +/* + disable -Wcast-function-type + the number of arguments of some JIT functions is smaller than that of T +*/ +template<class T, class S> +T func_ptr_cast(S func) +{ + return reinterpret_cast<T>(reinterpret_cast<void*>(func)); +} struct Block { const Unit *p; // pointer to original FpT.v_ size_t n; @@ -152,7 +163,8 @@ enum PrimeMode { enum MaskMode { NoMask = 0, // throw if greater or equal SmallMask = 1, // 1-bit smaller mask if greater or equal - MaskAndMod = 2 // mask and substract if greater or equal + MaskAndMod = 2, // mask and substract if greater or equal + Mod = 3 // mod p }; struct Op { @@ -165,6 +177,7 @@ struct Op { mpz_class mp; uint32_t pmod4; mcl::SquareRoot sq; + mcl::Modp modp; Unit half[maxUnitSize]; // (p + 1) / 2 Unit oneRep[maxUnitSize]; // 1(=inv R if Montgomery) /* @@ -193,8 +206,6 @@ struct Op { void2u fp2_sqrA_; void3u fpDbl_addA_; void3u fpDbl_subA_; - void3u fpDbl_addPreA_; - void3u fpDbl_subPreA_; void3u fpDbl_mulPreA_; void2u fpDbl_sqrPreA_; void2u fpDbl_modA_; @@ -282,8 +293,6 @@ struct Op { fp2_sqrA_ = 0; fpDbl_addA_ = 0; fpDbl_subA_ = 0; - fpDbl_addPreA_ = 0; - fpDbl_subPreA_ = 0; fpDbl_mulPreA_ = 0; fpDbl_sqrPreA_ = 0; fpDbl_modA_ = 0; @@ -345,8 +354,7 @@ struct Op { */ fp_mul(y, x, R2, p); } - bool init(const mpz_class& p, size_t maxBitSize, Mode mode, size_t mclMaxBitSize = MCL_MAX_BIT_SIZE); - void initFp2(int xi_a); + bool init(const mpz_class& p, size_t maxBitSize, int xi_a, Mode mode, size_t mclMaxBitSize = MCL_MAX_BIT_SIZE); #ifdef MCL_USE_XBYAK static FpGenerator* createFpGenerator(); static void destroyFpGenerator(FpGenerator *fg); diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/randgen.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/randgen.hpp index 4bfb30b03..30502fc10 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/randgen.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/randgen.hpp @@ -15,10 +15,16 @@ namespace mcl { struct RandomGeneratorJS { - void read(void *buf, size_t bufSize) + void read(bool *pb, void *buf, uint32_t byteSize) { + // cf. https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues + if (byteSize > 65536) { + *pb = false; + return; + } // use crypto.getRandomValues - EM_ASM({Module.cryptoGetRandomValues($0, $1)}, buf, bufSize); + EM_ASM({Module.cryptoGetRandomValues($0, $1)}, buf, byteSize); + *pb = true; } }; } // mcl @@ -38,28 +44,33 @@ namespace mcl { namespace fp { namespace local { template<class RG> -void readWrapper(void *self, void *buf, uint32_t bufSize) +uint32_t readWrapper(void *self, void *buf, uint32_t byteSize) { - reinterpret_cast<RG*>(self)->read((uint8_t*)buf, bufSize); + bool b; + reinterpret_cast<RG*>(self)->read(&b, (uint8_t*)buf, byteSize); + if (b) return byteSize; + return 0; } #if 0 // #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 template<> -inline void readWrapper<std::random_device>(void *self, void *buf, uint32_t bufSize) +inline uint32_t readWrapper<std::random_device>(void *self, void *buf, uint32_t byteSize) { + const uint32_t keep = byteSize; std::random_device& rg = *reinterpret_cast<std::random_device*>(self); uint8_t *p = reinterpret_cast<uint8_t*>(buf); uint32_t v; - while (bufSize >= 4) { + while (byteSize >= 4) { v = rg(); memcpy(p, &v, 4); p += 4; - bufSize -= 4; + byteSize -= 4; } - if (bufSize > 0) { + if (byteSize > 0) { v = rg(); - memcpy(p, &v, bufSize); + memcpy(p, &v, byteSize); } + return keep; } #endif } // local @@ -67,7 +78,7 @@ inline void readWrapper<std::random_device>(void *self, void *buf, uint32_t bufS wrapper of cryptographically secure pseudo random number generator */ class RandGen { - typedef void (*readFuncType)(void *self, void *buf, uint32_t bufSize); + typedef uint32_t (*readFuncType)(void *self, void *buf, uint32_t byteSize); void *self_; readFuncType readFunc_; public: @@ -87,16 +98,17 @@ public: , readFunc_(local::readWrapper<RG>) { } - void read(void *out, size_t byteSize) + void read(bool *pb, void *out, size_t byteSize) { - readFunc_(self_, out, static_cast<uint32_t>(byteSize)); + uint32_t size = readFunc_(self_, out, static_cast<uint32_t>(byteSize)); + *pb = size == byteSize; } #ifdef MCL_DONT_USE_CSPRNG bool isZero() const { return false; } /* return false to avoid copying default rg */ #else bool isZero() const { return self_ == 0 && readFunc_ == 0; } #endif - static RandGen& get() + static RandGen& getDefaultRandGen() { #ifdef MCL_DONT_USE_CSPRNG static RandGen wrg; @@ -109,14 +121,32 @@ public: #endif return wrg; } + static RandGen& get() + { + static RandGen wrg(getDefaultRandGen()); + return wrg; + } /* rg must be thread safe - rg.read(void *buf, size_t bufSize); + rg.read(void *buf, size_t byteSize); */ static void setRandGen(const RandGen& rg) { get() = rg; } + /* + set rand function + if self and readFunc are NULL then set default rand function + */ + static void setRandFunc(void *self, readFuncType readFunc) + { + if (self == 0 && readFunc == 0) { + setRandGen(getDefaultRandGen()); + } else { + RandGen rg(self, readFunc); + setRandGen(rg); + } + } }; } } // mcl::fp diff --git a/vendor/github.com/dexon-foundation/mcl/include/mcl/vint.hpp b/vendor/github.com/dexon-foundation/mcl/include/mcl/vint.hpp index 32a51bb64..b087688c3 100644 --- a/vendor/github.com/dexon-foundation/mcl/include/mcl/vint.hpp +++ b/vendor/github.com/dexon-foundation/mcl/include/mcl/vint.hpp @@ -568,6 +568,7 @@ void divNM(T *q, size_t qn, T *r, const T *x, size_t xn, const T *y, size_t yn) yn = getRealSize(y, yn); if (x == y) { assert(xn == yn); + x_is_y: clearN(r, rn); if (q) { q[0] = 1; @@ -579,6 +580,7 @@ void divNM(T *q, size_t qn, T *r, const T *x, size_t xn, const T *y, size_t yn) /* if y > x then q = 0 and r = x */ + q_is_zero: copyN(r, x, xn); clearN(r + xn, rn - xn); if (q) clearN(q, qn); @@ -598,11 +600,61 @@ void divNM(T *q, size_t qn, T *r, const T *x, size_t xn, const T *y, size_t yn) clearN(r + 1, rn - 1); return; } + const size_t yTopBit = cybozu::bsr(y[yn - 1]); assert(yn >= 2); + if (xn == yn) { + const size_t xTopBit = cybozu::bsr(x[xn - 1]); + if (xTopBit < yTopBit) goto q_is_zero; + if (yTopBit == xTopBit) { + int ret = compareNM(x, xn, y, yn); + if (ret == 0) goto x_is_y; + if (ret < 0) goto q_is_zero; + if (r) { + subN(r, x, y, yn); + } + if (q) { + q[0] = 1; + clearN(q + 1, qn - 1); + } + return; + } + assert(xTopBit > yTopBit); + // fast reduction for larger than fullbit-3 size p + if (yTopBit >= sizeof(T) * 8 - 4) { + T *xx = (T*)CYBOZU_ALLOCA(sizeof(T) * xn); + T qv = 0; + if (yTopBit == sizeof(T) * 8 - 2) { + copyN(xx, x, xn); + } else { + qv = x[xn - 1] >> (yTopBit + 1); + mulu1(xx, y, yn, qv); + subN(xx, x, xx, xn); + xn = getRealSize(xx, xn); + } + for (;;) { + T ret = subN(xx, xx, y, yn); + if (ret) { + addN(xx, xx, y, yn); + break; + } + qv++; + xn = getRealSize(xx, xn); + } + if (r) { + copyN(r, xx, xn); + clearN(r + xn, rn - xn); + } + if (q) { + q[0] = qv; + clearN(q + 1, qn - 1); + } + return; + } + } /* bitwise left shift x and y to adjust MSB of y[yn - 1] = 1 */ - const size_t shift = sizeof(T) * 8 - 1 - cybozu::bsr(y[yn - 1]); + const size_t shift = sizeof(T) * 8 - 1 - yTopBit; T *xx = (T*)CYBOZU_ALLOCA(sizeof(T) * (xn + 1)); const T *yy; if (shift) { @@ -1124,8 +1176,15 @@ public: size_t unitSize = (sizeof(S) * size + sizeof(Unit) - 1) / sizeof(Unit); buf_.alloc(pb, unitSize); if (!*pb) return; - buf_[unitSize - 1] = 0; - memcpy(&buf_[0], x, sizeof(S) * size); + char *dst = (char *)&buf_[0]; + const char *src = (const char *)x; + size_t i = 0; + for (; i < sizeof(S) * size; i++) { + dst[i] = src[i]; + } + for (; i < sizeof(Unit) * unitSize; i++) { + dst[i] = 0; + } trim(unitSize); } /* @@ -1138,7 +1197,8 @@ public: size_t n = max.size(); buf_.alloc(pb, n); if (!*pb) return; - rg.read(&buf_[0], n * sizeof(buf_[0])); + rg.read(pb, &buf_[0], n * sizeof(buf_[0])); + if (!*pb) return; trim(n); *this %= max; } @@ -1231,7 +1291,8 @@ public: */ void setStr(bool *pb, const char *str, int base = 0) { - const size_t maxN = MCL_MAX_BIT_SIZE / (sizeof(MCL_SIZEOF_UNIT) * 8); + // allow twice size of MCL_MAX_BIT_SIZE because of multiplication + const size_t maxN = (MCL_MAX_BIT_SIZE * 2 + unitBitSize - 1) / unitBitSize; buf_.alloc(pb, maxN); if (!*pb) return; *pb = false; |