23inline uint32_t leftrot(uint32_t
x, uint8_t amount)
25 return (
x << amount) | (
x >> (32 - amount));
28inline uint32_t rightrot(uint32_t
x, uint8_t amount)
30 return (
x >> amount) | (
x << (32 - amount));
33inline uint64_t rightrot(uint64_t
x, uint8_t amount)
35 return (
x >> amount) | (
x << (64 - amount));
48 static const uint8_t shifts[64];
49 static const uint32_t constants[64];
52 bool isSupported(std::string function)
const override
54 return function ==
"md5";
57 void hash(std::string function,
const char *input, uint64_t length, Value &output)
const override
59 if (function !=
"md5")
60 throw eve::Exception(
"Hash function not supported by MD5 implementation");
62 uint32_t a0 = 0x67452301;
63 uint32_t b0 = 0xefcdab89;
64 uint32_t c0 = 0x98badcfe;
65 uint32_t d0 = 0x10325476;
68 uint64_t paddedLength = length + 1;
69 if (paddedLength % 64 < 56)
70 paddedLength += 56 - paddedLength % 64;
71 if (paddedLength % 64 > 56)
72 paddedLength += 120 - paddedLength % 64;
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;
80 *((uint64_t*) &padded[paddedLength]) = length * 8;
83 for (uint64_t i = 0; i < paddedLength; i += 64)
85 uint32_t *chunk = (uint32_t*) &padded[i];
94 for (
int j = 0; j < 64; j++)
98 F = (B & C) | (~B & D);
103 F = (D & B) | (~D & C);
120 B += leftrot(A + F + constants[j] + chunk[g], shifts[j]);
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);
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,
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,
174 bool isSupported(std::string function)
const override
176 return function ==
"sha1";
179 void hash(std::string function,
const char *input, uint64_t length, Value &output)
const override
181 if (function !=
"sha1")
182 throw eve::Exception(
"Hash function not supported by SHA1 implementation");
184 uint32_t intermediate[5] = {
185 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0
189 uint64_t paddedLength = length + 1;
190 if (paddedLength % 64 < 56)
191 paddedLength += 56 - paddedLength % 64;
192 if (paddedLength % 64 > 56)
193 paddedLength += 120 - paddedLength % 64;
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;
202 for (
int i = 0; i < 8; ++i, ++paddedLength)
203 padded[paddedLength] = (length >> (56 - i * 8)) & 0xFF;
208 for (uint64_t i = 0; i < paddedLength; i += 64)
210 uint32_t *chunk = (uint32_t*) &padded[i];
211 for (
int j = 0; j < 16; j++)
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;
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);
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];
228 for (
int j = 0; j < 80; j++)
230 uint32_t
temp = leftrot(A, 5) + E + words[j];
233 temp += 0x5A827999 + ((B & C) | (~B & D));
235 temp += 0x6ED9EBA1 + (B ^ C ^ D);
237 temp += 0x8F1BBCDC + ((B & C) | (B & D) | (C & D));
239 temp += 0xCA62C1D6 + (B ^ C ^ D);
248 intermediate[0] += A;
249 intermediate[1] += B;
250 intermediate[2] += C;
251 intermediate[3] += D;
252 intermediate[4] += E;
257 for (
int i = 0; i < 20; i += 4)
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;
276 static const uint32_t initial224[8];
277 static const uint32_t initial256[8];
278 static const uint32_t constants[64];
281 bool isSupported(std::string function)
const override
283 return function ==
"sha224" || function ==
"sha256";
286 void hash(std::string function,
const char *input, uint64_t length, Value &output)
const override
288 if (!isSupported(function))
289 throw eve::Exception(
"Hash function not supported by SHA-224/SHA-256 implementation");
292 uint64_t paddedLength = length + 1;
293 if (paddedLength % 64 < 56)
294 paddedLength += 56 - paddedLength % 64;
295 if (paddedLength % 64 > 56)
296 paddedLength += 120 - paddedLength % 64;
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;
305 for (
int i = 0; i < 8; ++i, ++paddedLength)
306 padded[paddedLength] = (length >> (56 - i * 8)) & 0xFF;
308 uint32_t intermediate[8];
309 if (function ==
"sha224")
310 memcpy(intermediate, initial224,
sizeof(intermediate));
312 memcpy(intermediate, initial256,
sizeof(intermediate));
317 for (uint64_t i = 0; i < paddedLength; i += 64)
319 uint32_t *chunk = (uint32_t*) &padded[i];
320 for (
int j = 0; j < 16; j++)
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;
328 for (
int j = 16; j < 64; j++)
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];
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];
344 for (
int j = 0; j < 64; j++)
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);
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;
375 if (function ==
"sha224")
378 for (
int i = 0; i < hashlength; i += 4)
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;
386 output.size = hashlength;
390const uint32_t SHA256::initial224[8] = {
391 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
392 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
395const uint32_t SHA256::initial256[8] = {
396 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
397 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
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,
426 static const uint64_t initial384[8];
427 static const uint64_t initial512[8];
428 static const uint64_t constants[80];
431 bool isSupported(std::string function)
const override
433 return function ==
"sha384" || function ==
"sha512";
436 void hash(std::string function,
const char *input, uint64_t length, Value &output)
const override
438 if (!isSupported(function))
439 throw eve::Exception(
"Hash function not supported by SHA-384/SHA-512 implementation");
441 uint64_t intermediates[8];
442 if (function ==
"sha384")
443 memcpy(intermediates, initial384,
sizeof(intermediates));
445 memcpy(intermediates, initial512,
sizeof(intermediates));
448 uint64_t paddedLength = length + 1;
449 if (paddedLength % 128 < 112)
450 paddedLength += 112 - paddedLength % 128;
451 if (paddedLength % 128 > 112)
452 paddedLength += 240 - paddedLength % 128;
454 uint8_t *padded =
new uint8_t[paddedLength + 16];
456 memcpy(padded, input, length);
457 memset(padded + length, 0, paddedLength - length);
458 padded[length] = 0x80;
463 for (
int i = 0; i < 8; ++i, ++paddedLength)
464 padded[paddedLength] = (length >> (56 - i * 8)) & 0xFF;
469 for (uint64_t i = 0; i < paddedLength; i += 128)
471 uint64_t *chunk = (uint64_t*) &padded[i];
472 for (
int j = 0; j < 16; ++j)
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;
484 for (
int j = 16; j < 80; ++j)
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);
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];
500 for (
int j = 0; j < 80; ++j)
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);
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;
530 if (function ==
"sha384")
533 for (
int i = 0; i < hashlength; i += 8)
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;
545 output.size = hashlength;
549const uint64_t SHA512::initial384[8] = {
550 0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
551 0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4,
554const uint64_t SHA512::initial512[8] = {
555 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
556 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
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,