Initial revision
[pintos-anon] / src / lib / random.c
1 #include "random.h"
2 #include <stdint.h>
3
4 /* RC4-based pseudo-random state. */
5 static uint8_t s[256];
6 static uint8_t s_i, s_j;
7
8 static inline void
9 swap_byte (uint8_t *a, uint8_t *b) 
10 {
11   uint8_t t = *a;
12   *a = *b;
13   *b = t;
14 }
15
16 static uint8_t
17 key_byte (int idx) 
18 {
19   return idx ^ 0xff;
20 }
21
22 void
23 random_init (void)
24 {
25   int i;
26   uint8_t j;
27
28   for (i = 0; i < 256; i++) 
29     s[i] = i;
30   for (i = j = 0; i < 256; i++) 
31     {
32       j += s[i] + key_byte (i);
33       swap_byte (s + i, s + j);
34     }
35
36   s_i = s_j = 0;
37 }
38
39 void
40 random_bytes (void *buf_, size_t size) 
41 {
42   uint8_t *buf;
43
44   for (buf = buf_; size-- > 0; buf++)
45     {
46       uint8_t s_k;
47       
48       s_i++;
49       s_j += s[s_i];
50       swap_byte (s + s_i, s + s_j);
51
52       s_k = s[s_i] + s[s_j];
53       *buf = s[s_k];
54     }
55 }
56
57 /* Returns a pseudo-random unsigned long. */
58 unsigned long
59 random_ulong (void) 
60 {
61   unsigned long ul;
62   random_bytes (&ul, sizeof ul);
63   return ul;
64 }