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