1 /* This file is derived from sober128 implementation in corosync
2 cluster engine. corosync cluster engine borrows the implementation
5 The latest version of the original code can be found at
6 http://libtom.org/?page=features according to which this code is in the
11 * ---------------------------------------------------------------------
12 * LibTomCrypt, modular cryptographic library -- Tom St Denis
14 * LibTomCrypt is a library that provides various cryptographic
15 * algorithms in a highly modular and flexible manner.
17 * The library is free for all purposes without any express
20 * Tom St Denis, tomstdenis@iahu.ca, http://libtom.org/?page=features
24 #include <string.h> /* for memcpy */
26 #define CONST64(n) n ## ULL
28 typedef unsigned long ulong32;
29 typedef unsigned long long ulong64;
31 #ifdef WORDS_BIGENDIAN
37 #if defined(__WORDSIZE)
39 #define ENDIAN_64BITWORD
42 #define ENDIAN_32BITWORD
45 /* XXX need to find a better default
47 #define ENDIAN_32BITWORD
50 /* ---- HELPER MACROS ---- */
53 #define STORE32L(x, y) \
54 { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
55 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
57 #define LOAD32L(x, y) \
58 { x = ((unsigned long)((y)[3] & 255)<<24) | \
59 ((unsigned long)((y)[2] & 255)<<16) | \
60 ((unsigned long)((y)[1] & 255)<<8) | \
61 ((unsigned long)((y)[0] & 255)); }
63 #define STORE64L(x, y) \
64 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
65 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
66 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
67 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
69 #define LOAD64L(x, y) \
70 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
71 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
72 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
73 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
75 #define STORE32H(x, y) \
76 { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
77 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
79 #define LOAD32H(x, y) \
80 { x = ((unsigned long)((y)[0] & 255)<<24) | \
81 ((unsigned long)((y)[1] & 255)<<16) | \
82 ((unsigned long)((y)[2] & 255)<<8) | \
83 ((unsigned long)((y)[3] & 255)); }
85 #define STORE64H(x, y) \
86 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
87 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
88 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
89 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
91 #define LOAD64H(x, y) \
92 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
93 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
94 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
95 (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
97 #endif /* ENDIAN_NEUTRAL */
101 #define STORE32H(x, y) \
102 { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
103 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
105 #define LOAD32H(x, y) \
106 { x = ((unsigned long)((y)[0] & 255)<<24) | \
107 ((unsigned long)((y)[1] & 255)<<16) | \
108 ((unsigned long)((y)[2] & 255)<<8) | \
109 ((unsigned long)((y)[3] & 255)); }
111 #define STORE64H(x, y) \
112 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
113 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
114 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
115 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
117 #define LOAD64H(x, y) \
118 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
119 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
120 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
121 (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
123 #ifdef ENDIAN_32BITWORD
125 #define STORE32L(x, y) \
126 { unsigned long __t = (x); memcpy(y, &__t, 4); }
128 #define LOAD32L(x, y) \
131 #define STORE64L(x, y) \
132 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
133 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
134 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
135 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
137 #define LOAD64L(x, y) \
138 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
139 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
140 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
141 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
143 #else /* 64-bit words then */
145 #define STORE32L(x, y) \
146 { unsigned long __t = (x); memcpy(y, &__t, 4); }
148 #define LOAD32L(x, y) \
149 { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
151 #define STORE64L(x, y) \
152 { ulong64 __t = (x); memcpy(y, &__t, 8); }
154 #define LOAD64L(x, y) \
155 { memcpy(&(x), y, 8); }
157 #endif /* ENDIAN_64BITWORD */
159 #endif /* ENDIAN_LITTLE */
162 #define STORE32L(x, y) \
163 { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
164 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
166 #define LOAD32L(x, y) \
167 { x = ((unsigned long)((y)[3] & 255)<<24) | \
168 ((unsigned long)((y)[2] & 255)<<16) | \
169 ((unsigned long)((y)[1] & 255)<<8) | \
170 ((unsigned long)((y)[0] & 255)); }
172 #define STORE64L(x, y) \
173 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
174 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
175 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
176 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
178 #define LOAD64L(x, y) \
179 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
180 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
181 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
182 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
184 #ifdef ENDIAN_32BITWORD
186 #define STORE32H(x, y) \
187 { unsigned long __t = (x); memcpy(y, &__t, 4); }
189 #define LOAD32H(x, y) \
192 #define STORE64H(x, y) \
193 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
194 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
195 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
196 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
198 #define LOAD64H(x, y) \
199 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
200 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
201 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
202 (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
204 #else /* 64-bit words then */
206 #define STORE32H(x, y) \
207 { unsigned long __t = (x); memcpy(y, &__t, 4); }
209 #define LOAD32H(x, y) \
210 { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
212 #define STORE64H(x, y) \
213 { ulong64 __t = (x); memcpy(y, &__t, 8); }
215 #define LOAD64H(x, y) \
216 { memcpy(&(x), y, 8); }
218 #endif /* ENDIAN_64BITWORD */
219 #endif /* ENDIAN_BIG */
221 #define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \
222 ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )
224 #if defined(__GNUC__) && defined(__i386__) && !defined(INTEL_CC)
226 static inline unsigned long ROL(unsigned long word, int i)
228 __asm__("roll %%cl,%0"
230 :"0" (word),"c" (i));
234 static inline unsigned long ROR(unsigned long word, int i)
236 __asm__("rorl %%cl,%0"
238 :"0" (word),"c" (i));
244 /* rotates the hard way */
245 #define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
246 #define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
250 #define ROL64(x, y) \
251 ( (((x)<<((ulong64)(y)&63)) | \
252 (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
254 #define ROR64(x, y) \
255 ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
256 ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
260 #define MAX(x, y) ( ((x)>(y))?(x):(y) )
261 #define MIN(x, y) ( ((x)<(y))?(x):(y) )
263 /* extract a byte portably */
264 #define byte(x, n) (((x) >> (8 * (n))) & 255)
266 #define CONST64(n) n ## ULL
270 * The mycrypt_macros.h file
273 /* ---- HELPER MACROS ---- */
274 #ifdef ENDIAN_NEUTRAL
276 #define STORE32L(x, y) \
277 { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
278 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
280 #define LOAD32L(x, y) \
281 { x = ((unsigned long)((y)[3] & 255)<<24) | \
282 ((unsigned long)((y)[2] & 255)<<16) | \
283 ((unsigned long)((y)[1] & 255)<<8) | \
284 ((unsigned long)((y)[0] & 255)); }
286 #define STORE64L(x, y) \
287 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
288 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
289 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
290 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
292 #define LOAD64L(x, y) \
293 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
294 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
295 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
296 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
298 #define STORE32H(x, y) \
299 { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
300 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
302 #define LOAD32H(x, y) \
303 { x = ((unsigned long)((y)[0] & 255)<<24) | \
304 ((unsigned long)((y)[1] & 255)<<16) | \
305 ((unsigned long)((y)[2] & 255)<<8) | \
306 ((unsigned long)((y)[3] & 255)); }
308 #define STORE64H(x, y) \
309 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
310 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
311 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
312 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
314 #define LOAD64H(x, y) \
315 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
316 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
317 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
318 (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
320 #endif /* ENDIAN_NEUTRAL */
324 #define STORE32H(x, y) \
325 { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
326 (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
328 #define LOAD32H(x, y) \
329 { x = ((unsigned long)((y)[0] & 255)<<24) | \
330 ((unsigned long)((y)[1] & 255)<<16) | \
331 ((unsigned long)((y)[2] & 255)<<8) | \
332 ((unsigned long)((y)[3] & 255)); }
334 #define STORE64H(x, y) \
335 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
336 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
337 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
338 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
340 #define LOAD64H(x, y) \
341 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
342 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
343 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
344 (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
346 #ifdef ENDIAN_32BITWORD
348 #define STORE32L(x, y) \
349 { unsigned long __t = (x); memcpy(y, &__t, 4); }
351 #define LOAD32L(x, y) \
354 #define STORE64L(x, y) \
355 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
356 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
357 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
358 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
360 #define LOAD64L(x, y) \
361 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
362 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
363 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
364 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
366 #else /* 64-bit words then */
368 #define STORE32L(x, y) \
369 { unsigned long __t = (x); memcpy(y, &__t, 4); }
371 #define LOAD32L(x, y) \
372 { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
374 #define STORE64L(x, y) \
375 { ulong64 __t = (x); memcpy(y, &__t, 8); }
377 #define LOAD64L(x, y) \
378 { memcpy(&(x), y, 8); }
380 #endif /* ENDIAN_64BITWORD */
382 #endif /* ENDIAN_LITTLE */
385 #define STORE32L(x, y) \
386 { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
387 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
389 #define LOAD32L(x, y) \
390 { x = ((unsigned long)((y)[3] & 255)<<24) | \
391 ((unsigned long)((y)[2] & 255)<<16) | \
392 ((unsigned long)((y)[1] & 255)<<8) | \
393 ((unsigned long)((y)[0] & 255)); }
395 #define STORE64L(x, y) \
396 { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
397 (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
398 (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
399 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
401 #define LOAD64L(x, y) \
402 { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
403 (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
404 (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
405 (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
407 #ifdef ENDIAN_32BITWORD
409 #define STORE32H(x, y) \
410 { unsigned long __t = (x); memcpy(y, &__t, 4); }
412 #define LOAD32H(x, y) \
415 #define STORE64H(x, y) \
416 { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
417 (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
418 (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
419 (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
421 #define LOAD64H(x, y) \
422 { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
423 (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
424 (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
425 (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
427 #else /* 64-bit words then */
429 #define STORE32H(x, y) \
430 { unsigned long __t = (x); memcpy(y, &__t, 4); }
432 #define LOAD32H(x, y) \
433 { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
435 #define STORE64H(x, y) \
436 { ulong64 __t = (x); memcpy(y, &__t, 8); }
438 #define LOAD64H(x, y) \
439 { memcpy(&(x), y, 8); }
441 #endif /* ENDIAN_64BITWORD */
442 #endif /* ENDIAN_BIG */
444 #define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \
445 ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )
448 #define ROL64(x, y) \
449 ( (((x)<<((ulong64)(y)&63)) | \
450 (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
452 #define ROR64(x, y) \
453 ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
454 ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
458 #define MAX(x, y) ( ((x)>(y))?(x):(y) )
459 #define MIN(x, y) ( ((x)<(y))?(x):(y) )
461 /* extract a byte portably */
462 #define byte(x, n) (((x) >> (8 * (n))) & 255)
464 /* Id: s128multab.h 213 2003-12-16 04:27:12Z ggr $ */
465 /* @(#)TuringMultab.h 1.3 (QUALCOMM) 02/09/03 */
466 /* Multiplication table for Turing using 0xD02B4367 */
468 static const ulong32 Multab[256] = {
469 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9,
470 0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478,
471 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746,
472 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697,
473 0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A,
474 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB,
475 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5,
476 0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04,
477 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2,
478 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613,
479 0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D,
480 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC,
481 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51,
482 0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80,
483 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE,
484 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F,
485 0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F,
486 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE,
487 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90,
488 0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41,
489 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC,
490 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D,
491 0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703,
492 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2,
493 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14,
494 0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5,
495 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB,
496 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A,
497 0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787,
498 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656,
499 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568,
500 0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9,
501 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748,
502 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699,
503 0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7,
504 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476,
505 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB,
506 0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A,
507 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34,
508 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5,
509 0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523,
510 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2,
511 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC,
512 0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D,
513 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0,
514 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61,
515 0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F,
516 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E,
517 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E,
518 0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F,
519 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71,
520 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0,
521 0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D,
522 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC,
523 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2,
524 0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433,
525 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5,
526 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24,
527 0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A,
528 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB,
529 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566,
530 0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7,
531 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789,
532 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658,
535 /* Id: s128sbox.h 213 2003-12-16 04:27:12Z ggr $ */
536 /* Sbox for SOBER-128 */
538 * This is really the combination of two SBoxes; the least significant
539 * 24 bits comes from:
540 * 8->32 Sbox generated by Millan et. al. at Queensland University of
541 * Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter,
542 * "On the Design of 8*32 S-boxes". Unpublished report, by the
543 * Information Systems Research Centre,
544 * Queensland University of Technology, 1999.
546 * The most significant 8 bits are the Skipjack "F table", which can be
547 * found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf .
548 * In this optimised table, though, the intent is to XOR the word from
549 * the table selected by the high byte with the input word. Thus, the
550 * high byte is actually the Skipjack F-table entry XORED with its
553 static const ulong32 Sbox[256] = {
554 0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4,
555 0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae,
556 0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c,
557 0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35,
558 0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e,
559 0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b,
560 0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f,
561 0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1,
562 0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd,
563 0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3,
564 0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f,
565 0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36,
566 0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf,
567 0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816,
568 0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d,
569 0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af,
570 0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6,
571 0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418,
572 0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0,
573 0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd,
574 0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088,
575 0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759,
576 0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895,
577 0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66,
578 0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc,
579 0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1,
580 0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911,
581 0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e,
582 0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515,
583 0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133,
584 0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226,
585 0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084,
586 0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb,
587 0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184,
588 0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420,
589 0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02,
590 0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655,
591 0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c,
592 0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418,
593 0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473,
594 0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a,
595 0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0,
596 0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21,
597 0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36,
598 0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5,
599 0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6,
600 0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0,
601 0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795,
602 0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0,
603 0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78,
604 0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da,
605 0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a,
606 0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118,
607 0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed,
608 0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd,
609 0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b,
610 0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921,
611 0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e,
612 0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5,
613 0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8,
614 0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376,
615 0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a,
616 0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8,
617 0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40,
621 /* Implementation of SOBER-128 by Tom St Denis.
622 * Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
625 /* don't change these... */
627 #define FOLD N /* how many iterations of folding to do */
628 #define INITKONST 0x6996c53a /* value of KONST to use during key loading */
629 #define KEYP 15 /* where to insert key words */
630 #define FOLDP 4 /* where to insert non-linear feedback */
632 #define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF))
634 static ulong32 BYTE2WORD(unsigned char *b)
641 #define WORD2BYTE(w, b) STORE32L(b, w)
643 static void XORWORD(ulong32 w, unsigned char *b)
651 /* give correct offset for the current position of the register,
652 * where logically R[0] is at position "zero".
654 #define OFF(zero, i) (((zero)+(i)) % N)
657 /* After stepping, "zero" moves right one place */
659 R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF];
661 static void cycle(ulong32 *R)
668 for (i = 1; i < N; ++i) {
674 /* Return a non-linear function of some parts of the register.
676 #define NLFUNC(c,z) \
678 t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \
679 t ^= Sbox[(t >> 24) & 0xFF]; \
681 t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \
682 t ^= Sbox[(t >> 24) & 0xFF]; \
683 t = t + c->R[OFF(z,13)]; \
686 static ulong32 nltap(sober128_prng *c)
693 /* initialise to known state
695 int sober128_start(sober128_prng *c)
699 /* Register initialised to Fibonacci numbers */
702 for (i = 2; i < N; ++i) {
703 c->R[i] = c->R[i-1] + c->R[i-2];
705 c->konst = INITKONST;
707 /* next add_entropy will be the key */
714 /* Save the current register state
716 static void s128_savestate(sober128_prng *c)
719 for (i = 0; i < N; ++i) {
720 c->initR[i] = c->R[i];
724 /* initialise to previously saved register state
726 static void s128_reloadstate(sober128_prng *c)
730 for (i = 0; i < N; ++i) {
731 c->R[i] = c->initR[i];
735 /* Initialise "konst"
737 static void s128_genkonst(sober128_prng *c)
744 } while ((newkonst & 0xFF000000) == 0);
748 /* Load key material into the register
756 /* nonlinear diffusion of register for key */
757 #define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t;
758 static void s128_diffuse(sober128_prng *c)
761 /* relies on FOLD == N == 17! */
781 int sober128_add_entropy(const unsigned char *buf, unsigned long len, sober128_prng *c)
787 /* this is the first call to the add_entropy so this input is the key */
788 /* len must be multiple of 4 bytes */
789 /* assert ((len & 3) == 0); */
791 for (i = 0; i < len; i += 4) {
792 k = BYTE2WORD((unsigned char *)&buf[i]);
798 /* also fold in the length of the key */
810 /* ok we are adding an IV then... */
813 /* len must be multiple of 4 bytes */
814 /* assert ((len & 3) == 0); */
816 for (i = 0; i < len; i += 4) {
817 k = BYTE2WORD((unsigned char *)&buf[i]);
823 /* also fold in the length of the key */
834 /* XOR pseudo-random bytes into buffer
836 #define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, buf+(z*4));
838 unsigned long sober128_read(unsigned char *buf, unsigned long nbytes, sober128_prng *c)
844 /* handle any previously buffered bytes */
845 while (c->nbuf != 0 && nbytes != 0) {
846 *buf++ ^= c->sbuf & 0xFF;
853 /* do lots at a time, if there's enough to do */
854 while (nbytes >= N*4) {
877 /* do small or odd size buffers the slow way */
878 while (4 <= nbytes) {
886 /* handle any trailing bytes */
891 while (c->nbuf != 0 && nbytes != 0) {
892 *buf++ ^= c->sbuf & 0xFF;
903 * Editor modelines - http://www.wireshark.org/tools/modelines.html
908 * indent-tabs-mode: nil
911 * vi: set shiftwidth=4 tabstop=8 expandtab:
912 * :indentSize=4:tabSize=8:noTabs=true: