1 /* Bob Jenkins's cryptographic random number generator, ISAAC.
3 Copyright (C) 1999-2006 Free Software Foundation, Inc.
4 Copyright (C) 1997, 1998, 1999 Colin Plumb.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software Foundation,
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 Written by Colin Plumb. */
23 * --------------------------------------------------------------------
24 * We need a source of random numbers for some data.
25 * Cryptographically secure is desirable, but it's not life-or-death
26 * so I can be a little bit experimental in the choice of RNGs here.
28 * This generator is based somewhat on RC4, but has analysis
29 * <http://burtleburtle.net/bob/rand/isaacafa.html>
30 * pointing to it actually being better. I like it because it's nice
31 * and fast, and because the author did good work analyzing it.
32 * --------------------------------------------------------------------
36 #include "rand-isaac.h"
41 #include "gethrxtime.h"
44 /* This index operation is more efficient on many processors */
46 (* (uint32_t *) ((char *) (mm) \
47 + ((x) & (ISAAC_WORDS - 1) * sizeof (uint32_t))))
50 * The central step. This uses two temporaries, x and y. mm is the
51 * whole state array, while m is a pointer to the current word. off is
52 * the offset from m to the word ISAAC_WORDS/2 words away in the mm array,
53 * i.e. +/- ISAAC_WORDS/2.
55 #define isaac_step(mix, a, b, mm, m, off, r) \
57 a = ((a) ^ (mix)) + (m)[off], \
59 *(m) = y = ind (mm, x) + (a) + (b), \
60 *(r) = b = ind (mm, (y) >> ISAAC_LOG) + x \
63 /* Use and update *S to generate random data to fill R. */
65 isaac_refill (struct isaac_state
*s
, uint32_t r
[ISAAC_WORDS
])
67 uint32_t a
, b
; /* Caches of a and b */
68 uint32_t x
, y
; /* Temps needed by isaac_step macro */
69 uint32_t *m
= s
->mm
; /* Pointer into state array */
76 isaac_step (a
<< 13, a
, b
, s
->mm
, m
, ISAAC_WORDS
/ 2, r
);
77 isaac_step (a
>> 6, a
, b
, s
->mm
, m
+ 1, ISAAC_WORDS
/ 2, r
+ 1);
78 isaac_step (a
<< 2, a
, b
, s
->mm
, m
+ 2, ISAAC_WORDS
/ 2, r
+ 2);
79 isaac_step (a
>> 16, a
, b
, s
->mm
, m
+ 3, ISAAC_WORDS
/ 2, r
+ 3);
82 while ((m
+= 4) < s
->mm
+ ISAAC_WORDS
/ 2);
85 isaac_step (a
<< 13, a
, b
, s
->mm
, m
, -ISAAC_WORDS
/ 2, r
);
86 isaac_step (a
>> 6, a
, b
, s
->mm
, m
+ 1, -ISAAC_WORDS
/ 2, r
+ 1);
87 isaac_step (a
<< 2, a
, b
, s
->mm
, m
+ 2, -ISAAC_WORDS
/ 2, r
+ 2);
88 isaac_step (a
>> 16, a
, b
, s
->mm
, m
+ 3, -ISAAC_WORDS
/ 2, r
+ 3);
91 while ((m
+= 4) < s
->mm
+ ISAAC_WORDS
);
97 * The basic seed-scrambling step for initialization, based on Bob
98 * Jenkins' 256-bit hash.
100 #define mix(a,b,c,d,e,f,g,h) \
101 ( a ^= b << 11, d += a, \
102 b += c, b ^= c >> 2, e += b, \
103 c += d, c ^= d << 8, f += c, \
104 d += e, d ^= e >> 16, g += d, \
105 e += f, e ^= f << 10, h += e, \
106 f += g, f ^= g >> 4, a += f, \
107 g += h, g ^= h << 8, b += g, \
108 h += a, h ^= a >> 9, c += h, \
111 /* The basic ISAAC initialization pass. */
113 isaac_mix (struct isaac_state
*s
, uint32_t const seed
[/* ISAAC_WORDS */])
116 uint32_t a
= s
->iv
[0];
117 uint32_t b
= s
->iv
[1];
118 uint32_t c
= s
->iv
[2];
119 uint32_t d
= s
->iv
[3];
120 uint32_t e
= s
->iv
[4];
121 uint32_t f
= s
->iv
[5];
122 uint32_t g
= s
->iv
[6];
123 uint32_t h
= s
->iv
[7];
125 for (i
= 0; i
< ISAAC_WORDS
; i
+= 8)
136 mix (a
, b
, c
, d
, e
, f
, g
, h
);
158 #if 0 /* Provided for reference only; not used in this code */
160 * Initialize the ISAAC RNG with the given seed material.
161 * Its size MUST be a multiple of ISAAC_BYTES, and may be
162 * stored in the s->mm array.
164 * This is a generalization of the original ISAAC initialization code
165 * to support larger seed sizes. For seed sizes of 0 and ISAAC_BYTES,
169 isaac_init (struct isaac_state
*s
, uint32_t const *seed
, size_t seedsize
)
171 static uint32_t const iv
[8] =
173 0x1367df5a, 0x95d90059, 0xc3163e4b, 0x0f421ad8,
174 0xd92a4a78, 0xa51a3c49, 0xc4efea1b, 0x30609119};
178 /* The initialization of iv is a precomputed form of: */
179 for (i
= 0; i
< 7; i
++)
180 iv
[i
] = 0x9e3779b9; /* the golden ratio */
181 for (i
= 0; i
< 4; ++i
) /* scramble it */
182 mix (iv
[0], iv
[1], iv
[2], iv
[3], iv
[4], iv
[5], iv
[6], iv
[7]);
184 s
->a
= s
->b
= s
->c
= 0;
186 for (i
= 0; i
< 8; i
++)
191 /* First pass (as in reference ISAAC code) */
193 /* Second and subsequent passes (extension to ISAAC) */
194 while (seedsize
-= ISAAC_BYTES
)
197 for (i
= 0; i
< ISAAC_WORDS
; i
++)
199 isaac_mix (s
, s
->mm
);
204 /* The no seed case (as in reference ISAAC code) */
205 for (i
= 0; i
< ISAAC_WORDS
; i
++)
210 isaac_mix (s
, s
->mm
);
214 /* Initialize *S to a somewhat-random value. */
216 isaac_seed_start (struct isaac_state
*s
)
218 static uint32_t const iv
[8] =
220 0x1367df5a, 0x95d90059, 0xc3163e4b, 0x0f421ad8,
221 0xd92a4a78, 0xa51a3c49, 0xc4efea1b, 0x30609119
225 /* The initialization of iv is a precomputed form of: */
227 for (i
= 0; i
< 7; i
++)
228 iv
[i
] = 0x9e3779b9; /* the golden ratio */
229 for (i
= 0; i
< 4; ++i
) /* scramble it */
230 mix (iv
[0], iv
[1], iv
[2], iv
[3], iv
[4], iv
[5], iv
[6], iv
[7]);
233 memset (s
->mm
, 0, sizeof s
->mm
);
234 memcpy (s
->iv
, iv
, sizeof s
->iv
);
236 /* s->c gets used for a data pointer during the seeding phase */
237 s
->a
= s
->b
= s
->c
= 0;
240 /* Add a buffer of seed material. */
242 isaac_seed_data (struct isaac_state
*s
, void const *buffer
, size_t size
)
244 unsigned char const *buf
= buffer
;
249 avail
= sizeof s
->mm
- s
->c
; /* s->c is used as a write pointer */
251 /* Do any full buffers that are necessary */
254 p
= (unsigned char *) s
->mm
+ s
->c
;
255 for (i
= 0; i
< avail
; i
++)
259 isaac_mix (s
, s
->mm
);
261 avail
= sizeof s
->mm
;
264 /* And the final partial block */
265 p
= (unsigned char *) s
->mm
+ s
->c
;
266 for (i
= 0; i
< size
; i
++)
272 /* End of seeding phase; get everything ready to produce output. */
274 isaac_seed_finish (struct isaac_state
*s
)
276 isaac_mix (s
, s
->mm
);
277 isaac_mix (s
, s
->mm
);
278 /* Now reinitialize c to start things off right */
281 #define ISAAC_SEED(s,x) isaac_seed_data (s, &(x), sizeof (x))
283 /* Initialize *S to a somewhat-random value; this starts seeding,
284 seeds with somewhat-random data, and finishes seeding. */
286 isaac_seed (struct isaac_state
*s
)
288 isaac_seed_start (s
);
290 { pid_t t
= getpid (); ISAAC_SEED (s
, t
); }
291 { pid_t t
= getppid (); ISAAC_SEED (s
, t
); }
292 { uid_t t
= getuid (); ISAAC_SEED (s
, t
); }
293 { gid_t t
= getgid (); ISAAC_SEED (s
, t
); }
296 xtime_t t
= gethrxtime ();
300 isaac_seed_finish (s
);