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, 2019, 2021, 2023 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// The SHA-256 implementation is taken from https://github.com/amosnier/sha-2. All functions and constants in the 
20// tHash_SHA256 namespace should be considered unencumbered as per Alain Mosnier's licence file: 
21// 
22// This is free and unencumbered software released into the public domain. 
23// 
24// Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form 
25// or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. 
26// 
27// In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright 
28// interest in the software to the public domain. We make this dedication for the benefit of the public at large and to 
29// the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in 
30// perpetuity of all present and future rights to this software under copyright law. 
31// 
32// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE 
33// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE 
34// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
35// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
36// 
37// For more information, please refer to <http://unlicense.org> 
38 
39#include <Foundation/tStandard.h> 
40#include <Foundation/tHash.h> 
41 
42 
43uint32 tHash::tHashDataFast32(const uint8* data, int length, uint32 iv
44
45 uint32 hash = iv
46 while (length--) 
47
48 hash += hash << 5
49 hash += *(uint8*)data++; 
50
51 
52 return hash
53
54 
55 
56// This 32bit hash was written originally by Robert J. Jenkins Jr., 1997. See http://burtleburtle.net/bob/hash/evahash.html 
57namespace tHash_JEN32 
58
59 inline void Mix(uint32& a, uint32& b, uint32& c
60
61 a -= b; a -= c; a ^= (c>>13); 
62 b -= c; b -= a; b ^= (a<<8); 
63 c -= a; c -= b; c ^= (b>>13); 
64 a -= b; a -= c; a ^= (c>>12); 
65 b -= c; b -= a; b ^= (a<<16); 
66 c -= a; c -= b; c ^= (b>>5); 
67 a -= b; a -= c; a ^= (c>>3); 
68 b -= c; b -= a; b ^= (a<<10); 
69 c -= a; c -= b; c ^= (b>>15); 
70
71
72 
73 
74uint32 tHash::tHashData32(const uint8* data, int length, uint32 iv
75
76 uint32 a,b,c; // The internal state. 
77 int len; // How many key bytes still need mixing. 
78 
79 len = length
80 a = b = 0x9e3779b9; // The golden ratio; an arbitrary value. 
81 c = iv; // Variable initialization of internal state. 
82 
83 // Do as many 12 byte chunks as we can. 
84 while (len >= 12
85
86 a += data[0] + (uint32(data[1]) << 8) + (uint32(data[2]) << 16) + (uint32(data[3]) << 24); 
87 b += data[4] + (uint32(data[5]) << 8) + (uint32(data[6]) << 16) + (uint32(data[7]) << 24); 
88 c += data[8] + (uint32(data[9]) << 8) + (uint32(data[10]) << 16) + (uint32(data[11]) << 24); 
89 tHash_JEN32::Mix(a,b,c); 
90 data += 12; len -= 12
91
92 
93 // Finish up the last 11 bytes. 
94 c += length
95 switch (len) // All the case statements fall through. 
96
97 case 11: c += uint32(data[10]) << 24
98 case 10: c += uint32(data[9]) << 16
99 case 9 : c += uint32(data[8]) << 8; // The first byte of c is reserved for the length. 
100 case 8 : b += uint32(data[7]) << 24
101 case 7 : b += uint32(data[6]) << 16
102 case 6 : b += uint32(data[5]) << 8
103 case 5 : b += data[4]; 
104 case 4 : a += uint32(data[3]) << 24
105 case 3 : a += uint32(data[2]) << 16
106 case 2 : a += uint32(data[1]) << 8
107 case 1 : a += data[0]; 
108
109 tHash_JEN32::Mix(a,b,c); 
110 return c
111
112 
113 
114// This 64bit hash was written originally by Robert J. Jenkins Jr., 1997. See http://burtleburtle.net/bob/hash/evahash.html 
115namespace tHash_JEN64 
116
117 inline void Mix(uint64& a, uint64& b, uint64& c
118
119 a -= b; a -= c; a ^= (c >> 43); 
120 b -= c; b -= a; b ^= (a << 9); 
121 c -= a; c -= b; c ^= (b >> 8); 
122 a -= b; a -= c; a ^= (c >> 38); 
123 b -= c; b -= a; b ^= (a << 23); 
124 c -= a; c -= b; c ^= (b >> 5); 
125 a -= b; a -= c; a ^= (c >> 35); 
126 b -= c; b -= a; b ^= (a << 49); 
127 c -= a; c -= b; c ^= (b >> 11); 
128 a -= b; a -= c; a ^= (c >> 12); 
129 b -= c; b -= a; b ^= (a << 18); 
130 c -= a; c -= b; c ^= (b >> 22); 
131
132
133 
134 
135uint64 tHash::tHashData64(const uint8* data, int length, uint64 iv
136
137 uint64 a,b,c; // The internal state. 
138 int len; // How many key bytes still need mixing. 
139 
140 len = length
141 a = b = 0x9e3779b97f4a7c13ULL; // The golden ratio; an arbitrary value. 
142 c = iv; // Variable initialization of internal state. 
143 
144 // Do as many 24 byte chunks as we can. 
145 while (len >= 24
146
147 a += (uint64(data[0]) << 0 ) + (uint64(data[1]) << 8 ) + (uint64(data[2]) << 16) + (uint64(data[3]) << 24
148 + (uint64(data[4]) << 32) + (uint64(data[5]) << 40) + (uint64(data[6]) << 48) + (uint64(data[7]) << 56); 
149 
150 b += (uint64(data[8]) << 0 ) + (uint64(data[9]) << 8 ) + (uint64(data[10]) << 16) + (uint64(data[11]) << 24
151 + (uint64(data[12]) << 32) + (uint64(data[13]) << 40) + (uint64(data[14]) << 48) + (uint64(data[15]) << 56); 
152 
153 c += (uint64(data[16]) << 0 ) + (uint64(data[17]) << 8 ) + (uint64(data[18]) << 16) + (uint64(data[19]) << 24
154 + (uint64(data[20]) << 32) + (uint64(data[21]) << 40) + (uint64(data[22]) << 48) + (uint64(data[23]) << 56); 
155 
156 tHash_JEN64::Mix(a,b,c); 
157 data += 24; len -= 24
158
159 
160 // Finish up the last 23 bytes. 
161 c += length
162 switch (len) // All the case statements fall through. 
163
164 case 23: c += uint64(data[22]) << 56
165 case 22: c += uint64(data[21]) << 48
166 case 21: c += uint64(data[20]) << 40
167 case 20: c += uint64(data[19]) << 32
168 case 19: c += uint64(data[18]) << 24
169 case 18: c += uint64(data[17]) << 16
170 case 17: c += uint64(data[16]) << 8; // The first byte of c is reserved for the length. 
171 
172 case 16: b += uint64(data[15]) << 56
173 case 15: b += uint64(data[14]) << 48
174 case 14: b += uint64(data[13]) << 40
175 case 13: b += uint64(data[12]) << 32
176 case 12: b += uint64(data[11]) << 24
177 case 11: b += uint64(data[10]) << 16
178 case 10: b += uint64(data[9]) << 8
179 case 9 : b += uint64(data[8]) << 0
180 
181 case 8: a += uint64(data[7]) << 56
182 case 7: a += uint64(data[6]) << 48
183 case 6: a += uint64(data[5]) << 40
184 case 5: a += uint64(data[4]) << 32
185 case 4: a += uint64(data[3]) << 24
186 case 3: a += uint64(data[2]) << 16
187 case 2: a += uint64(data[1]) << 8
188 case 1: a += uint64(data[0]) << 0
189
190 
191 tHash_JEN64::Mix(a,b,c); 
192 return c
193
194 
195 
196namespace tHash_MD5 
197
198 // Here is the 128 bit MD5 hash algorithm. Constants for MD5Transform routine: 
199 const static int S11 = 7
200 const static int S12 = 12
201 const static int S13 = 17
202 const static int S14 = 22
203 const static int S21 = 5
204 const static int S22 = 9
205 const static int S23 = 14
206 const static int S24 = 20
207 const static int S31 = 4
208 const static int S32 = 11
209 const static int S33 = 16
210 const static int S34 = 23
211 const static int S41 = 6
212 const static int S42 = 10
213 const static int S43 = 15
214 const static int S44 = 21
215 const static int BlockSize = 64
216  
217 // Decodes input (uint8) into output (uint32). Assumes len is a multiple of 4. 
218 void Decode(uint32* output, const uint8* input, int length); 
219 
220 // Encodes input (uint32) into output (uint8). Assumes len is a multiple of 4. 
221 void Encode(uint8* output, const uint32* input, int length); 
222 
223 // Apply MD5 algo on a block. 
224 void Transform(uint32 state[4], const uint8* block); 
225 
226 void Update(uint32 count[2], uint32 state[4], const uint8* data, uint32 length, uint8 buffer[BlockSize]); 
227 
228 uint32 F(uint32 x, uint32 y, uint32 z) { return (x&y) | (~x&z); } 
229 uint32 G(uint32 x, uint32 y, uint32 z) { return (x&z) | (y&~z); } 
230 uint32 H(uint32 x, uint32 y, uint32 z) { return x^y^z; } 
231 uint32 I(uint32 x, uint32 y, uint32 z) { return y ^ (x | ~z); } 
232 uint32 RotateLeft(uint32 x, int n) { return (x << n) | (x >> (32-n)); } 
233 void FF(uint32& a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac) { a = RotateLeft(x: a + F(x: b, y: c, z: d) + x + ac, n: s) + b; } 
234 void GG(uint32& a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac) { a = RotateLeft(x: a + G(x: b, y: c, z: d) + x + ac, n: s) + b; } 
235 void HH(uint32& a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac) { a = RotateLeft(x: a + H(x: b, y: c, z: d) + x + ac, n: s) + b; } 
236 void II(uint32& a, uint32 b, uint32 c, uint32 d, uint32 x, uint32 s, uint32 ac) { a = RotateLeft(x: a + I(x: b, y: c, z: d) + x + ac, n: s) + b; } 
237}; 
238 
239 
240void tHash_MD5::Decode(uint32* output, const uint8* input, int length
241
242 for (int i = 0, j = 0; j < length; i++, j += 4
243
244 uint32 j0 = uint32(input[j]); 
245 uint32 j1 = uint32(input[j+1]); 
246 uint32 j2 = uint32(input[j+2]); 
247 uint32 j3 = uint32(input[j+3]); 
248 output[i] = (j0 | (j1 << 8) | (j2 << 16) | (j3 << 24)); 
249
250
251 
252 
253void tHash_MD5::Encode(uint8* output, const uint32* input, int length
254
255 for (int i = 0, j = 0; j < length; i++, j += 4
256
257 output[j] = input[i] & 0xFF
258 output[j+1] = (input[i] >> 8) & 0xFF
259 output[j+2] = (input[i] >> 16) & 0xFF
260 output[j+3] = (input[i] >> 24) & 0xFF
261
262
263 
264 
265void tHash_MD5::Transform(uint32 state[4], const uint8* block
266
267 uint32 a = state[0]; 
268 uint32 b = state[1]; 
269 uint32 c = state[2]; 
270 uint32 d = state[3]; 
271 uint32 x[16]; 
272 
273 Decode(output: x, input: block, length: BlockSize); 
274 
275 // Round 1 
276 tHash_MD5::FF(a, b, c, d, x: x[ 0], s: tHash_MD5::S11, ac: 0xd76aa478); // 1 
277 tHash_MD5::FF(a&: d, b: a, c: b, d: c, x: x[ 1], s: tHash_MD5::S12, ac: 0xe8c7b756); // 2 
278 tHash_MD5::FF(a&: c, b: d, c: a, d: b, x: x[ 2], s: tHash_MD5::S13, ac: 0x242070db); // 3 
279 tHash_MD5::FF(a&: b, b: c, c: d, d: a, x: x[ 3], s: tHash_MD5::S14, ac: 0xc1bdceee); // 4 
280 tHash_MD5::FF(a, b, c, d, x: x[ 4], s: tHash_MD5::S11, ac: 0xf57c0faf); // 5 
281 tHash_MD5::FF(a&: d, b: a, c: b, d: c, x: x[ 5], s: tHash_MD5::S12, ac: 0x4787c62a); // 6 
282 tHash_MD5::FF(a&: c, b: d, c: a, d: b, x: x[ 6], s: tHash_MD5::S13, ac: 0xa8304613); // 7 
283 tHash_MD5::FF(a&: b, b: c, c: d, d: a, x: x[ 7], s: tHash_MD5::S14, ac: 0xfd469501); // 8 
284 tHash_MD5::FF(a, b, c, d, x: x[ 8], s: tHash_MD5::S11, ac: 0x698098d8); // 9 
285 tHash_MD5::FF(a&: d, b: a, c: b, d: c, x: x[ 9], s: tHash_MD5::S12, ac: 0x8b44f7af); // 10 
286 tHash_MD5::FF(a&: c, b: d, c: a, d: b, x: x[10], s: tHash_MD5::S13, ac: 0xffff5bb1); // 11 
287 tHash_MD5::FF(a&: b, b: c, c: d, d: a, x: x[11], s: tHash_MD5::S14, ac: 0x895cd7be); // 12 
288 tHash_MD5::FF(a, b, c, d, x: x[12], s: tHash_MD5::S11, ac: 0x6b901122); // 13 
289 tHash_MD5::FF(a&: d, b: a, c: b, d: c, x: x[13], s: tHash_MD5::S12, ac: 0xfd987193); // 14 
290 tHash_MD5::FF(a&: c, b: d, c: a, d: b, x: x[14], s: tHash_MD5::S13, ac: 0xa679438e); // 15 
291 tHash_MD5::FF(a&: b, b: c, c: d, d: a, x: x[15], s: tHash_MD5::S14, ac: 0x49b40821); // 16 
292 
293 // Round 2 
294 tHash_MD5::GG(a, b, c, d, x: x[ 1], s: tHash_MD5::S21, ac: 0xf61e2562); // 17 
295 tHash_MD5::GG(a&: d, b: a, c: b, d: c, x: x[ 6], s: tHash_MD5::S22, ac: 0xc040b340); // 18 
296 tHash_MD5::GG(a&: c, b: d, c: a, d: b, x: x[11], s: tHash_MD5::S23, ac: 0x265e5a51); // 19 
297 tHash_MD5::GG(a&: b, b: c, c: d, d: a, x: x[ 0], s: tHash_MD5::S24, ac: 0xe9b6c7aa); // 20 
298 tHash_MD5::GG(a, b, c, d, x: x[ 5], s: tHash_MD5::S21, ac: 0xd62f105d); // 21 
299 tHash_MD5::GG(a&: d, b: a, c: b, d: c, x: x[10], s: tHash_MD5::S22, ac: 0x02441453); // 22 
300 tHash_MD5::GG(a&: c, b: d, c: a, d: b, x: x[15], s: tHash_MD5::S23, ac: 0xd8a1e681); // 23 
301 tHash_MD5::GG(a&: b, b: c, c: d, d: a, x: x[ 4], s: tHash_MD5::S24, ac: 0xe7d3fbc8); // 24 
302 tHash_MD5::GG(a, b, c, d, x: x[ 9], s: tHash_MD5::S21, ac: 0x21e1cde6); // 25 
303 tHash_MD5::GG(a&: d, b: a, c: b, d: c, x: x[14], s: tHash_MD5::S22, ac: 0xc33707d6); // 26 
304 tHash_MD5::GG(a&: c, b: d, c: a, d: b, x: x[ 3], s: tHash_MD5::S23, ac: 0xf4d50d87); // 27 
305 tHash_MD5::GG(a&: b, b: c, c: d, d: a, x: x[ 8], s: tHash_MD5::S24, ac: 0x455a14ed); // 28 
306 tHash_MD5::GG(a, b, c, d, x: x[13], s: tHash_MD5::S21, ac: 0xa9e3e905); // 29 
307 tHash_MD5::GG(a&: d, b: a, c: b, d: c, x: x[ 2], s: tHash_MD5::S22, ac: 0xfcefa3f8); // 30 
308 tHash_MD5::GG(a&: c, b: d, c: a, d: b, x: x[ 7], s: tHash_MD5::S23, ac: 0x676f02d9); // 31 
309 tHash_MD5::GG(a&: b, b: c, c: d, d: a, x: x[12], s: tHash_MD5::S24, ac: 0x8d2a4c8a); // 32 
310 
311 // Round 3 
312 tHash_MD5::HH(a, b, c, d, x: x[ 5], s: tHash_MD5::S31, ac: 0xfffa3942); // 33 
313 tHash_MD5::HH(a&: d, b: a, c: b, d: c, x: x[ 8], s: tHash_MD5::S32, ac: 0x8771f681); // 34 
314 tHash_MD5::HH(a&: c, b: d, c: a, d: b, x: x[11], s: tHash_MD5::S33, ac: 0x6d9d6122); // 35 
315 tHash_MD5::HH(a&: b, b: c, c: d, d: a, x: x[14], s: tHash_MD5::S34, ac: 0xfde5380c); // 36 
316 tHash_MD5::HH(a, b, c, d, x: x[ 1], s: tHash_MD5::S31, ac: 0xa4beea44); // 37 
317 tHash_MD5::HH(a&: d, b: a, c: b, d: c, x: x[ 4], s: tHash_MD5::S32, ac: 0x4bdecfa9); // 38 
318 tHash_MD5::HH(a&: c, b: d, c: a, d: b, x: x[ 7], s: tHash_MD5::S33, ac: 0xf6bb4b60); // 39 
319 tHash_MD5::HH(a&: b, b: c, c: d, d: a, x: x[10], s: tHash_MD5::S34, ac: 0xbebfbc70); // 40 
320 tHash_MD5::HH(a, b, c, d, x: x[13], s: tHash_MD5::S31, ac: 0x289b7ec6); // 41 
321 tHash_MD5::HH(a&: d, b: a, c: b, d: c, x: x[ 0], s: tHash_MD5::S32, ac: 0xeaa127fa); // 42 
322 tHash_MD5::HH(a&: c, b: d, c: a, d: b, x: x[ 3], s: tHash_MD5::S33, ac: 0xd4ef3085); // 43 
323 tHash_MD5::HH(a&: b, b: c, c: d, d: a, x: x[ 6], s: tHash_MD5::S34, ac: 0x04881d05); // 44 
324 tHash_MD5::HH(a, b, c, d, x: x[ 9], s: tHash_MD5::S31, ac: 0xd9d4d039); // 45 
325 tHash_MD5::HH(a&: d, b: a, c: b, d: c, x: x[12], s: tHash_MD5::S32, ac: 0xe6db99e5); // 46 
326 tHash_MD5::HH(a&: c, b: d, c: a, d: b, x: x[15], s: tHash_MD5::S33, ac: 0x1fa27cf8); // 47 
327 tHash_MD5::HH(a&: b, b: c, c: d, d: a, x: x[ 2], s: tHash_MD5::S34, ac: 0xc4ac5665); // 48 
328 
329 // Round 4 
330 tHash_MD5::II(a, b, c, d, x: x[ 0], s: tHash_MD5::S41, ac: 0xf4292244); // 49 
331 tHash_MD5::II(a&: d, b: a, c: b, d: c, x: x[ 7], s: tHash_MD5::S42, ac: 0x432aff97); // 50 
332 tHash_MD5::II(a&: c, b: d, c: a, d: b, x: x[14], s: tHash_MD5::S43, ac: 0xab9423a7); // 51 
333 tHash_MD5::II(a&: b, b: c, c: d, d: a, x: x[ 5], s: tHash_MD5::S44, ac: 0xfc93a039); // 52 
334 tHash_MD5::II(a, b, c, d, x: x[12], s: tHash_MD5::S41, ac: 0x655b59c3); // 53 
335 tHash_MD5::II(a&: d, b: a, c: b, d: c, x: x[ 3], s: tHash_MD5::S42, ac: 0x8f0ccc92); // 54 
336 tHash_MD5::II(a&: c, b: d, c: a, d: b, x: x[10], s: tHash_MD5::S43, ac: 0xffeff47d); // 55 
337 tHash_MD5::II(a&: b, b: c, c: d, d: a, x: x[ 1], s: tHash_MD5::S44, ac: 0x85845dd1); // 56 
338 tHash_MD5::II(a, b, c, d, x: x[ 8], s: tHash_MD5::S41, ac: 0x6fa87e4f); // 57 
339 tHash_MD5::II(a&: d, b: a, c: b, d: c, x: x[15], s: tHash_MD5::S42, ac: 0xfe2ce6e0); // 58 
340 tHash_MD5::II(a&: c, b: d, c: a, d: b, x: x[ 6], s: tHash_MD5::S43, ac: 0xa3014314); // 59 
341 tHash_MD5::II(a&: b, b: c, c: d, d: a, x: x[13], s: tHash_MD5::S44, ac: 0x4e0811a1); // 60 
342 tHash_MD5::II(a, b, c, d, x: x[ 4], s: tHash_MD5::S41, ac: 0xf7537e82); // 61 
343 tHash_MD5::II(a&: d, b: a, c: b, d: c, x: x[11], s: tHash_MD5::S42, ac: 0xbd3af235); // 62 
344 tHash_MD5::II(a&: c, b: d, c: a, d: b, x: x[ 2], s: tHash_MD5::S43, ac: 0x2ad7d2bb); // 63 
345 tHash_MD5::II(a&: b, b: c, c: d, d: a, x: x[ 9], s: tHash_MD5::S44, ac: 0xeb86d391); // 64 
346 
347 state[0] += a
348 state[1] += b
349 state[2] += c
350 state[3] += d
351 
352 // Clear sensitive information. 
353 tStd::tMemset(dest: x, val: 0, numBytes: sizeof(x)); 
354
355 
356 
357void tHash_MD5::Update(uint32 count[2], uint32 state[4], const uint8* data, uint32 length, uint8 buffer[BlockSize]) 
358
359 int index = count[0] / 8 % BlockSize; // Compute number of bytes mod 64. 
360 
361 // Update number of bits. 
362 if ((count[0] += (length << 3)) < (length << 3)) 
363 count[1]++; 
364 count[1] += (length >> 29); 
365 
366 uint32 firstpart = 64 - index; // Number of bytes we need to fill in buffer. 
367 
368 // Transform as many times as possible. 
369 uint32 i = 0
370 if (length >= firstpart
371
372 // Fill buffer first, transform. 
373 tStd::tMemcpy(dest: &buffer[index], src: data, numBytes: firstpart); 
374 Transform(state, block: buffer); 
375 
376 // Transform chunks of blocksize (64 bytes). 
377 for (i = firstpart; i + BlockSize <= length; i += BlockSize
378 Transform(state, block: &data[i]); 
379 
380 index = 0
381
382 
383 // Buffer remaining input. 
384 tStd::tMemcpy(dest: &buffer[index], src: &data[i], numBytes: length-i); 
385
386 
387 
388tuint128 tHash::tHashDataMD5(const uint8* data, int len, tuint128 iv
389
390 uint32 length = len
391 uint8 buffer[tHash_MD5::BlockSize]; // Bytes that didn't fit in last 64 byte chunk. 
392 uint32 count[2]; // 64bit counter for number of bits (lo, hi). 
393 uint32 state[4]; // Digest so far. 
394 uint8 digest[16]; // The result. 
395 
396 // Phase 1. Initialize state variables. 
397 count[0] = 0
398 count[1] = 0
399 
400 // The default initialization constants given by the iv are specified by the MD5 spec. 
401 state[0] = uint32(iv >> (128-32*1)); // Default IV: 0x67452301; 
402 state[1] = uint32(iv >> (128-32*2)); // Default IV: 0xefcdab89; 
403 state[2] = uint32(iv >> (128-32*3)); // Default IV: 0x98badcfe; 
404 state[3] = uint32(iv); // Default IV: 0x10325476; 
405 
406 // Phase 2. Block update. Could be put in a loop to process multiple chunks of data. Continues an MD5 
407 // message-digest operation, processing another message block. 
408 tHash_MD5::Update(count, state, data, length, buffer); 
409 
410 // Phase 3. Finalize. 
411 // Ends an MD5 message-digest operation, writing the the message digest and clearing the context. 
412 static uint8 padding[64] = 
413
414 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
415 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
416 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
417 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
418 }; 
419 
420 // Save number of bits. 
421 unsigned char bits[8]; 
422 tHash_MD5::Encode(output: bits, input: count, length: 8); 
423 
424 // Pad out to 56 mod 64. 
425 int index = count[0] / 8 % 64
426 int padLen = (index < 56) ? (56 - index) : (120 - index); 
427 tHash_MD5::Update(count, state, data: padding, length: padLen, buffer); 
428 
429 // Append length (before padding). 
430 tHash_MD5::Update(count, state, data: bits, length: 8, buffer); 
431 
432 // Store state in digest. 
433 tHash_MD5::Encode(output: digest, input: state, length: 16); 
434 
435 // Clear sensitive information. 
436 tStd::tMemset(dest: buffer, val: 0, numBytes: sizeof buffer); 
437 tStd::tMemset(dest: count, val: 0, numBytes: sizeof count); 
438 
439 // Digest is now valid. The lower indexed numbers are least significant so we need to reverse the order. 
440 tuint128 result
441 tAssert(sizeof(result) == sizeof(digest)); 
442 
443 for (int i = 0; i < 16; i++) 
444 ((uint8*)&result)[15-i] = digest[i]; 
445 
446 return result
447
448 
449 
450// This 256bit hash was written originally by Robert J. Jenkins Jr., 1997. See http://burtleburtle.net/bob/hash/evahash.html 
451namespace tHash_JEN256 
452
453 inline void Mix(uint32& a, uint32& b, uint32& c, uint32& d, uint32& e, uint32& f, uint32& g, uint32& h
454
455 a ^= b << 11; d += a; b += c
456 b ^= c >> 2; e += b; c += d
457 c ^= d << 8; f += c; d += e
458 d ^= e >> 16; g += d; e += f
459 e ^= f << 10; h += e; f += g
460 f ^= g >> 4; a += f; g += h
461 g ^= h << 8; b += g; h += a
462 h ^= a >> 9; c += h; a += b
463
464
465 
466 
467tuint256 tHash::tHashData256(const uint8* data, int len, tuint256 iv
468
469 // Use the length and level. Add in the golden ratio. Remember, 'a' is most significant. 
470 uint32 length = len
471 uint32& A = iv.Element(i: 7); uint32& B = iv.Element(i: 6); uint32& C = iv.Element(i: 5); uint32& D = iv.Element(i: 4); 
472 uint32& E = iv.Element(i: 3); uint32& F = iv.Element(i: 2); uint32& G = iv.Element(i: 1); uint32& H = iv.Element(i: 0); 
473 uint32 a, b, c, d, e, f, g, h
474 a = A; b = B; c = C; d = D
475 e = E; f = F; g = G; h = H
476 
477 // Process most of the key. 
478 while (len >= 32
479
480 a += *(uint32*)(data+0); 
481 b += *(uint32*)(data+4); 
482 c += *(uint32*)(data+8); 
483 d += *(uint32*)(data+12); 
484 e += *(uint32*)(data+16); 
485 f += *(uint32*)(data+20); 
486 g += *(uint32*)(data+24); 
487 h += *(uint32*)(data+28); 
488 tHash_JEN256::Mix(a, b, c, d, e, f, g, h); 
489 tHash_JEN256::Mix(a, b, c, d, e, f, g, h); 
490 tHash_JEN256::Mix(a, b, c, d, e, f, g, h); 
491 tHash_JEN256::Mix(a, b, c, d, e, f, g, h); 
492 data += 32; len -= 32
493
494 
495 // Process the last 31 bytes. 
496 h += length
497 switch (len
498
499 case 31: h += (data[30] << 24); 
500 case 30: h += (data[29] << 16); 
501 case 29: h += (data[28] << 8); 
502 case 28: g += (data[27] << 24); 
503 case 27: g += (data[26] << 16); 
504 case 26: g += (data[25] << 8); 
505 case 25: g += data[24]; 
506 case 24: f += (data[23] << 24); 
507 case 23: f += (data[22] << 16); 
508 case 22: f += (data[21] << 8); 
509 case 21: f += data[20]; 
510 case 20: e += (data[19] << 24); 
511 case 19: e += (data[18] << 16); 
512 case 18: e += (data[17] << 8); 
513 case 17: e += data[16]; 
514 case 16: d += (data[15] << 24); 
515 case 15: d += (data[14] << 16); 
516 case 14: d += (data[13] << 8); 
517 case 13: d += data[12]; 
518 case 12: c += (data[11] << 24); 
519 case 11: c += (data[10] << 16); 
520 case 10: c += (data[9] << 8); 
521 case 9 : c += data[8]; 
522 case 8 : b += (data[7] << 24); 
523 case 7 : b += (data[6] << 16); 
524 case 6 : b += (data[5] << 8); 
525 case 5 : b += data[4]; 
526 case 4 : a += (data[3] << 24); 
527 case 3 : a += (data[2] << 16); 
528 case 2 : a += (data[1] << 8); 
529 case 1 : a += data[0]; 
530
531 
532 tHash_JEN256::Mix(a, b, c, d, e, f, g, h); 
533 tHash_JEN256::Mix(a, b, c, d, e, f, g, h); 
534 tHash_JEN256::Mix(a, b, c, d, e, f, g, h); 
535 tHash_JEN256::Mix(a, b, c, d, e, f, g, h); 
536 
537 A = a; B = b; C = c; D = d
538 E = e; F = f; G = g; H = h
539 return iv
540
541 
542 
543namespace tHash_SHA256 
544
545 const int HashSizeBytes = 32
546 const int ChunkSizeBytes = 64
547 const int TotalLenLen = 8
548 
549 struct State 
550
551 uint8* Hash
552 uint8 Chunk[ChunkSizeBytes]; 
553 uint8* ChunkPos
554 int SpaceLeft
555 int TotalLen
556 uint32 H[8]; 
557 }; 
558 uint32 RightRot(uint32 value, int count); 
559 void ConsumeChunk(uint32* h, const uint8* p); 
560 
561 void Init(State*, uint8 hash[HashSizeBytes], tuint256 iv); 
562 void Write(State*, const uint8* data, int len); 
563 uint8* Close(State*); 
564 void Calc(uint8 hash[HashSizeBytes], const uint8* input, int len, tuint256 iv); 
565}; 
566 
567 
568inline uint32 tHash_SHA256::RightRot(uint32 value, int count
569
570 tAssert((count >= 0) && (count <= 32)); 
571 return (value >> count) | (value << (32 - count)); 
572
573 
574 
575void tHash_SHA256::ConsumeChunk(uint32* h, const uint8* p
576
577 uint32 ah[8]; 
578 for (int i = 0; i < 8; i++) 
579 ah[i] = h[i]; 
580 
581 uint32 w[16]; 
582 for (int i = 0; i < 4; i++) 
583
584 for (int j = 0; j < 16; j++) 
585
586 if (i == 0
587
588 w[j] = (uint32(p[0]) << 24) | (uint32(p[1]) << 16) | (uint32(p[2]) << 8) | uint32(p[3]); 
589 p += 4
590
591 else 
592
593 const uint32 s0 = RightRot(value: w[(j + 1 ) & 0xf], count: 7 ) ^ RightRot(value: w[(j + 1 ) & 0xf], count: 18) ^ (w[(j + 1 ) & 0xf] >> 3); 
594 const uint32 s1 = RightRot(value: w[(j + 14) & 0xf], count: 17) ^ RightRot(value: w[(j + 14) & 0xf], count: 19) ^ (w[(j + 14) & 0xf] >> 10); 
595 w[j] = w[j] + s0 + w[(j + 9) & 0xf] + s1
596
597 const uint32 s1 = RightRot(value: ah[4], count: 6) ^ RightRot(value: ah[4], count: 11) ^ RightRot(value: ah[4], count: 25); 
598 const uint32 ch = (ah[4] & ah[5]) ^ (~ah[4] & ah[6]); 
599 
600 static const uint32 k[] = 
601
602 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4
603 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe
604 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f
605 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7
606 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc
607 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b
608 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116
609 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3
610 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7
611 0xc67178f2 
612 }; 
613 
614 const uint32 temp1 = ah[7] + s1 + ch + k[i << 4 | j] + w[j]; 
615 const uint32 s0 = RightRot(value: ah[0], count: 2) ^ RightRot(value: ah[0], count: 13) ^ RightRot(value: ah[0], count: 22); 
616 const uint32 maj = (ah[0] & ah[1]) ^ (ah[0] & ah[2]) ^ (ah[1] & ah[2]); 
617 const uint32 temp2 = s0 + maj
618 
619 ah[7] = ah[6]; 
620 ah[6] = ah[5]; 
621 ah[5] = ah[4]; 
622 ah[4] = ah[3] + temp1
623 ah[3] = ah[2]; 
624 ah[2] = ah[1]; 
625 ah[1] = ah[0]; 
626 ah[0] = temp1 + temp2
627
628
629 
630 for (int i = 0; i < 8; i++) 
631 h[i] += ah[i]; 
632
633 
634 
635void tHash_SHA256::Init(State* state, uint8 hash[HashSizeBytes], tuint256 iv
636
637 state->Hash = hash
638 state->ChunkPos = state->Chunk
639 state->SpaceLeft = ChunkSizeBytes
640 state->TotalLen = 0
641 
642 state->H[0] = uint32(iv >> (256-32*1)); // Default IV: 0x6a09e667 
643 state->H[1] = uint32(iv >> (256-32*2)); // Default IV: 0xbb67ae85 
644 state->H[2] = uint32(iv >> (256-32*3)); // Default IV: 0x3c6ef372 
645 state->H[3] = uint32(iv >> (256-32*4)); // Default IV: 0xa54ff53a 
646 state->H[4] = uint32(iv >> (256-32*5)); // Default IV: 0x510e527f 
647 state->H[5] = uint32(iv >> (256-32*6)); // Default IV: 0x9b05688c 
648 state->H[6] = uint32(iv >> (256-32*7)); // Default IV: 0x1f83d9ab 
649 state->H[7] = uint32(iv >> (256-32*8)); // Default IV: 0x5be0cd19 
650
651 
652 
653void tHash_SHA256::Write(State* state, const uint8* data, int len
654
655 state->TotalLen += len
656 const uint8* p = data
657 
658 while (len > 0
659
660 if ((state->SpaceLeft == ChunkSizeBytes) && (len >= ChunkSizeBytes)) 
661
662 ConsumeChunk(h: state->H, p); 
663 len -= ChunkSizeBytes
664 p += ChunkSizeBytes
665 continue
666
667 
668 const int consumedLen = len < state->SpaceLeft ? len : state->SpaceLeft
669 tStd::tMemcpy(dest: state->ChunkPos, src: p, numBytes: consumedLen); 
670 state->SpaceLeft -= consumedLen
671 len -= consumedLen
672 p += consumedLen
673 if (state->SpaceLeft == 0
674
675 ConsumeChunk(h: state->H, p: state->Chunk); 
676 state->ChunkPos = state->Chunk
677 state->SpaceLeft = ChunkSizeBytes
678
679 else 
680
681 state->ChunkPos += consumedLen
682
683
684
685 
686 
687uint8* tHash_SHA256::Close(State* state
688
689 uint8* pos = state->ChunkPos
690 int spaceLeft = state->SpaceLeft
691 uint32* h = state->H
692 
693 *pos++ = 0x80
694 --spaceLeft
695 
696 if (spaceLeft < TotalLenLen
697
698 tStd::tMemset(dest: pos, val: 0x00, numBytes: spaceLeft); 
699 ConsumeChunk(h, p: state->Chunk); 
700 pos = state->Chunk
701 spaceLeft = ChunkSizeBytes
702
703 const int left = spaceLeft - TotalLenLen
704 tStd::tMemset(dest: pos, val: 0x00, numBytes: left); 
705 pos += left
706 int len = state->TotalLen
707 pos[7] = uint8(len << 3); 
708 len >>= 5
709 
710 for (int i = 6; i >= 0; --i
711
712 pos[i] = uint8(len); 
713 len >>= 8
714
715 ConsumeChunk(h, p: state->Chunk); 
716 
717 int j = 0
718 uint8* hash = state->Hash
719 for (int i = 0; i < 8; i++) 
720
721 hash[j++] = uint8(h[i] >> 24); 
722 hash[j++] = uint8(h[i] >> 16); 
723 hash[j++] = uint8(h[i] >> 8); 
724 hash[j++] = uint8(h[i]); 
725
726 return state->Hash
727
728 
729 
730void tHash_SHA256::Calc(uint8 hash[HashSizeBytes], const uint8* input, int len, tuint256 iv
731
732 State state
733 Init(state: &state, hash, iv); 
734 Write(state: &state, data: input, len); 
735 Close(state: &state); 
736
737 
738 
739tuint256 tHash::tHashDataSHA256(const uint8* data, int length, tuint256 iv
740
741 uint8 hash[tHash_SHA256::HashSizeBytes]; 
742 tStd::tMemset(dest: hash, val: 0, numBytes: tHash_SHA256::HashSizeBytes); 
743 
744 tHash_SHA256::Calc(hash, input: data, len: length, iv); 
745 tuint256 result
746 result.SetFromBytes(hash); 
747 
748 return result
749
750