Skip to content

Instantly share code, notes, and snippets.

@jakiki6
Created March 26, 2024 13:08
Show Gist options
  • Save jakiki6/3aa6f17953582790d86d16d832ae5be8 to your computer and use it in GitHub Desktop.
Save jakiki6/3aa6f17953582790d86d16d832ae5be8 to your computer and use it in GitHub Desktop.
#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