/* Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni, Joan Daemen, Michaƫl Peeters, Gilles Van Assche and Ronny Van Keer, hereby denoted as "the implementer". For more information, feedback or questions, please refer to our websites: http://keccak.noekeon.org/ http://keyak.noekeon.org/ http://ketje.noekeon.org/ To the extent possible under law, the implementer has waived all copyright and related or neighboring rights to the source code in this file. http://creativecommons.org/publicdomain/zero/1.0/ */ #define FOR(i,n) for(i=0; i> 1; } static u64 load64(const u8 *x) { ui i; u64 u = 0; FOR(i, 8) { u <<= 8; u |= x[7 - i]; } return u; } static void store64(u8 *x, u64 u) { ui i; FOR(i, 8) { x[i] = u; u >>= 8; } } static void xor64(u8 *x, u64 u) { ui i; FOR(i, 8) { x[i] ^= u; u >>= 8; } } #define rL(x, y) load64((u8*)s + 8 * (x + 5 * y)) #define wL(x, y, l) store64((u8*)s + 8 * (x + 5 * y), l) #define XL(x, y, l) xor64((u8*)s + 8 * (x + 5 * y), l) #define ROL(a, o) ((((u64)a) << o) ^ (((u64)a) >> (64 - o))) static void KeccakF1600(void *s) { ui r, x, y, i, j, Y; u8 R = 0x01; u64 C[5], D; for (i = 0; i < 24; i++) { FOR(x, 5) C[x] = rL(x, 0) ^ rL(x, 1) ^ rL(x, 2) ^ rL(x, 3) ^ rL(x, 4); FOR(x, 5) { D = C[(x + 4) % 5] ^ ROL(C[(x + 1) % 5], 1); FOR(y, 5) XL(x, y, D); } x = 1; y = r = 0; D = rL(x, y); FOR(j, 24) { r += j + 1; Y = (2 * x + 3 * y) % 5; x = y; y = Y; C[0] = rL(x, y); wL(x, y, ROL(D, r % 64)); D = C[0]; } FOR(y, 5) { FOR(x, 5) C[x] = rL(x, y); FOR(x, 5) wL(x, y, C[x] ^ ((~C[(x + 1) % 5]) & C[(x + 2) % 5])); } FOR(j, 7) if (LFSR86540(&R)) XL(0, 0, (u64)1 << ((1 << j) - 1)); } } static void Keccak(ui r, const u8 *in, u64 inLen, u8 sfx, u8 *out, u64 outLen) { u8 s[200]; ui R = r / 8; ui i, b = 0; FOR(i, 200) s[i] = 0; /* absorb */ while (inLen > 0) { b = (inLen < R)? inLen : R; FOR(i, b) s[i] ^= in[i]; in += b; inLen -= b; if (b == R) { KeccakF1600(s); b = 0; } } /* pad */ s[b] ^= sfx; if ((sfx & 0x80) && (b == (R - 1))) KeccakF1600(s); s[R - 1] ^= 0x80; KeccakF1600(s); /* squeeze */ while (outLen > 0) { b = (outLen < R)? outLen : R; FOR(i, b) out[i] = s[i]; out += b; outLen -= b; if (outLen > 0) KeccakF1600(s); } } /** * Compute the hash value for osl version 2 tables. * * \param data Pointer to the data to compute the hash value from. * \param len The length of \a data in bytes. * \param result must point to an area at least 20 bytes large. */ void sha3_hash(const char *data, unsigned long len, unsigned char *result) { Keccak(1152, (const u8*)data, len, 0x06, result, 20); }