aboutsummaryrefslogtreecommitdiff
path: root/win32/isaac.c
diff options
context:
space:
mode:
Diffstat (limited to 'win32/isaac.c')
-rw-r--r--win32/isaac.c96
1 files changed, 48 insertions, 48 deletions
diff --git a/win32/isaac.c b/win32/isaac.c
index 8e9da9baf..ba51d199a 100644
--- a/win32/isaac.c
+++ b/win32/isaac.c
@@ -19,34 +19,36 @@ You may use this code in any way you wish, and it is free. No warrantee.
19*/ 19*/
20#include "libbb.h" 20#include "libbb.h"
21 21
22/* external results */ 22typedef struct {
23static uint32_t randrsl[256]; 23 /* external results */
24 uint32_t randrsl[256];
24 25
25/* internal state */ 26 /* internal state */
26static uint32_t mm[256]; 27 uint32_t mm[256];
27static uint32_t aa=0, bb=0, cc=0; 28 uint32_t aa, bb, cc;
29} isaac_t;
28 30
29 31
30static void isaac(void) 32static void isaac(isaac_t *t)
31{ 33{
32 register uint32_t i,x,y; 34 register uint32_t i,x,y;
33 35
34 cc = cc + 1; /* cc just gets incremented once per 256 results */ 36 t->cc = t->cc + 1; /* cc just gets incremented once per 256 results */
35 bb = bb + cc; /* then combined with bb */ 37 t->bb = t->bb + t->cc; /* then combined with bb */
36 38
37 for (i=0; i<256; ++i) 39 for (i=0; i<256; ++i)
38 { 40 {
39 x = mm[i]; 41 x = t->mm[i];
40 switch (i%4) 42 switch (i%4)
41 { 43 {
42 case 0: aa = aa^(aa<<13); break; 44 case 0: t->aa = t->aa^(t->aa<<13); break;
43 case 1: aa = aa^(aa>>6); break; 45 case 1: t->aa = t->aa^(t->aa>>6); break;
44 case 2: aa = aa^(aa<<2); break; 46 case 2: t->aa = t->aa^(t->aa<<2); break;
45 case 3: aa = aa^(aa>>16); break; 47 case 3: t->aa = t->aa^(t->aa>>16); break;
46 } 48 }
47 aa = mm[(i+128)%256] + aa; 49 t->aa = t->mm[(i+128)%256] + t->aa;
48 mm[i] = y = mm[(x>>2)%256] + aa + bb; 50 t->mm[i] = y = t->mm[(x>>2)%256] + t->aa + t->bb;
49 randrsl[i] = bb = mm[(y>>10)%256] + x; 51 t->randrsl[i] = t->bb = t->mm[(y>>10)%256] + x;
50 52
51 /* Note that bits 2..9 are chosen from x but 10..17 are chosen 53 /* Note that bits 2..9 are chosen from x but 10..17 are chosen
52 from y. The only important thing here is that 2..9 and 10..17 54 from y. The only important thing here is that 2..9 and 10..17
@@ -71,11 +73,11 @@ static void isaac(void)
71 h^=a>>9; c+=h; a+=b; \ 73 h^=a>>9; c+=h; a+=b; \
72} 74}
73 75
74static void randinit(int flag) 76static void randinit(isaac_t *t, int flag)
75{ 77{
76 int i; 78 int i;
77 uint32_t a,b,c,d,e,f,g,h; 79 uint32_t a,b,c,d,e,f,g,h;
78 aa=bb=cc=0; 80 t->aa = t->bb = t->cc = 0;
79 a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */ 81 a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
80 82
81 for (i=0; i<4; ++i) /* scramble it */ 83 for (i=0; i<4; ++i) /* scramble it */
@@ -87,27 +89,28 @@ static void randinit(int flag)
87 { 89 {
88 if (flag) /* use all the information in the seed */ 90 if (flag) /* use all the information in the seed */
89 { 91 {
90 a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3]; 92 a+=t->randrsl[i ]; b+=t->randrsl[i+1]; c+=t->randrsl[i+2];
91 e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7]; 93 d+=t->randrsl[i+3]; e+=t->randrsl[i+4]; f+=t->randrsl[i+5];
94 g+=t->randrsl[i+6]; h+=t->randrsl[i+7];
92 } 95 }
93 mix(a,b,c,d,e,f,g,h); 96 mix(a,b,c,d,e,f,g,h);
94 mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; 97 t->mm[i ]=a; t->mm[i+1]=b; t->mm[i+2]=c; t->mm[i+3]=d;
95 mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; 98 t->mm[i+4]=e; t->mm[i+5]=f; t->mm[i+6]=g; t->mm[i+7]=h;
96 } 99 }
97 100
98 if (flag) 101 if (flag)
99 { /* do a second pass to make all of the seed affect all of mm */ 102 { /* do a second pass to make all of the seed affect all of mm */
100 for (i=0; i<256; i+=8) 103 for (i=0; i<256; i+=8)
101 { 104 {
102 a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3]; 105 a+=t->mm[i ]; b+=t->mm[i+1]; c+=t->mm[i+2]; d+=t->mm[i+3];
103 e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7]; 106 e+=t->mm[i+4]; f+=t->mm[i+5]; g+=t->mm[i+6]; h+=t->mm[i+7];
104 mix(a,b,c,d,e,f,g,h); 107 mix(a,b,c,d,e,f,g,h);
105 mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; 108 t->mm[i ]=a; t->mm[i+1]=b; t->mm[i+2]=c; t->mm[i+3]=d;
106 mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; 109 t->mm[i+4]=e; t->mm[i+5]=f; t->mm[i+6]=g; t->mm[i+7]=h;
107 } 110 }
108 } 111 }
109 112
110 isaac(); /* fill in the first set of results */ 113 isaac(t); /* fill in the first set of results */
111} 114}
112 115
113/* call 'fn' to put data in 'dt' then copy it to generator state */ 116/* call 'fn' to put data in 'dt' then copy it to generator state */
@@ -115,7 +118,7 @@ static void randinit(int flag)
115 fn(&dt); \ 118 fn(&dt); \
116 u = (uint32_t *)&dt; \ 119 u = (uint32_t *)&dt; \
117 for (j=0; j<sizeof(dt)/sizeof(uint32_t); ++j) { \ 120 for (j=0; j<sizeof(dt)/sizeof(uint32_t); ++j) { \
118 randrsl[i++] = *u++; \ 121 t->randrsl[i++] = *u++; \
119 } 122 }
120 123
121/* 124/*
@@ -123,7 +126,7 @@ static void randinit(int flag)
123 * This is unlikely to be very robust: don't rely on it for 126 * This is unlikely to be very robust: don't rely on it for
124 * anything that needs to be secure. 127 * anything that needs to be secure.
125 */ 128 */
126static void get_entropy(void) 129static void get_entropy(isaac_t *t)
127{ 130{
128 int i, j, len; 131 int i, j, len;
129 SYSTEMTIME tm; 132 SYSTEMTIME tm;
@@ -136,9 +139,9 @@ static void get_entropy(void)
136 unsigned char buf[16]; 139 unsigned char buf[16];
137 140
138 i = 0; 141 i = 0;
139 randrsl[i++] = (uint32_t)GetCurrentProcessId(); 142 t->randrsl[i++] = (uint32_t)GetCurrentProcessId();
140 randrsl[i++] = (uint32_t)GetCurrentThreadId(); 143 t->randrsl[i++] = (uint32_t)GetCurrentThreadId();
141 randrsl[i++] = (uint32_t)GetTickCount(); 144 t->randrsl[i++] = (uint32_t)GetTickCount();
142 145
143 GET_DATA(GetLocalTime, tm) 146 GET_DATA(GetLocalTime, tm)
144 GET_DATA(GlobalMemoryStatus, ms) 147 GET_DATA(GlobalMemoryStatus, ms)
@@ -159,12 +162,12 @@ static void get_entropy(void)
159 162
160 u = (uint32_t *)buf; 163 u = (uint32_t *)buf;
161 for (j=0; j<sizeof(buf)/sizeof(uint32_t); ++j) { 164 for (j=0; j<sizeof(buf)/sizeof(uint32_t); ++j) {
162 randrsl[i++] = *u++; 165 t->randrsl[i++] = *u++;
163 } 166 }
164 167
165#if 0 168#if 0
166 { 169 {
167 unsigned char *p = (unsigned char *)randrsl; 170 unsigned char *p = (unsigned char *)t->randrsl;
168 171
169 for (j=0; j<i*sizeof(uint32_t); ++j) { 172 for (j=0; j<i*sizeof(uint32_t); ++j) {
170 fprintf(stderr, "%02x", *p++); 173 fprintf(stderr, "%02x", *p++);
@@ -180,8 +183,8 @@ static void get_entropy(void)
180#endif 183#endif
181} 184}
182 185
183#define RAND_BYTES sizeof(randrsl) 186#define RAND_BYTES sizeof(t->randrsl)
184#define RAND_WORDS (sizeof(randrsl)/sizeof(randrsl[0])) 187#define RAND_WORDS (sizeof(t->randrsl)/sizeof(t->randrsl[0]))
185 188
186/* 189/*
187 * Place 'count' random bytes in the buffer 'buf'. You're responsible 190 * Place 'count' random bytes in the buffer 'buf'. You're responsible
@@ -189,29 +192,26 @@ static void get_entropy(void)
189 */ 192 */
190ssize_t get_random_bytes(void *buf, ssize_t count) 193ssize_t get_random_bytes(void *buf, ssize_t count)
191{ 194{
192 static int initialised = 0; 195 static isaac_t *t = NULL;
193 static int rand_index = 0; 196 static int rand_index = 0;
194 int i;
195 ssize_t save_count = count; 197 ssize_t save_count = count;
196 unsigned char *ptr = (unsigned char *)randrsl; 198 unsigned char *ptr;
197 199
198 if (buf == NULL || count < 0) { 200 if (buf == NULL || count < 0) {
199 errno = EINVAL; 201 errno = EINVAL;
200 return -1; 202 return -1;
201 } 203 }
202 204
203 if (!initialised) { 205 if (!t) {
204 aa = bb = cc = (uint32_t)0; 206 t = xzalloc(sizeof(isaac_t));
205 for (i=0; i<RAND_WORDS; ++i)
206 mm[i] = randrsl[i] = (uint32_t)0;
207 207
208 get_entropy(); 208 get_entropy(t);
209 randinit(1); 209 randinit(t, 1);
210 isaac(); 210 isaac(t);
211 rand_index = 0; 211 rand_index = 0;
212 initialised = 1;
213 } 212 }
214 213
214 ptr = (unsigned char *)t->randrsl;
215 while (count > 0) { 215 while (count > 0) {
216 int bytes_left = RAND_BYTES - rand_index; 216 int bytes_left = RAND_BYTES - rand_index;
217 217
@@ -231,7 +231,7 @@ ssize_t get_random_bytes(void *buf, ssize_t count)
231 231
232 if (rand_index >= RAND_BYTES) { 232 if (rand_index >= RAND_BYTES) {
233 /* generate more */ 233 /* generate more */
234 isaac(); 234 isaac(t);
235 rand_index = 0; 235 rand_index = 0;
236 } 236 }
237 } 237 }