diff options
Diffstat (limited to 'win32/isaac.c')
-rw-r--r-- | win32/isaac.c | 96 |
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 */ | 22 | typedef struct { |
23 | static uint32_t randrsl[256]; | 23 | /* external results */ |
24 | uint32_t randrsl[256]; | ||
24 | 25 | ||
25 | /* internal state */ | 26 | /* internal state */ |
26 | static uint32_t mm[256]; | 27 | uint32_t mm[256]; |
27 | static uint32_t aa=0, bb=0, cc=0; | 28 | uint32_t aa, bb, cc; |
29 | } isaac_t; | ||
28 | 30 | ||
29 | 31 | ||
30 | static void isaac(void) | 32 | static 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 | ||
74 | static void randinit(int flag) | 76 | static 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 | */ |
126 | static void get_entropy(void) | 129 | static 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 | */ |
190 | ssize_t get_random_bytes(void *buf, ssize_t count) | 193 | ssize_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 | } |