a portable and fast pairing-based cryptography library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
mcl/include/mcl/randgen.hpp

126 lines
2.7 KiB

#pragma once
/**
@file
@brief definition of Op
@author MITSUNARI Shigeo(@herumi)
@license modified new BSD license
http://opensource.org/licenses/BSD-3-Clause
*/
#ifdef MCL_DONT_USE_CSPRNG
// nothing
#elif defined(MCL_USE_WEB_CRYPTO_API)
#include <emscripten.h>
namespace mcl {
struct RandomGeneratorJS {
void read(void *buf, size_t bufSize)
{
// use crypto.getRandomValues
EM_ASM({Module.cryptoGetRandomValues($0, $1)}, buf, bufSize);
}
};
} // mcl
#else
#include <cybozu/random_generator.hpp>
#if 0 // #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
#include <random>
#endif
#endif
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4521)
#endif
namespace mcl { namespace fp {
namespace local {
template<class RG>
void readWrapper(void *self, void *buf, uint32_t bufSize)
{
reinterpret_cast<RG*>(self)->read((uint8_t*)buf, bufSize);
}
#if 0 // #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11
template<>
inline 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 RandGen {
typedef void (*readFuncType)(void *self, void *buf, uint32_t bufSize);
void *self_;
readFuncType readFunc_;
public:
RandGen() : self_(0), readFunc_(0) {}
RandGen(void *self, readFuncType readFunc) : self_(self) , readFunc_(readFunc) {}
RandGen(const RandGen& rhs) : self_(rhs.self_), readFunc_(rhs.readFunc_) {}
RandGen(RandGen& rhs) : self_(rhs.self_), readFunc_(rhs.readFunc_) {}
RandGen& operator=(const RandGen& rhs)
{
self_ = rhs.self_;
readFunc_ = rhs.readFunc_;
return *this;
}
template<class RG>
RandGen(RG& rg)
: self_(reinterpret_cast<void*>(&rg))
, readFunc_(local::readWrapper<RG>)
{
}
void read(void *out, size_t byteSize)
{
readFunc_(self_, out, static_cast<uint32_t>(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()
{
#ifdef MCL_DONT_USE_CSPRNG
static RandGen wrg;
#elif defined(MCL_USE_WEB_CRYPTO_API)
static mcl::RandomGeneratorJS rg;
static RandGen wrg(rg);
#else
static cybozu::RandomGenerator rg;
static RandGen wrg(rg);
#endif
return wrg;
}
/*
rg must be thread safe
rg.read(void *buf, size_t bufSize);
*/
static void setRandGen(const RandGen& rg)
{
get() = rg;
}
};
} } // mcl::fp
#ifdef _MSC_VER
#pragma warning(pop)
#endif