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