#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 = 0xee9398aa; s.x0.l = 0xdb67f03d; s.x1.h = 0x8bb21831; s.x1.l = 0xc60f1002; s.x2.h = 0xb48a92db; s.x2.l = 0x98d5da62; s.x3.h = 0x43189921; s.x3.l = 0xb8f8e3e8; s.x4.h = 0x348fa5c9; s.x4.l = 0xd525e140; 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; }