diff options
Diffstat (limited to '')
-rw-r--r-- | 1600.c | 92 |
1 files changed, 92 insertions, 0 deletions
@@ -0,0 +1,92 @@ +/* See LICENSE file for copyright and license details. */ + + +/** + * 64-bit Keccak-f round constants + */ +static const uint64_t rc64[] = { + UINT64_C(0x0000000000000001), UINT64_C(0x0000000000008082), UINT64_C(0x800000000000808A), UINT64_C(0x8000000080008000), + UINT64_C(0x000000000000808B), UINT64_C(0x0000000080000001), UINT64_C(0x8000000080008081), UINT64_C(0x8000000000008009), + UINT64_C(0x000000000000008A), UINT64_C(0x0000000000000088), UINT64_C(0x0000000080008009), UINT64_C(0x000000008000000A), + UINT64_C(0x000000008000808B), UINT64_C(0x800000000000008B), UINT64_C(0x8000000000008089), UINT64_C(0x8000000000008003), + UINT64_C(0x8000000000008002), UINT64_C(0x8000000000000080), UINT64_C(0x000000000000800A), UINT64_C(0x800000008000000A), + UINT64_C(0x8000000080008081), UINT64_C(0x8000000000008080), UINT64_C(0x0000000080000001), UINT64_C(0x8000000080008008) +}; + + +/** + * Rotate a 64-bit word + * + * @param x:uint64_t The value to rotate + * @param n:long int Rotation steps, may not be zero + * @return :uint64_t The value rotated + */ +#define rotate64(x, n) ((uint64_t)(((uint64_t)(x) >> (64L - (n))) | ((uint64_t)(x) << (n)))) + + +/** + * 64-bit word version of `libkeccak_f_round` + * + * @param state The hashing state + * @param rc The round contant for this round + */ +LIBKECCAK_GCC_ONLY(__attribute__((__nonnull__, __nothrow__, __hot__))) +static void +libkeccak_f_round64(register struct libkeccak_state *state, register uint64_t rc) +{ + uint64_t *restrict A = state->S.w64; + uint64_t B[25], C[5], da, db, dc, dd, de; + + /* θ step (step 1 of 3). */ +#define X(N) C[N] = A[N * 5] ^ A[N * 5 + 1] ^ A[N * 5 + 2] ^ A[N * 5 + 3] ^ A[N * 5 + 4] + LIST_5(X, ;); +#undef X + + /* θ step (step 2 of 3). */ + da = C[4] ^ rotate64(C[1], 1); + dd = C[2] ^ rotate64(C[4], 1); + db = C[0] ^ rotate64(C[2], 1); + de = C[3] ^ rotate64(C[0], 1); + dc = C[1] ^ rotate64(C[3], 1); + + /* ρ and π steps, with last two part of θ. */ +#define X(bi, ai, dv, r) B[bi] = rotate64(A[ai] ^ dv, r) + B[0] = A[0] ^ da; X( 1, 15, dd, 28); X( 2, 5, db, 1); X( 3, 20, de, 27); X( 4, 10, dc, 62); + X( 5, 6, db, 44); X( 6, 21, de, 20); X( 7, 11, dc, 6); X( 8, 1, da, 36); X( 9, 16, dd, 55); + X(10, 12, dc, 43); X(11, 2, da, 3); X(12, 17, dd, 25); X(13, 7, db, 10); X(14, 22, de, 39); + X(15, 18, dd, 21); X(16, 8, db, 45); X(17, 23, de, 8); X(18, 13, dc, 15); X(19, 3, da, 41); + X(20, 24, de, 14); X(21, 14, dc, 61); X(22, 4, da, 18); X(23, 19, dd, 56); X(24, 9, db, 2); +#undef X + + /* ξ step. */ +#define X(N) A[N] = B[N] ^ ((~(B[(N + 5) % 25])) & B[(N + 10) % 25]) + LIST_25(X, ;); +#undef X + + /* ι step. */ + A[0] ^= rc; +} + + +/** + * 64-bit lane version of `libkeccak_to_lane` + * + * @param message The message + * @param msglen The length of the message + * @param rr Bitrate in bytes + * @param off The offset in the message + * @return The lane + */ +LIBKECCAK_GCC_ONLY(__attribute__((__nonnull__, __nothrow__, __pure__, __hot__, __warn_unused_result__, __gnu_inline__))) +static inline uint64_t +libkeccak_to_lane64(register const unsigned char *message, register size_t msglen, register long int rr, size_t off) +{ + register long int n = (long)((msglen < (size_t)rr ? msglen : (size_t)rr) - off); + uint64_t rc = 0; + message += off; +#define X(N) if (__builtin_expect(N < n, 1)) rc |= (uint64_t)message[N] << (N * 8);\ + else return rc + LIST_8(X, ;); +#undef X + return rc; +} |