github.com/platonnetwork/platon-go@v0.7.6/cases/tool/win/bls_win/include/cybozu/sha2.hpp (about)

     1  #pragma once
     2  /**
     3  	@file
     4  	@brief SHA-256, SHA-512 class
     5  	@author MITSUNARI Shigeo(@herumi)
     6  	@license modified new BSD license
     7  	http://opensource.org/licenses/BSD-3-Clause
     8  */
     9  #if !defined(CYBOZU_DONT_USE_OPENSSL) && !defined(MCL_DONT_USE_OPENSSL)
    10  	#define CYBOZU_USE_OPENSSL_SHA
    11  #endif
    12  
    13  #ifndef CYBOZU_DONT_USE_STRING
    14  #include <string>
    15  #endif
    16  
    17  #ifdef CYBOZU_USE_OPENSSL_SHA
    18  #ifdef __APPLE__
    19  	#pragma GCC diagnostic push
    20  	#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    21  #endif
    22  #include <openssl/sha.h>
    23  #ifdef _MSC_VER
    24  	#include <cybozu/link_libeay32.hpp>
    25  #endif
    26  
    27  #ifdef __APPLE__
    28  	#pragma GCC diagnostic pop
    29  #endif
    30  
    31  namespace cybozu {
    32  
    33  class Sha256 {
    34  	SHA256_CTX ctx_;
    35  public:
    36  	Sha256()
    37  	{
    38  		clear();
    39  	}
    40  	void clear()
    41  	{
    42  		SHA256_Init(&ctx_);
    43  	}
    44  	void update(const void *buf, size_t bufSize)
    45  	{
    46  		SHA256_Update(&ctx_, buf, bufSize);
    47  	}
    48  	size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize)
    49  	{
    50  		if (mdSize < SHA256_DIGEST_LENGTH) return 0;
    51  		update(buf, bufSize);
    52  		SHA256_Final(reinterpret_cast<uint8_t*>(md), &ctx_);
    53  		return SHA256_DIGEST_LENGTH;
    54  	}
    55  #ifndef CYBOZU_DONT_USE_STRING
    56  	void update(const std::string& buf)
    57  	{
    58  		update(buf.c_str(), buf.size());
    59  	}
    60  	std::string digest(const std::string& buf)
    61  	{
    62  		return digest(buf.c_str(), buf.size());
    63  	}
    64  	std::string digest(const void *buf, size_t bufSize)
    65  	{
    66  		std::string md(SHA256_DIGEST_LENGTH, 0);
    67  		digest(&md[0], md.size(), buf, bufSize);
    68  		return md;
    69  	}
    70  #endif
    71  };
    72  
    73  class Sha512 {
    74  	SHA512_CTX ctx_;
    75  public:
    76  	Sha512()
    77  	{
    78  		clear();
    79  	}
    80  	void clear()
    81  	{
    82  		SHA512_Init(&ctx_);
    83  	}
    84  	void update(const void *buf, size_t bufSize)
    85  	{
    86  		SHA512_Update(&ctx_, buf, bufSize);
    87  	}
    88  	size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize)
    89  	{
    90  		if (mdSize < SHA512_DIGEST_LENGTH) return 0;
    91  		update(buf, bufSize);
    92  		SHA512_Final(reinterpret_cast<uint8_t*>(md), &ctx_);
    93  		return SHA512_DIGEST_LENGTH;
    94  	}
    95  #ifndef CYBOZU_DONT_USE_STRING
    96  	void update(const std::string& buf)
    97  	{
    98  		update(buf.c_str(), buf.size());
    99  	}
   100  	std::string digest(const std::string& buf)
   101  	{
   102  		return digest(buf.c_str(), buf.size());
   103  	}
   104  	std::string digest(const void *buf, size_t bufSize)
   105  	{
   106  		std::string md(SHA512_DIGEST_LENGTH, 0);
   107  		digest(&md[0], md.size(), buf, bufSize);
   108  		return md;
   109  	}
   110  #endif
   111  };
   112  
   113  } // cybozu
   114  
   115  #else
   116  
   117  #include <cybozu/endian.hpp>
   118  #include <memory.h>
   119  #include <assert.h>
   120  
   121  namespace cybozu {
   122  
   123  namespace sha2_local {
   124  
   125  template<class T>
   126  T min_(T x, T y) { return x < y ? x : y;; }
   127  
   128  inline uint32_t rot32(uint32_t x, int s)
   129  {
   130  #ifdef _MSC_VER
   131  	return _rotr(x, s);
   132  #else
   133  	return (x >> s) | (x << (32 - s));
   134  #endif
   135  }
   136  
   137  inline uint64_t rot64(uint64_t x, int s)
   138  {
   139  #ifdef _MSC_VER
   140  	return _rotr64(x, s);
   141  #else
   142  	return (x >> s) | (x << (64 - s));
   143  #endif
   144  }
   145  
   146  template<class T>
   147  struct Common {
   148  	void term(uint8_t *buf, size_t bufSize)
   149  	{
   150  		assert(bufSize < T::blockSize_);
   151  		T& self = static_cast<T&>(*this);
   152  		const uint64_t totalSize = self.totalSize_ + bufSize;
   153  
   154  		buf[bufSize] = uint8_t(0x80); /* top bit = 1 */
   155  		memset(&buf[bufSize + 1], 0, T::blockSize_ - bufSize - 1);
   156  		if (bufSize >= T::blockSize_ - T::msgLenByte_) {
   157  			self.round(buf);
   158  			memset(buf, 0, T::blockSize_ - 8); // clear stack
   159  		}
   160  		cybozu::Set64bitAsBE(&buf[T::blockSize_ - 8], totalSize * 8);
   161  		self.round(buf);
   162  	}
   163  	void inner_update(const uint8_t *buf, size_t bufSize)
   164  	{
   165  		T& self = static_cast<T&>(*this);
   166  		if (bufSize == 0) return;
   167  		if (self.roundBufSize_ > 0) {
   168  			size_t size = sha2_local::min_(T::blockSize_ - self.roundBufSize_, bufSize);
   169  			memcpy(self.roundBuf_ + self.roundBufSize_, buf, size);
   170  			self.roundBufSize_ += size;
   171  			buf += size;
   172  			bufSize -= size;
   173  		}
   174  		if (self.roundBufSize_ == T::blockSize_) {
   175  			self.round(self.roundBuf_);
   176  			self.roundBufSize_ = 0;
   177  		}
   178  		while (bufSize >= T::blockSize_) {
   179  			assert(self.roundBufSize_ == 0);
   180  			self.round(buf);
   181  			buf += T::blockSize_;
   182  			bufSize -= T::blockSize_;
   183  		}
   184  		if (bufSize > 0) {
   185  			assert(bufSize < T::blockSize_);
   186  			assert(self.roundBufSize_ == 0);
   187  			memcpy(self.roundBuf_, buf, bufSize);
   188  			self.roundBufSize_ = bufSize;
   189  		}
   190  		assert(self.roundBufSize_ < T::blockSize_);
   191  	}
   192  };
   193  
   194  } // cybozu::sha2_local
   195  
   196  class Sha256 : public sha2_local::Common<Sha256> {
   197  	friend struct sha2_local::Common<Sha256>;
   198  private:
   199  	static const size_t blockSize_ = 64;
   200  	static const size_t hSize_ = 8;
   201  	static const size_t msgLenByte_ = 8;
   202  	uint64_t totalSize_;
   203  	size_t roundBufSize_;
   204  	uint8_t roundBuf_[blockSize_];
   205  	uint32_t h_[hSize_];
   206  	static const size_t outByteSize_ = hSize_ * sizeof(uint32_t);
   207  	const uint32_t *k_;
   208  
   209  	template<size_t i0, size_t i1, size_t i2, size_t i3, size_t i4, size_t i5, size_t i6, size_t i7>
   210  	void round1(uint32_t *s, uint32_t *w, int i)
   211  	{
   212  		using namespace sha2_local;
   213  		uint32_t e = s[i4];
   214  		uint32_t h = s[i7];
   215  		h += rot32(e, 6) ^ rot32(e, 11) ^ rot32(e, 25);
   216  		uint32_t f = s[i5];
   217  		uint32_t g = s[i6];
   218  		h += g ^ (e & (f ^ g));
   219  		h += k_[i];
   220  		h += w[i];
   221  		s[i3] += h;
   222  		uint32_t a = s[i0];
   223  		uint32_t b = s[i1];
   224  		uint32_t c = s[i2];
   225  		h += rot32(a, 2) ^ rot32(a, 13) ^ rot32(a, 22);
   226  		h += ((a | b) & c) | (a & b);
   227  		s[i7] = h;
   228  	}
   229  	/**
   230  		@param buf [in] buffer(64byte)
   231  	*/
   232  	void round(const uint8_t *buf)
   233  	{
   234  		using namespace sha2_local;
   235  		uint32_t w[64];
   236  		for (int i = 0; i < 16; i++) {
   237  			w[i] = cybozu::Get32bitAsBE(&buf[i * 4]);
   238  		}
   239  		for (int i = 16 ; i < 64; i++) {
   240  			uint32_t t = w[i - 15];
   241  			uint32_t s0 = rot32(t, 7) ^ rot32(t, 18) ^ (t >> 3);
   242  			t = w[i - 2];
   243  			uint32_t s1 = rot32(t, 17) ^ rot32(t, 19) ^ (t >> 10);
   244  			w[i] = w[i - 16] + s0 + w[i - 7] + s1;
   245  		}
   246  		uint32_t s[8];
   247  		for (int i = 0; i < 8; i++) {
   248  			s[i] = h_[i];
   249  		}
   250  		for (int i = 0; i < 64; i += 8) {
   251  			round1<0, 1, 2, 3, 4, 5, 6, 7>(s, w, i + 0);
   252  			round1<7, 0, 1, 2, 3, 4, 5, 6>(s, w, i + 1);
   253  			round1<6, 7, 0, 1, 2, 3, 4, 5>(s, w, i + 2);
   254  			round1<5, 6, 7, 0, 1, 2, 3, 4>(s, w, i + 3);
   255  			round1<4, 5, 6, 7, 0, 1, 2, 3>(s, w, i + 4);
   256  			round1<3, 4, 5, 6, 7, 0, 1, 2>(s, w, i + 5);
   257  			round1<2, 3, 4, 5, 6, 7, 0, 1>(s, w, i + 6);
   258  			round1<1, 2, 3, 4, 5, 6, 7, 0>(s, w, i + 7);
   259  		}
   260  		for (int i = 0; i < 8; i++) {
   261  			h_[i] += s[i];
   262  		}
   263  		totalSize_ += blockSize_;
   264  	}
   265  public:
   266  	Sha256()
   267  	{
   268  		clear();
   269  	}
   270  	void clear()
   271  	{
   272  		static const uint32_t kTbl[] = {
   273  			0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
   274  			0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
   275  			0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
   276  			0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
   277  			0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
   278  			0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
   279  			0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
   280  			0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
   281  		};
   282  		k_ = kTbl;
   283  		totalSize_ = 0;
   284  		roundBufSize_ = 0;
   285  		h_[0] = 0x6a09e667;
   286  		h_[1] = 0xbb67ae85;
   287  		h_[2] = 0x3c6ef372;
   288  		h_[3] = 0xa54ff53a;
   289  		h_[4] = 0x510e527f;
   290  		h_[5] = 0x9b05688c;
   291  		h_[6] = 0x1f83d9ab;
   292  		h_[7] = 0x5be0cd19;
   293  	}
   294  	void update(const void *buf, size_t bufSize)
   295  	{
   296  		inner_update(reinterpret_cast<const uint8_t*>(buf), bufSize);
   297  	}
   298  	size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize)
   299  	{
   300  		if (mdSize < outByteSize_) return 0;
   301  		update(buf, bufSize);
   302  		term(roundBuf_, roundBufSize_);
   303  		char *p = reinterpret_cast<char*>(md);
   304  		for (size_t i = 0; i < hSize_; i++) {
   305  			cybozu::Set32bitAsBE(&p[i * sizeof(h_[0])], h_[i]);
   306  		}
   307  		return outByteSize_;
   308  	}
   309  #ifndef CYBOZU_DONT_USE_STRING
   310  	void update(const std::string& buf)
   311  	{
   312  		update(buf.c_str(), buf.size());
   313  	}
   314  	std::string digest(const std::string& buf)
   315  	{
   316  		return digest(buf.c_str(), buf.size());
   317  	}
   318  	std::string digest(const void *buf, size_t bufSize)
   319  	{
   320  		std::string md(outByteSize_, 0);
   321  		digest(&md[0], md.size(), buf, bufSize);
   322  		return md;
   323  	}
   324  #endif
   325  };
   326  
   327  class Sha512 : public sha2_local::Common<Sha512> {
   328  	friend struct sha2_local::Common<Sha512>;
   329  private:
   330  	static const size_t blockSize_ = 128;
   331  	static const size_t hSize_ = 8;
   332  	static const size_t msgLenByte_ = 16;
   333  	uint64_t totalSize_;
   334  	size_t roundBufSize_;
   335  	uint8_t roundBuf_[blockSize_];
   336  	uint64_t h_[hSize_];
   337  	static const size_t outByteSize_ = hSize_ * sizeof(uint64_t);
   338  	const uint64_t *k_;
   339  
   340  	template<size_t i0, size_t i1, size_t i2, size_t i3, size_t i4, size_t i5, size_t i6, size_t i7>
   341  	void round1(uint64_t *S, const uint64_t *w, size_t i)
   342  	{
   343  		using namespace sha2_local;
   344  		uint64_t& a = S[i0];
   345  		uint64_t& b = S[i1];
   346  		uint64_t& c = S[i2];
   347  		uint64_t& d = S[i3];
   348  		uint64_t& e = S[i4];
   349  		uint64_t& f = S[i5];
   350  		uint64_t& g = S[i6];
   351  		uint64_t& h = S[i7];
   352  
   353  		uint64_t s1 = rot64(e, 14) ^ rot64(e, 18) ^ rot64(e, 41);
   354  		uint64_t ch = g ^ (e & (f ^ g));
   355  		uint64_t t0 = h + s1 + ch + k_[i] + w[i];
   356  		uint64_t s0 = rot64(a, 28) ^ rot64(a, 34) ^ rot64(a, 39);
   357  		uint64_t maj = ((a | b) & c) | (a & b);
   358  		uint64_t t1 = s0 + maj;
   359  		d += t0;
   360  		h = t0 + t1;
   361  	}
   362  	/**
   363  		@param buf [in] buffer(64byte)
   364  	*/
   365  	void round(const uint8_t *buf)
   366  	{
   367  		using namespace sha2_local;
   368  		uint64_t w[80];
   369  		for (int i = 0; i < 16; i++) {
   370  			w[i] = cybozu::Get64bitAsBE(&buf[i * 8]);
   371  		}
   372  		for (int i = 16 ; i < 80; i++) {
   373  			uint64_t t = w[i - 15];
   374  			uint64_t s0 = rot64(t, 1) ^ rot64(t, 8) ^ (t >> 7);
   375  			t = w[i - 2];
   376  			uint64_t s1 = rot64(t, 19) ^ rot64(t, 61) ^ (t >> 6);
   377  			w[i] = w[i - 16] + s0 + w[i - 7] + s1;
   378  		}
   379  		uint64_t s[8];
   380  		for (int i = 0; i < 8; i++) {
   381  			s[i] = h_[i];
   382  		}
   383  		for (int i = 0; i < 80; i += 8) {
   384  			round1<0, 1, 2, 3, 4, 5, 6, 7>(s, w, i + 0);
   385  			round1<7, 0, 1, 2, 3, 4, 5, 6>(s, w, i + 1);
   386  			round1<6, 7, 0, 1, 2, 3, 4, 5>(s, w, i + 2);
   387  			round1<5, 6, 7, 0, 1, 2, 3, 4>(s, w, i + 3);
   388  			round1<4, 5, 6, 7, 0, 1, 2, 3>(s, w, i + 4);
   389  			round1<3, 4, 5, 6, 7, 0, 1, 2>(s, w, i + 5);
   390  			round1<2, 3, 4, 5, 6, 7, 0, 1>(s, w, i + 6);
   391  			round1<1, 2, 3, 4, 5, 6, 7, 0>(s, w, i + 7);
   392  		}
   393  		for (int i = 0; i < 8; i++) {
   394  			h_[i] += s[i];
   395  		}
   396  		totalSize_ += blockSize_;
   397  	}
   398  public:
   399  	Sha512()
   400  	{
   401  		clear();
   402  	}
   403  	void clear()
   404  	{
   405  		static const uint64_t kTbl[] = {
   406  		    0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL,
   407  		    0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
   408  		    0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
   409  		    0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
   410  		    0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL,
   411  		    0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
   412  		    0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL,
   413  		    0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
   414  		    0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
   415  		    0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
   416  		    0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL,
   417  		    0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
   418  		    0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL,
   419  		    0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
   420  		    0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
   421  		    0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
   422  		};
   423  		k_ = kTbl;
   424  		totalSize_ = 0;
   425  		roundBufSize_ = 0;
   426  		h_[0] = 0x6a09e667f3bcc908ull;
   427  		h_[1] = 0xbb67ae8584caa73bull;
   428  		h_[2] = 0x3c6ef372fe94f82bull;
   429  		h_[3] = 0xa54ff53a5f1d36f1ull;
   430  		h_[4] = 0x510e527fade682d1ull;
   431  		h_[5] = 0x9b05688c2b3e6c1full;
   432  		h_[6] = 0x1f83d9abfb41bd6bull;
   433  		h_[7] = 0x5be0cd19137e2179ull;
   434  	}
   435  	void update(const void *buf, size_t bufSize)
   436  	{
   437  		inner_update(reinterpret_cast<const uint8_t*>(buf), bufSize);
   438  	}
   439  	size_t digest(void *md, size_t mdSize, const void *buf, size_t bufSize)
   440  	{
   441  		if (mdSize < outByteSize_) return 0;
   442  		update(buf, bufSize);
   443  		term(roundBuf_, roundBufSize_);
   444  		char *p = reinterpret_cast<char*>(md);
   445  		for (size_t i = 0; i < hSize_; i++) {
   446  			cybozu::Set64bitAsBE(&p[i * sizeof(h_[0])], h_[i]);
   447  		}
   448  		return outByteSize_;
   449  	}
   450  #ifndef CYBOZU_DONT_USE_STRING
   451  	void update(const std::string& buf)
   452  	{
   453  		update(buf.c_str(), buf.size());
   454  	}
   455  	std::string digest(const std::string& buf)
   456  	{
   457  		return digest(buf.c_str(), buf.size());
   458  	}
   459  	std::string digest(const void *buf, size_t bufSize)
   460  	{
   461  		std::string md(outByteSize_, 0);
   462  		digest(&md[0], md.size(), buf, bufSize);
   463  		return md;
   464  	}
   465  #endif
   466  };
   467  
   468  } // cybozu
   469  
   470  #endif