Files
RandQuik/src/cha1c.h
T

30 lines
1.1 KiB
C

#include <stdint.h>
#include <string.h>
// clang-format off
#define QUARTERSTEP(a, b, c, n) a += b; c ^= a; c = (c << n) | (c >> (32 - n))
#define QUARTERROUND(a, b, c, d) {\
QUARTERSTEP(a, b, d, 16); QUARTERSTEP(c, d, b, 12); \
QUARTERSTEP(a, b, d, 8); QUARTERSTEP(c, d, b, 7); }
static inline uint64_t _cha_block(uint8_t* buf, size_t bufsize, uint32_t state[16], unsigned rounds) {
unsigned blocks = bufsize / 64;
uint32_t* out = (uint32_t*)buf;
uint32_t x[16];
for (unsigned b = blocks; b-->0;) {
for (unsigned i = 0; i < 16; ++i) x[i] = state[i]; // Faster than memcpy
for (unsigned i = rounds / 2; i-->0;) {
// Mix columns, then diagonals
for (unsigned j = 0; j < 4; ++j) QUARTERROUND(x[j], x[4 + j], x[8 + j], x[12 + j]);
for (unsigned j = 0; j < 4; ++j) QUARTERROUND(x[j], x[4 + (j+1)%4], x[8 + (j+2)%4], x[12 + (j+3)%4]);
}
for (unsigned i = 0; i < 16; ++i) *out++ = x[i] + state[i];
++*(uint64_t*)(state + 12); // Increment counter
}
memset(x, 0, sizeof x);
return blocks * CHA_BLOCK_SIZE;
}
#undef QUARTERROUND
#undef QUARTERSTEP