#ifndef WORD_H_ #define WORD_H_ #include #include "config.h" typedef struct { uint32_t e; uint32_t o; } word_t; __forceinline word_t WORD_T(uint64_t x) { return (word_t){.o = x >> 32, .e = x}; } __forceinline uint64_t UINT64_T(word_t x) { return (uint64_t)x.o << 32 | x.e; } __forceinline uint64_t TOBI32(uint64_t in); __forceinline uint64_t FROMBI32(uint64_t in); __forceinline word_t U64TOWORD(uint64_t x) { uint64_t w = TOBI32(x); return (word_t){.o = w >> 32, .e = w}; } __forceinline uint64_t WORDTOU64(word_t w) { return FROMBI32((uint64_t)w.o << 32 | w.e); } #define XOR(a, b) \ do { \ word_t tb = b; \ (a).e ^= tb.e; \ (a).o ^= tb.o; \ } while (0) #define AND(a, b) \ do { \ word_t tb = b; \ (a).e &= tb.e; \ (a).o &= tb.o; \ } while (0) __forceinline uint32_t ROR32(uint32_t x, int n) { return x >> n | x << (32 - n); } __forceinline word_t ROR64(word_t x, int n) { word_t r; r.e = (n % 2) ? ROR32(x.o, (n - 1) / 2) : ROR32(x.e, n / 2); r.o = (n % 2) ? ROR32(x.e, (n + 1) / 2) : ROR32(x.o, n / 2); return r; } __forceinline word_t KEYROT(word_t lo2hi, word_t hi2lo) { word_t r; r.o = lo2hi.o << 16 | hi2lo.o >> 16; r.e = lo2hi.e << 16 | hi2lo.e >> 16; return r; } __forceinline int NOTZERO(word_t a, word_t b) { int result = 0; for (int i = 0; i < 8; ++i) result |= ((uint8_t*)&a)[i]; for (int i = 0; i < 8; ++i) result |= ((uint8_t*)&b)[i]; return result; } /* set padding byte in 64-bit Ascon word */ __forceinline word_t PAD(int i) { return WORD_T((uint64_t)(0x08 << (28 - 4 * i)) << 32); } /* byte mask for 64-bit Ascon word (1 <= n <= 8) */ __forceinline word_t XMASK(int n) { uint32_t mask = 0x0fffffff >> (n * 4 - 4); return WORD_T((uint64_t)mask << 32 | mask); } /* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ __forceinline uint64_t TOBI32(uint64_t in) { uint32_t hi = in >> 32; uint32_t lo = in; uint32_t r0, r1; r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); r0 = (lo & 0x0000FFFF) | (hi << 16); r1 = (lo >> 16) | (hi & 0xFFFF0000); return (uint64_t)r1 << 32 | r0; } /* credit to Henry S. Warren, Hacker's Delight, Addison-Wesley, 2002 */ __forceinline uint64_t FROMBI32(uint64_t in) { uint32_t r0 = in; uint32_t r1 = in >> 32; uint32_t lo = (r0 & 0x0000FFFF) | (r1 << 16); uint32_t hi = (r0 >> 16) | (r1 & 0xFFFF0000); r0 = (lo ^ (lo >> 8)) & 0x0000FF00, lo ^= r0 ^ (r0 << 8); r0 = (lo ^ (lo >> 4)) & 0x00F000F0, lo ^= r0 ^ (r0 << 4); r0 = (lo ^ (lo >> 2)) & 0x0C0C0C0C, lo ^= r0 ^ (r0 << 2); r0 = (lo ^ (lo >> 1)) & 0x22222222, lo ^= r0 ^ (r0 << 1); r1 = (hi ^ (hi >> 8)) & 0x0000FF00, hi ^= r1 ^ (r1 << 8); r1 = (hi ^ (hi >> 4)) & 0x00F000F0, hi ^= r1 ^ (r1 << 4); r1 = (hi ^ (hi >> 2)) & 0x0C0C0C0C, hi ^= r1 ^ (r1 << 2); r1 = (hi ^ (hi >> 1)) & 0x22222222, hi ^= r1 ^ (r1 << 1); return (uint64_t)hi << 32 | lo; } #endif /* WORD_H_ */