1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
6 * The library is free for all purposes without any express
10 /* ---- HELPER MACROS ---- */
13 #define STORE32L(x, y) \
14 do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
15 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)
17 #define LOAD32L(x, y) \
18 do { x = ((ulong32)((y)[3] & 255)<<24) | \
19 ((ulong32)((y)[2] & 255)<<16) | \
20 ((ulong32)((y)[1] & 255)<<8) | \
21 ((ulong32)((y)[0] & 255)); } while(0)
23 #define STORE64L(x, y) \
24 do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
25 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
26 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
27 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)
29 #define LOAD64L(x, y) \
30 do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
31 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
32 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
33 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0)
35 #define STORE32H(x, y) \
36 do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
37 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0)
39 #define LOAD32H(x, y) \
40 do { x = ((ulong32)((y)[0] & 255)<<24) | \
41 ((ulong32)((y)[1] & 255)<<16) | \
42 ((ulong32)((y)[2] & 255)<<8) | \
43 ((ulong32)((y)[3] & 255)); } while(0)
45 #define STORE64H(x, y) \
46 do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
47 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
48 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
49 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0)
51 #define LOAD64H(x, y) \
52 do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
53 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
54 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
55 (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0)
58 #elif defined(ENDIAN_LITTLE)
60 #ifdef LTC_HAVE_BSWAP_BUILTIN
62 #define STORE32H(x, y) \
63 do { ulong32 __t = __builtin_bswap32 ((x)); \
64 XMEMCPY ((y), &__t, 4); } while(0)
66 #define LOAD32H(x, y) \
67 do { XMEMCPY (&(x), (y), 4); \
68 (x) = __builtin_bswap32 ((x)); } while(0)
70 #elif !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__))))
72 #define STORE32H(x, y) \
79 #define LOAD32H(x, y) \
87 #define STORE32H(x, y) \
88 do { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
89 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } while(0)
91 #define LOAD32H(x, y) \
92 do { x = ((ulong32)((y)[0] & 255)<<24) | \
93 ((ulong32)((y)[1] & 255)<<16) | \
94 ((ulong32)((y)[2] & 255)<<8) | \
95 ((ulong32)((y)[3] & 255)); } while(0)
99 #ifdef LTC_HAVE_BSWAP_BUILTIN
101 #define STORE64H(x, y) \
102 do { ulong64 __t = __builtin_bswap64 ((x)); \
103 XMEMCPY ((y), &__t, 8); } while(0)
105 #define LOAD64H(x, y) \
106 do { XMEMCPY (&(x), (y), 8); \
107 (x) = __builtin_bswap64 ((x)); } while(0)
109 /* x86_64 processor */
110 #elif !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__))
112 #define STORE64H(x, y) \
117 ::"r"(x), "r"(y): "memory");
119 #define LOAD64H(x, y) \
123 :"=r"(x): "r"(y): "memory");
127 #define STORE64H(x, y) \
128 do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
129 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
130 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
131 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0)
133 #define LOAD64H(x, y) \
134 do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
135 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
136 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
137 (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } while(0)
141 #ifdef ENDIAN_32BITWORD
143 #define STORE32L(x, y) \
144 do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
146 #define LOAD32L(x, y) \
147 do { XMEMCPY(&(x), y, 4); } while(0)
149 #define STORE64L(x, y) \
150 do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
151 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
152 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
153 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)
155 #define LOAD64L(x, y) \
156 do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
157 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
158 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
159 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0)
161 #else /* 64-bit words then */
163 #define STORE32L(x, y) \
164 do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
166 #define LOAD32L(x, y) \
167 do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
169 #define STORE64L(x, y) \
170 do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0)
172 #define LOAD64L(x, y) \
173 do { XMEMCPY(&(x), y, 8); } while(0)
175 #endif /* ENDIAN_64BITWORD */
177 #elif defined(ENDIAN_BIG)
179 #define STORE32L(x, y) \
180 do { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
181 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)
183 #define LOAD32L(x, y) \
184 do { x = ((ulong32)((y)[3] & 255)<<24) | \
185 ((ulong32)((y)[2] & 255)<<16) | \
186 ((ulong32)((y)[1] & 255)<<8) | \
187 ((ulong32)((y)[0] & 255)); } while(0)
189 #define STORE64L(x, y) \
190 do { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
191 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
192 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
193 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } while(0)
195 #define LOAD64L(x, y) \
196 do { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
197 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
198 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
199 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } while(0)
201 #ifdef ENDIAN_32BITWORD
203 #define STORE32H(x, y) \
204 do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
206 #define LOAD32H(x, y) \
207 do { XMEMCPY(&(x), y, 4); } while(0)
209 #define STORE64H(x, y) \
210 do { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
211 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
212 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
213 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } while(0)
215 #define LOAD64H(x, y) \
216 do { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
217 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
218 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
219 (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } while(0)
221 #else /* 64-bit words then */
223 #define STORE32H(x, y) \
224 do { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } while(0)
226 #define LOAD32H(x, y) \
227 do { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } while(0)
229 #define STORE64H(x, y) \
230 do { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } while(0)
232 #define LOAD64H(x, y) \
233 do { XMEMCPY(&(x), y, 8); } while(0)
235 #endif /* ENDIAN_64BITWORD */
236 #endif /* ENDIAN_BIG */
238 #define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \
239 ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )
243 #if defined(_MSC_VER)
246 /* instrinsic rotate */
248 #pragma intrinsic(_lrotr,_lrotl)
249 #define ROR(x,n) _lrotr(x,n)
250 #define ROL(x,n) _lrotl(x,n)
251 #define RORc(x,n) _lrotr(x,n)
252 #define ROLc(x,n) _lrotl(x,n)
254 #elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)
257 static inline ulong32 ROL(ulong32 word, int i)
261 :"0" (word),"c" (i));
265 static inline ulong32 ROR(ulong32 word, int i)
269 :"0" (word),"c" (i));
275 #define ROLc(word,i) ({ \
276 ulong32 __ROLc_tmp = (word); \
277 __asm__ ("roll %2, %0" : \
278 "=r" (__ROLc_tmp) : \
283 #define RORc(word,i) ({ \
284 ulong32 __RORc_tmp = (word); \
285 __asm__ ("rorl %2, %0" : \
286 "=r" (__RORc_tmp) : \
299 #elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
302 static inline ulong32 ROL(ulong32 word, int i)
304 asm ("rotlw %0,%0,%2"
306 :"0" (word),"r" (i));
310 static inline ulong32 ROR(ulong32 word, int i)
312 asm ("rotlw %0,%0,%2"
314 :"0" (word),"r" (32-i));
320 static inline ulong32 ROLc(ulong32 word, const int i)
322 asm ("rotlwi %0,%0,%2"
324 :"0" (word),"I" (i));
328 static inline ulong32 RORc(ulong32 word, const int i)
330 asm ("rotrwi %0,%0,%2"
332 :"0" (word),"I" (i));
346 /* rotates the hard way */
347 #define ROL(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)
348 #define ROR(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)
349 #define ROLc(x, y) ( (((ulong32)(x)<<(ulong32)((y)&31)) | (((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)
350 #define RORc(x, y) ( ((((ulong32)(x)&0xFFFFFFFFUL)>>(ulong32)((y)&31)) | ((ulong32)(x)<<(ulong32)((32-((y)&31))&31))) & 0xFFFFFFFFUL)
356 #if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(_WIN64) && !defined(LTC_NO_ASM)
358 static inline ulong64 ROL64(ulong64 word, int i)
362 :"0" (word),"c" (i));
366 static inline ulong64 ROR64(ulong64 word, int i)
370 :"0" (word),"c" (i));
376 #define ROL64c(word,i) ({ \
377 ulong64 __ROL64c_tmp = word; \
378 __asm__ ("rolq %2, %0" : \
379 "=r" (__ROL64c_tmp) : \
380 "0" (__ROL64c_tmp), \
384 #define ROR64c(word,i) ({ \
385 ulong64 __ROR64c_tmp = word; \
386 __asm__ ("rorq %2, %0" : \
387 "=r" (__ROR64c_tmp) : \
388 "0" (__ROR64c_tmp), \
393 #else /* LTC_NO_ROLC */
400 #else /* Not x86_64 */
402 #define ROL64(x, y) \
403 ( (((x)<<((ulong64)(y)&63)) | \
404 (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))
406 #define ROR64(x, y) \
407 ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
408 ((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))
410 #define ROL64c(x, y) \
411 ( (((x)<<((ulong64)(y)&63)) | \
412 (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))
414 #define ROR64c(x, y) \
415 ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
416 ((x)<<(((ulong64)64-((y)&63))&63))) & CONST64(0xFFFFFFFFFFFFFFFF))
421 #define MAX(x, y) ( ((x)>(y))?(x):(y) )
425 #define MIN(x, y) ( ((x)<(y))?(x):(y) )
428 #ifndef LTC_UNUSED_PARAM
429 #define LTC_UNUSED_PARAM(x) (void)(x)
432 /* extract a byte portably */
434 #define byte(x, n) ((unsigned char)((x) >> (8 * (n))))
436 #define byte(x, n) (((x) >> (8 * (n))) & 255)
439 /* there is no snprintf before Visual C++ 2015 */
440 #if defined(_MSC_VER) && _MSC_VER < 1900
441 #define snprintf _snprintf
444 /* ref: $Format:%D$ */
445 /* git commit: $Format:%H$ */
446 /* commit time: $Format:%ai$ */