1/* fix for MSVC ...evil! */
2#ifdef _MSC_VER
3   #define CONST64(n) n ## ui64
4   typedef unsigned __int64 ulong64;
5#else
6   #define CONST64(n) n ## ULL
7   typedef unsigned long long ulong64;
8#endif
9
10/* this is the "32-bit at least" data type
11 * Re-define it to suit your platform but it must be at least 32-bits
12 */
13#if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__))
14   typedef unsigned ulong32;
15#else
16   typedef unsigned long ulong32;
17#endif
18
19/* ---- HELPER MACROS ---- */
20#ifdef ENDIAN_NEUTRAL
21
22#define STORE32L(x, y)                                                                     \
23     { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
24       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
25
26#define LOAD32L(x, y)                            \
27     { x = ((unsigned long)((y)[3] & 255)<<24) | \
28           ((unsigned long)((y)[2] & 255)<<16) | \
29           ((unsigned long)((y)[1] & 255)<<8)  | \
30           ((unsigned long)((y)[0] & 255)); }
31
32#define STORE64L(x, y)                                                                     \
33     { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \
34       (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \
35       (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
36       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
37
38#define LOAD64L(x, y)                                                       \
39     { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
40           (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
41           (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
42           (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
43
44#define STORE32H(x, y)                                                                     \
45     { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);   \
46       (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
47
48#define LOAD32H(x, y)                            \
49     { x = ((unsigned long)((y)[0] & 255)<<24) | \
50           ((unsigned long)((y)[1] & 255)<<16) | \
51           ((unsigned long)((y)[2] & 255)<<8)  | \
52           ((unsigned long)((y)[3] & 255)); }
53
54#define STORE64H(x, y)                                                                     \
55   { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \
56     (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \
57     (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \
58     (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
59
60#define LOAD64H(x, y)                                                      \
61   { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
62         (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
63         (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
64         (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
65
66#endif /* ENDIAN_NEUTRAL */
67
68#ifdef ENDIAN_LITTLE
69
70#if !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__))))
71
72#define STORE32H(x, y)           \
73asm __volatile__ (               \
74   "bswapl %0     \n\t"          \
75   "movl   %0,(%1)\n\t"          \
76   "bswapl %0     \n\t"          \
77      ::"r"(x), "r"(y));
78
79#define LOAD32H(x, y)          \
80asm __volatile__ (             \
81   "movl (%1),%0\n\t"          \
82   "bswapl %0\n\t"             \
83   :"=r"(x): "r"(y));
84
85#else
86
87#define STORE32H(x, y)                                                                     \
88     { (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); }
90
91#define LOAD32H(x, y)                            \
92     { x = ((unsigned long)((y)[0] & 255)<<24) | \
93           ((unsigned long)((y)[1] & 255)<<16) | \
94           ((unsigned long)((y)[2] & 255)<<8)  | \
95           ((unsigned long)((y)[3] & 255)); }
96
97#endif
98
99
100/* x86_64 processor */
101#if !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__))
102
103#define STORE64H(x, y)           \
104asm __volatile__ (               \
105   "bswapq %0     \n\t"          \
106   "movq   %0,(%1)\n\t"          \
107   "bswapq %0     \n\t"          \
108      ::"r"(x), "r"(y));
109
110#define LOAD64H(x, y)          \
111asm __volatile__ (             \
112   "movq (%1),%0\n\t"          \
113   "bswapq %0\n\t"             \
114   :"=r"(x): "r"(y));
115
116#else
117
118#define STORE64H(x, y)                                                                     \
119   { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \
120     (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \
121     (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \
122     (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
123
124#define LOAD64H(x, y)                                                      \
125   { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
126         (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
127         (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
128         (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
129
130#endif
131
132#ifdef ENDIAN_32BITWORD
133
134#define STORE32L(x, y)        \
135     { ulong32  __t = (x); XMEMCPY(y, &__t, 4); }
136
137#define LOAD32L(x, y)         \
138     XMEMCPY(&(x), y, 4);
139
140#define STORE64L(x, y)                                                                     \
141     { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \
142       (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \
143       (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
144       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
145
146#define LOAD64L(x, y)                                                       \
147     { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
148           (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
149           (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
150           (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
151
152#else /* 64-bit words then  */
153
154#define STORE32L(x, y)        \
155     { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
156
157#define LOAD32L(x, y)         \
158     { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
159
160#define STORE64L(x, y)        \
161     { ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
162
163#define LOAD64L(x, y)         \
164    { XMEMCPY(&(x), y, 8); }
165
166#endif /* ENDIAN_64BITWORD */
167
168#endif /* ENDIAN_LITTLE */
169
170#ifdef ENDIAN_BIG
171#define STORE32L(x, y)                                                                     \
172     { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
173       (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
174
175#define LOAD32L(x, y)                            \
176     { x = ((unsigned long)((y)[3] & 255)<<24) | \
177           ((unsigned long)((y)[2] & 255)<<16) | \
178           ((unsigned long)((y)[1] & 255)<<8)  | \
179           ((unsigned long)((y)[0] & 255)); }
180
181#define STORE64L(x, y)                                                                     \
182   { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);     \
183     (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);     \
184     (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);     \
185     (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
186
187#define LOAD64L(x, y)                                                      \
188   { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
189         (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
190         (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
191         (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
192
193#ifdef ENDIAN_32BITWORD
194
195#define STORE32H(x, y)        \
196     { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
197
198#define LOAD32H(x, y)         \
199     XMEMCPY(&(x), y, 4);
200
201#define STORE64H(x, y)                                                                     \
202     { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);   \
203       (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);   \
204       (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);   \
205       (y)[6] = (unsigned char)(((x)>>8)&255);  (y)[7] = (unsigned char)((x)&255); }
206
207#define LOAD64H(x, y)                                                       \
208     { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
209           (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
210           (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
211           (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
212
213#else /* 64-bit words then  */
214
215#define STORE32H(x, y)        \
216     { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
217
218#define LOAD32H(x, y)         \
219     { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
220
221#define STORE64H(x, y)        \
222     { ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
223
224#define LOAD64H(x, y)         \
225    { XMEMCPY(&(x), y, 8); }
226
227#endif /* ENDIAN_64BITWORD */
228#endif /* ENDIAN_BIG */
229
230#define BSWAP(x)  ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL)  | \
231                    ((x>>8)&0x0000FF00UL)  | ((x<<8)&0x00FF0000UL) )
232
233
234/* 32-bit Rotates */
235#if defined(_MSC_VER)
236
237/* instrinsic rotate */
238#include <stdlib.h>
239#pragma intrinsic(_lrotr,_lrotl)
240#define ROR(x,n) _lrotr(x,n)
241#define ROL(x,n) _lrotl(x,n)
242#define RORc(x,n) _lrotr(x,n)
243#define ROLc(x,n) _lrotl(x,n)
244
245#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)
246
247static inline unsigned ROL(unsigned word, int i)
248{
249   asm ("roll %%cl,%0"
250      :"=r" (word)
251      :"0" (word),"c" (i));
252   return word;
253}
254
255static inline unsigned ROR(unsigned word, int i)
256{
257   asm ("rorl %%cl,%0"
258      :"=r" (word)
259      :"0" (word),"c" (i));
260   return word;
261}
262
263#ifndef LTC_NO_ROLC
264
265static inline unsigned ROLc(unsigned word, const int i)
266{
267   asm ("roll %2,%0"
268      :"=r" (word)
269      :"0" (word),"I" (i));
270   return word;
271}
272
273static inline unsigned RORc(unsigned word, const int i)
274{
275   asm ("rorl %2,%0"
276      :"=r" (word)
277      :"0" (word),"I" (i));
278   return word;
279}
280
281#else
282
283#define ROLc ROL
284#define RORc ROR
285
286#endif
287
288#elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
289
290static inline unsigned ROL(unsigned word, int i)
291{
292   asm ("rotlw %0,%0,%2"
293      :"=r" (word)
294      :"0" (word),"r" (i));
295   return word;
296}
297
298static inline unsigned ROR(unsigned word, int i)
299{
300   asm ("rotlw %0,%0,%2"
301      :"=r" (word)
302      :"0" (word),"r" (32-i));
303   return word;
304}
305
306#ifndef LTC_NO_ROLC
307
308static inline unsigned ROLc(unsigned word, const int i)
309{
310   asm ("rotlwi %0,%0,%2"
311      :"=r" (word)
312      :"0" (word),"I" (i));
313   return word;
314}
315
316static inline unsigned RORc(unsigned word, const int i)
317{
318   asm ("rotrwi %0,%0,%2"
319      :"=r" (word)
320      :"0" (word),"I" (i));
321   return word;
322}
323
324#else
325
326#define ROLc ROL
327#define RORc ROR
328
329#endif
330
331
332#else
333
334/* rotates the hard way */
335#define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
336#define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
337#define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
338#define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
339
340#endif
341
342
343/* 64-bit Rotates */
344#if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM)
345
346static inline unsigned long ROL64(unsigned long word, int i)
347{
348   asm("rolq %%cl,%0"
349      :"=r" (word)
350      :"0" (word),"c" (i));
351   return word;
352}
353
354static inline unsigned long ROR64(unsigned long word, int i)
355{
356   asm("rorq %%cl,%0"
357      :"=r" (word)
358      :"0" (word),"c" (i));
359   return word;
360}
361
362#ifndef LTC_NO_ROLC
363
364static inline unsigned long ROL64c(unsigned long word, const int i)
365{
366   asm("rolq %2,%0"
367      :"=r" (word)
368      :"0" (word),"J" (i));
369   return word;
370}
371
372static inline unsigned long ROR64c(unsigned long word, const int i)
373{
374   asm("rorq %2,%0"
375      :"=r" (word)
376      :"0" (word),"J" (i));
377   return word;
378}
379
380#else /* LTC_NO_ROLC */
381
382#define ROL64c ROL64
383#define ROR64c ROR64
384
385#endif
386
387#else /* Not x86_64  */
388
389#define ROL64(x, y) \
390    ( (((x)<<((ulong64)(y)&63)) | \
391      (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
392
393#define ROR64(x, y) \
394    ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
395      ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
396
397#define ROL64c(x, y) \
398    ( (((x)<<((ulong64)(y)&63)) | \
399      (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
400
401#define ROR64c(x, y) \
402    ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
403      ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
404
405#endif
406
407#ifndef MAX
408   #define MAX(x, y) ( ((x)>(y))?(x):(y) )
409#endif
410
411#ifndef MIN
412   #define MIN(x, y) ( ((x)<(y))?(x):(y) )
413#endif
414
415/* extract a byte portably */
416#ifdef _MSC_VER
417   #define byte(x, n) ((unsigned char)((x) >> (8 * (n))))
418#else
419   #define byte(x, n) (((x) >> (8 * (n))) & 255)
420#endif
421
422/* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_macros.h,v $ */
423/* $Revision: 1.15 $ */
424/* $Date: 2006/11/29 23:43:57 $ */
425