github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/mcl/randgen.hpp (about) 1 #pragma once 2 /** 3 @file 4 @brief definition of Op 5 @author MITSUNARI Shigeo(@herumi) 6 @license modified new BSD license 7 http://opensource.org/licenses/BSD-3-Clause 8 */ 9 #ifdef MCL_DONT_USE_CSPRNG 10 11 // nothing 12 13 #elif defined(MCL_USE_WEB_CRYPTO_API) 14 #include <emscripten.h> 15 16 namespace mcl { 17 struct RandomGeneratorJS { 18 void read(bool *pb, void *buf, uint32_t byteSize) 19 { 20 // cf. https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues 21 if (byteSize > 65536) { 22 *pb = false; 23 return; 24 } 25 // use crypto.getRandomValues 26 EM_ASM({Module.cryptoGetRandomValues($0, $1)}, buf, byteSize); 27 *pb = true; 28 } 29 }; 30 } // mcl 31 32 #else 33 #include <cybozu/random_generator.hpp> 34 #if 0 // #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 35 #include <random> 36 #endif 37 #endif 38 #ifdef _MSC_VER 39 #pragma warning(push) 40 #pragma warning(disable : 4521) 41 #endif 42 namespace mcl { namespace fp { 43 44 namespace local { 45 46 template<class RG> 47 uint32_t readWrapper(void *self, void *buf, uint32_t byteSize) 48 { 49 bool b; 50 reinterpret_cast<RG*>(self)->read(&b, (uint8_t*)buf, byteSize); 51 if (b) return byteSize; 52 return 0; 53 } 54 55 #if 0 // #if CYBOZU_CPP_VERSION >= CYBOZU_CPP_VERSION_CPP11 56 template<> 57 inline uint32_t readWrapper<std::random_device>(void *self, void *buf, uint32_t byteSize) 58 { 59 const uint32_t keep = byteSize; 60 std::random_device& rg = *reinterpret_cast<std::random_device*>(self); 61 uint8_t *p = reinterpret_cast<uint8_t*>(buf); 62 uint32_t v; 63 while (byteSize >= 4) { 64 v = rg(); 65 memcpy(p, &v, 4); 66 p += 4; 67 byteSize -= 4; 68 } 69 if (byteSize > 0) { 70 v = rg(); 71 memcpy(p, &v, byteSize); 72 } 73 return keep; 74 } 75 #endif 76 } // local 77 /* 78 wrapper of cryptographically secure pseudo random number generator 79 */ 80 class RandGen { 81 typedef uint32_t (*readFuncType)(void *self, void *buf, uint32_t byteSize); 82 void *self_; 83 readFuncType readFunc_; 84 public: 85 RandGen() : self_(0), readFunc_(0) {} 86 RandGen(void *self, readFuncType readFunc) : self_(self) , readFunc_(readFunc) {} 87 RandGen(const RandGen& rhs) : self_(rhs.self_), readFunc_(rhs.readFunc_) {} 88 RandGen(RandGen& rhs) : self_(rhs.self_), readFunc_(rhs.readFunc_) {} 89 RandGen& operator=(const RandGen& rhs) 90 { 91 self_ = rhs.self_; 92 readFunc_ = rhs.readFunc_; 93 return *this; 94 } 95 template<class RG> 96 RandGen(RG& rg) 97 : self_(reinterpret_cast<void*>(&rg)) 98 , readFunc_(local::readWrapper<RG>) 99 { 100 } 101 void read(bool *pb, void *out, size_t byteSize) 102 { 103 uint32_t size = readFunc_(self_, out, static_cast<uint32_t>(byteSize)); 104 *pb = size == byteSize; 105 } 106 #ifdef MCL_DONT_USE_CSPRNG 107 bool isZero() const { return false; } /* return false to avoid copying default rg */ 108 #else 109 bool isZero() const { return self_ == 0 && readFunc_ == 0; } 110 #endif 111 static RandGen& getDefaultRandGen() 112 { 113 #ifdef MCL_DONT_USE_CSPRNG 114 static RandGen wrg; 115 #elif defined(MCL_USE_WEB_CRYPTO_API) 116 static mcl::RandomGeneratorJS rg; 117 static RandGen wrg(rg); 118 #else 119 static cybozu::RandomGenerator rg; 120 static RandGen wrg(rg); 121 #endif 122 return wrg; 123 } 124 static RandGen& get() 125 { 126 static RandGen wrg(getDefaultRandGen()); 127 return wrg; 128 } 129 /* 130 rg must be thread safe 131 rg.read(void *buf, size_t byteSize); 132 */ 133 static void setRandGen(const RandGen& rg) 134 { 135 get() = rg; 136 } 137 /* 138 set rand function 139 if self and readFunc are NULL then set default rand function 140 */ 141 static void setRandFunc(void *self, readFuncType readFunc) 142 { 143 if (self == 0 && readFunc == 0) { 144 setRandGen(getDefaultRandGen()); 145 } else { 146 RandGen rg(self, readFunc); 147 setRandGen(rg); 148 } 149 } 150 }; 151 152 } } // mcl::fp 153 154 #ifdef _MSC_VER 155 #pragma warning(pop) 156 #endif