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) \ 73 asm __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) \ 80 asm __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) \ 104 asm __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) \ 111 asm __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 247 static 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 255 static 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 265 static 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 273 static 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 290 static 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 298 static 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 308 static 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 316 static 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 346 static 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 354 static 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 364 static 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 372 static 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$ */ 423 /* $Revision$ */ 424 /* $Date$ */ 425