W_Engine_Team_Study

hash.cpp 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. #include <stdint.h>
  2. #include <string>
  3. #define HASH_LEFT_ROTATE32(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
  4. #define HASH_RIGHT_ROTATE32(x, c) (((x) >> (c)) | ((x) << (32 - (c))))
  5. #define HASH_LEFT_ROTATE64(x, c) (((x) << (c)) | ((x) >> (64 - (c))))
  6. #define HASH_RIGHT_ROTATE64(x, c) (((x) >> (c)) | ((x) << (64 - (c))))
  7. namespace
  8. {
  9. #define FORCEINLINE __forceinline
  10. #define __LITTLE_ENDIAN__ 1
  11. template <int i> struct DKNumber { enum { Value = i }; };
  12. /// byteorder swap template functions.
  13. FORCEINLINE uint32_t SwitchIntegralByteOrder(uint32_t n)
  14. {
  15. static_assert(sizeof(uint32_t) == 4, "Invalid type size");
  16. return
  17. ((n & 0xff000000) >> 24) |
  18. ((n & 0x00ff0000) >> 8) |
  19. ((n & 0x0000ff00) << 8) |
  20. ((n & 0x000000ff) << 24);
  21. }
  22. FORCEINLINE uint64_t SwitchIntegralByteOrder(uint64_t n)
  23. {
  24. static_assert(sizeof(uint64_t) == 8, "Invalid type size");
  25. return
  26. ((n & 0xff00000000000000ULL) >> 56) |
  27. ((n & 0x00ff000000000000ULL) >> 40) |
  28. ((n & 0x0000ff0000000000ULL) >> 24) |
  29. ((n & 0x000000ff00000000ULL) >> 8) |
  30. ((n & 0x00000000ff000000ULL) << 8) |
  31. ((n & 0x0000000000ff0000ULL) << 24) |
  32. ((n & 0x000000000000ff00ULL) << 40) |
  33. ((n & 0x00000000000000ffULL) << 56);
  34. }
  35. /// swap byte order for 4 bytes
  36. template <typename T> FORCEINLINE T SwitchIntegralByteOrder(T n, DKNumber<4>)
  37. {
  38. static_assert(sizeof(T) == 4, "Invalid type size");
  39. auto r = SwitchIntegralByteOrder(reinterpret_cast<uint32_t&>(n));
  40. return reinterpret_cast<T&>(r);
  41. }
  42. template <typename T> FORCEINLINE T SwitchIntegralByteOrder(T n, DKNumber<8>)
  43. {
  44. static_assert(sizeof(T) == 8, "Invalid type size");
  45. auto r = SwitchIntegralByteOrder(reinterpret_cast<uint64_t&>(n));
  46. return reinterpret_cast<T&>(r);
  47. }
  48. template <typename T> FORCEINLINE T SystemToBigEndian(T n)
  49. {
  50. static_assert(std::is_integral<T>::value, "Argument must be integer.");
  51. #ifdef __LITTLE_ENDIAN__
  52. return SwitchIntegralByteOrder(n, DKNumber<sizeof(T)>());
  53. #endif
  54. return n;
  55. }
  56. /// change byte order: System -> Little-Endian
  57. template <typename T> FORCEINLINE T SystemToLittleEndian(T n)
  58. {
  59. static_assert(std::is_integral<T>::value, "Argument must be integer.");
  60. #ifdef __BIG_ENDIAN__
  61. return DKSwitchIntegralByteOrder(n, DKNumber<sizeof(T)>());
  62. #endif
  63. return n;
  64. }
  65. template <typename BASE, int BIT> struct HashResult
  66. {
  67. enum {
  68. UnitSize = sizeof(BASE),
  69. Length = BIT / (sizeof(BASE) * 8),
  70. };
  71. BASE digest[Length]; ///< hash digest in unit size (usually uint32_t)
  72. int Compare(const HashResult& r) const
  73. {
  74. int d = 0;
  75. for (int i = 0; d == 0 && i < Length; ++i)
  76. {
  77. d = static_cast<int>(this->digest[i] - r.digest[i]);
  78. }
  79. return d;
  80. }
  81. bool operator == (const HashResult& r) const { return Compare(r) == 0; }
  82. bool operator != (const HashResult& r) const { return Compare(r) != 0; }
  83. bool operator > (const HashResult& r) const { return Compare(r) > 0; }
  84. bool operator < (const HashResult& r) const { return Compare(r) < 0; }
  85. bool operator >= (const HashResult& r) const { return Compare(r) >= 0; }
  86. bool operator <= (const HashResult& r) const { return Compare(r) <= 0; }
  87. std::string String(void) const ///< represent hash digest as a string
  88. {
  89. char buff[Length * 8];
  90. char* tmp = buff;
  91. for (size_t i = 0; i < Length; ++i)
  92. {
  93. BASE val = SystemToBigEndian(digest[i]);
  94. for (size_t k = 0; k < sizeof(BASE); ++k)
  95. {
  96. unsigned char v = reinterpret_cast<unsigned char*>(&val)[k];
  97. unsigned char v1 = (v >> 4) & 0x0f;
  98. unsigned char v2 = v & 0x0f;
  99. *(tmp++) = v1 <= 9 ? v1 + '0' : 'a' + (v1 - 10);
  100. *(tmp++) = v2 <= 9 ? v2 + '0' : 'a' + (v2 - 10);
  101. }
  102. }
  103. return std::string(buff, Length * 8);
  104. }
  105. };
  106. typedef HashResult<uint32_t, 160> HashResultSHA1;
  107. ////////////////////////////////////////////////////////////////////////////////
  108. // Context
  109. // store hash result, varies size by hash algorithm.
  110. // hash32 (CRC32) uses hash[0] only.
  111. // hash128 (MD5) uses hash[0]~[3].
  112. // hash160 (SHA-1) uses hash[0]~[4].
  113. // hash224,256 (SHA-224, SHA-256) uses hash[0]~[7].
  114. // hash384,512 (SHA-384, SHA-512) uses hash[0]~[15].
  115. struct Context
  116. {
  117. union {
  118. uint64_t hash64[8];
  119. uint32_t hash32[16];
  120. };
  121. // saves message length (length x 8)
  122. uint64_t low; // md5, sha1, sha224/256 could save 64bits.(56bits actually)
  123. uint64_t high; // sha384/512 could save 128bits.(120bits actually)
  124. union {
  125. uint64_t data64[16]; // use 16 for sha384/512, otherwise 8.
  126. uint32_t data32[32];
  127. uint8_t data8[128];
  128. };
  129. uint32_t num; // remains length (not processed)
  130. uint32_t len; // message hash length (bytes)
  131. };
  132. using HashContext = Context;
  133. ////////////////////////////////////////////////////////////////////////////////
  134. // init context
  135. static inline void HashInit32(HashContext* ctx)
  136. {
  137. memset(ctx, 0, sizeof(HashContext));
  138. ctx->len = 4;
  139. }
  140. static inline void HashInit128(HashContext* ctx)
  141. {
  142. memset(ctx, 0, sizeof(HashContext));
  143. ctx->hash32[0] = (unsigned long)0x67452301;
  144. ctx->hash32[1] = (unsigned long)0xEFCDAB89;
  145. ctx->hash32[2] = (unsigned long)0x98BADCFE;
  146. ctx->hash32[3] = (unsigned long)0x10325476;
  147. ctx->len = 16;
  148. }
  149. static inline void HashInit160(HashContext* ctx)
  150. {
  151. memset(ctx, 0, sizeof(HashContext));
  152. ctx->hash32[0] = (unsigned long)0x67452301;
  153. ctx->hash32[1] = (unsigned long)0xefcdab89;
  154. ctx->hash32[2] = (unsigned long)0x98badcfe;
  155. ctx->hash32[3] = (unsigned long)0x10325476;
  156. ctx->hash32[4] = (unsigned long)0xc3d2e1f0;
  157. ctx->len = 20;
  158. }
  159. static inline void HashInit224(HashContext* ctx)
  160. {
  161. memset(ctx, 0, sizeof(HashContext));
  162. ctx->hash32[0] = (unsigned long)0xc1059ed8;
  163. ctx->hash32[1] = (unsigned long)0x367cd507;
  164. ctx->hash32[2] = (unsigned long)0x3070dd17;
  165. ctx->hash32[3] = (unsigned long)0xf70e5939;
  166. ctx->hash32[4] = (unsigned long)0xffc00b31;
  167. ctx->hash32[5] = (unsigned long)0x68581511;
  168. ctx->hash32[6] = (unsigned long)0x64f98fa7;
  169. ctx->hash32[7] = (unsigned long)0xbefa4fa4;
  170. ctx->len = 28;
  171. }
  172. static inline void HashInit256(HashContext* ctx)
  173. {
  174. memset(ctx, 0, sizeof(HashContext));
  175. ctx->hash32[0] = (unsigned long)0x6a09e667;
  176. ctx->hash32[1] = (unsigned long)0xbb67ae85;
  177. ctx->hash32[2] = (unsigned long)0x3c6ef372;
  178. ctx->hash32[3] = (unsigned long)0xa54ff53a;
  179. ctx->hash32[4] = (unsigned long)0x510e527f;
  180. ctx->hash32[5] = (unsigned long)0x9b05688c;
  181. ctx->hash32[6] = (unsigned long)0x1f83d9ab;
  182. ctx->hash32[7] = (unsigned long)0x5be0cd19;
  183. ctx->len = 32;
  184. }
  185. static inline void HashInit384(HashContext* ctx)
  186. {
  187. memset(ctx, 0, sizeof(HashContext));
  188. ctx->hash64[0] = 0xcbbb9d5dc1059ed8ULL;
  189. ctx->hash64[1] = 0x629a292a367cd507ULL;
  190. ctx->hash64[2] = 0x9159015a3070dd17ULL;
  191. ctx->hash64[3] = 0x152fecd8f70e5939ULL;
  192. ctx->hash64[4] = 0x67332667ffc00b31ULL;
  193. ctx->hash64[5] = 0x8eb44a8768581511ULL;
  194. ctx->hash64[6] = 0xdb0c2e0d64f98fa7ULL;
  195. ctx->hash64[7] = 0x47b5481dbefa4fa4ULL;
  196. ctx->len = 48;
  197. }
  198. static inline void HashInit512(HashContext* ctx)
  199. {
  200. memset(ctx, 0, sizeof(HashContext));
  201. ctx->hash64[0] = 0x6a09e667f3bcc908ULL;
  202. ctx->hash64[1] = 0xbb67ae8584caa73bULL;
  203. ctx->hash64[2] = 0x3c6ef372fe94f82bULL;
  204. ctx->hash64[3] = 0xa54ff53a5f1d36f1ULL;
  205. ctx->hash64[4] = 0x510e527fade682d1ULL;
  206. ctx->hash64[5] = 0x9b05688c2b3e6c1fULL;
  207. ctx->hash64[6] = 0x1f83d9abfb41bd6bULL;
  208. ctx->hash64[7] = 0x5be0cd19137e2179ULL;
  209. ctx->len = 64;
  210. }
  211. ////////////////////////////////////////////////////////////////////////////////
  212. // update context digest
  213. static void HashUpdate32(HashContext* ctx, const void* p, size_t len)
  214. {
  215. static const uint32_t K[] =
  216. {
  217. 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
  218. 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
  219. 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
  220. 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
  221. 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
  222. 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
  223. 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
  224. 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
  225. 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
  226. 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
  227. 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
  228. 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
  229. 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
  230. 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
  231. 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
  232. 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
  233. 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
  234. 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
  235. 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
  236. 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
  237. 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
  238. 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
  239. 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
  240. 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
  241. 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
  242. 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
  243. 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
  244. 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
  245. 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
  246. 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
  247. 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
  248. 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
  249. };
  250. uint32_t crc = ~(ctx->hash32[0]);
  251. for (size_t i = 0; i < len; i++)
  252. crc = K[(crc ^ ((const uint8_t*)p)[i]) & 0xff] ^ (crc >> 8);
  253. ctx->hash32[0] = ~crc;
  254. }
  255. static void HashDigest128(HashContext* ctx, const void* p, size_t count)
  256. {
  257. uint32_t A, B, C, D, F;
  258. uint32_t W[16];
  259. static const uint32_t R[] = {
  260. 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, // round 0
  261. 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, // round 1
  262. 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, // round 2
  263. 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 // round 3
  264. };
  265. static const uint32_t K[] = {
  266. 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  267. 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  268. 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
  269. 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  270. 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  271. 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  272. 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  273. 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
  274. };
  275. for (size_t i = 0; i < count; i++)
  276. {
  277. A = ctx->hash32[0];
  278. B = ctx->hash32[1];
  279. C = ctx->hash32[2];
  280. D = ctx->hash32[3];
  281. for (int x = 0; x < 16; x++)
  282. {
  283. W[x] = SystemToLittleEndian(reinterpret_cast<const uint32_t*>(p)[i * 16 + x]);
  284. }
  285. int n = 0;
  286. unsigned int tmp;
  287. for (; n < 16; n++)
  288. {
  289. F = ((B & C) | ((~B) & D));
  290. tmp = D; D = C; C = B;
  291. B += HASH_LEFT_ROTATE32(A + F + K[n] + W[n], R[n]);
  292. A = tmp;
  293. }
  294. for (; n < 32; n++)
  295. {
  296. F = ((B & D) | ((~D) & C));
  297. tmp = D; D = C; C = B;
  298. B += HASH_LEFT_ROTATE32(A + F + K[n] + W[(5 * n + 1) % 16], R[n]);
  299. A = tmp;
  300. }
  301. for (; n < 48; n++)
  302. {
  303. F = (B ^ C ^ D);
  304. tmp = D; D = C; C = B;
  305. B += HASH_LEFT_ROTATE32(A + F + K[n] + W[(3 * n + 5) % 16], R[n]);
  306. A = tmp;
  307. }
  308. for (; n < 64; n++)
  309. {
  310. F = (C ^ (B | (~D)));
  311. tmp = D; D = C; C = B;
  312. B += HASH_LEFT_ROTATE32(A + F + K[n] + W[(7 * n) % 16], R[n]);
  313. A = tmp;
  314. }
  315. ctx->hash32[0] += A;
  316. ctx->hash32[1] += B;
  317. ctx->hash32[2] += C;
  318. ctx->hash32[3] += D;
  319. }
  320. }
  321. static void HashDigest160(HashContext* ctx, const void* p, size_t count)
  322. {
  323. uint32_t A, B, C, D, E, T;
  324. uint32_t W[80];
  325. for (size_t i = 0; i < count; i++)
  326. {
  327. A = ctx->hash32[0];
  328. B = ctx->hash32[1];
  329. C = ctx->hash32[2];
  330. D = ctx->hash32[3];
  331. E = ctx->hash32[4];
  332. for (int x = 0; x < 16; x++)
  333. {
  334. W[x] = SystemToBigEndian(reinterpret_cast<const uint32_t*>(p)[i * 16 + x]);
  335. }
  336. for (int x = 16; x < 80; x++)
  337. {
  338. W[x] = HASH_LEFT_ROTATE32(W[x - 3] ^ W[x - 8] ^ W[x - 14] ^ W[x - 16], 1);
  339. }
  340. int n = 0;
  341. for (; n < 20; n++)
  342. {
  343. T = HASH_LEFT_ROTATE32(A, 5) + ((B & C) | ((~B) & D)) + E + W[n] + 0x5A827999;
  344. E = D; D = C; C = HASH_LEFT_ROTATE32(B, 30); B = A; A = T;
  345. }
  346. for (; n < 40; n++)
  347. {
  348. T = HASH_LEFT_ROTATE32(A, 5) + (B ^ C ^ D) + E + W[n] + 0x6ED9EBA1;
  349. E = D; D = C; C = HASH_LEFT_ROTATE32(B, 30); B = A; A = T;
  350. }
  351. for (; n < 60; n++)
  352. {
  353. T = HASH_LEFT_ROTATE32(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[n] + 0x8F1BBCDC;
  354. E = D; D = C; C = HASH_LEFT_ROTATE32(B, 30); B = A; A = T;
  355. }
  356. for (; n < 80; n++)
  357. {
  358. T = HASH_LEFT_ROTATE32(A, 5) + (B ^ C ^ D) + E + W[n] + 0xCA62C1D6;
  359. E = D; D = C; C = HASH_LEFT_ROTATE32(B, 30); B = A; A = T;
  360. }
  361. ctx->hash32[0] += A;
  362. ctx->hash32[1] += B;
  363. ctx->hash32[2] += C;
  364. ctx->hash32[3] += D;
  365. ctx->hash32[4] += E;
  366. }
  367. }
  368. static void HashDigest256(HashContext* ctx, const void* p, size_t count)
  369. {
  370. uint32_t A, B, C, D, E, F, G, H;
  371. static const uint32_t K[] = {
  372. 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  373. 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  374. 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  375. 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  376. 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  377. 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  378. 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  379. 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
  380. };
  381. uint32_t W[64];
  382. for (size_t i = 0; i < count; i++)
  383. {
  384. A = ctx->hash32[0];
  385. B = ctx->hash32[1];
  386. C = ctx->hash32[2];
  387. D = ctx->hash32[3];
  388. E = ctx->hash32[4];
  389. F = ctx->hash32[5];
  390. G = ctx->hash32[6];
  391. H = ctx->hash32[7];
  392. for (int x = 0; x < 16; x++)
  393. {
  394. W[x] = SystemToBigEndian(reinterpret_cast<const uint32_t*>(p)[i * 16 + x]);
  395. }
  396. for (int x = 16; x < 64; x++)
  397. {
  398. unsigned int s0 = HASH_RIGHT_ROTATE32(W[x - 15], 7) ^ HASH_RIGHT_ROTATE32(W[x - 15], 18) ^ (W[x - 15] >> 3);
  399. unsigned int s1 = HASH_RIGHT_ROTATE32(W[x - 2], 17) ^ HASH_RIGHT_ROTATE32(W[x - 2], 19) ^ (W[x - 2] >> 10);
  400. W[x] = W[x - 16] + s0 + W[x - 7] + s1;
  401. }
  402. uint32_t s0, s1;
  403. uint32_t maj;
  404. uint32_t t1, t2;
  405. uint32_t ch;
  406. for (int n = 0; n < 64; n++)
  407. {
  408. s0 = HASH_RIGHT_ROTATE32(A, 2) ^ HASH_RIGHT_ROTATE32(A, 13) ^ HASH_RIGHT_ROTATE32(A, 22);
  409. maj = (A & B) ^ (A & C) ^ (B & C);
  410. t2 = s0 + maj;
  411. s1 = HASH_RIGHT_ROTATE32(E, 6) ^ HASH_RIGHT_ROTATE32(E, 11) ^ HASH_RIGHT_ROTATE32(E, 25);
  412. ch = (E & F) ^ ((~E) & G);
  413. t1 = H + s1 + ch + K[n] + W[n];
  414. H = G;
  415. G = F;
  416. F = E;
  417. E = D + t1;
  418. D = C;
  419. C = B;
  420. B = A;
  421. A = t1 + t2;
  422. }
  423. ctx->hash32[0] += A;
  424. ctx->hash32[1] += B;
  425. ctx->hash32[2] += C;
  426. ctx->hash32[3] += D;
  427. ctx->hash32[4] += E;
  428. ctx->hash32[5] += F;
  429. ctx->hash32[6] += G;
  430. ctx->hash32[7] += H;
  431. }
  432. }
  433. static void HashDigest512(HashContext* ctx, const void* p, size_t count)
  434. {
  435. uint64_t A, B, C, D, E, F, G, H;
  436. static const uint64_t K[] = {
  437. 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
  438. 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
  439. 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
  440. 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
  441. 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
  442. 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
  443. 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
  444. 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
  445. 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
  446. 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
  447. 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
  448. 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
  449. 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
  450. 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
  451. 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
  452. 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
  453. 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
  454. 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
  455. 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
  456. 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
  457. };
  458. uint64_t W[80];
  459. for (size_t i = 0; i < count; i++)
  460. {
  461. A = ctx->hash64[0];
  462. B = ctx->hash64[1];
  463. C = ctx->hash64[2];
  464. D = ctx->hash64[3];
  465. E = ctx->hash64[4];
  466. F = ctx->hash64[5];
  467. G = ctx->hash64[6];
  468. H = ctx->hash64[7];
  469. for (int x = 0; x < 16; x++)
  470. {
  471. W[x] = SystemToBigEndian(reinterpret_cast<const uint64_t*>(p)[i * 16 + x]);
  472. }
  473. for (int x = 16; x < 80; x++)
  474. {
  475. uint64_t s0 = HASH_RIGHT_ROTATE64(W[x - 15], 1) ^ HASH_RIGHT_ROTATE64(W[x - 15], 8) ^ (W[x - 15] >> 7);
  476. uint64_t s1 = HASH_RIGHT_ROTATE64(W[x - 2], 19) ^ HASH_RIGHT_ROTATE64(W[x - 2], 61) ^ (W[x - 2] >> 6);
  477. W[x] = W[x - 16] + s0 + W[x - 7] + s1;
  478. }
  479. uint64_t s0, s1;
  480. uint64_t maj;
  481. uint64_t t1, t2;
  482. uint64_t ch;
  483. for (int n = 0; n < 80; n++)
  484. {
  485. s0 = HASH_RIGHT_ROTATE64(A, 28) ^ HASH_RIGHT_ROTATE64(A, 34) ^ HASH_RIGHT_ROTATE64(A, 39);
  486. maj = (A & B) ^ (A & C) ^ (B & C);
  487. t2 = s0 + maj;
  488. s1 = HASH_RIGHT_ROTATE64(E, 14) ^ HASH_RIGHT_ROTATE64(E, 18) ^ HASH_RIGHT_ROTATE64(E, 41);
  489. ch = (E & F) ^ ((~E) & G);
  490. t1 = H + s1 + ch + K[n] + W[n];
  491. H = G;
  492. G = F;
  493. F = E;
  494. E = D + t1;
  495. D = C;
  496. C = B;
  497. B = A;
  498. A = t1 + t2;
  499. }
  500. ctx->hash64[0] += A;
  501. ctx->hash64[1] += B;
  502. ctx->hash64[2] += C;
  503. ctx->hash64[3] += D;
  504. ctx->hash64[4] += E;
  505. ctx->hash64[5] += F;
  506. ctx->hash64[6] += G;
  507. ctx->hash64[7] += H;
  508. }
  509. }
  510. // HashUpdate : updates hash digest, using all algorithms except for CRC32
  511. template <typename HashDigest> static void HashUpdate(HashContext* ctx, size_t block_size, const void* p, size_t len, HashDigest hash_func)
  512. {
  513. const uint8_t *data = (const uint8_t*)p;
  514. if (len == 0)
  515. return;
  516. // 4 bytes integer type if cBlock is 64
  517. // 8 bytes integer type if cBlock is 128
  518. size_t baseTypeSize = block_size / 16;
  519. if (baseTypeSize > 4)
  520. {
  521. uint64_t len2 = ctx->low + (((uint64_t)len) << 3);
  522. if (len2 < ctx->low) // overflow!
  523. ctx->high++;
  524. ctx->high += ((uint64_t)len) >> 61;
  525. ctx->low = len2;
  526. }
  527. else
  528. {
  529. ctx->low += ((uint64_t)len) << 3;
  530. }
  531. size_t n = ctx->num;
  532. if (n != 0)
  533. {
  534. if (len >= block_size || len + n >= block_size)
  535. {
  536. memcpy(ctx->data8 + n, data, block_size - n);
  537. hash_func(ctx, ctx->data8, 1);
  538. n = (size_t)(block_size - n);
  539. data += n;
  540. len -= n;
  541. ctx->num = 0;
  542. memset(ctx->data8, 0, (size_t)block_size);
  543. }
  544. else
  545. {
  546. memcpy(ctx->data8 + n, data, len);
  547. ctx->num += (uint32_t)len;
  548. return;
  549. }
  550. }
  551. n = len / block_size;
  552. if (n > 0)
  553. {
  554. hash_func(ctx, data, n);
  555. n *= block_size;
  556. data += n;
  557. len -= n;
  558. }
  559. if (len != 0)
  560. {
  561. ctx->num = (uint32_t)len;
  562. memcpy(ctx->data8, data, len);
  563. }
  564. }
  565. template <typename HashDigest> static void HashFinal(HashContext* ctx, size_t block_size, HashDigest hash_func, bool bLittleEndian)
  566. {
  567. size_t n = ctx->num;
  568. // 1. add one bit to end of messages. (MD5, SHA1)
  569. // 2. fill message's 512bits with 0. (64bytes, required length for one hash)
  570. // 3. add total message length as big-endian integer.
  571. ctx->data8[n++] = 0x80;
  572. // 4 bytes integer type if cBlock is 64.
  573. // 8 bytes integer type if cBlock is 128.
  574. size_t baseTypeSize = block_size / 16;
  575. if (n > block_size - baseTypeSize * 2)
  576. {
  577. memset(ctx->data8 + n, 0, (size_t)(block_size - n));
  578. n = 0;
  579. hash_func(ctx, ctx->data8, 1);
  580. }
  581. // fill with 0, except for last 2 blocks
  582. memset(ctx->data8 + n, 0, (size_t)(block_size - n - (baseTypeSize * 2)));
  583. // set last 2 blocks with low, high values.
  584. if (baseTypeSize > 4)
  585. {
  586. if (bLittleEndian)
  587. {
  588. ctx->data64[14] = SystemToLittleEndian(ctx->low);
  589. ctx->data64[15] = SystemToLittleEndian(ctx->high);
  590. }
  591. else
  592. {
  593. ctx->data64[14] = SystemToBigEndian(ctx->high);
  594. ctx->data64[15] = SystemToBigEndian(ctx->low);
  595. }
  596. }
  597. else
  598. {
  599. if (bLittleEndian)
  600. {
  601. ctx->data64[7] = SystemToLittleEndian(ctx->low);
  602. }
  603. else
  604. {
  605. ctx->data64[7] = SystemToBigEndian(ctx->low);
  606. }
  607. }
  608. hash_func(ctx, ctx->data8, 1);
  609. ctx->num = 0;
  610. #ifdef __LITTLE_ENDIAN__
  611. // SHA Family calculated as Big-Endian, swapping bytes-order.
  612. if (baseTypeSize > 4 && !bLittleEndian)
  613. {
  614. for (int i = 0; i < 8; i++)
  615. {
  616. uint32_t tmp = ctx->hash32[i * 2];
  617. ctx->hash32[i * 2] = ctx->hash32[i * 2 + 1];
  618. ctx->hash32[i * 2 + 1] = tmp;
  619. }
  620. }
  621. #endif
  622. }
  623. HashResultSHA1 HashSHA1(const void* p, size_t len)
  624. {
  625. HashContext ctx;
  626. HashInit160(&ctx);
  627. HashUpdate(&ctx, 64, p, len, HashDigest160);
  628. HashFinal(&ctx, 64, HashDigest160, false);
  629. HashResultSHA1 res;
  630. for (int i = 0; i < 5; i++)
  631. res.digest[i] = ctx.hash32[i];
  632. return res;
  633. }
  634. }
  635. std::string sha1(const void* p, size_t s)
  636. {
  637. return HashSHA1(p, s).String();
  638. }