#include #include "api.h" #include "endian.h" #include "permutations.h" #define RATE (64 / 8) #define PA_ROUNDS 12 int crypto_hash(unsigned char* out, const unsigned char* in, unsigned long long inlen) { state s; u64 outlen; // initialization s.x0.h = 0xb57e273b; s.x0.l = 0x814cd416; s.x1.h = 0x2b510425; s.x1.l = 0x62ae2420; s.x2.h = 0x66a3a776; s.x2.l = 0x8ddf2218; s.x3.h = 0x5aad0a7a; s.x3.l = 0x8153650c; s.x4.h = 0x4f3e0e32; s.x4.l = 0x539493b6; u32_2 t0; u64 tmp0; // absorb plaintext while (inlen >= RATE) { tmp0 = (*(u64*)in); t0 = to_big(tmp0); s.x0.h ^= t0.h; s.x0.l ^= t0.l; P(&s, START_ROUND(PA_ROUNDS)); inlen -= RATE; in += RATE; } u8 bytes[16]; memcpy(bytes, in, inlen); memset(bytes + inlen, 0, 16 - inlen); bytes[inlen] ^= 0x80; u64* tmp = (u64*)bytes; t0 = to_big(tmp[0]); s.x0.h ^= t0.h; s.x0.l ^= t0.l; P(&s, START_ROUND(PA_ROUNDS)); // squeeze hash outlen = CRYPTO_BYTES; while (outlen >= RATE) { tmp0 = from_big(s.x0); *(u64*)out = tmp0; P(&s, START_ROUND(PA_ROUNDS)); outlen -= RATE; out += RATE; } return 0; }