diff options
author | MITSUNARI Shigeo <herumi@nifty.com> | 2018-02-05 15:32:00 +0800 |
---|---|---|
committer | MITSUNARI Shigeo <herumi@nifty.com> | 2018-02-05 15:32:00 +0800 |
commit | afce65fbba2f895fdb5668d8c4bbb4f050ad4c99 (patch) | |
tree | 7344296bab8c81d0603939e540aa36dddc6e95ee | |
parent | 40b6278d4787ed51ff164b62e2369ff5e9d450ce (diff) | |
download | dexon-mcl-afce65fbba2f895fdb5668d8c4bbb4f050ad4c99.tar.gz dexon-mcl-afce65fbba2f895fdb5668d8c4bbb4f050ad4c99.tar.zst dexon-mcl-afce65fbba2f895fdb5668d8c4bbb4f050ad4c99.zip |
add WrapperRG
-rw-r--r-- | include/mcl/fp.hpp | 14 | ||||
-rw-r--r-- | include/mcl/op.hpp | 64 | ||||
-rw-r--r-- | include/mcl/util.hpp | 40 | ||||
-rw-r--r-- | src/fp.cpp | 16 | ||||
-rw-r--r-- | test/fp_util_test.cpp | 39 |
5 files changed, 121 insertions, 52 deletions
diff --git a/include/mcl/fp.hpp b/include/mcl/fp.hpp index 2a79e57..d500086 100644 --- a/include/mcl/fp.hpp +++ b/include/mcl/fp.hpp @@ -57,6 +57,8 @@ std::string littleEndianToHexStr(const void *buf, size_t bufSize); bool isEnableJIT(); // 1st call is not threadsafe +void getRandVal(Unit *out, WrapperRG& rg, const Unit *in, size_t bitSize); + namespace local { inline bool isSpace(char c) @@ -305,12 +307,16 @@ public: b.p = &v_[0]; } } - template<class RG> - void setRand(RG& rg) + void setByCSPRNG(mcl::fp::WrapperRG rg = mcl::fp::WrapperRG()) { + if (rg.isZero()) rg = op_.wrapperRg; fp::getRandVal(v_, rg, op_.p, op_.bitSize); toMont(); } + void setRand(mcl::fp::WrapperRG rg = mcl::fp::WrapperRG()) + { + setByCSPRNG(rg); + } /* hash msg and mask with (1 << (bitLen - 1)) - 1 */ @@ -466,6 +472,10 @@ public: { op_.hash = hash; } + static inline void setWrapperRG(void *self, void (*readFunc)(void *self, void *buf, uint32_t bufSize)) + { + op_.wrapperRg.set(self, readFunc); + } }; template<class tag, size_t maxBitSize> fp::Op FpT<tag, maxBitSize>::op_; diff --git a/include/mcl/op.hpp b/include/mcl/op.hpp index 10c3b2c..a5913ca 100644 --- a/include/mcl/op.hpp +++ b/include/mcl/op.hpp @@ -7,6 +7,7 @@ http://opensource.org/licenses/BSD-3-Clause */ #include <mcl/gmp_util.hpp> +#include <memory.h> #ifndef MCL_MAX_BIT_SIZE #define MCL_MAX_BIT_SIZE 521 @@ -21,6 +22,10 @@ #define MCL_MAX_HASH_BIT_SIZE 512 +#if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 +#include <random> +#endif + namespace mcl { /* @@ -137,6 +142,63 @@ enum PrimeMode { PM_NICT_P521 }; +namespace local { + +template<class RG> +void readWrapper(void *self, void *buf, uint32_t bufSize) +{ + reinterpret_cast<RG*>(self)->read((uint8_t*)buf, bufSize); +} + +#if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 +template<> +void readWrapper<std::random_device>(void *self, void *buf, uint32_t bufSize) +{ + std::random_device& rg = *reinterpret_cast<std::random_device*>(self); + uint8_t *p = reinterpret_cast<uint8_t*>(buf); + uint32_t v; + while (bufSize >= 4) { + v = rg(); + memcpy(p, &v, 4); + p += 4; + bufSize -= 4; + } + if (bufSize > 0) { + v = rg(); + memcpy(p, &v, bufSize); + } +} +#endif +} // local +/* + wrapper of cryptographically secure pseudo random number generator +*/ +class WrapperRG { + typedef void (*readFuncType)(void *self, void *buf, uint32_t bufSize); + void *self_; + readFuncType readFunc_; +public: + WrapperRG() : self_(0), readFunc_(0) {} + WrapperRG(void *self, readFuncType readFunc) : self_(self) , readFunc_(readFunc) {} + template<class RG> + WrapperRG(RG& rg) + : self_(reinterpret_cast<void*>(&rg)) + , readFunc_(local::readWrapper<RG>) + { + } + void read(void *out, size_t byteSize) + { + readFunc_(self_, out, byteSize); + } + bool isZero() const { return self_ == 0 && readFunc_ == 0; } + void clear() { self_ = 0; readFunc_ = 0; } + void set(void *self, void (*readFunc)(void *self,void *buf, uint32_t bufSize)) + { + self_ = self; + readFunc_ = readFunc; + } +}; + struct Op { /* don't change the layout of rp and p @@ -203,6 +265,7 @@ struct Op { void2u fp2_sqr; void2u fp2_mul_xi; uint32_t (*hash)(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize); + WrapperRG wrapperRg; PrimeMode primeMode; bool isFullBit; // true if bitSize % uniSize == 0 @@ -276,6 +339,7 @@ struct Op { isMont = false; isFastMod = false; hash = 0; + wrapperRg.clear(); } void fromMont(Unit* y, const Unit *x) const { diff --git a/include/mcl/util.hpp b/include/mcl/util.hpp index f1c2cfd..452420b 100644 --- a/include/mcl/util.hpp +++ b/include/mcl/util.hpp @@ -146,46 +146,6 @@ size_t getNonZeroArraySize(const T *x, size_t n) return 1; } -namespace impl { - -template<class T, class RG> -static void readN(T* out, size_t n, RG& rg) -{ - if (sizeof(T) == 8) { - for (size_t i = 0; i < n; i++) { - T L = rg(); - T H = rg(); - out[i] = L | (uint64_t(H) << 32); - } - } else { - for (size_t i = 0; i < n; i++) { - out[i] = rg(); - } - } -} - -} // impl -/* - get random value less than in[] - n = (bitSize + sizeof(T) * 8) / (sizeof(T) * 8) - input in[0..n) - output out[n..n) - 0 <= out < in -*/ -template<class RG, class T> -void getRandVal(T *out, RG& rg, const T *in, size_t bitSize) -{ - const size_t TbitSize = sizeof(T) * 8; - const size_t n = (bitSize + TbitSize - 1) / TbitSize; - const size_t rem = bitSize & (TbitSize - 1); - for (;;) { - impl::readN(out, n, rg); -// rg.read(out, n); - if (rem > 0) out[n - 1] &= (T(1) << rem) - 1; - if (isLessArray(out, in, n)) return; - } -} - /* @param out [inout] : set element of G ; out = x^y[] @param x [in] @@ -17,11 +17,14 @@ #endif #include <cybozu/atoi.hpp> #include <cybozu/itoa.hpp> +#include <cybozu/random_generator.hpp> #ifdef _MSC_VER #pragma warning(disable : 4127) #endif +cybozu::RandomGenerator s_cybozuRandomGenerator; + namespace mcl { namespace fp { @@ -194,6 +197,17 @@ bool isEnableJIT() #endif } +void getRandVal(Unit *out, WrapperRG& rg, const Unit *in, size_t bitSize) +{ + const size_t n = (bitSize + UnitBitSize - 1) / UnitBitSize; + const size_t rem = bitSize & (UnitBitSize - 1); + for (;;) { + rg.read(out, n * sizeof(Unit)); + if (rem > 0) out[n - 1] &= (Unit(1) << rem) - 1; + if (isLessArray(out, in, n)) return; + } +} + static uint32_t sha256(void *out, uint32_t maxOutSize, const void *msg, uint32_t msgSize) { const uint32_t hashSize = 256 / 8; @@ -218,6 +232,7 @@ static uint32_t sha512(void *out, uint32_t maxOutSize, const void *msg, uint32_t return hashSize; } + #ifndef MCL_USE_VINT static inline void set_mpz_t(mpz_t& z, const Unit* p, int n) { @@ -540,6 +555,7 @@ void Op::init(const std::string& mstr, size_t maxBitSize, Mode mode, size_t mclM } else { hash = sha512; } + wrapperRg = mcl::fp::WrapperRG(s_cybozuRandomGenerator); } void arrayToStr(std::string& str, const Unit *x, size_t n, int ioMode) diff --git a/test/fp_util_test.cpp b/test/fp_util_test.cpp index c57e616..51bd529 100644 --- a/test/fp_util_test.cpp +++ b/test/fp_util_test.cpp @@ -131,25 +131,33 @@ CYBOZU_TEST_AUTO(isLessOrEqualArray) struct Rand { std::vector<uint32_t> v; + const uint8_t *p; size_t pos; - void read(uint32_t *x, size_t n) + size_t endPos; + void read(void *x, size_t n) { - if (v.size() < pos + n) throw cybozu::Exception("Rand:get:bad n") << v.size() << pos << n; - std::copy(v.begin() + pos, v.begin() + pos + n, x); + if (pos + n > endPos) throw cybozu::Exception("Rand:get:bad n") << pos << n << endPos; + uint8_t *dst = (uint8_t*)x; + memcpy(dst, p + pos, n); pos += n; } uint32_t operator()() { - if (pos >= v.size()) throw cybozu::Exception("Rand:get:bad n") << v.size() << pos; - pos++; - return v[pos - 1]; + char buf[4]; + read(buf, 4); + uint32_t v; + memcpy(&v, buf, 4); + return v; } Rand(const uint32_t *x, size_t n) - : pos(0) + : p(0) + , pos(0) { for (size_t i = 0; i < n; i++) { v.push_back(x[i]); } + p = (uint8_t*)&v[0]; + endPos = v.size() * 4; } }; @@ -169,10 +177,21 @@ CYBOZU_TEST_AUTO(getRandVal) }; for (size_t i = 0; i < CYBOZU_NUM_OF_ARRAY(tbl); i++) { Rand rg(tbl[i].r, rn); +#if CYBOZU_OS_BIT == 64 + uint64_t out[1]; + const uint64_t *mod = (const uint64_t*)tbl[i].mod; + const uint64_t *expect = (const uint64_t*)tbl[i].expect; +#else uint32_t out[2]; - mcl::fp::getRandVal(out, rg, tbl[i].mod, tbl[i].bitSize); - CYBOZU_TEST_EQUAL(out[0], tbl[i].expect[0]); - CYBOZU_TEST_EQUAL(out[1], tbl[i].expect[1]); + const uint32_t *mod = tbl[i].mod; + const uint32_t *expect = tbl[i].expect; +#endif + mcl::fp::WrapperRG wrg(rg); + mcl::fp::getRandVal(out, wrg, mod, tbl[i].bitSize); + CYBOZU_TEST_EQUAL(out[0], expect[0]); +#if CYBOZU_OS_BIT == 32 + CYBOZU_TEST_EQUAL(out[1], expect[1]); +#endif } } |