123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698 |
-
- #include <stdint.h>
- #include <string>
-
- #define HASH_LEFT_ROTATE32(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
- #define HASH_RIGHT_ROTATE32(x, c) (((x) >> (c)) | ((x) << (32 - (c))))
-
- #define HASH_LEFT_ROTATE64(x, c) (((x) << (c)) | ((x) >> (64 - (c))))
- #define HASH_RIGHT_ROTATE64(x, c) (((x) >> (c)) | ((x) << (64 - (c))))
-
- namespace
- {
-
- #define FORCEINLINE __forceinline
- #define __LITTLE_ENDIAN__ 1
-
- template <int i> struct DKNumber { enum { Value = i }; };
-
- /// byteorder swap template functions.
- FORCEINLINE uint32_t SwitchIntegralByteOrder(uint32_t n)
- {
- static_assert(sizeof(uint32_t) == 4, "Invalid type size");
- return
- ((n & 0xff000000) >> 24) |
- ((n & 0x00ff0000) >> 8) |
- ((n & 0x0000ff00) << 8) |
- ((n & 0x000000ff) << 24);
- }
- FORCEINLINE uint64_t SwitchIntegralByteOrder(uint64_t n)
- {
- static_assert(sizeof(uint64_t) == 8, "Invalid type size");
- return
- ((n & 0xff00000000000000ULL) >> 56) |
- ((n & 0x00ff000000000000ULL) >> 40) |
- ((n & 0x0000ff0000000000ULL) >> 24) |
- ((n & 0x000000ff00000000ULL) >> 8) |
- ((n & 0x00000000ff000000ULL) << 8) |
- ((n & 0x0000000000ff0000ULL) << 24) |
- ((n & 0x000000000000ff00ULL) << 40) |
- ((n & 0x00000000000000ffULL) << 56);
- }
- /// swap byte order for 4 bytes
- template <typename T> FORCEINLINE T SwitchIntegralByteOrder(T n, DKNumber<4>)
- {
- static_assert(sizeof(T) == 4, "Invalid type size");
- auto r = SwitchIntegralByteOrder(reinterpret_cast<uint32_t&>(n));
- return reinterpret_cast<T&>(r);
- }
- template <typename T> FORCEINLINE T SwitchIntegralByteOrder(T n, DKNumber<8>)
- {
- static_assert(sizeof(T) == 8, "Invalid type size");
- auto r = SwitchIntegralByteOrder(reinterpret_cast<uint64_t&>(n));
- return reinterpret_cast<T&>(r);
- }
- template <typename T> FORCEINLINE T SystemToBigEndian(T n)
- {
- static_assert(std::is_integral<T>::value, "Argument must be integer.");
- #ifdef __LITTLE_ENDIAN__
- return SwitchIntegralByteOrder(n, DKNumber<sizeof(T)>());
- #endif
- return n;
- }
- /// change byte order: System -> Little-Endian
- template <typename T> FORCEINLINE T SystemToLittleEndian(T n)
- {
- static_assert(std::is_integral<T>::value, "Argument must be integer.");
- #ifdef __BIG_ENDIAN__
- return DKSwitchIntegralByteOrder(n, DKNumber<sizeof(T)>());
- #endif
- return n;
- }
-
- template <typename BASE, int BIT> struct HashResult
- {
- enum {
- UnitSize = sizeof(BASE),
- Length = BIT / (sizeof(BASE) * 8),
- };
- BASE digest[Length]; ///< hash digest in unit size (usually uint32_t)
- int Compare(const HashResult& r) const
- {
- int d = 0;
- for (int i = 0; d == 0 && i < Length; ++i)
- {
- d = static_cast<int>(this->digest[i] - r.digest[i]);
- }
- return d;
- }
-
- bool operator == (const HashResult& r) const { return Compare(r) == 0; }
- bool operator != (const HashResult& r) const { return Compare(r) != 0; }
- bool operator > (const HashResult& r) const { return Compare(r) > 0; }
- bool operator < (const HashResult& r) const { return Compare(r) < 0; }
- bool operator >= (const HashResult& r) const { return Compare(r) >= 0; }
- bool operator <= (const HashResult& r) const { return Compare(r) <= 0; }
-
- std::string String(void) const ///< represent hash digest as a string
- {
- char buff[Length * 8];
- char* tmp = buff;
- for (size_t i = 0; i < Length; ++i)
- {
- BASE val = SystemToBigEndian(digest[i]);
- for (size_t k = 0; k < sizeof(BASE); ++k)
- {
- unsigned char v = reinterpret_cast<unsigned char*>(&val)[k];
- unsigned char v1 = (v >> 4) & 0x0f;
- unsigned char v2 = v & 0x0f;
-
- *(tmp++) = v1 <= 9 ? v1 + '0' : 'a' + (v1 - 10);
- *(tmp++) = v2 <= 9 ? v2 + '0' : 'a' + (v2 - 10);
- }
- }
- return std::string(buff, Length * 8);
- }
- };
-
- typedef HashResult<uint32_t, 160> HashResultSHA1;
-
- ////////////////////////////////////////////////////////////////////////////////
- // Context
- // store hash result, varies size by hash algorithm.
- // hash32 (CRC32) uses hash[0] only.
- // hash128 (MD5) uses hash[0]~[3].
- // hash160 (SHA-1) uses hash[0]~[4].
- // hash224,256 (SHA-224, SHA-256) uses hash[0]~[7].
- // hash384,512 (SHA-384, SHA-512) uses hash[0]~[15].
- struct Context
- {
- union {
- uint64_t hash64[8];
- uint32_t hash32[16];
- };
- // saves message length (length x 8)
- uint64_t low; // md5, sha1, sha224/256 could save 64bits.(56bits actually)
- uint64_t high; // sha384/512 could save 128bits.(120bits actually)
-
- union {
- uint64_t data64[16]; // use 16 for sha384/512, otherwise 8.
- uint32_t data32[32];
- uint8_t data8[128];
- };
- uint32_t num; // remains length (not processed)
- uint32_t len; // message hash length (bytes)
- };
-
- using HashContext = Context;
- ////////////////////////////////////////////////////////////////////////////////
- // init context
- static inline void HashInit32(HashContext* ctx)
- {
- memset(ctx, 0, sizeof(HashContext));
- ctx->len = 4;
- }
-
- static inline void HashInit128(HashContext* ctx)
- {
- memset(ctx, 0, sizeof(HashContext));
- ctx->hash32[0] = (unsigned long)0x67452301;
- ctx->hash32[1] = (unsigned long)0xEFCDAB89;
- ctx->hash32[2] = (unsigned long)0x98BADCFE;
- ctx->hash32[3] = (unsigned long)0x10325476;
- ctx->len = 16;
- }
-
- static inline void HashInit160(HashContext* ctx)
- {
- memset(ctx, 0, sizeof(HashContext));
- ctx->hash32[0] = (unsigned long)0x67452301;
- ctx->hash32[1] = (unsigned long)0xefcdab89;
- ctx->hash32[2] = (unsigned long)0x98badcfe;
- ctx->hash32[3] = (unsigned long)0x10325476;
- ctx->hash32[4] = (unsigned long)0xc3d2e1f0;
- ctx->len = 20;
- }
-
- static inline void HashInit224(HashContext* ctx)
- {
- memset(ctx, 0, sizeof(HashContext));
- ctx->hash32[0] = (unsigned long)0xc1059ed8;
- ctx->hash32[1] = (unsigned long)0x367cd507;
- ctx->hash32[2] = (unsigned long)0x3070dd17;
- ctx->hash32[3] = (unsigned long)0xf70e5939;
- ctx->hash32[4] = (unsigned long)0xffc00b31;
- ctx->hash32[5] = (unsigned long)0x68581511;
- ctx->hash32[6] = (unsigned long)0x64f98fa7;
- ctx->hash32[7] = (unsigned long)0xbefa4fa4;
- ctx->len = 28;
- }
-
- static inline void HashInit256(HashContext* ctx)
- {
- memset(ctx, 0, sizeof(HashContext));
- ctx->hash32[0] = (unsigned long)0x6a09e667;
- ctx->hash32[1] = (unsigned long)0xbb67ae85;
- ctx->hash32[2] = (unsigned long)0x3c6ef372;
- ctx->hash32[3] = (unsigned long)0xa54ff53a;
- ctx->hash32[4] = (unsigned long)0x510e527f;
- ctx->hash32[5] = (unsigned long)0x9b05688c;
- ctx->hash32[6] = (unsigned long)0x1f83d9ab;
- ctx->hash32[7] = (unsigned long)0x5be0cd19;
- ctx->len = 32;
- }
-
- static inline void HashInit384(HashContext* ctx)
- {
- memset(ctx, 0, sizeof(HashContext));
- ctx->hash64[0] = 0xcbbb9d5dc1059ed8ULL;
- ctx->hash64[1] = 0x629a292a367cd507ULL;
- ctx->hash64[2] = 0x9159015a3070dd17ULL;
- ctx->hash64[3] = 0x152fecd8f70e5939ULL;
- ctx->hash64[4] = 0x67332667ffc00b31ULL;
- ctx->hash64[5] = 0x8eb44a8768581511ULL;
- ctx->hash64[6] = 0xdb0c2e0d64f98fa7ULL;
- ctx->hash64[7] = 0x47b5481dbefa4fa4ULL;
- ctx->len = 48;
- }
-
- static inline void HashInit512(HashContext* ctx)
- {
- memset(ctx, 0, sizeof(HashContext));
- ctx->hash64[0] = 0x6a09e667f3bcc908ULL;
- ctx->hash64[1] = 0xbb67ae8584caa73bULL;
- ctx->hash64[2] = 0x3c6ef372fe94f82bULL;
- ctx->hash64[3] = 0xa54ff53a5f1d36f1ULL;
- ctx->hash64[4] = 0x510e527fade682d1ULL;
- ctx->hash64[5] = 0x9b05688c2b3e6c1fULL;
- ctx->hash64[6] = 0x1f83d9abfb41bd6bULL;
- ctx->hash64[7] = 0x5be0cd19137e2179ULL;
- ctx->len = 64;
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // update context digest
- static void HashUpdate32(HashContext* ctx, const void* p, size_t len)
- {
- static const uint32_t K[] =
- {
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
- 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
- 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
- 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
- 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
- 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
- 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
- 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
- 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
- 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
- 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
- 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
- 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
- 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
- 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
- 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
- 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
- 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
- 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
- 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
- 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
- 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
- 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
- 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
- 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
- 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
- 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
- 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
- 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
- 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
- };
-
- uint32_t crc = ~(ctx->hash32[0]);
-
- for (size_t i = 0; i < len; i++)
- crc = K[(crc ^ ((const uint8_t*)p)[i]) & 0xff] ^ (crc >> 8);
-
- ctx->hash32[0] = ~crc;
- }
-
- static void HashDigest128(HashContext* ctx, const void* p, size_t count)
- {
- uint32_t A, B, C, D, F;
- uint32_t W[16];
-
- static const uint32_t R[] = {
- 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, // round 0
- 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, // round 1
- 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, // round 2
- 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 // round 3
- };
- static const uint32_t K[] = {
- 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
- 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
- 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
- 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
- 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
- 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
- 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
- 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
- };
-
- for (size_t i = 0; i < count; i++)
- {
- A = ctx->hash32[0];
- B = ctx->hash32[1];
- C = ctx->hash32[2];
- D = ctx->hash32[3];
-
- for (int x = 0; x < 16; x++)
- {
- W[x] = SystemToLittleEndian(reinterpret_cast<const uint32_t*>(p)[i * 16 + x]);
- }
-
- int n = 0;
- unsigned int tmp;
- for (; n < 16; n++)
- {
- F = ((B & C) | ((~B) & D));
- tmp = D; D = C; C = B;
- B += HASH_LEFT_ROTATE32(A + F + K[n] + W[n], R[n]);
- A = tmp;
- }
- for (; n < 32; n++)
- {
- F = ((B & D) | ((~D) & C));
- tmp = D; D = C; C = B;
- B += HASH_LEFT_ROTATE32(A + F + K[n] + W[(5 * n + 1) % 16], R[n]);
- A = tmp;
- }
- for (; n < 48; n++)
- {
- F = (B ^ C ^ D);
- tmp = D; D = C; C = B;
- B += HASH_LEFT_ROTATE32(A + F + K[n] + W[(3 * n + 5) % 16], R[n]);
- A = tmp;
- }
- for (; n < 64; n++)
- {
- F = (C ^ (B | (~D)));
- tmp = D; D = C; C = B;
- B += HASH_LEFT_ROTATE32(A + F + K[n] + W[(7 * n) % 16], R[n]);
- A = tmp;
- }
-
- ctx->hash32[0] += A;
- ctx->hash32[1] += B;
- ctx->hash32[2] += C;
- ctx->hash32[3] += D;
- }
- }
-
- static void HashDigest160(HashContext* ctx, const void* p, size_t count)
- {
- uint32_t A, B, C, D, E, T;
- uint32_t W[80];
-
- for (size_t i = 0; i < count; i++)
- {
- A = ctx->hash32[0];
- B = ctx->hash32[1];
- C = ctx->hash32[2];
- D = ctx->hash32[3];
- E = ctx->hash32[4];
-
- for (int x = 0; x < 16; x++)
- {
- W[x] = SystemToBigEndian(reinterpret_cast<const uint32_t*>(p)[i * 16 + x]);
- }
- for (int x = 16; x < 80; x++)
- {
- W[x] = HASH_LEFT_ROTATE32(W[x - 3] ^ W[x - 8] ^ W[x - 14] ^ W[x - 16], 1);
- }
-
- int n = 0;
- for (; n < 20; n++)
- {
- T = HASH_LEFT_ROTATE32(A, 5) + ((B & C) | ((~B) & D)) + E + W[n] + 0x5A827999;
- E = D; D = C; C = HASH_LEFT_ROTATE32(B, 30); B = A; A = T;
- }
- for (; n < 40; n++)
- {
- T = HASH_LEFT_ROTATE32(A, 5) + (B ^ C ^ D) + E + W[n] + 0x6ED9EBA1;
- E = D; D = C; C = HASH_LEFT_ROTATE32(B, 30); B = A; A = T;
- }
- for (; n < 60; n++)
- {
- T = HASH_LEFT_ROTATE32(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[n] + 0x8F1BBCDC;
- E = D; D = C; C = HASH_LEFT_ROTATE32(B, 30); B = A; A = T;
- }
- for (; n < 80; n++)
- {
- T = HASH_LEFT_ROTATE32(A, 5) + (B ^ C ^ D) + E + W[n] + 0xCA62C1D6;
- E = D; D = C; C = HASH_LEFT_ROTATE32(B, 30); B = A; A = T;
- }
- ctx->hash32[0] += A;
- ctx->hash32[1] += B;
- ctx->hash32[2] += C;
- ctx->hash32[3] += D;
- ctx->hash32[4] += E;
- }
- }
-
- static void HashDigest256(HashContext* ctx, const void* p, size_t count)
- {
- uint32_t A, B, C, D, E, F, G, H;
- static const uint32_t K[] = {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
- };
- uint32_t W[64];
- for (size_t i = 0; i < count; i++)
- {
- A = ctx->hash32[0];
- B = ctx->hash32[1];
- C = ctx->hash32[2];
- D = ctx->hash32[3];
- E = ctx->hash32[4];
- F = ctx->hash32[5];
- G = ctx->hash32[6];
- H = ctx->hash32[7];
-
- for (int x = 0; x < 16; x++)
- {
- W[x] = SystemToBigEndian(reinterpret_cast<const uint32_t*>(p)[i * 16 + x]);
- }
- for (int x = 16; x < 64; x++)
- {
- unsigned int s0 = HASH_RIGHT_ROTATE32(W[x - 15], 7) ^ HASH_RIGHT_ROTATE32(W[x - 15], 18) ^ (W[x - 15] >> 3);
- unsigned int s1 = HASH_RIGHT_ROTATE32(W[x - 2], 17) ^ HASH_RIGHT_ROTATE32(W[x - 2], 19) ^ (W[x - 2] >> 10);
- W[x] = W[x - 16] + s0 + W[x - 7] + s1;
- }
-
- uint32_t s0, s1;
- uint32_t maj;
- uint32_t t1, t2;
- uint32_t ch;
- for (int n = 0; n < 64; n++)
- {
- s0 = HASH_RIGHT_ROTATE32(A, 2) ^ HASH_RIGHT_ROTATE32(A, 13) ^ HASH_RIGHT_ROTATE32(A, 22);
- maj = (A & B) ^ (A & C) ^ (B & C);
- t2 = s0 + maj;
- s1 = HASH_RIGHT_ROTATE32(E, 6) ^ HASH_RIGHT_ROTATE32(E, 11) ^ HASH_RIGHT_ROTATE32(E, 25);
- ch = (E & F) ^ ((~E) & G);
- t1 = H + s1 + ch + K[n] + W[n];
-
- H = G;
- G = F;
- F = E;
- E = D + t1;
- D = C;
- C = B;
- B = A;
- A = t1 + t2;
- }
-
- ctx->hash32[0] += A;
- ctx->hash32[1] += B;
- ctx->hash32[2] += C;
- ctx->hash32[3] += D;
- ctx->hash32[4] += E;
- ctx->hash32[5] += F;
- ctx->hash32[6] += G;
- ctx->hash32[7] += H;
- }
- }
-
- static void HashDigest512(HashContext* ctx, const void* p, size_t count)
- {
- uint64_t A, B, C, D, E, F, G, H;
- static const uint64_t K[] = {
- 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
- 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
- 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
- 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
- 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
- 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
- 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
- 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
- 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
- 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
- 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
- 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
- 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
- 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
- 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
- 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
- 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
- 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
- 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
- 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
- };
- uint64_t W[80];
- for (size_t i = 0; i < count; i++)
- {
- A = ctx->hash64[0];
- B = ctx->hash64[1];
- C = ctx->hash64[2];
- D = ctx->hash64[3];
- E = ctx->hash64[4];
- F = ctx->hash64[5];
- G = ctx->hash64[6];
- H = ctx->hash64[7];
-
- for (int x = 0; x < 16; x++)
- {
- W[x] = SystemToBigEndian(reinterpret_cast<const uint64_t*>(p)[i * 16 + x]);
- }
- for (int x = 16; x < 80; x++)
- {
- uint64_t s0 = HASH_RIGHT_ROTATE64(W[x - 15], 1) ^ HASH_RIGHT_ROTATE64(W[x - 15], 8) ^ (W[x - 15] >> 7);
- uint64_t s1 = HASH_RIGHT_ROTATE64(W[x - 2], 19) ^ HASH_RIGHT_ROTATE64(W[x - 2], 61) ^ (W[x - 2] >> 6);
- W[x] = W[x - 16] + s0 + W[x - 7] + s1;
- }
-
- uint64_t s0, s1;
- uint64_t maj;
- uint64_t t1, t2;
- uint64_t ch;
- for (int n = 0; n < 80; n++)
- {
- s0 = HASH_RIGHT_ROTATE64(A, 28) ^ HASH_RIGHT_ROTATE64(A, 34) ^ HASH_RIGHT_ROTATE64(A, 39);
- maj = (A & B) ^ (A & C) ^ (B & C);
- t2 = s0 + maj;
- s1 = HASH_RIGHT_ROTATE64(E, 14) ^ HASH_RIGHT_ROTATE64(E, 18) ^ HASH_RIGHT_ROTATE64(E, 41);
- ch = (E & F) ^ ((~E) & G);
- t1 = H + s1 + ch + K[n] + W[n];
-
- H = G;
- G = F;
- F = E;
- E = D + t1;
- D = C;
- C = B;
- B = A;
- A = t1 + t2;
- }
-
- ctx->hash64[0] += A;
- ctx->hash64[1] += B;
- ctx->hash64[2] += C;
- ctx->hash64[3] += D;
- ctx->hash64[4] += E;
- ctx->hash64[5] += F;
- ctx->hash64[6] += G;
- ctx->hash64[7] += H;
- }
- }
-
- // HashUpdate : updates hash digest, using all algorithms except for CRC32
- template <typename HashDigest> static void HashUpdate(HashContext* ctx, size_t block_size, const void* p, size_t len, HashDigest hash_func)
- {
- const uint8_t *data = (const uint8_t*)p;
-
- if (len == 0)
- return;
-
- // 4 bytes integer type if cBlock is 64
- // 8 bytes integer type if cBlock is 128
- size_t baseTypeSize = block_size / 16;
-
- if (baseTypeSize > 4)
- {
- uint64_t len2 = ctx->low + (((uint64_t)len) << 3);
- if (len2 < ctx->low) // overflow!
- ctx->high++;
- ctx->high += ((uint64_t)len) >> 61;
- ctx->low = len2;
- }
- else
- {
- ctx->low += ((uint64_t)len) << 3;
- }
-
- size_t n = ctx->num;
- if (n != 0)
- {
- if (len >= block_size || len + n >= block_size)
- {
- memcpy(ctx->data8 + n, data, block_size - n);
- hash_func(ctx, ctx->data8, 1);
- n = (size_t)(block_size - n);
- data += n;
- len -= n;
- ctx->num = 0;
- memset(ctx->data8, 0, (size_t)block_size);
- }
- else
- {
- memcpy(ctx->data8 + n, data, len);
- ctx->num += (uint32_t)len;
- return;
- }
- }
- n = len / block_size;
- if (n > 0)
- {
- hash_func(ctx, data, n);
- n *= block_size;
- data += n;
- len -= n;
- }
- if (len != 0)
- {
- ctx->num = (uint32_t)len;
- memcpy(ctx->data8, data, len);
- }
- }
-
- template <typename HashDigest> static void HashFinal(HashContext* ctx, size_t block_size, HashDigest hash_func, bool bLittleEndian)
- {
- size_t n = ctx->num;
-
- // 1. add one bit to end of messages. (MD5, SHA1)
- // 2. fill message's 512bits with 0. (64bytes, required length for one hash)
- // 3. add total message length as big-endian integer.
- ctx->data8[n++] = 0x80;
-
- // 4 bytes integer type if cBlock is 64.
- // 8 bytes integer type if cBlock is 128.
- size_t baseTypeSize = block_size / 16;
-
- if (n > block_size - baseTypeSize * 2)
- {
- memset(ctx->data8 + n, 0, (size_t)(block_size - n));
- n = 0;
- hash_func(ctx, ctx->data8, 1);
- }
- // fill with 0, except for last 2 blocks
- memset(ctx->data8 + n, 0, (size_t)(block_size - n - (baseTypeSize * 2)));
-
- // set last 2 blocks with low, high values.
- if (baseTypeSize > 4)
- {
- if (bLittleEndian)
- {
- ctx->data64[14] = SystemToLittleEndian(ctx->low);
- ctx->data64[15] = SystemToLittleEndian(ctx->high);
- }
- else
- {
- ctx->data64[14] = SystemToBigEndian(ctx->high);
- ctx->data64[15] = SystemToBigEndian(ctx->low);
- }
- }
- else
- {
- if (bLittleEndian)
- {
- ctx->data64[7] = SystemToLittleEndian(ctx->low);
- }
- else
- {
- ctx->data64[7] = SystemToBigEndian(ctx->low);
- }
- }
-
- hash_func(ctx, ctx->data8, 1);
- ctx->num = 0;
-
- #ifdef __LITTLE_ENDIAN__
- // SHA Family calculated as Big-Endian, swapping bytes-order.
- if (baseTypeSize > 4 && !bLittleEndian)
- {
- for (int i = 0; i < 8; i++)
- {
- uint32_t tmp = ctx->hash32[i * 2];
- ctx->hash32[i * 2] = ctx->hash32[i * 2 + 1];
- ctx->hash32[i * 2 + 1] = tmp;
- }
- }
- #endif
- }
-
- HashResultSHA1 HashSHA1(const void* p, size_t len)
- {
- HashContext ctx;
- HashInit160(&ctx);
- HashUpdate(&ctx, 64, p, len, HashDigest160);
- HashFinal(&ctx, 64, HashDigest160, false);
-
- HashResultSHA1 res;
- for (int i = 0; i < 5; i++)
- res.digest[i] = ctx.hash32[i];
- return res;
- }
- }
-
- std::string sha1(const void* p, size_t s)
- {
- return HashSHA1(p, s).String();
- }
|