2 * random.c: Internal random number generator, guaranteed to work
3 * the same way on all platforms. Used when generating an initial
4 * game state from a random game seed; required to ensure that game
5 * seeds can be exchanged between versions of a puzzle compiled for
8 * The generator is based on SHA-1. This is almost certainly
9 * overkill, but I had the SHA-1 code kicking around and it was
10 * easier to reuse it than to do anything else!
19 /* ----------------------------------------------------------------------
20 * Core SHA algorithm: processes 16-word blocks into a message digest.
23 #define rol(x,y) ( ((x) << (y)) | (((uint32)x) >> (32-y)) )
25 static void SHA_Core_Init(uint32 h
[5])
34 static void SHATransform(uint32
* digest
, uint32
* block
)
40 for (t
= 0; t
< 16; t
++)
43 for (t
= 16; t
< 80; t
++) {
44 uint32 tmp
= w
[t
- 3] ^ w
[t
- 8] ^ w
[t
- 14] ^ w
[t
- 16];
54 for (t
= 0; t
< 20; t
++) {
56 rol(a
, 5) + ((b
& c
) | (d
& ~b
)) + e
+ w
[t
] + 0x5a827999;
63 for (t
= 20; t
< 40; t
++) {
64 uint32 tmp
= rol(a
, 5) + (b
^ c
^ d
) + e
+ w
[t
] + 0x6ed9eba1;
71 for (t
= 40; t
< 60; t
++) {
73 5) + ((b
& c
) | (b
& d
) | (c
& d
)) + e
+ w
[t
] +
81 for (t
= 60; t
< 80; t
++) {
82 uint32 tmp
= rol(a
, 5) + (b
^ c
^ d
) + e
+ w
[t
] + 0xca62c1d6;
97 /* ----------------------------------------------------------------------
98 * Outer SHA algorithm: take an arbitrary length byte string,
99 * convert it into 16-word blocks with the prescribed padding at
100 * the end, and pass those blocks to the core SHA algorithm.
103 void SHA_Init(SHA_State
* s
)
107 s
->lenhi
= s
->lenlo
= 0;
110 void SHA_Bytes(SHA_State
* s
, void *p
, int len
)
112 unsigned char *q
= (unsigned char *) p
;
113 uint32 wordblock
[16];
118 * Update the length field.
121 s
->lenhi
+= (s
->lenlo
< lenw
);
123 if (s
->blkused
&& s
->blkused
+ len
< 64) {
125 * Trivial case: just add to the block.
127 memcpy(s
->block
+ s
->blkused
, q
, len
);
131 * We must complete and process at least one block.
133 while (s
->blkused
+ len
>= 64) {
134 memcpy(s
->block
+ s
->blkused
, q
, 64 - s
->blkused
);
135 q
+= 64 - s
->blkused
;
136 len
-= 64 - s
->blkused
;
137 /* Now process the block. Gather bytes big-endian into words */
138 for (i
= 0; i
< 16; i
++) {
140 (((uint32
) s
->block
[i
* 4 + 0]) << 24) |
141 (((uint32
) s
->block
[i
* 4 + 1]) << 16) |
142 (((uint32
) s
->block
[i
* 4 + 2]) << 8) |
143 (((uint32
) s
->block
[i
* 4 + 3]) << 0);
145 SHATransform(s
->h
, wordblock
);
148 memcpy(s
->block
, q
, len
);
153 void SHA_Final(SHA_State
* s
, unsigned char *output
)
160 if (s
->blkused
>= 56)
161 pad
= 56 + 64 - s
->blkused
;
163 pad
= 56 - s
->blkused
;
165 lenhi
= (s
->lenhi
<< 3) | (s
->lenlo
>> (32 - 3));
166 lenlo
= (s
->lenlo
<< 3);
170 SHA_Bytes(s
, &c
, pad
);
172 c
[0] = (unsigned char)((lenhi
>> 24) & 0xFF);
173 c
[1] = (unsigned char)((lenhi
>> 16) & 0xFF);
174 c
[2] = (unsigned char)((lenhi
>> 8) & 0xFF);
175 c
[3] = (unsigned char)((lenhi
>> 0) & 0xFF);
176 c
[4] = (unsigned char)((lenlo
>> 24) & 0xFF);
177 c
[5] = (unsigned char)((lenlo
>> 16) & 0xFF);
178 c
[6] = (unsigned char)((lenlo
>> 8) & 0xFF);
179 c
[7] = (unsigned char)((lenlo
>> 0) & 0xFF);
183 for (i
= 0; i
< 5; i
++) {
184 output
[i
* 4] = (unsigned char)((s
->h
[i
] >> 24) & 0xFF);
185 output
[i
* 4 + 1] = (unsigned char)((s
->h
[i
] >> 16) & 0xFF);
186 output
[i
* 4 + 2] = (unsigned char)((s
->h
[i
] >> 8) & 0xFF);
187 output
[i
* 4 + 3] = (unsigned char)((s
->h
[i
]) & 0xFF);
191 void SHA_Simple(void *p
, int len
, unsigned char *output
)
196 SHA_Bytes(&s
, p
, len
);
197 SHA_Final(&s
, output
);
200 /* ----------------------------------------------------------------------
201 * The random number generator.
204 struct random_state
{
205 unsigned char seedbuf
[40];
206 unsigned char databuf
[20];
210 random_state
*random_new(char *seed
, int len
)
214 state
= snew(random_state
);
216 SHA_Simple(seed
, len
, state
->seedbuf
);
217 SHA_Simple(state
->seedbuf
, 20, state
->seedbuf
+ 20);
218 SHA_Simple(state
->seedbuf
, 40, state
->databuf
);
224 random_state
*random_copy(random_state
*tocopy
)
226 random_state
*result
;
227 result
= snew(random_state
);
228 memcpy(result
->seedbuf
, tocopy
->seedbuf
, sizeof(result
->seedbuf
));
229 memcpy(result
->databuf
, tocopy
->databuf
, sizeof(result
->databuf
));
230 result
->pos
= tocopy
->pos
;
234 unsigned long random_bits(random_state
*state
, int bits
)
236 unsigned long ret
= 0;
239 for (n
= 0; n
< bits
; n
+= 8) {
240 if (state
->pos
>= 20) {
243 for (i
= 0; i
< 20; i
++) {
244 if (state
->seedbuf
[i
] != 0xFF) {
248 state
->seedbuf
[i
] = 0;
250 SHA_Simple(state
->seedbuf
, 40, state
->databuf
);
253 ret
= (ret
<< 8) | state
->databuf
[state
->pos
++];
257 * `(1 << bits) - 1' is not good enough, since if bits==32 on a
258 * 32-bit machine, behaviour is undefined and Intel has a nasty
259 * habit of shifting left by zero instead. We'll shift by
260 * bits-1 and then separately shift by one.
262 ret
&= (1 << (bits
-1)) * 2 - 1;
266 unsigned long random_upto(random_state
*state
, unsigned long limit
)
269 unsigned long max
, divisor
, data
;
271 while ((limit
>> bits
) != 0)
278 divisor
= max
/ limit
;
279 max
= limit
* divisor
;
282 data
= random_bits(state
, bits
);
283 } while (data
>= max
);
285 return data
/ divisor
;
288 void random_free(random_state
*state
)
293 char *random_state_encode(random_state
*state
)
298 for (i
= 0; i
< lenof(state
->seedbuf
); i
++)
299 len
+= sprintf(retbuf
+len
, "%02x", state
->seedbuf
[i
]);
300 for (i
= 0; i
< lenof(state
->databuf
); i
++)
301 len
+= sprintf(retbuf
+len
, "%02x", state
->databuf
[i
]);
302 len
+= sprintf(retbuf
+len
, "%02x", state
->pos
);
304 return dupstr(retbuf
);
307 random_state
*random_state_decode(char *input
)
310 int pos
, byte
, digits
;
312 state
= snew(random_state
);
314 memset(state
->seedbuf
, 0, sizeof(state
->seedbuf
));
315 memset(state
->databuf
, 0, sizeof(state
->databuf
));
323 if (v
>= '0' && v
<= '9')
325 else if (v
>= 'A' && v
<= 'F')
327 else if (v
>= 'a' && v
<= 'f')
332 byte
= (byte
<< 4) | v
;
337 * We have a byte. Put it somewhere.
339 if (pos
< lenof(state
->seedbuf
))
340 state
->seedbuf
[pos
++] = byte
;
341 else if (pos
< lenof(state
->seedbuf
) + lenof(state
->databuf
))
342 state
->databuf
[pos
++ - lenof(state
->seedbuf
)] = byte
;
343 else if (pos
== lenof(state
->seedbuf
) + lenof(state
->databuf
) &&
344 byte
<= lenof(state
->databuf
))