Path: blob/master/libs/tomcrypt/src/headers/tomcrypt_macros.h
5971 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/89/* ---- HELPER MACROS ---- */10#ifdef ENDIAN_NEUTRAL1112#define STORE32L(x, y) \13do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \14(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)1516#define LOAD32L(x, y) \17do { x = ((ulong32)((y)[3] & 255)<<24) | \18((ulong32)((y)[2] & 255)<<16) | \19((ulong32)((y)[1] & 255)<<8) | \20((ulong32)((y)[0] & 255)); } while(0)2122#define STORE64L(x, y) \23do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \24(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \25(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \26(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)2728#define LOAD64L(x, y) \29do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \30(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \31(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \32(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0)3334#define STORE32H(x, y) \35do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \36(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0)3738#define LOAD32H(x, y) \39do { x = ((ulong32)((y)[0] & 255)<<24) | \40((ulong32)((y)[1] & 255)<<16) | \41((ulong32)((y)[2] & 255)<<8) | \42((ulong32)((y)[3] & 255)); } while(0)4344#define STORE64H(x, y) \45do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \46(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \47(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \48(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0)4950#define LOAD64H(x, y) \51do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \52(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \53(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \54(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0)555657#elif defined(ENDIAN_LITTLE)5859#ifdef LTC_HAVE_BSWAP_BUILTIN6061#define STORE32H(x, y) \62do { ulong32 __t = __builtin_bswap32 ((x)); \63XMEMCPY ((y), &__t, 4); } while(0)6465#define LOAD32H(x, y) \66do { XMEMCPY (&(x), (y), 4); \67(x) = __builtin_bswap32 ((x)); } while(0)6869#elif !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__))))7071#define STORE32H(x, y) \72asm __volatile__ ( \73"bswapl %0 \n\t" \74"movl %0,(%1)\n\t" \75"bswapl %0 \n\t" \76::"r"(x), "r"(y));7778#define LOAD32H(x, y) \79asm __volatile__ ( \80"movl (%1),%0\n\t" \81"bswapl %0\n\t" \82:"=r"(x): "r"(y));8384#else8586#define STORE32H(x, y) \87do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \88(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0)8990#define LOAD32H(x, y) \91do { x = ((ulong32)((y)[0] & 255)<<24) | \92((ulong32)((y)[1] & 255)<<16) | \93((ulong32)((y)[2] & 255)<<8) | \94((ulong32)((y)[3] & 255)); } while(0)9596#endif9798#ifdef LTC_HAVE_BSWAP_BUILTIN99100#define STORE64H(x, y) \101do { ulong64 __t = __builtin_bswap64 ((x)); \102XMEMCPY ((y), &__t, 8); } while(0)103104#define LOAD64H(x, y) \105do { XMEMCPY (&(x), (y), 8); \106(x) = __builtin_bswap64 ((x)); } while(0)107108/* x86_64 processor */109#elif !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__))110111#define STORE64H(x, y) \112asm __volatile__ ( \113"bswapq %0 \n\t" \114"movq %0,(%1)\n\t" \115"bswapq %0 \n\t" \116::"r"(x), "r"(y): "memory");117118#define LOAD64H(x, y) \119asm __volatile__ ( \120"movq (%1),%0\n\t" \121"bswapq %0\n\t" \122:"=r"(x): "r"(y): "memory");123124#else125126#define STORE64H(x, y) \127do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \128(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \129(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \130(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0)131132#define LOAD64H(x, y) \133do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \134(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \135(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \136(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0)137138#endif139140#ifdef ENDIAN_32BITWORD141142#define STORE32L(x, y) \143do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)144145#define LOAD32L(x, y) \146do { XMEMCPY(&(x), y, 4); } while(0)147148#define STORE64L(x, y) \149do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \150(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \151(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \152(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)153154#define LOAD64L(x, y) \155do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \156(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \157(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \158(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0)159160#else /* 64-bit words then */161162#define STORE32L(x, y) \163do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)164165#define LOAD32L(x, y) \166do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)167168#define STORE64L(x, y) \169do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0)170171#define LOAD64L(x, y) \172do { XMEMCPY(&(x), y, 8); } while(0)173174#endif /* ENDIAN_64BITWORD */175176#elif defined(ENDIAN_BIG)177178#define STORE32L(x, y) \179do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \180(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)181182#define LOAD32L(x, y) \183do { x = ((ulong32)((y)[3] & 255)<<24) | \184((ulong32)((y)[2] & 255)<<16) | \185((ulong32)((y)[1] & 255)<<8) | \186((ulong32)((y)[0] & 255)); } while(0)187188#define STORE64L(x, y) \189do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \190(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \191(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \192(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)193194#define LOAD64L(x, y) \195do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \196(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \197(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \198(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0)199200#ifdef ENDIAN_32BITWORD201202#define STORE32H(x, y) \203do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)204205#define LOAD32H(x, y) \206do { XMEMCPY(&(x), y, 4); } while(0)207208#define STORE64H(x, y) \209do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \210(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \211(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \212(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0)213214#define LOAD64H(x, y) \215do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \216(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \217(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \218(((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } while(0)219220#else /* 64-bit words then */221222#define STORE32H(x, y) \223do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)224225#define LOAD32H(x, y) \226do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)227228#define STORE64H(x, y) \229do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0)230231#define LOAD64H(x, y) \232do { XMEMCPY(&(x), y, 8); } while(0)233234#endif /* ENDIAN_64BITWORD */235#endif /* ENDIAN_BIG */236237#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \238((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )239240241/* 32-bit Rotates */242#if defined(_MSC_VER)243#define LTC_ROx_ASM244245/* instrinsic rotate */246#include <stdlib.h>247#pragma intrinsic(_lrotr,_lrotl)248#define ROR(x,n) _lrotr(x,n)249#define ROL(x,n) _lrotl(x,n)250#define RORc(x,n) _lrotr(x,n)251#define ROLc(x,n) _lrotl(x,n)252253#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)254#define LTC_ROx_ASM255256static inline ulong32 ROL(ulong32 word, int i)257{258asm ("roll %%cl,%0"259:"=r" (word)260:"0" (word),"c" (i));261return word;262}263264static inline ulong32 ROR(ulong32 word, int i)265{266asm ("rorl %%cl,%0"267:"=r" (word)268:"0" (word),"c" (i));269return word;270}271272#ifndef LTC_NO_ROLC273274#define ROLc(word,i) ({ \275ulong32 __ROLc_tmp = (word); \276__asm__ ("roll %2, %0" : \277"=r" (__ROLc_tmp) : \278"0" (__ROLc_tmp), \279"I" (i)); \280__ROLc_tmp; \281})282#define RORc(word,i) ({ \283ulong32 __RORc_tmp = (word); \284__asm__ ("rorl %2, %0" : \285"=r" (__RORc_tmp) : \286"0" (__RORc_tmp), \287"I" (i)); \288__RORc_tmp; \289})290291#else292293#define ROLc ROL294#define RORc ROR295296#endif297298#elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)299#define LTC_ROx_ASM300301static inline ulong32 ROL(ulong32 word, int i)302{303asm ("rotlw %0,%0,%2"304:"=r" (word)305:"0" (word),"r" (i));306return word;307}308309static inline ulong32 ROR(ulong32 word, int i)310{311asm ("rotlw %0,%0,%2"312:"=r" (word)313:"0" (word),"r" (32-i));314return word;315}316317#ifndef LTC_NO_ROLC318319static inline ulong32 ROLc(ulong32 word, const int i)320{321asm ("rotlwi %0,%0,%2"322:"=r" (word)323:"0" (word),"I" (i));324return word;325}326327static inline ulong32 RORc(ulong32 word, const int i)328{329asm ("rotrwi %0,%0,%2"330:"=r" (word)331:"0" (word),"I" (i));332return word;333}334335#else336337#define ROLc ROL338#define RORc ROR339340#endif341342343#else344345/* rotates the hard way */346#define ROL(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)347#define ROR(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)348#define ROLc(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)349#define RORc(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)350351#endif352353354/* 64-bit Rotates */355#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(_WIN64) && !defined(LTC_NO_ASM)356357static inline ulong64 ROL64(ulong64 word, int i)358{359asm("rolq %%cl,%0"360:"=r" (word)361:"0" (word),"c" (i));362return word;363}364365static inline ulong64 ROR64(ulong64 word, int i)366{367asm("rorq %%cl,%0"368:"=r" (word)369:"0" (word),"c" (i));370return word;371}372373#ifndef LTC_NO_ROLC374375#define ROL64c(word,i) ({ \376ulong64 __ROL64c_tmp = word; \377__asm__ ("rolq %2, %0" : \378"=r" (__ROL64c_tmp) : \379"0" (__ROL64c_tmp), \380"J" (i)); \381__ROL64c_tmp; \382})383#define ROR64c(word,i) ({ \384ulong64 __ROR64c_tmp = word; \385__asm__ ("rorq %2, %0" : \386"=r" (__ROR64c_tmp) : \387"0" (__ROR64c_tmp), \388"J" (i)); \389__ROR64c_tmp; \390})391392#else /* LTC_NO_ROLC */393394#define ROL64c ROL64395#define ROR64c ROR64396397#endif398399#else /* Not x86_64 */400401#define ROL64(x, y) \402( (((x)<<((ulong64)(y)&63)) | \403(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))404405#define ROR64(x, y) \406( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \407((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))408409#define ROL64c(x, y) \410( (((x)<<((ulong64)(y)&63)) | \411(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))412413#define ROR64c(x, y) \414( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \415((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))416417#endif418419#ifndef MAX420#define MAX(x, y) ( ((x)>(y))?(x):(y) )421#endif422423#ifndef MIN424#define MIN(x, y) ( ((x)<(y))?(x):(y) )425#endif426427#ifndef LTC_UNUSED_PARAM428#define LTC_UNUSED_PARAM(x) (void)(x)429#endif430431/* extract a byte portably */432#ifdef _MSC_VER433#define byte(x, n) ((unsigned char)((x) >> (8 * (n))))434#else435#define byte(x, n) (((x) >> (8 * (n))) & 255)436#endif437438/* there is no snprintf before Visual C++ 2015 */439#if defined(_MSC_VER) && _MSC_VER < 1900440#define snprintf _snprintf441#endif442443444