isaac.c
Go to the documentation of this file.
1 /*
2 ------------------------------------------------------------------------------
3 http://burtleburtle.net/bob/rand/isaac.html
4 rand.c: By Bob Jenkins. My random number generator, ISAAC. Public Domain
5 MODIFIED:
6  960327: Creation (addition of randinit, really)
7  970719: use context, not global variables, for internal state
8  980324: make a portable version
9  010626: Note this is public domain
10 ------------------------------------------------------------------------------
11 */
12
13 RCSID("\$Id: fff1a35d89a7d1bcf98c34bd1e44f85eda2388c6 \$")
14
16
17 #define RANDSIZL (8) /* I recommend 8 for crypto, 4 for simulations */
18 #define RANDSIZ (1<<RANDSIZL)
19
20 #define ind(mm,x) ((mm)[(x>>2)&(RANDSIZ-1)])
21 #define rngstep(mix,a,b,mm,m,m2,r,x) \
22 { \
23  x = *m; \
24  a = ((a^(mix)) + *(m2++)) & 0xffffffff; \
25  *(m++) = y = (ind(mm,x) + a + b) & 0xffffffff; \
26  *(r++) = b = (ind(mm,y>>RANDSIZL) + x) & 0xffffffff; \
27 }
28
29 void fr_isaac(fr_randctx *ctx)
30 {
31  register uint32_t a,b,x,y,*m,*mm,*m2,*r,*mend;
32  mm=ctx->randmem; r=ctx->randrsl;
33  a = ctx->randa; b = (ctx->randb + (++ctx->randc)) & 0xffffffff;
34  for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
35  {
36  rngstep( a<<13, a, b, mm, m, m2, r, x);
37  rngstep( a>>6 , a, b, mm, m, m2, r, x);
38  rngstep( a<<2 , a, b, mm, m, m2, r, x);
39  rngstep( a>>16, a, b, mm, m, m2, r, x);
40  }
41  for (m2 = mm; m2<mend; )
42  {
43  rngstep( a<<13, a, b, mm, m, m2, r, x);
44  rngstep( a>>6 , a, b, mm, m, m2, r, x);
45  rngstep( a<<2 , a, b, mm, m, m2, r, x);
46  rngstep( a>>16, a, b, mm, m, m2, r, x);
47  }
48  ctx->randb = b; ctx->randa = a;
49 }
50
51
52 #define mix(a,b,c,d,e,f,g,h) \
53 { \
54  a^=b<<11; d+=a; b+=c; \
55  b^=c>>2; e+=b; c+=d; \
56  c^=d<<8; f+=c; d+=e; \
57  d^=e>>16; g+=d; e+=f; \
58  e^=f<<10; h+=e; f+=g; \
59  f^=g>>4; a+=f; g+=h; \
60  g^=h<<8; b+=g; h+=a; \
61  h^=a>>9; c+=h; a+=b; \
62 }
63
64 /* if (flag==1), then use the contents of randrsl[] to initialize mm[]. */
65 void fr_randinit(fr_randctx *ctx, int flag)
66 {
67  int i;
68  uint32_t a,b,c,d,e,f,g,h;
69  uint32_t *m,*r;
70  ctx->randa = ctx->randb = ctx->randc = 0;
71  m=ctx->randmem;
72  r=ctx->randrsl;
73  a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
74
75  for (i=0; i<4; ++i) { /* scramble it */
76  mix(a,b,c,d,e,f,g,h);
77  }
78
79  if (flag) {
80  /* initialize using the contents of r[] as the seed */
81  for (i=0; i<RANDSIZ; i+=8) {
82  a+=r[i ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3];
83  e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7];
84  mix(a,b,c,d,e,f,g,h);
85  m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
86  m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
87  }
88  /* do a second pass to make all of the seed affect all of m */
89  for (i=0; i<RANDSIZ; i+=8) {
90  a+=m[i ]; b+=m[i+1]; c+=m[i+2]; d+=m[i+3];
91  e+=m[i+4]; f+=m[i+5]; g+=m[i+6]; h+=m[i+7];
92  mix(a,b,c,d,e,f,g,h);
93  m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
94  m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
95  }
96  } else {
97  for (i=0; i<RANDSIZ; i+=8) {
98  /* fill in mm[] with messy stuff */
99  mix(a,b,c,d,e,f,g,h);
100  m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
101  m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
102  }
103  }
104
105  fr_isaac(ctx); /* fill in the first set of results */
106  ctx->randcnt=RANDSIZ; /* prepare to use the first set of results */
107 }
108
109
110 #ifdef TEST
111 /*
112  * For testing. Output should be the same as
113  *
114  * http://burtleburtle.net/bob/rand/randvect.txt
115  */
116 int main()
117 {
118  uint32_t i,j;
119  fr_randctx ctx;
120
121  ctx.randa = ctx.randb = ctx.randc = (uint32_t)0;
122
123  for (i=0; i<256; ++i) ctx.randrsl[i]=(uint32_t)0;
124  fr_randinit(&ctx, 1);
125  for (i=0; i<2; ++i) {
126  fr_isaac(&ctx);
127  for (j=0; j<256; ++j) {
128  printf("%.8lx",ctx.randrsl[j]);
129  if ((j&7)==7) printf("\n");
130  }
131  }
132 }
133 #endif
uint32_t randmem[256]
#define RANDSIZ
Definition: isaac.c:18
uint32_t randc
void fr_isaac(fr_randctx *ctx)
Definition: isaac.c:29
void fr_randinit(fr_randctx *ctx, int flag)
Definition: isaac.c:65
uint32_t randrsl[256]
uint32_t randb
int main(int argc, char *argv[])