Coverage Report

Created: 2023-12-08 06:56

/src/freeradius-server/src/lib/util/isaac.c
Line
Count
Source (jump to first uncovered line)
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
 */
11
RCSID("$Id: 34a829076fb450282b995ff0c58c4eaf88f8334f $")
12
13
#include <freeradius-devel/util/rand.h>
14
15
10.4k
#define RANDSIZL   (8)  /* I recommend 8 for crypto, 4 for simulations */
16
10.4k
#define RANDSIZ    (1 << RANDSIZL)
17
18
9.21k
#define ind(mm,x)  ((mm)[(x >> 2) &(RANDSIZ-1)])
19
4.60k
#define rngstep(mix, a, b, mm, m, m2, r, x) \
20
4.60k
do { \
21
4.60k
  x = *m;  \
22
4.60k
  a = ((a^(mix)) + *(m2++)) & 0xffffffff; \
23
4.60k
  *(m++) = y = (ind(mm, x) + a + b) & 0xffffffff; \
24
4.60k
  *(r++) = b = (ind(mm, y >> RANDSIZL) + x) & 0xffffffff; \
25
4.60k
} while (0)
26
27
void fr_isaac(fr_randctx *ctx)
28
18
{
29
18
  register uint32_t a, b, x, y, *m, *mm, *m2, *r, *mend;
30
31
18
  mm = ctx->randmem;
32
18
  r = ctx->randrsl;
33
18
  a = ctx->randa;
34
18
  b = (ctx->randb + (++ctx->randc)) & 0xffffffff;
35
36
594
  for (m = mm, mend = m2 = m + (RANDSIZ / 2); m < mend; ) {
37
576
    rngstep(a << 13, a, b, mm, m, m2, r, x);
38
576
    rngstep(a >> 6 , a, b, mm, m, m2, r, x);
39
576
    rngstep(a << 2 , a, b, mm, m, m2, r, x);
40
576
    rngstep(a >> 16, a, b, mm, m, m2, r, x);
41
576
  }
42
594
  for (m2 = mm; m2 < mend; ) {
43
576
    rngstep(a << 13, a, b, mm, m, m2, r, x);
44
576
    rngstep(a >> 6 , a, b, mm, m, m2, r, x);
45
576
    rngstep(a << 2 , a, b, mm, m, m2, r, x);
46
576
    rngstep(a >> 16, a, b, mm, m, m2, r, x);
47
576
  }
48
18
  ctx->randb = b;
49
18
  ctx->randa = a;
50
18
}
51
52
53
1.22k
#define mix(a,b,c,d,e,f,g,h) \
54
1.22k
do { \
55
1.22k
  a ^= b << 11; d += a; b += c; \
56
1.22k
  b ^= c >> 2;  e += b; c += d; \
57
1.22k
  c ^= d << 8;  f += c; d += e; \
58
1.22k
  d ^= e >> 16; g += d; e += f; \
59
1.22k
  e ^= f << 10; h += e; f += g; \
60
1.22k
  f ^= g >> 4;  a += f; g += h; \
61
1.22k
  g ^= h << 8;  b += g; h += a; \
62
1.22k
  h ^= a >> 9;  c += h; a += b; \
63
1.22k
} while (0)
64
65
/* if (flag==1), then use the contents of randrsl[] to initialize mm[]. */
66
void fr_rand_init(fr_randctx *ctx, int flag)
67
18
{
68
18
  int   i;
69
18
  uint32_t  a, b, c, d, e, f, g, h;
70
18
  uint32_t  *m, *r;
71
72
18
  ctx->randa = ctx->randb = ctx->randc = 0;
73
18
  m = ctx->randmem;
74
18
  r = ctx->randrsl;
75
18
  a = b = c = d = e = f = g = h = 0x9e3779b9;  /* the golden ratio */
76
77
  /* scramble it */
78
90
  for (i = 0; i < 4; ++i) mix(a, b, c, d, e, f, g, h);
79
80
18
  if (flag) {
81
    /* initialize using the contents of r[] as the seed */
82
594
    for (i = 0; i < RANDSIZ; i += 8) {
83
576
      a += r[i    ]; b += r[i + 1]; c +=r [i + 2]; d += r[i + 3];
84
576
      e += r[i + 4]; f += r[i + 5]; g +=r [i + 6]; h += r[i + 7];
85
576
      mix(a, b, c, d, e, f, g, h);
86
576
      m[i    ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d;
87
576
      m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h;
88
576
    }
89
    /* do a second pass to make all of the seed affect all of m */
90
594
    for (i = 0; i < RANDSIZ; i += 8) {
91
576
      a += m[i    ]; b += m[i + 1]; c += m[i + 2]; d += m[i + 3];
92
576
      e += m[i + 4]; f += m[i + 5]; g += m[i + 6]; h += m[i + 7];
93
576
      mix(a, b, c, d, e, f, g, h);
94
576
      m[i    ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d;
95
576
      m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h;
96
576
    }
97
18
  } else {
98
0
    for (i = 0; i < RANDSIZ; i += 8) {
99
      /* fill in mm[] with messy stuff */
100
0
      mix(a, b, c, d, e, f, g, h);
101
0
      m[i    ] = a; m[i + 1] = b; m[i + 2] = c; m[i + 3] = d;
102
0
      m[i + 4] = e; m[i + 5] = f; m[i + 6] = g; m[i + 7] = h;
103
0
    }
104
0
  }
105
106
18
  fr_isaac(ctx);       /* fill in the first set of results */
107
18
  ctx->randcnt = RANDSIZ;  /* prepare to use the first set of results */
108
18
}
109
110
111
#ifdef TEST
112
/*
113
 *  For testing.  Output should be the same as
114
 *
115
 *  http://burtleburtle.net/bob/rand/randvect.txt
116
 */
117
int main()
118
{
119
  uint32_t  i,j;
120
  fr_randctx  ctx;
121
122
  ctx.randa = ctx.randb = ctx.randc = (uint32_t)0;
123
124
  for (i = 0; i < 256; ++i) ctx.randrsl[i] = (uint32_t)0;
125
126
  fr_rand_init(&ctx, 1);
127
  for (i = 0; i < 2; ++i) {
128
    fr_isaac(&ctx);
129
    for (j = 0; j < 256; ++j) {
130
      printf("%.8lx",ctx.randrsl[j]);
131
      if ((j & 7) == 7) printf("\n");
132
    }
133
  }
134
}
135
#endif