aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/dexon-foundation/mcl/include
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/dexon-foundation/mcl/include')
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/random_generator.hpp34
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/sha2.hpp345
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/cybozu/xorshift.hpp113
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/array.hpp25
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/bn.h62
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/bn.hpp119
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/curve_type.h19
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/ec.hpp104
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/ecparam.hpp51
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/elgamal.hpp18
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/fp.hpp66
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/fp_tower.hpp330
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/gmp_util.hpp95
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/impl/bn_c_impl.hpp643
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/lagrange.hpp22
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/op.hpp24
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/randgen.hpp58
-rw-r--r--vendor/github.com/dexon-foundation/mcl/include/mcl/vint.hpp71
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;