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