X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=sha3.c;fp=sha3.c;h=aa83b8a0f9a0ed52afb6cfaa7955820b65aafd4a;hb=54a55d51c5919dbac29f42e2b1ab9403785e48f7;hp=0000000000000000000000000000000000000000;hpb=6811bf3ef3f157e82c189f22e0b5cedd8a8ba1db;p=osl.git diff --git a/sha3.c b/sha3.c new file mode 100644 index 0000000..aa83b8a --- /dev/null +++ b/sha3.c @@ -0,0 +1,157 @@ +/* +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/ +*/ + +/* + * Note for osl + * ~~~~~~~~~~~~ + * This is NOT the hash function which will eventually be part of an osl + * release. It will be replaced by whatever git comes up as the successor of + * sha1. This hash function is FOR TESTING ONLY. + */ + +#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); +}