载入中...
搜索中...
未找到
HashFunction.cpp
浏览该文件的文档.
1
2
3#include "HashFunction.h"
4#include "common/Exception.h"
5
6#include <cstring>
7
8// FIXME: Probably trivial by having tole and tobe functions, which can be ifdeffed to being identity functions
9#ifdef LOVE_BIG_ENDIAN
10# error Hashing not yet implemented for big endian
11#endif
12
13namespace eve
14{
15namespace data
16{
17
18namespace
19{
20namespace impl
21{
22
23inline uint32_t leftrot(uint32_t x, uint8_t amount)
24{
25 return (x << amount) | (x >> (32 - amount));
26}
27
28inline uint32_t rightrot(uint32_t x, uint8_t amount)
29{
30 return (x >> amount) | (x << (32 - amount));
31}
32
33inline uint64_t rightrot(uint64_t x, uint8_t amount)
34{
35 return (x >> amount) | (x << (64 - amount));
36}
37
45class MD5 : public HashFunction
46{
47private:
48 static const uint8_t shifts[64];
49 static const uint32_t constants[64];
50
51public:
52 bool isSupported(std::string function) const override
53 {
54 return function == "md5";
55 }
56
57 void hash(std::string function, const char *input, uint64_t length, Value &output) const override
58 {
59 if (function != "md5")
60 throw eve::Exception("Hash function not supported by MD5 implementation");
61
62 uint32_t a0 = 0x67452301;
63 uint32_t b0 = 0xefcdab89;
64 uint32_t c0 = 0x98badcfe;
65 uint32_t d0 = 0x10325476;
66
67 //Do the required padding (MD5, SHA1 and SHA2 use the same padding)
68 uint64_t paddedLength = length + 1; //Consider the appended bit
69 if (paddedLength % 64 < 56)
70 paddedLength += 56 - paddedLength % 64;
71 if (paddedLength % 64 > 56)
72 paddedLength += 120 - paddedLength % 64;
73
74 uint8_t *padded = new uint8_t[paddedLength + 8];
75 memcpy(padded, input, length);
76 memset(padded + length, 0, paddedLength - length);
77 padded[length] = 0x80;
78
79 //Now we need the length in bits
80 *((uint64_t*) &padded[paddedLength]) = length * 8;
81 paddedLength += 8;
82
83 for (uint64_t i = 0; i < paddedLength; i += 64)
84 {
85 uint32_t *chunk = (uint32_t*) &padded[i];
86
87 uint32_t A = a0;
88 uint32_t B = b0;
89 uint32_t C = c0;
90 uint32_t D = d0;
91 uint32_t F;
92 uint32_t g;
93
94 for (int j = 0; j < 64; j++)
95 {
96 if (j < 16)
97 {
98 F = (B & C) | (~B & D);
99 g = j;
100 }
101 else if (j < 32)
102 {
103 F = (D & B) | (~D & C);
104 g = (5*j + 1) % 16;
105 }
106 else if (j < 48)
107 {
108 F = B ^ C ^ D;
109 g = (3*j + 5) % 16;
110 }
111 else
112 {
113 F = C ^ (B | ~D);
114 g = (7*j) % 16;
115 }
116
117 uint32_t temp = D;
118 D = C;
119 C = B;
120 B += leftrot(A + F + constants[j] + chunk[g], shifts[j]);
121 A = temp;
122 }
123
124 a0 += A;
125 b0 += B;
126 c0 += C;
127 d0 += D;
128 }
129
130 delete[] padded;
131
132 memcpy(&output.data[ 0], &a0, 4);
133 memcpy(&output.data[ 4], &b0, 4);
134 memcpy(&output.data[ 8], &c0, 4);
135 memcpy(&output.data[12], &d0, 4);
136 output.size = 16;
137 }
138} md5;
139
140const uint8_t MD5::shifts[64] = {
141 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
142 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
143 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
144 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21,
145};
146
147const uint32_t MD5::constants[64] = {
148 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
149 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
150 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
151 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
152 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
153 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
154 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
155 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
156 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
157 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
158 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
159 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
160 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
161 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
162 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
163 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
164};
165
171class SHA1 : public HashFunction
172{
173public:
174 bool isSupported(std::string function) const override
175 {
176 return function == "sha1";
177 }
178
179 void hash(std::string function, const char *input, uint64_t length, Value &output) const override
180 {
181 if (function != "sha1")
182 throw eve::Exception("Hash function not supported by SHA1 implementation");
183
184 uint32_t intermediate[5] = {
185 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
186 };
187
188 //Do the required padding (MD5, SHA1 and SHA2 use the same padding)
189 uint64_t paddedLength = length + 1; //Consider the appended bit
190 if (paddedLength % 64 < 56)
191 paddedLength += 56 - paddedLength % 64;
192 if (paddedLength % 64 > 56)
193 paddedLength += 120 - paddedLength % 64;
194
195 uint8_t *padded = new uint8_t[paddedLength + 8];
196 memcpy(padded, input, length);
197 memset(padded + length, 0, paddedLength - length);
198 padded[length] = 0x80;
199
200 // Now we need the length in bits (big endian)
201 length *= 8;
202 for (int i = 0; i < 8; ++i, ++paddedLength)
203 padded[paddedLength] = (length >> (56 - i * 8)) & 0xFF;
204
205 // Allocate our extended words
206 uint32_t words[80];
207
208 for (uint64_t i = 0; i < paddedLength; i += 64)
209 {
210 uint32_t *chunk = (uint32_t*) &padded[i];
211 for (int j = 0; j < 16; j++)
212 {
213 char *c = (char*) &words[j];
214 c[0] = (chunk[j] >> 24) & 0xFF;
215 c[1] = (chunk[j] >> 16) & 0xFF;
216 c[2] = (chunk[j] >> 8) & 0xFF;
217 c[3] = (chunk[j] >> 0) & 0xFF;
218 }
219 for (int j = 16; j < 80; j++)
220 words[j] = leftrot(words[j-3] ^ words[j-8] ^ words[j-14] ^ words[j-16], 1);
221
222 uint32_t A = intermediate[0];
223 uint32_t B = intermediate[1];
224 uint32_t C = intermediate[2];
225 uint32_t D = intermediate[3];
226 uint32_t E = intermediate[4];
227
228 for (int j = 0; j < 80; j++)
229 {
230 uint32_t temp = leftrot(A, 5) + E + words[j];
231
232 if (j < 20)
233 temp += 0x5A827999 + ((B & C) | (~B & D));
234 else if (j < 40)
235 temp += 0x6ED9EBA1 + (B ^ C ^ D);
236 else if (j < 60)
237 temp += 0x8F1BBCDC + ((B & C) | (B & D) | (C & D));
238 else
239 temp += 0xCA62C1D6 + (B ^ C ^ D);
240
241 E = D;
242 D = C;
243 C = leftrot(B, 30);
244 B = A;
245 A = temp;
246 }
247
248 intermediate[0] += A;
249 intermediate[1] += B;
250 intermediate[2] += C;
251 intermediate[3] += D;
252 intermediate[4] += E;
253 }
254
255 delete[] padded;
256
257 for (int i = 0; i < 20; i += 4)
258 {
259 output.data[i+0] = (intermediate[i/4] >> 24) & 0xFF;
260 output.data[i+1] = (intermediate[i/4] >> 16) & 0xFF;
261 output.data[i+2] = (intermediate[i/4] >> 8) & 0xFF;
262 output.data[i+3] = (intermediate[i/4] >> 0) & 0xFF;
263 }
264
265 output.size = 20;
266 }
267} sha1;
268
272// SHA-2: SHA-224 and SHA-256
273class SHA256 : public HashFunction
274{
275private:
276 static const uint32_t initial224[8];
277 static const uint32_t initial256[8];
278 static const uint32_t constants[64];
279
280public:
281 bool isSupported(std::string function) const override
282 {
283 return function == "sha224" || function == "sha256";
284 }
285
286 void hash(std::string function, const char *input, uint64_t length, Value &output) const override
287 {
288 if (!isSupported(function))
289 throw eve::Exception("Hash function not supported by SHA-224/SHA-256 implementation");
290
291 //Do the required padding (MD5, SHA1 and SHA2 use the same padding)
292 uint64_t paddedLength = length + 1; //Consider the appended bit
293 if (paddedLength % 64 < 56)
294 paddedLength += 56 - paddedLength % 64;
295 if (paddedLength % 64 > 56)
296 paddedLength += 120 - paddedLength % 64;
297
298 uint8_t *padded = new uint8_t[paddedLength + 8];
299 memcpy(padded, input, length);
300 memset(padded + length, 0, paddedLength - length);
301 padded[length] = 0x80;
302
303 // Now we need the length in bits (big endian)
304 length *= 8;
305 for (int i = 0; i < 8; ++i, ++paddedLength)
306 padded[paddedLength] = (length >> (56 - i * 8)) & 0xFF;
307
308 uint32_t intermediate[8];
309 if (function == "sha224")
310 memcpy(intermediate, initial224, sizeof(intermediate));
311 else
312 memcpy(intermediate, initial256, sizeof(intermediate));
313
314 // Allocate our extended words
315 uint32_t words[64];
316
317 for (uint64_t i = 0; i < paddedLength; i += 64)
318 {
319 uint32_t *chunk = (uint32_t*) &padded[i];
320 for (int j = 0; j < 16; j++)
321 {
322 char *c = (char*) &words[j];
323 c[0] = (chunk[j] >> 24) & 0xFF;
324 c[1] = (chunk[j] >> 16) & 0xFF;
325 c[2] = (chunk[j] >> 8) & 0xFF;
326 c[3] = (chunk[j] >> 0) & 0xFF;
327 }
328 for (int j = 16; j < 64; j++)
329 {
330 words[j] = rightrot(words[j-2], 17) ^ rightrot(words[j-2], 19) ^ (words[j-2] >> 10);
331 words[j] += rightrot(words[j-15], 7) ^ rightrot(words[j-15], 18) ^ (words[j-15] >> 3);
332 words[j] += words[j-7] + words[j-16];
333 }
334
335 uint32_t A = intermediate[0];
336 uint32_t B = intermediate[1];
337 uint32_t C = intermediate[2];
338 uint32_t D = intermediate[3];
339 uint32_t E = intermediate[4];
340 uint32_t F = intermediate[5];
341 uint32_t G = intermediate[6];
342 uint32_t H = intermediate[7];
343
344 for (int j = 0; j < 64; j++)
345 {
346 uint32_t temp1 = H + constants[j] + words[j];
347 temp1 += rightrot(E, 6) ^ rightrot(E, 11) ^ rightrot(E, 25);
348 temp1 += (E & F) ^ (~E & G);
349 uint32_t temp2 = rightrot(A, 2) ^ rightrot(A, 13) ^ rightrot(A, 22);
350 temp2 += (A & B) ^ (A & C) ^ (B & C);
351
352 H = G;
353 G = F;
354 F = E;
355 E = D + temp1;
356 D = C;
357 C = B;
358 B = A;
359 A = temp1 + temp2;
360 }
361
362 intermediate[0] += A;
363 intermediate[1] += B;
364 intermediate[2] += C;
365 intermediate[3] += D;
366 intermediate[4] += E;
367 intermediate[5] += F;
368 intermediate[6] += G;
369 intermediate[7] += H;
370 }
371
372 delete[] padded;
373
374 int hashlength = 32;
375 if (function == "sha224")
376 hashlength = 28;
377
378 for (int i = 0; i < hashlength; i += 4)
379 {
380 output.data[i+0] = (intermediate[i/4] >> 24) & 0xFF;
381 output.data[i+1] = (intermediate[i/4] >> 16) & 0xFF;
382 output.data[i+2] = (intermediate[i/4] >> 8) & 0xFF;
383 output.data[i+3] = (intermediate[i/4] >> 0) & 0xFF;
384 }
385
386 output.size = hashlength;
387 }
388} sha256;
389
390const uint32_t SHA256::initial224[8] = {
391 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
392 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
393};
394
395const uint32_t SHA256::initial256[8] = {
396 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
397 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
398};
399
400const uint32_t SHA256::constants[64] = {
401 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
402 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
403 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
404 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
405 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
406 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
407 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
408 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
409 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
410 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
411 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
412 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
413 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
414 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
415 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
416 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
417};
418
422// SHA-2: SHA-384 and SHA-512
423class SHA512 : public HashFunction
424{
425private:
426 static const uint64_t initial384[8];
427 static const uint64_t initial512[8];
428 static const uint64_t constants[80];
429
430public:
431 bool isSupported(std::string function) const override
432 {
433 return function == "sha384" || function == "sha512";
434 }
435
436 void hash(std::string function, const char *input, uint64_t length, Value &output) const override
437 {
438 if (!isSupported(function))
439 throw eve::Exception("Hash function not supported by SHA-384/SHA-512 implementation");
440
441 uint64_t intermediates[8];
442 if (function == "sha384")
443 memcpy(intermediates, initial384, sizeof(intermediates));
444 else
445 memcpy(intermediates, initial512, sizeof(intermediates));
446
447 //Do the required padding
448 uint64_t paddedLength = length + 1; //Consider the appended bit
449 if (paddedLength % 128 < 112)
450 paddedLength += 112 - paddedLength % 128;
451 if (paddedLength % 128 > 112)
452 paddedLength += 240 - paddedLength % 128;
453
454 uint8_t *padded = new uint8_t[paddedLength + 16];
455 paddedLength += 8;
456 memcpy(padded, input, length);
457 memset(padded + length, 0, paddedLength - length);
458 padded[length] = 0x80;
459
460 // Now we need the length in bits (big endian), note we only write a 64-bit int, so
461 // we have filled the first 8 bytes with zeroes
462 length *= 8;
463 for (int i = 0; i < 8; ++i, ++paddedLength)
464 padded[paddedLength] = (length >> (56 - i * 8)) & 0xFF;
465
466 // Allocate our extended words
467 uint64_t words[80];
468
469 for (uint64_t i = 0; i < paddedLength; i += 128)
470 {
471 uint64_t *chunk = (uint64_t*) &padded[i];
472 for (int j = 0; j < 16; ++j)
473 {
474 char *c = (char*) &words[j];
475 c[0] = (chunk[j] >> 56) & 0xFF;
476 c[1] = (chunk[j] >> 48) & 0xFF;
477 c[2] = (chunk[j] >> 40) & 0xFF;
478 c[3] = (chunk[j] >> 32) & 0xFF;
479 c[4] = (chunk[j] >> 24) & 0xFF;
480 c[5] = (chunk[j] >> 16) & 0xFF;
481 c[6] = (chunk[j] >> 8) & 0xFF;
482 c[7] = (chunk[j] >> 0) & 0xFF;
483 }
484 for (int j = 16; j < 80; ++j)
485 {
486 words[j] = words[j-7] + words[j-16];
487 words[j] += rightrot(words[j-2], 19) ^ rightrot(words[j-2], 61) ^ (words[j-2] >> 6);
488 words[j] += rightrot(words[j-15], 1) ^ rightrot(words[j-15], 8) ^ (words[j-15] >> 7);
489 }
490
491 uint64_t A = intermediates[0];
492 uint64_t B = intermediates[1];
493 uint64_t C = intermediates[2];
494 uint64_t D = intermediates[3];
495 uint64_t E = intermediates[4];
496 uint64_t F = intermediates[5];
497 uint64_t G = intermediates[6];
498 uint64_t H = intermediates[7];
499
500 for (int j = 0; j < 80; ++j)
501 {
502 uint64_t temp1 = H + constants[j] + words[j];
503 temp1 += rightrot(E, 14) ^ rightrot(E, 18) ^ rightrot(E, 41);
504 temp1 += (E & F) ^ (~E & G);
505 uint64_t temp2 = rightrot(A, 28) ^ rightrot(A, 34) ^ rightrot(A, 39);
506 temp2 += (A & B) ^ (A & C) ^ (B & C);
507 H = G;
508 G = F;
509 F = E;
510 E = D + temp1;
511 D = C;
512 C = B;
513 B = A;
514 A = temp1 + temp2;
515 }
516
517 intermediates[0] += A;
518 intermediates[1] += B;
519 intermediates[2] += C;
520 intermediates[3] += D;
521 intermediates[4] += E;
522 intermediates[5] += F;
523 intermediates[6] += G;
524 intermediates[7] += H;
525 }
526
527 delete[] padded;
528
529 int hashlength = 64;
530 if (function == "sha384")
531 hashlength = 48;
532
533 for (int i = 0; i < hashlength; i += 8)
534 {
535 output.data[i+0] = (intermediates[i/8] >> 56) & 0xFF;
536 output.data[i+1] = (intermediates[i/8] >> 48) & 0xFF;
537 output.data[i+2] = (intermediates[i/8] >> 40) & 0xFF;
538 output.data[i+3] = (intermediates[i/8] >> 32) & 0xFF;
539 output.data[i+4] = (intermediates[i/8] >> 24) & 0xFF;
540 output.data[i+5] = (intermediates[i/8] >> 16) & 0xFF;
541 output.data[i+6] = (intermediates[i/8] >> 8) & 0xFF;
542 output.data[i+7] = (intermediates[i/8] >> 0) & 0xFF;
543 }
544
545 output.size = hashlength;
546 }
547} sha512;
548
549const uint64_t SHA512::initial384[8] = {
550 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
551 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4,
552};
553
554const uint64_t SHA512::initial512[8] = {
555 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
556 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
557};
558
559const uint64_t SHA512::constants[80] = {
560 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
561 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
562 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
563 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
564 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
565 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
566 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
567 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
568 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
569 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
570 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
571 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
572 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
573 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
574 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
575 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
576 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
577 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
578 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
579 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
580};
581
582} // impl
583}
584
586{
587 if (function == "md5")
588 return &impl::md5;
589 if (function == "sha1")
590 return &impl::sha1;
591 if (function == "sha224" || function == "sha256")
592 return &impl::sha256;
593 if (function == "sha384" || function == "sha512")
594 return &impl::sha512;
595 return nullptr;
596}
597
598} // data
599} // eve
void * impl
int x
Definition Grass.cpp:135
int temp
uint32_t c
Light2D::Data * data
static HashFunction * getHashFunction(std::string function)
Get a HashFunction instance for the given function.
std::string hash(std::string function, Data *input)
Hash the input, producing an set of bytes as output.
Definition Build.cpp:11