The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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: 26a821633e00d0fed1f4db9f17345c271f85a515 $")
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/* if (flag==1), then use the contents of randrsl[] to initialize mm[]. */
85void fr_isaac_init(fr_randctx *ctx, int flag)
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 a = b = c = d = e = f = g = h = 0x9e3779b9; /* the golden ratio */
95
96 /* scramble it */
97 for (i = 0; i < 4; ++i) {
98 /* coverity[overflow_const] */
99 mix(a, b, c, d, e, f, g, h);
100 }
101
102 if (flag) {
103 /* initialize using the contents of r[] as the seed */
104 for (i = 0; i < RANDSIZ; i += 8) {
105 a += r[i ]; b += r[i + 1]; c +=r [i + 2]; d += r[i + 3];
106 e += r[i + 4]; f += r[i + 5]; g +=r [i + 6]; h += r[i + 7];
107 mix(a, b, c, d, e, f, g, h);
108 m[i ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d;
109 m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h;
110 }
111 /* do a second pass to make all of the seed affect all of m */
112 for (i = 0; i < RANDSIZ; i += 8) {
113 a += m[i ]; b += m[i + 1]; c += m[i + 2]; d += m[i + 3];
114 e += m[i + 4]; f += m[i + 5]; g += m[i + 6]; h += m[i + 7];
115 mix(a, b, c, d, e, f, g, h);
116 m[i ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d;
117 m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h;
118 }
119 } else {
120 for (i = 0; i < RANDSIZ; i += 8) {
121 /* fill in mm[] with messy stuff */
122 mix(a, b, c, d, e, f, g, h);
123 m[i ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d;
124 m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h;
125 }
126 }
127
128 fr_isaac(ctx); /* fill in the first set of results */
129 ctx->randcnt = RANDSIZ; /* prepare to use the first set of results */
130}
131
132
133#ifdef TEST
134/*
135 * For testing. Output should be the same as
136 *
137 * http://burtleburtle.net/bob/rand/randvect.txt
138 */
139int main()
140{
141 uint32_t i,j;
142 fr_randctx ctx;
143
144 ctx.randa = ctx.randb = ctx.randc = (uint32_t)0;
145
146 for (i = 0; i < 256; ++i) ctx.randrsl[i] = (uint32_t)0;
147
148 fr_isaac_init(&ctx, 1);
149 for (i = 0; i < 2; ++i) {
150 fr_isaac(&ctx);
151 for (j = 0; j < 256; ++j) {
152 printf("%.8lx",ctx.randrsl[j]);
153 if ((j & 7) == 7) printf("\n");
154 }
155 }
156}
157#endif
#define RCSID(id)
Definition build.h:483
int main(int argc, char **argv)
Definition dhcpclient.c:524
void fr_isaac_init(fr_randctx *ctx, int flag)
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