#ifndef ROUND_H_ #define ROUND_H_ #include "ascon.h" #include "printstate.h" static inline uint32_t ROR32(uint32_t x, int n) { return x >> n | x << (-n & 31); } static inline uint64_t ROR(uint64_t x, int n) { uint32_t al = (uint32_t)x; uint32_t ah = x >> 32; uint32_t bl, bh; bl = (n % 2) ? ROR32(ah, (n - 1) / 2) : ROR32(al, n / 2); bh = (n % 2) ? ROR32(al, (n + 1) / 2) : ROR32(ah, n / 2); return (uint64_t)bh << 32 | bl; } static inline void ROUND(state_t* s, uint64_t C) { state_t t; /* addition of round constant */ s->x[2] ^= C; /* printstate(" round constant", s); */ /* substitution layer */ s->x[0] ^= s->x[4]; s->x[4] ^= s->x[3]; s->x[2] ^= s->x[1]; /* start of keccak s-box */ t.x[0] = s->x[0] ^ (~s->x[1] & s->x[2]); t.x[1] = s->x[1] ^ (~s->x[2] & s->x[3]); t.x[2] = s->x[2] ^ (~s->x[3] & s->x[4]); t.x[3] = s->x[3] ^ (~s->x[4] & s->x[0]); t.x[4] = s->x[4] ^ (~s->x[0] & s->x[1]); /* end of keccak s-box */ t.x[1] ^= t.x[0]; t.x[0] ^= t.x[4]; t.x[3] ^= t.x[2]; t.x[2] = ~t.x[2]; /* printstate(" substitution layer", &t); */ /* linear diffusion layer */ s->x[0] = t.x[0] ^ ROR(t.x[0], 19) ^ ROR(t.x[0], 28); s->x[1] = t.x[1] ^ ROR(t.x[1], 61) ^ ROR(t.x[1], 39); s->x[2] = t.x[2] ^ ROR(t.x[2], 1) ^ ROR(t.x[2], 6); s->x[3] = t.x[3] ^ ROR(t.x[3], 10) ^ ROR(t.x[3], 17); s->x[4] = t.x[4] ^ ROR(t.x[4], 7) ^ ROR(t.x[4], 41); printstate(" round output", s); } #endif /* ROUND_H_ */