1// tHash.cpp 
2// 
3// Hash functions for various kinds of data. Using 64 or 256 bit versions if you want to avoid collisions. There are two 
4// 32 bit hash functions. A fast version used for most string hashes, and a slower but better version. All functions 
5// return the supplied initialization vector(iv) if there was no data to hash. To compute a single hash from multiple 
6// data sources like strings, binary data, or files, you do NOT need to consolidate all the source data into one buffer 
7// first. Just set the initialization vector to the hash computed from the previous step. 
8// 
9// Copyright (c) 2004-2006, 2015, 2017, 2020 Tristan Grimmer. 
10// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby 
11// granted, provided that the above copyright notice and this permission notice appear in all copies. 
12// 
13// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 
14// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 
15// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
16// AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
17// PERFORMANCE OF THIS SOFTWARE. 
18 
19#include <Foundation/tStandard.h> 
20#include <Foundation/tHash.h> 
21 
22 
23uint32 tHash::tHashDataFast32(const uint8* data, int length, uint32 iv) 
24{ 
25 uint32 hash = iv; 
26 while (length--) 
27 { 
28 hash += hash << 5; 
29 hash += *(uint8*)data++; 
30 } 
31 
32 return hash; 
33} 
34 
35 
36// This 32bit hash was written originally by Robert J. Jenkins Jr., 1997 
37// See http://burtleburtle.net/bob/hash/evahash.html 
38namespace tHash 
39{ 
40 inline void Mix32(uint32& a, uint32& b, uint32& c) 
41 { 
42 a -= b; a -= c; a ^= (c>>13); 
43 b -= c; b -= a; b ^= (a<<8); 
44 c -= a; c -= b; c ^= (b>>13); 
45 a -= b; a -= c; a ^= (c>>12); 
46 b -= c; b -= a; b ^= (a<<16); 
47 c -= a; c -= b; c ^= (b>>5); 
48 a -= b; a -= c; a ^= (c>>3); 
49 b -= c; b -= a; b ^= (a<<10); 
50 c -= a; c -= b; c ^= (b>>15); 
51 } 
52} 
53 
54 
55uint32 tHash::tHashData32(const uint8* data, int length, uint32 iv) 
56{ 
57 uint32 a,b,c; // The internal state. 
58 int len; // How many key bytes still need mixing. 
59 
60 len = length; 
61 a = b = 0x9e3779b9; // The golden ratio; an arbitrary value. 
62 c = iv; // Variable initialization of internal state. 
63 
64 // Do as many 12 byte chunks as we can. 
65 while (len >= 12) 
66 { 
67 a += data[0] + (uint32(data[1]) << 8) + (uint32(data[2]) << 16) + (uint32(data[3]) << 24); 
68 b += data[4] + (uint32(data[5]) << 8) + (uint32(data[6]) << 16) + (uint32(data[7]) << 24); 
69 c += data[8] + (uint32(data[9]) << 8) + (uint32(data[10]) << 16) + (uint32(data[11]) << 24); 
70 tHash::Mix32(a,b,c); 
71 data += 12; len -= 12; 
72 } 
73 
74 // Finish up the last 11 bytes. 
75 c += length; 
76 switch (len) // All the case statements fall through. 
77 { 
78 case 11: c += uint32(data[10]) << 24; 
79 case 10: c += uint32(data[9]) << 16; 
80 case 9 : c += uint32(data[8]) << 8; // The first byte of c is reserved for the length. 
81 case 8 : b += uint32(data[7]) << 24; 
82 case 7 : b += uint32(data[6]) << 16; 
83 case 6 : b += uint32(data[5]) << 8; 
84 case 5 : b += data[4]; 
85 case 4 : a += uint32(data[3]) << 24; 
86 case 3 : a += uint32(data[2]) << 16; 
87 case 2 : a += uint32(data[1]) << 8; 
88 case 1 : a += data[0]; 
89 } 
90 tHash::Mix32(a,b,c); 
91 
92 return c; 
93} 
94 
95 
96// This 64bit hash was written originally by Robert J. Jenkins Jr., 1997 
97// See http://burtleburtle.net/bob/hash/evahash.html 
98namespace tHash 
99{ 
100 inline void Mix64(uint64& a, uint64& b, uint64& c) 
101 { 
102 a -= b; a -= c; a ^= (c>>43); 
103 b -= c; b -= a; b ^= (a<<9); 
104 c -= a; c -= b; c ^= (b>>8); 
105 a -= b; a -= c; a ^= (c>>38); 
106 b -= c; b -= a; b ^= (a<<23); 
107 c -= a; c -= b; c ^= (b>>5); 
108 a -= b; a -= c; a ^= (c>>35); 
109 b -= c; b -= a; b ^= (a<<49); 
110 c -= a; c -= b; c ^= (b>>11); 
111 a -= b; a -= c; a ^= (c>>12); 
112 b -= c; b -= a; b ^= (a<<18); 
113 c -= a; c -= b; c ^= (b>>22); 
114 } 
115} 
116 
117 
118uint64 tHash::tHashData64(const uint8* data, int length, uint64 iv) 
119{ 
120 uint64 a,b,c; // The internal state. 
121 int len; // How many key bytes still need mixing. 
122 
123 len = length; 
124 a = b = 0x9e3779b97f4a7c13ULL; // The golden ratio; an arbitrary value. 
125 c = iv; // Variable initialization of internal state. 
126 
127 // Do as many 24 byte chunks as we can. 
128 while (len >= 24) 
129 { 
130 a += (uint64(data[0]) << 0) + (uint64(data[1]) << 8) + (uint64(data[2]) << 16) + (uint64(data[3]) << 24) 
131 + (uint64(data[4]) << 32) + (uint64(data[5]) << 40) + (uint64(data[6]) << 48) + (uint64(data[7]) << 56); 
132 
133 b += (uint64(data[8]) << 0) + (uint64(data[9]) << 8) + (uint64(data[10]) << 16) + (uint64(data[11]) << 24) 
134 + (uint64(data[12]) << 32) + (uint64(data[13]) << 40) + (uint64(data[14]) << 48) + (uint64(data[15]) << 56); 
135 
136 c += (uint64(data[16]) << 0) + (uint64(data[17]) << 8) + (uint64(data[18]) << 16) + (uint64(data[19]) << 24) 
137 + (uint64(data[20]) << 32) + (uint64(data[21]) << 40) + (uint64(data[22]) << 48) + (uint64(data[23]) << 56); 
138 
139 tHash::Mix64(a,b,c); 
140 data += 24; len -= 24; 
141 } 
142 
143 // Finish up the last 23 bytes. 
144 c += length; 
145 switch (len) // All the case statements fall through. 
146 { 
147 case 23: c += uint64(data[22]) << 56; 
148 case 22: c += uint64(data[21]) << 48; 
149 case 21: c += uint64(data[20]) << 40; 
150 case 20: c += uint64(data[19]) << 32; 
151 case 19: c += uint64(data[18]) << 24; 
152 case 18: c += uint64(data[17]) << 16; 
153 case 17: c += uint64(data[16]) << 8; // The first byte of c is reserved for the length. 
154 
155 case 16: b += uint64(data[15]) << 56; 
156 case 15: b += uint64(data[14]) << 48; 
157 case 14: b += uint64(data[13]) << 40; 
158 case 13: b += uint64(data[12]) << 32; 
159 case 12: b += uint64(data[11]) << 24; 
160 case 11: b += uint64(data[10]) << 16; 
161 case 10: b += uint64(data[9]) << 8; 
162 case 9 : b += uint64(data[8]) << 0; 
163 
164 case 8: a += uint64(data[7]) << 56; 
165 case 7: a += uint64(data[6]) << 48; 
166 case 6: a += uint64(data[5]) << 40; 
167 case 5: a += uint64(data[4]) << 32; 
168 case 4: a += uint64(data[3]) << 24; 
169 case 3: a += uint64(data[2]) << 16; 
170 case 2: a += uint64(data[1]) << 8; 
171 case 1: a += uint64(data[0]) << 0; 
172 } 
173 
174 tHash::Mix64(a,b,c); 
175 
176 return c; 
177} 
178 
179 
180// Here is the 128 bit MD5 hash algorithm. 
181namespace tHash 
182{ 
183 // Below are constants for MD5Transform routine. 
184 const static int MD5_S11 = 7; 
185 const static int MD5_S12 = 12; 
186 const static int MD5_S13 = 17; 
187 const static int MD5_S14 = 22; 
188 const static int MD5_S21 = 5; 
189 const static int MD5_S22 = 9; 
190 const static int MD5_S23 = 14; 
191 const static int MD5_S24 = 20; 
192 const static int MD5_S31 = 4; 
193 const static int MD5_S32 = 11; 
194 const static int MD5_S33 = 16; 
195 const static int MD5_S34 = 23; 
196 const static int MD5_S41 = 6; 
197 const static int MD5_S42 = 10; 
198 const static int MD5_S43 = 15; 
199 const static int MD5_S44 = 21; 
200 
201 const static int iMD5BlockSize = 64; 
202  
203 // Decodes input (uint8) into output (uint32). Assumes len is a multiple of 4. 
204 void MD5Decode(uint32* output, const uint8* input, int length); 
205 
206 // Encodes input (uint32) into output (uint8). Assumes len is a multiple of 4. 
207 void MD5Encode(uint8* output, const uint32* input, int length); 
208 
209 // Apply MD5 algo on a block. 
210 void MD5Transform(uint32 state[4], const uint8* block); 
211 
212 void MD5Update(uint32 count[2], uint32 state[4], const uint8* data, uint32 length, uint8 buffer[iMD5BlockSize]); 
213 
214 uint32 MD5_F(uint32 x, uint32 y, uint32 z) { return (x&y) | (~x&z); } 
215 uint32 MD5_G(uint32 x, uint32 y, uint32 z) { return (x&z) | (y&~z); } 
216 uint32 MD5_H(uint32 x, uint32 y, uint32 z) { return x^y^z; } 
217 uint32 MD5_I(uint32 x, uint32 y, uint32 z) { return y ^ (x | ~z); } 
218 uint32 MD5_RotateLeft(uint32 x, int n) { return (x << n) | (x >> (32-n)); } 
219 void MD5_FF(uint32& a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac) { a = MD5_RotateLeft(a + MD5_F(b, c, d) + x + ac, s) + b; } 
220 void MD5_GG(uint32& a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac) { a = MD5_RotateLeft(a + MD5_G(b, c, d) + x + ac, s) + b; } 
221 void MD5_HH(uint32& a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac) { a = MD5_RotateLeft(a + MD5_H(b, c, d) + x + ac, s) + b; } 
222 void MD5_II(uint32& a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac) { a = MD5_RotateLeft(a + MD5_I(b, c, d) + x + ac, s) + b; } 
223}; 
224 
225 
226void tHash::MD5Decode(uint32* output, const uint8* input, int length) 
227{ 
228 for (int i = 0, j = 0; j < length; i++, j += 4) 
229 { 
230 uint32 j0 = uint32(input[j]); 
231 uint32 j1 = uint32(input[j+1]); 
232 uint32 j2 = uint32(input[j+2]); 
233 uint32 j3 = uint32(input[j+3]); 
234 output[i] = (j0 | (j1 << 8) | (j2 << 16) | (j3 << 24)); 
235 } 
236} 
237 
238 
239void tHash::MD5Encode(uint8* output, const uint32* input, int length) 
240{ 
241 for (int i = 0, j = 0; j < length; i++, j += 4) 
242 { 
243 output[j] = input[i] & 0xFF; 
244 output[j+1] = (input[i] >> 8) & 0xFF; 
245 output[j+2] = (input[i] >> 16) & 0xFF; 
246 output[j+3] = (input[i] >> 24) & 0xFF; 
247 } 
248} 
249 
250 
251void tHash::MD5Transform(uint32 state[4], const uint8* block) 
252{ 
253 uint32 a = state[0]; 
254 uint32 b = state[1]; 
255 uint32 c = state[2]; 
256 uint32 d = state[3]; 
257 uint32 x[16]; 
258 
259 MD5Decode(x, block, iMD5BlockSize); 
260 
261 // Round 1 
262 tHash::MD5_FF(a, b, c, d, x[ 0], tHash::MD5_S11, 0xd76aa478); // 1 
263 tHash::MD5_FF(d, a, b, c, x[ 1], tHash::MD5_S12, 0xe8c7b756); // 2 
264 tHash::MD5_FF(c, d, a, b, x[ 2], tHash::MD5_S13, 0x242070db); // 3 
265 tHash::MD5_FF(b, c, d, a, x[ 3], tHash::MD5_S14, 0xc1bdceee); // 4 
266 tHash::MD5_FF(a, b, c, d, x[ 4], tHash::MD5_S11, 0xf57c0faf); // 5 
267 tHash::MD5_FF(d, a, b, c, x[ 5], tHash::MD5_S12, 0x4787c62a); // 6 
268 tHash::MD5_FF(c, d, a, b, x[ 6], tHash::MD5_S13, 0xa8304613); // 7 
269 tHash::MD5_FF(b, c, d, a, x[ 7], tHash::MD5_S14, 0xfd469501); // 8 
270 tHash::MD5_FF(a, b, c, d, x[ 8], tHash::MD5_S11, 0x698098d8); // 9 
271 tHash::MD5_FF(d, a, b, c, x[ 9], tHash::MD5_S12, 0x8b44f7af); // 10 
272 tHash::MD5_FF(c, d, a, b, x[10], tHash::MD5_S13, 0xffff5bb1); // 11 
273 tHash::MD5_FF(b, c, d, a, x[11], tHash::MD5_S14, 0x895cd7be); // 12 
274 tHash::MD5_FF(a, b, c, d, x[12], tHash::MD5_S11, 0x6b901122); // 13 
275 tHash::MD5_FF(d, a, b, c, x[13], tHash::MD5_S12, 0xfd987193); // 14 
276 tHash::MD5_FF(c, d, a, b, x[14], tHash::MD5_S13, 0xa679438e); // 15 
277 tHash::MD5_FF(b, c, d, a, x[15], tHash::MD5_S14, 0x49b40821); // 16 
278 
279 // Round 2 
280 tHash::MD5_GG(a, b, c, d, x[ 1], tHash::MD5_S21, 0xf61e2562); // 17 
281 tHash::MD5_GG(d, a, b, c, x[ 6], tHash::MD5_S22, 0xc040b340); // 18 
282 tHash::MD5_GG(c, d, a, b, x[11], tHash::MD5_S23, 0x265e5a51); // 19 
283 tHash::MD5_GG(b, c, d, a, x[ 0], tHash::MD5_S24, 0xe9b6c7aa); // 20 
284 tHash::MD5_GG(a, b, c, d, x[ 5], tHash::MD5_S21, 0xd62f105d); // 21 
285 tHash::MD5_GG(d, a, b, c, x[10], tHash::MD5_S22, 0x02441453); // 22 
286 tHash::MD5_GG(c, d, a, b, x[15], tHash::MD5_S23, 0xd8a1e681); // 23 
287 tHash::MD5_GG(b, c, d, a, x[ 4], tHash::MD5_S24, 0xe7d3fbc8); // 24 
288 tHash::MD5_GG(a, b, c, d, x[ 9], tHash::MD5_S21, 0x21e1cde6); // 25 
289 tHash::MD5_GG(d, a, b, c, x[14], tHash::MD5_S22, 0xc33707d6); // 26 
290 tHash::MD5_GG(c, d, a, b, x[ 3], tHash::MD5_S23, 0xf4d50d87); // 27 
291 tHash::MD5_GG(b, c, d, a, x[ 8], tHash::MD5_S24, 0x455a14ed); // 28 
292 tHash::MD5_GG(a, b, c, d, x[13], tHash::MD5_S21, 0xa9e3e905); // 29 
293 tHash::MD5_GG(d, a, b, c, x[ 2], tHash::MD5_S22, 0xfcefa3f8); // 30 
294 tHash::MD5_GG(c, d, a, b, x[ 7], tHash::MD5_S23, 0x676f02d9); // 31 
295 tHash::MD5_GG(b, c, d, a, x[12], tHash::MD5_S24, 0x8d2a4c8a); // 32 
296 
297 // Round 3 
298 tHash::MD5_HH(a, b, c, d, x[ 5], tHash::MD5_S31, 0xfffa3942); // 33 
299 tHash::MD5_HH(d, a, b, c, x[ 8], tHash::MD5_S32, 0x8771f681); // 34 
300 tHash::MD5_HH(c, d, a, b, x[11], tHash::MD5_S33, 0x6d9d6122); // 35 
301 tHash::MD5_HH(b, c, d, a, x[14], tHash::MD5_S34, 0xfde5380c); // 36 
302 tHash::MD5_HH(a, b, c, d, x[ 1], tHash::MD5_S31, 0xa4beea44); // 37 
303 tHash::MD5_HH(d, a, b, c, x[ 4], tHash::MD5_S32, 0x4bdecfa9); // 38 
304 tHash::MD5_HH(c, d, a, b, x[ 7], tHash::MD5_S33, 0xf6bb4b60); // 39 
305 tHash::MD5_HH(b, c, d, a, x[10], tHash::MD5_S34, 0xbebfbc70); // 40 
306 tHash::MD5_HH(a, b, c, d, x[13], tHash::MD5_S31, 0x289b7ec6); // 41 
307 tHash::MD5_HH(d, a, b, c, x[ 0], tHash::MD5_S32, 0xeaa127fa); // 42 
308 tHash::MD5_HH(c, d, a, b, x[ 3], tHash::MD5_S33, 0xd4ef3085); // 43 
309 tHash::MD5_HH(b, c, d, a, x[ 6], tHash::MD5_S34, 0x04881d05); // 44 
310 tHash::MD5_HH(a, b, c, d, x[ 9], tHash::MD5_S31, 0xd9d4d039); // 45 
311 tHash::MD5_HH(d, a, b, c, x[12], tHash::MD5_S32, 0xe6db99e5); // 46 
312 tHash::MD5_HH(c, d, a, b, x[15], tHash::MD5_S33, 0x1fa27cf8); // 47 
313 tHash::MD5_HH(b, c, d, a, x[ 2], tHash::MD5_S34, 0xc4ac5665); // 48 
314 
315 // Round 4 
316 tHash::MD5_II(a, b, c, d, x[ 0], tHash::MD5_S41, 0xf4292244); // 49 
317 tHash::MD5_II(d, a, b, c, x[ 7], tHash::MD5_S42, 0x432aff97); // 50 
318 tHash::MD5_II(c, d, a, b, x[14], tHash::MD5_S43, 0xab9423a7); // 51 
319 tHash::MD5_II(b, c, d, a, x[ 5], tHash::MD5_S44, 0xfc93a039); // 52 
320 tHash::MD5_II(a, b, c, d, x[12], tHash::MD5_S41, 0x655b59c3); // 53 
321 tHash::MD5_II(d, a, b, c, x[ 3], tHash::MD5_S42, 0x8f0ccc92); // 54 
322 tHash::MD5_II(c, d, a, b, x[10], tHash::MD5_S43, 0xffeff47d); // 55 
323 tHash::MD5_II(b, c, d, a, x[ 1], tHash::MD5_S44, 0x85845dd1); // 56 
324 tHash::MD5_II(a, b, c, d, x[ 8], tHash::MD5_S41, 0x6fa87e4f); // 57 
325 tHash::MD5_II(d, a, b, c, x[15], tHash::MD5_S42, 0xfe2ce6e0); // 58 
326 tHash::MD5_II(c, d, a, b, x[ 6], tHash::MD5_S43, 0xa3014314); // 59 
327 tHash::MD5_II(b, c, d, a, x[13], tHash::MD5_S44, 0x4e0811a1); // 60 
328 tHash::MD5_II(a, b, c, d, x[ 4], tHash::MD5_S41, 0xf7537e82); // 61 
329 tHash::MD5_II(d, a, b, c, x[11], tHash::MD5_S42, 0xbd3af235); // 62 
330 tHash::MD5_II(c, d, a, b, x[ 2], tHash::MD5_S43, 0x2ad7d2bb); // 63 
331 tHash::MD5_II(b, c, d, a, x[ 9], tHash::MD5_S44, 0xeb86d391); // 64 
332 
333 state[0] += a; 
334 state[1] += b; 
335 state[2] += c; 
336 state[3] += d; 
337 
338 // Clear sensitive information. 
339 tStd::tMemset(x, 0, sizeof(x)); 
340} 
341 
342 
343void tHash::MD5Update(uint32 count[2], uint32 state[4], const uint8* data, uint32 length, uint8 buffer[iMD5BlockSize]) 
344{ 
345 int index = count[0] / 8 % iMD5BlockSize; // Compute number of bytes mod 64. 
346 
347 // Update number of bits. 
348 if ((count[0] += (length << 3)) < (length << 3)) 
349 count[1]++; 
350 count[1] += (length >> 29); 
351 
352 uint32 firstpart = 64 - index; // Number of bytes we need to fill in buffer. 
353 
354 // Transform as many times as possible. 
355 uint32 i = 0; 
356 if (length >= firstpart) 
357 { 
358 // Fill buffer first, transform. 
359 tStd::tMemcpy(&buffer[index], data, firstpart); 
360 MD5Transform(state, buffer); 
361 
362 // Transform chunks of blocksize (64 bytes). 
363 for (i = firstpart; i + iMD5BlockSize <= length; i += iMD5BlockSize) 
364 MD5Transform(state, &data[i]); 
365 
366 index = 0; 
367 } 
368 
369 // Buffer remaining input. 
370 tStd::tMemcpy(&buffer[index], &data[i], length-i); 
371} 
372 
373 
374tuint128 tHash::tHashDataMD5(const uint8* data, int len, tuint128 iv) 
375{ 
376 uint32 length = len; 
377 uint8 buffer[tHash::iMD5BlockSize]; // Bytes that didn't fit in last 64 byte chunk. 
378 uint32 count[2]; // 64bit counter for number of bits (lo, hi). 
379 uint32 state[4]; // Digest so far. 
380 uint8 digest[16]; // The result. 
381 
382 // Phase 1. Initialize state variables. 
383 count[0] = 0; 
384 count[1] = 0; 
385 state[0] = 0x67452301; // Load magic initialization constants. 
386 state[1] = 0xefcdab89; 
387 state[2] = 0x98badcfe; 
388 state[3] = 0x10325476; 
389 
390 // Phase 2. Block update. Could be put in a loop to process multiple chunks of data. Continues an MD5 
391 // message-digest operation, processing another message block. 
392 tHash::MD5Update(count, state, data, length, buffer); 
393 
394 // Phase 3. Finalize. 
395 // Ends an MD5 message-digest operation, writing the the message digest and clearing the context. 
396 static uint8 padding[64] = 
397 { 
398 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
399 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
400 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
401 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
402 }; 
403 
404 // Save number of bits. 
405 unsigned char bits[8]; 
406 tHash::MD5Encode(bits, count, 8); 
407 
408 // Pad out to 56 mod 64. 
409 int index = count[0] / 8 % 64; 
410 int padLen = (index < 56) ? (56 - index) : (120 - index); 
411 tHash::MD5Update(count, state, padding, padLen, buffer); 
412 
413 // Append length (before padding). 
414 tHash::MD5Update(count, state, bits, 8, buffer); 
415 
416 // Store state in digest 
417 tHash::MD5Encode(digest, state, 16); 
418 
419 // Clear sensitive information. 
420 tStd::tMemset(buffer, 0, sizeof buffer); 
421 tStd::tMemset(count, 0, sizeof count); 
422 
423 // Digest is now valid. The lower indexed numbers are least significant so we need to reverse the order. 
424 tuint128 result; 
425 tAssert(sizeof(result) == sizeof(digest)); 
426 
427 for (int i = 0; i < 16; i++) 
428 ((uint8*)&result)[15-i] = digest[i]; 
429 
430 return result; 
431} 
432 
433 
434// This 256bit hash was written originally by Robert J. Jenkins Jr., 1997 
435// See http://burtleburtle.net/bob/hash/evahash.html 
436namespace tHash 
437{ 
438 inline void Mix256(uint32& a, uint32& b, uint32& c, uint32& d, uint32& e, uint32& f, uint32& g, uint32& h) 
439 { 
440 a ^= b<<11; d += a; b += c; 
441 b ^= c>>2; e += b; c += d; 
442 c ^= d<<8; f += c; d += e; 
443 d ^= e>>16; g += d; e += f; 
444 e ^= f<<10; h += e; f += g; 
445 f ^= g>>4; a += f; g += h; 
446 g ^= h<<8; b += g; h += a; 
447 h ^= a>>9; c += h; a += b; 
448 } 
449} 
450 
451 
452tuint256 tHash::tHashData256(const uint8* data, int len, tuint256 iv) 
453{ 
454 uint32 a, b, c, d, e, f, g, h, length; 
455 
456 // Use the length and level. Add in the golden ratio. Remember, 'a' is most significant. 
457 length = len; 
458 uint32& A = iv.RawElement(7); uint32& B = iv.RawElement(6); uint32& C = iv.RawElement(5); uint32& D = iv.RawElement(4); 
459 uint32& E = iv.RawElement(3); uint32& F = iv.RawElement(2); uint32& G = iv.RawElement(1); uint32& H = iv.RawElement(0); 
460 a = A; b = B; c = C; d = D; 
461 e = E; f = F; g = G; h = H; 
462 
463 // Process most of the key. 
464 while (len >= 32) 
465 { 
466 a += *(uint32*)(data+0); 
467 b += *(uint32*)(data+4); 
468 c += *(uint32*)(data+8); 
469 d += *(uint32*)(data+12); 
470 e += *(uint32*)(data+16); 
471 f += *(uint32*)(data+20); 
472 g += *(uint32*)(data+24); 
473 h += *(uint32*)(data+28); 
474 tHash::Mix256(a,b,c,d,e,f,g,h); 
475 tHash::Mix256(a,b,c,d,e,f,g,h); 
476 tHash::Mix256(a,b,c,d,e,f,g,h); 
477 tHash::Mix256(a,b,c,d,e,f,g,h); 
478 data += 32; len -= 32; 
479 } 
480 
481 // Process the last 31 bytes. 
482 h += length; 
483 switch (len) 
484 { 
485 case 31: h += (data[30] << 24); 
486 case 30: h += (data[29] << 16); 
487 case 29: h += (data[28] << 8); 
488 case 28: g += (data[27] << 24); 
489 case 27: g += (data[26] << 16); 
490 case 26: g += (data[25] << 8); 
491 case 25: g += data[24]; 
492 case 24: f += (data[23] << 24); 
493 case 23: f += (data[22] << 16); 
494 case 22: f += (data[21] << 8); 
495 case 21: f += data[20]; 
496 case 20: e += (data[19] << 24); 
497 case 19: e += (data[18] << 16); 
498 case 18: e += (data[17] << 8); 
499 case 17: e += data[16]; 
500 case 16: d += (data[15] << 24); 
501 case 15: d += (data[14] << 16); 
502 case 14: d += (data[13] << 8); 
503 case 13: d += data[12]; 
504 case 12: c += (data[11] << 24); 
505 case 11: c += (data[10] << 16); 
506 case 10: c += (data[9] << 8); 
507 case 9 : c += data[8]; 
508 case 8 : b += (data[7] << 24); 
509 case 7 : b += (data[6] << 16); 
510 case 6 : b += (data[5] << 8); 
511 case 5 : b += data[4]; 
512 case 4 : a += (data[3] << 24); 
513 case 3 : a += (data[2] << 16); 
514 case 2 : a += (data[1] << 8); 
515 case 1 : a += data[0]; 
516 } 
517 
518 tHash::Mix256(a,b,c,d,e,f,g,h); 
519 tHash::Mix256(a,b,c,d,e,f,g,h); 
520 tHash::Mix256(a,b,c,d,e,f,g,h); 
521 tHash::Mix256(a,b,c,d,e,f,g,h); 
522 
523 A = a; B = b; C = c; D = d; 
524 E = e; F = f; G = g; H = h; 
525 return iv; 
526} 
527