The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
isaac.c
Go to the documentation of this file.
1/** Bob Jenkin's random number generator
2 *
3 * Bob's random number generator, ISAAC. Public Domain.
4 *
5 * http://burtleburtle.net/bob/rand/isaac.html
6 *
7 * @file src/lib/util/isaac.c
8 *
9 * @author Bob Jenkins.
10 */
11RCSID("$Id: bdb4080869a84aff8aec6350b4e529871768d996 $")
12
13#include <freeradius-devel/util/rand.h>
14
15#define RANDSIZL (8) /* I recommend 8 for crypto, 4 for simulations */
16#define RANDSIZ (1 << RANDSIZL)
17
18#define ind(mm,x) ((mm)[(x >> 2) &(RANDSIZ-1)])
19#define rngstep(mix, a, b, mm, m, m2, r, x) \
20do { \
21 x = *m; \
22 a = ((a^(mix)) + *(m2++)) & 0xffffffff; \
23 *(m++) = y = (ind(mm, x) + a + b) & 0xffffffff; \
24 *(r++) = b = (ind(mm, y >> RANDSIZL) + x) & 0xffffffff; \
25} while (0)
26
27#ifdef ISAAC_PLUS
28/*
29 * https://eprint.iacr.org/2006/438.pdf
30 *
31 * - replace shift by rotate
32 * - replace "a+b" with "a^b"
33 * - change "x+s" to "x+(s^a)"
34 */
35#define rotr(x, n) (((x) << n) | ((x) >> (32 - n)))
36#define ind(mm,x) ((mm)[rotr(x, 2) & (RANDSIZ-1)])
37#define rngstep(mix, a, b, mm, m, m2, r, x) \
38do { \
39 x = *m; \
40 a = ((a^(mix)) + *(m2++)) & 0xffffffff; \
41 *(m++) = y = (ind(mm, x) + (a ^ b)) & 0xffffffff; \
42 *(r++) = b = ((ind(mm, y >> RANDSIZL) ^ a) + x) & 0xffffffff; \
43} while (0)
44#endif
45
47{
48 register uint32_t a, b, x, y, *m, *mm, *m2, *r, *mend;
49
50 mm = ctx->randmem;
51 r = ctx->randrsl;
52 a = ctx->randa;
53 b = (ctx->randb + (++ctx->randc)) & 0xffffffff;
54
55 for (m = mm, mend = m2 = m + (RANDSIZ / 2); m < mend; ) {
56 rngstep(a << 13, a, b, mm, m, m2, r, x);
57 rngstep(a >> 6 , a, b, mm, m, m2, r, x);
58 rngstep(a << 2 , a, b, mm, m, m2, r, x);
59 rngstep(a >> 16, a, b, mm, m, m2, r, x);
60 }
61 for (m2 = mm; m2 < mend; ) {
62 rngstep(a << 13, a, b, mm, m, m2, r, x);
63 rngstep(a >> 6 , a, b, mm, m, m2, r, x);
64 rngstep(a << 2 , a, b, mm, m, m2, r, x);
65 rngstep(a >> 16, a, b, mm, m, m2, r, x);
66 }
67 ctx->randb = b;
68 ctx->randa = a;
69}
70
71
72#define mix(a,b,c,d,e,f,g,h) \
73do { \
74 a ^= b << 11; d += a; b += c; \
75 b ^= c >> 2; e += b; c += d; \
76 c ^= d << 8; f += c; d += e; \
77 d ^= e >> 16; g += d; e += f; \
78 e ^= f << 10; h += e; f += g; \
79 f ^= g >> 4; a += f; g += h; \
80 g ^= h << 8; b += g; h += a; \
81 h ^= a >> 9; c += h; a += b; \
82} while (0)
83
84/* use the contents of randrsl[] to initialize mm[]. */
86{
87 int i;
88 uint32_t a, b, c, d, e, f, g, h;
89 uint32_t *m, *r;
90
91 ctx->randa = ctx->randb = ctx->randc = 0;
92 m = ctx->randmem;
93 r = ctx->randrsl;
94
95 /*
96 * The golden ratio 0x9e3779b9 in each of a to h, scrambled by
97 * four rounds of mix(). The values are precomputed because
98 * mix() on constants is all known-value overflow.
99 */
100 a = 0x1367df5a;
101 b = 0x95d90059;
102 c = 0xc3163e4b;
103 d = 0x0f421ad8;
104 e = 0xd92a4a78;
105 f = 0xa51a3c49;
106 g = 0xc4efea1b;
107 h = 0x30609119;
108
109 /* initialize using the contents of r[] as the seed */
110 for (i = 0; i < RANDSIZ; i += 8) {
111 a += r[i ]; b += r[i + 1]; c +=r [i + 2]; d += r[i + 3];
112 e += r[i + 4]; f += r[i + 5]; g +=r [i + 6]; h += r[i + 7];
113 mix(a, b, c, d, e, f, g, h);
114 m[i ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d;
115 m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h;
116 }
117 /* do a second pass to make all of the seed affect all of m */
118 for (i = 0; i < RANDSIZ; i += 8) {
119 a += m[i ]; b += m[i + 1]; c += m[i + 2]; d += m[i + 3];
120 e += m[i + 4]; f += m[i + 5]; g += m[i + 6]; h += m[i + 7];
121 mix(a, b, c, d, e, f, g, h);
122 m[i ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d;
123 m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h;
124 }
125
126 fr_isaac(ctx); /* fill in the first set of results */
127 ctx->randcnt = RANDSIZ; /* prepare to use the first set of results */
128}
129
130
131#ifdef TEST
132/*
133 * For testing. Output should be the same as
134 *
135 * http://burtleburtle.net/bob/rand/randvect.txt
136 */
137int main()
138{
139 uint32_t i,j;
140 fr_randctx ctx;
141
142 ctx.randa = ctx.randb = ctx.randc = (uint32_t)0;
143
144 for (i = 0; i < 256; ++i) ctx.randrsl[i] = (uint32_t)0;
145
146 fr_isaac_init(&ctx);
147 for (i = 0; i < 2; ++i) {
148 fr_isaac(&ctx);
149 for (j = 0; j < 256; ++j) {
150 printf("%.8lx",ctx.randrsl[j]);
151 if ((j & 7) == 7) printf("\n");
152 }
153 }
154}
155#endif
#define RCSID(id)
Definition build.h:603
int main(int argc, char **argv)
Definition dhcpclient.c:530
void fr_isaac_init(fr_randctx *ctx)
Definition isaac.c:85
#define RANDSIZ
Definition isaac.c:16
void fr_isaac(fr_randctx *ctx)
Definition isaac.c:46
#define rngstep(mix, a, b, mm, m, m2, r, x)
Definition isaac.c:19
#define mix(a, b, c, d, e, f, g, h)
Definition isaac.c:72
unsigned int uint32_t
uint32_t randb
Definition rand.h:43
uint32_t randmem[256]
Definition rand.h:41
uint32_t randrsl[256]
Definition rand.h:40
uint32_t randc
Definition rand.h:44
uint32_t randcnt
Definition rand.h:39
uint32_t randa
Definition rand.h:42