/******************************************************************************************** * Supersingular Isogeny Key Encapsulation Library * * Abstract: configuration file and platform-dependent macros *********************************************************************************************/ #ifndef __CONFIG_H__ #define __CONFIG_H__ #include #include #include // Definition of operating system #define OS_LINUX 1 #if defined(__LINUX__) // Linux OS #define OS_TARGET OS_LINUX #else #error -- "Unsupported OS" #endif // Definition of compiler #define COMPILER_GCC 1 #define COMPILER_CLANG 2 #if defined(__GNUC__) // GNU GCC compiler #define COMPILER COMPILER_GCC #elif defined(__clang__) // Clang compiler #define COMPILER COMPILER_CLANG #else #error -- "Unsupported COMPILER" #endif // Definition of the targeted architecture and basic data types #define TARGET_AMD64 1 #if defined(_AMD64_) #define TARGET TARGET_AMD64 #define RADIX 64 #define LOG2RADIX 6 typedef uint64_t digit_t; // Unsigned 64-bit digit #else #error -- "Unsupported ARCHITECTURE" #endif #define RADIX64 64 // Selection of implementation: optimized_fast with x64 assembly #if defined(_OPTIMIZED_FAST_) #define OPTIMIZED_FAST_IMPLEMENTATION #endif // Extended datatype support #define UINT128_SUPPORT typedef unsigned uint128_t __attribute__((mode(TI))); // Macro definitions #define NBITS_TO_NBYTES(nbits) (((nbits)+7)/8) // Conversion macro from number of bits to number of bytes #define NBITS_TO_NWORDS(nbits) (((nbits)+(sizeof(digit_t)*8)-1)/(sizeof(digit_t)*8)) // Conversion macro from number of bits to number of computer words #define NBYTES_TO_NWORDS(nbytes) (((nbytes)+sizeof(digit_t)-1)/sizeof(digit_t)) // Conversion macro from number of bytes to number of computer words // Macro to avoid compiler warnings when detecting unreferenced parameters #define UNREFERENCED_PARAMETER(PAR) ((void)(PAR)) /********************** Constant-time unsigned comparisons ***********************/ // The following functions return 1 (TRUE) if condition is true, 0 (FALSE) otherwise static __inline unsigned int is_digit_nonzero_ct(digit_t x) { // Is x != 0? return (unsigned int)((x | (0-x)) >> (RADIX-1)); } static __inline unsigned int is_digit_zero_ct(digit_t x) { // Is x = 0? return (unsigned int)(1 ^ is_digit_nonzero_ct(x)); } static __inline unsigned int is_digit_lessthan_ct(digit_t x, digit_t y) { // Is x < y? return (unsigned int)((x ^ ((x ^ y) | ((x - y) ^ y))) >> (RADIX-1)); } /********************** Macros for platform-dependent operations **********************/ // Digit multiplication #define MUL(multiplier, multiplicand, hi, lo) \ { uint128_t tempReg = (uint128_t)(multiplier) * (uint128_t)(multiplicand); \ *(hi) = (digit_t)(tempReg >> RADIX); \ (lo) = (digit_t)tempReg; } // Digit addition with carry #define ADDC(carryIn, addend1, addend2, carryOut, sumOut) \ { uint128_t tempReg = (uint128_t)(addend1) + (uint128_t)(addend2) + (uint128_t)(carryIn); \ (carryOut) = (digit_t)(tempReg >> RADIX); \ (sumOut) = (digit_t)tempReg; } // Digit subtraction with borrow #define SUBC(borrowIn, minuend, subtrahend, borrowOut, differenceOut) \ { uint128_t tempReg = (uint128_t)(minuend) - (uint128_t)(subtrahend) - (uint128_t)(borrowIn); \ (borrowOut) = (digit_t)(tempReg >> (sizeof(uint128_t)*8 - 1)); \ (differenceOut) = (digit_t)tempReg; } // Digit shift right #define SHIFTR(highIn, lowIn, shift, shiftOut, DigitSize) \ (shiftOut) = ((lowIn) >> (shift)) ^ ((highIn) << (RADIX - (shift))); // Digit shift left #define SHIFTL(highIn, lowIn, shift, shiftOut, DigitSize) \ (shiftOut) = ((highIn) << (shift)) ^ ((lowIn) >> (RADIX - (shift))); #endif