Created
March 26, 2024 13:08
-
-
Save jakiki6/3aa6f17953582790d86d16d832ae5be8 to your computer and use it in GitHub Desktop.
Formatted https://raw.githubusercontent.com/XKCP/XKCP/master/Standalone/CompactFIPS202/C/Keccak-more-compact.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define FOR(i, n) for (i = 0; i < n; ++i) | |
#define ROL(a, o) ((((u64)a) << o) ^ (((u64)a) >> (64 - o))) | |
#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) | |
typedef unsigned char u8; | |
typedef unsigned long long int u64; | |
typedef unsigned int ui; | |
static void Keccak(ui r, ui c, const u8* in, u64 inLen, u8 sfx, u8* out, u64 outLen); | |
void shake128(const u8* in, u64 inLen, u8* out, u64 outLen) { | |
Keccak(1344, 256, in, inLen, 0x1F, out, outLen); | |
} | |
void shake256(const u8* in, u64 inLen, u8* out, u64 outLen) { | |
Keccak(1088, 512, in, inLen, 0x1F, out, outLen); | |
} | |
void sha3_224(const u8* in, u64 inLen, u8* out) { | |
Keccak(1152, 448, in, inLen, 0x06, out, 28); | |
} | |
void sha3_256(const u8* in, u64 inLen, u8* out) { | |
Keccak(1088, 512, in, inLen, 0x06, out, 32); | |
} | |
void sha3_384(const u8* in, u64 inLen, u8* out) { | |
Keccak(832, 768, in, inLen, 0x06, out, 48); | |
} | |
void sha3_512(const u8* in, u64 inLen, u8* out) { | |
Keccak(576, 1024, in, inLen, 0x06, out, 64); | |
} | |
static int LFSR86540(u8* R) { | |
(*R) = ((*R) << 1) ^ (((*R) & 0x80) ? 0x71 : 0); | |
return ((*R) & 2) >> 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; | |
} | |
} | |
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, ui c, const u8* in, u64 inLen, u8 sfx, u8* out, u64 outLen) { | |
/*initialize*/ 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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment