#ifndef LOADSTORE_H_ #define LOADSTORE_H_ #include #include "config.h" #include "endian.h" #include "word.h" /* 64-bit LSB mask (undefined for n == 0) */ #define MASK(n) (~0ull >> (64 - (n))) /* get byte from Ascon 64-bit word */ #define GETBYTE(x, i) ((uint8_t)((uint64_t)(x) >> (56 - 8 * (i)))) /* set byte in Ascon 64-bit word */ #define SETBYTE(b, i) ((uint64_t)(b) << (56 - 8 * (i))) #if ASCON_DATA_ACCESS == 'W' #ifndef NDEBUG #pragma message("Using wordwise data access") #endif __forceinline word_t LOAD64(const uint8_t* bytes) { uint64_t x = U64BIG(*(uint64_t*)bytes); return U64TOWORD(x); } __forceinline void STORE64(uint8_t* bytes, word_t w) { uint64_t x = WORDTOU64(w); *(uint64_t*)bytes = U64BIG(x); } __forceinline word_t LOAD(const uint8_t* bytes, int n) { uint64_t x = U64BIG(*(uint64_t*)bytes & MASK(8 * n)); return U64TOWORD(x); } __forceinline void STORE(uint8_t* bytes, word_t w, int n) { uint64_t x = WORDTOU64(w); *(uint64_t*)bytes &= ~MASK(8 * n); *(uint64_t*)bytes |= U64BIG(x); } #elif ASCON_DATA_ACCESS == 'M' #ifndef NDEBUG #pragma message("Using memcpy to access data") #endif #include #define LOAD64(bytes) LOAD(bytes, 8) #define STORE64(bytes, w) STORE(bytes, w, 8) __forceinline word_t LOAD(const uint8_t* bytes, int n) { uint64_t x = 0; memcpy((uint8_t*)&x, bytes, n); return U64TOWORD(U64BIG(x)); } __forceinline void STORE(uint8_t* bytes, word_t w, int n) { uint64_t x = U64BIG(WORDTOU64(w)); memcpy(bytes, (uint8_t*)&x, n); } #elif ASCON_DATA_ACCESS == 'B' #ifndef NDEBUG #pragma message("Using bytewise data access") #endif #define LOAD64(bytes) LOAD(bytes, 8) #define STORE64(bytes, w) STORE(bytes, w, 8) __forceinline word_t LOAD(const uint8_t* bytes, int n) { uint64_t x = 0; for (int i = 56; i >= 64 - n * 8; i -= 8) x |= (uint64_t)*bytes++ << i; return U64TOWORD(x); } __forceinline void STORE(uint8_t* bytes, word_t w, int n) { uint64_t x = WORDTOU64(w); for (int i = 56; i >= 64 - n * 8; i -= 8) *bytes++ = x >> i; } #elif ASCON_DATA_ACCESS == 'H' #ifndef NDEBUG #pragma message("Using hybrid data access") #endif #define LOAD64(bytes) LOAD(bytes, 8) #define STORE64(bytes, w) STORE(bytes, w, 8) __forceinline word_t LOAD(const uint8_t* bytes, int n) { uint64_t x = 0; if (n == 8) x = U64BIG(*(uint64_t*)bytes); else for (int i = 56; i >= 64 - n * 8; i -= 8) x |= (uint64_t)*bytes++ << i; return U64TOWORD(x); } __forceinline void STORE(uint8_t* bytes, word_t w, int n) { uint64_t x = WORDTOU64(w); if (n == 8) *(uint64_t*)bytes = U64BIG(x); else for (int i = 56; i >= 64 - n * 8; i -= 8) *bytes++ = x >> i; } #else #error "Ascon data access macro not defined correctly" #endif #endif /* LOADSTORE_H_ */