// Salsa hash function. Get seq array static void salsa20(uint8_t seq[64]) { uint32_t x[16], z[16]; int i, j; for(i = 0; i < 16; i++) x[i] = z[i] = LITTLEENDIAN((seq + (i * 4))); for(i = 0; i < 10; i++) doubleround(z); j = 0; for(i = 0; i < 16; i++) { z[i] += x[i]; seq[j++] = (uint8_t)(z[i]); seq[j++] = (uint8_t)(z[i] >> 8); seq[j++] = (uint8_t)(z[i] >> 16); seq[j++] = (uint8_t)(z[i] >> 24); } }
/// process 64 bytes void MD5::processBlock(const void* data) { // get last hash uint32_t a = m_hash[0]; uint32_t b = m_hash[1]; uint32_t c = m_hash[2]; uint32_t d = m_hash[3]; // data represented as 16x 32-bit words const uint32_t* words = (uint32_t*) data; // computations are little endian, swap data if necessary #if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN) #define LITTLEENDIAN(x) swap(x) #else #define LITTLEENDIAN(x) (x) #endif // first round uint32_t word0 = LITTLEENDIAN(words[ 0]); a = rotate(a + f1(b,c,d) + word0 + 0xd76aa478, 7) + b; uint32_t word1 = LITTLEENDIAN(words[ 1]); d = rotate(d + f1(a,b,c) + word1 + 0xe8c7b756, 12) + a; uint32_t word2 = LITTLEENDIAN(words[ 2]); c = rotate(c + f1(d,a,b) + word2 + 0x242070db, 17) + d; uint32_t word3 = LITTLEENDIAN(words[ 3]); b = rotate(b + f1(c,d,a) + word3 + 0xc1bdceee, 22) + c; uint32_t word4 = LITTLEENDIAN(words[ 4]); a = rotate(a + f1(b,c,d) + word4 + 0xf57c0faf, 7) + b; uint32_t word5 = LITTLEENDIAN(words[ 5]); d = rotate(d + f1(a,b,c) + word5 + 0x4787c62a, 12) + a; uint32_t word6 = LITTLEENDIAN(words[ 6]); c = rotate(c + f1(d,a,b) + word6 + 0xa8304613, 17) + d; uint32_t word7 = LITTLEENDIAN(words[ 7]); b = rotate(b + f1(c,d,a) + word7 + 0xfd469501, 22) + c; uint32_t word8 = LITTLEENDIAN(words[ 8]); a = rotate(a + f1(b,c,d) + word8 + 0x698098d8, 7) + b; uint32_t word9 = LITTLEENDIAN(words[ 9]); d = rotate(d + f1(a,b,c) + word9 + 0x8b44f7af, 12) + a; uint32_t word10 = LITTLEENDIAN(words[10]); c = rotate(c + f1(d,a,b) + word10 + 0xffff5bb1, 17) + d; uint32_t word11 = LITTLEENDIAN(words[11]); b = rotate(b + f1(c,d,a) + word11 + 0x895cd7be, 22) + c; uint32_t word12 = LITTLEENDIAN(words[12]); a = rotate(a + f1(b,c,d) + word12 + 0x6b901122, 7) + b; uint32_t word13 = LITTLEENDIAN(words[13]); d = rotate(d + f1(a,b,c) + word13 + 0xfd987193, 12) + a; uint32_t word14 = LITTLEENDIAN(words[14]); c = rotate(c + f1(d,a,b) + word14 + 0xa679438e, 17) + d; uint32_t word15 = LITTLEENDIAN(words[15]); b = rotate(b + f1(c,d,a) + word15 + 0x49b40821, 22) + c; // second round a = rotate(a + f2(b,c,d) + word1 + 0xf61e2562, 5) + b; d = rotate(d + f2(a,b,c) + word6 + 0xc040b340, 9) + a; c = rotate(c + f2(d,a,b) + word11 + 0x265e5a51, 14) + d; b = rotate(b + f2(c,d,a) + word0 + 0xe9b6c7aa, 20) + c; a = rotate(a + f2(b,c,d) + word5 + 0xd62f105d, 5) + b; d = rotate(d + f2(a,b,c) + word10 + 0x02441453, 9) + a; c = rotate(c + f2(d,a,b) + word15 + 0xd8a1e681, 14) + d; b = rotate(b + f2(c,d,a) + word4 + 0xe7d3fbc8, 20) + c; a = rotate(a + f2(b,c,d) + word9 + 0x21e1cde6, 5) + b; d = rotate(d + f2(a,b,c) + word14 + 0xc33707d6, 9) + a; c = rotate(c + f2(d,a,b) + word3 + 0xf4d50d87, 14) + d; b = rotate(b + f2(c,d,a) + word8 + 0x455a14ed, 20) + c; a = rotate(a + f2(b,c,d) + word13 + 0xa9e3e905, 5) + b; d = rotate(d + f2(a,b,c) + word2 + 0xfcefa3f8, 9) + a; c = rotate(c + f2(d,a,b) + word7 + 0x676f02d9, 14) + d; b = rotate(b + f2(c,d,a) + word12 + 0x8d2a4c8a, 20) + c; // third round a = rotate(a + f3(b,c,d) + word5 + 0xfffa3942, 4) + b; d = rotate(d + f3(a,b,c) + word8 + 0x8771f681, 11) + a; c = rotate(c + f3(d,a,b) + word11 + 0x6d9d6122, 16) + d; b = rotate(b + f3(c,d,a) + word14 + 0xfde5380c, 23) + c; a = rotate(a + f3(b,c,d) + word1 + 0xa4beea44, 4) + b; d = rotate(d + f3(a,b,c) + word4 + 0x4bdecfa9, 11) + a; c = rotate(c + f3(d,a,b) + word7 + 0xf6bb4b60, 16) + d; b = rotate(b + f3(c,d,a) + word10 + 0xbebfbc70, 23) + c; a = rotate(a + f3(b,c,d) + word13 + 0x289b7ec6, 4) + b; d = rotate(d + f3(a,b,c) + word0 + 0xeaa127fa, 11) + a; c = rotate(c + f3(d,a,b) + word3 + 0xd4ef3085, 16) + d; b = rotate(b + f3(c,d,a) + word6 + 0x04881d05, 23) + c; a = rotate(a + f3(b,c,d) + word9 + 0xd9d4d039, 4) + b; d = rotate(d + f3(a,b,c) + word12 + 0xe6db99e5, 11) + a; c = rotate(c + f3(d,a,b) + word15 + 0x1fa27cf8, 16) + d; b = rotate(b + f3(c,d,a) + word2 + 0xc4ac5665, 23) + c; // fourth round a = rotate(a + f4(b,c,d) + word0 + 0xf4292244, 6) + b; d = rotate(d + f4(a,b,c) + word7 + 0x432aff97, 10) + a; c = rotate(c + f4(d,a,b) + word14 + 0xab9423a7, 15) + d; b = rotate(b + f4(c,d,a) + word5 + 0xfc93a039, 21) + c; a = rotate(a + f4(b,c,d) + word12 + 0x655b59c3, 6) + b; d = rotate(d + f4(a,b,c) + word3 + 0x8f0ccc92, 10) + a; c = rotate(c + f4(d,a,b) + word10 + 0xffeff47d, 15) + d; b = rotate(b + f4(c,d,a) + word1 + 0x85845dd1, 21) + c; a = rotate(a + f4(b,c,d) + word8 + 0x6fa87e4f, 6) + b; d = rotate(d + f4(a,b,c) + word15 + 0xfe2ce6e0, 10) + a; c = rotate(c + f4(d,a,b) + word6 + 0xa3014314, 15) + d; b = rotate(b + f4(c,d,a) + word13 + 0x4e0811a1, 21) + c; a = rotate(a + f4(b,c,d) + word4 + 0xf7537e82, 6) + b; d = rotate(d + f4(a,b,c) + word11 + 0xbd3af235, 10) + a; c = rotate(c + f4(d,a,b) + word2 + 0x2ad7d2bb, 15) + d; b = rotate(b + f4(c,d,a) + word9 + 0xeb86d391, 21) + c; // update hash m_hash[0] += a; m_hash[1] += b; m_hash[2] += c; m_hash[3] += d; }
/// process a full block void Keccak::processBlock(const void* data) { #if defined(__BYTE_ORDER) && (__BYTE_ORDER != 0) && (__BYTE_ORDER == __BIG_ENDIAN) #define LITTLEENDIAN(x) swap(x) #else #define LITTLEENDIAN(x) (x) #endif const uint64_t* data64 = (const uint64_t*) data; // mix data into state for (unsigned int i = 0; i < m_blockSize / 8; i++) m_hash[i] ^= LITTLEENDIAN(data64[i]); // re-compute state for (unsigned int round = 0; round < KeccakRounds; round++) { // Theta uint64_t coefficients[5]; for (unsigned int i = 0; i < 5; i++) coefficients[i] = m_hash[i] ^ m_hash[i + 5] ^ m_hash[i + 10] ^ m_hash[i + 15] ^ m_hash[i + 20]; for (unsigned int i = 0; i < 5; i++) { uint64_t one = coefficients[mod5(i + 4)] ^ rotateLeft(coefficients[mod5(i + 1)], 1); m_hash[i ] ^= one; m_hash[i + 5] ^= one; m_hash[i + 10] ^= one; m_hash[i + 15] ^= one; m_hash[i + 20] ^= one; } // temporary uint64_t one; // Rho Pi uint64_t last = m_hash[1]; one = m_hash[10]; m_hash[10] = rotateLeft(last, 1); last = one; one = m_hash[ 7]; m_hash[ 7] = rotateLeft(last, 3); last = one; one = m_hash[11]; m_hash[11] = rotateLeft(last, 6); last = one; one = m_hash[17]; m_hash[17] = rotateLeft(last, 10); last = one; one = m_hash[18]; m_hash[18] = rotateLeft(last, 15); last = one; one = m_hash[ 3]; m_hash[ 3] = rotateLeft(last, 21); last = one; one = m_hash[ 5]; m_hash[ 5] = rotateLeft(last, 28); last = one; one = m_hash[16]; m_hash[16] = rotateLeft(last, 36); last = one; one = m_hash[ 8]; m_hash[ 8] = rotateLeft(last, 45); last = one; one = m_hash[21]; m_hash[21] = rotateLeft(last, 55); last = one; one = m_hash[24]; m_hash[24] = rotateLeft(last, 2); last = one; one = m_hash[ 4]; m_hash[ 4] = rotateLeft(last, 14); last = one; one = m_hash[15]; m_hash[15] = rotateLeft(last, 27); last = one; one = m_hash[23]; m_hash[23] = rotateLeft(last, 41); last = one; one = m_hash[19]; m_hash[19] = rotateLeft(last, 56); last = one; one = m_hash[13]; m_hash[13] = rotateLeft(last, 8); last = one; one = m_hash[12]; m_hash[12] = rotateLeft(last, 25); last = one; one = m_hash[ 2]; m_hash[ 2] = rotateLeft(last, 43); last = one; one = m_hash[20]; m_hash[20] = rotateLeft(last, 62); last = one; one = m_hash[14]; m_hash[14] = rotateLeft(last, 18); last = one; one = m_hash[22]; m_hash[22] = rotateLeft(last, 39); last = one; one = m_hash[ 9]; m_hash[ 9] = rotateLeft(last, 61); last = one; one = m_hash[ 6]; m_hash[ 6] = rotateLeft(last, 20); last = one; m_hash[ 1] = rotateLeft(last, 44); // Chi for (unsigned int j = 0; j < 25; j += 5) { // temporaries uint64_t one = m_hash[j]; uint64_t two = m_hash[j + 1]; m_hash[j] ^= m_hash[j + 2] & ~two; m_hash[j + 1] ^= m_hash[j + 3] & ~m_hash[j + 2]; m_hash[j + 2] ^= m_hash[j + 4] & ~m_hash[j + 3]; m_hash[j + 3] ^= one & ~m_hash[j + 4]; m_hash[j + 4] ^= two & ~one; } // Iota m_hash[0] ^= XorMasks[round]; } }