aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMITSUNARI Shigeo <herumi@nifty.com>2018-02-05 15:32:00 +0800
committerMITSUNARI Shigeo <herumi@nifty.com>2018-02-05 15:32:00 +0800
commitafce65fbba2f895fdb5668d8c4bbb4f050ad4c99 (patch)
tree7344296bab8c81d0603939e540aa36dddc6e95ee
parent40b6278d4787ed51ff164b62e2369ff5e9d450ce (diff)
downloaddexon-mcl-afce65fbba2f895fdb5668d8c4bbb4f050ad4c99.tar.gz
dexon-mcl-afce65fbba2f895fdb5668d8c4bbb4f050ad4c99.tar.zst
dexon-mcl-afce65fbba2f895fdb5668d8c4bbb4f050ad4c99.zip
add WrapperRG
-rw-r--r--include/mcl/fp.hpp14
-rw-r--r--include/mcl/op.hpp64
-rw-r--r--include/mcl/util.hpp40
-rw-r--r--src/fp.cpp16
-rw-r--r--test/fp_util_test.cpp39
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]
diff --git a/src/fp.cpp b/src/fp.cpp
index 078be1c..8579860 100644
--- a/src/fp.cpp
+++ b/src/fp.cpp
@@ -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
}
}