/******************************************************************************************** * Supersingular Isogeny Key Encapsulation Library * * Abstract: configuration file and platform-dependent macros *********************************************************************************************/ #ifndef __CONFIG_H__ #define __CONFIG_H__ #include "sike_r1_namespace.h" #include #include #include // 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 #define _AMD64_ // Definition of the targeted architecture and basic data types #define TARGET_AMD64 1 #define TARGET_x86 2 #define TARGET_ARM 3 #define TARGET_ARM64 4 #if defined(_AMD64_) #define TARGET TARGET_AMD64 #define RADIX 64 #define LOG2RADIX 6 typedef uint64_t digit_t; // Unsigned 64-bit digit #elif defined(_X86_) #define TARGET TARGET_x86 #define RADIX 32 #define LOG2RADIX 5 typedef uint32_t digit_t; // Unsigned 32-bit digit #elif defined(_ARM_) #define TARGET TARGET_ARM #define RADIX 32 #define LOG2RADIX 5 typedef uint32_t digit_t; // Unsigned 32-bit digit #elif defined(_ARM64_) #define TARGET TARGET_ARM64 #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_generic #if defined(_OPTIMIZED_GENERIC_) #define OPTIMIZED_GENERIC_IMPLEMENTATION #endif // Extended datatype support typedef uint64_t uint128_t[2]; // 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) \ digit_x_digit((multiplier), (multiplicand), &(lo)); // Digit addition with carry #define ADDC(carryIn, addend1, addend2, carryOut, sumOut) \ { digit_t tempReg = (addend1) + (digit_t)(carryIn); \ (sumOut) = (addend2) + tempReg; \ (carryOut) = (is_digit_lessthan_ct(tempReg, (digit_t)(carryIn)) | is_digit_lessthan_ct((sumOut), tempReg)); } // Digit subtraction with borrow #define SUBC(borrowIn, minuend, subtrahend, borrowOut, differenceOut) \ { digit_t tempReg = (minuend) - (subtrahend); \ unsigned int borrowReg = (is_digit_lessthan_ct((minuend), (subtrahend)) | ((borrowIn) & is_digit_zero_ct(tempReg))); \ (differenceOut) = tempReg - (digit_t)(borrowIn); \ (borrowOut) = borrowReg; } // Shift right with flexible datatype #define SHIFTR(highIn, lowIn, shift, shiftOut, DigitSize) \ (shiftOut) = ((lowIn) >> (shift)) ^ ((highIn) << (DigitSize - (shift))); // Shift left with flexible datatype #define SHIFTL(highIn, lowIn, shift, shiftOut, DigitSize) \ (shiftOut) = ((highIn) << (shift)) ^ ((lowIn) >> (DigitSize - (shift))); // 64x64-bit multiplication #define MUL128(multiplier, multiplicand, product) \ mp_mul((digit_t*)&(multiplier), (digit_t*)&(multiplicand), (digit_t*)&(product), NWORDS_FIELD/2); // 128-bit addition, inputs < 2^127 #define ADD128(addend1, addend2, addition) \ mp_add((digit_t*)(addend1), (digit_t*)(addend2), (digit_t*)(addition), NWORDS_FIELD); // 128-bit addition with output carry #define ADC128(addend1, addend2, carry, addition) \ (carry) = mp_add((digit_t*)(addend1), (digit_t*)(addend2), (digit_t*)(addition), NWORDS_FIELD); #endif