File Coverage

isaac.c
Criterion Covered Total %
statement 0 69 0.0
branch 0 26 0.0
condition n/a
subroutine n/a
pod n/a
total 0 95 0.0


line stmt bran cond sub pod time code
1             /*
2             * The ISAAC CSPRNG plus interface.
3             * Slightly modified readable.c from Bob Jenkins 1996.
4             */
5              
6             #include
7             #include
8             #include
9             #include "ptypes.h"
10             #include "isaac.h"
11              
12              
13             static uint32_t randrsl[256];
14             static uint32_t randcnt;
15              
16             /* internal state */
17             static uint32_t mm[256];
18             static uint32_t aa = 0, bb = 0, cc = 0;
19              
20 0           static void isaac(void)
21             {
22             uint32_t i,x,y;
23              
24 0           cc = cc + 1; /* cc just gets incremented once per 256 results */
25 0           bb = bb + cc; /* then combined with bb */
26              
27 0 0         for (i=0; i<256; ++i)
28             {
29 0           x = mm[i];
30 0           switch (i%4) {
31 0           case 0: aa = aa^(aa<<13); break;
32 0           case 1: aa = aa^(aa>>6); break;
33 0           case 2: aa = aa^(aa<<2); break;
34 0           case 3: aa = aa^(aa>>16); break;
35             }
36 0           aa = mm[(i+128)%256] + aa;
37 0           mm[i] = y = mm[(x>>2)%256] + aa + bb;
38 0           randrsl[i] = bb = mm[(y>>10)%256] + x;
39             }
40 0           randcnt = 0;
41 0           }
42             #define mix(a,b,c,d,e,f,g,h) \
43             { \
44             a^=b<<11; d+=a; b+=c; \
45             b^=c>>2; e+=b; c+=d; \
46             c^=d<<8; f+=c; d+=e; \
47             d^=e>>16; g+=d; e+=f; \
48             e^=f<<10; h+=e; f+=g; \
49             f^=g>>4; a+=f; g+=h; \
50             g^=h<<8; b+=g; h+=a; \
51             h^=a>>9; c+=h; a+=b; \
52             }
53              
54 0           static void randinit(void) {
55             int i;
56             uint32_t a,b,c,d,e,f,g,h;
57 0           aa=bb=cc=0;
58 0           a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
59              
60 0 0         for (i=0; i<4; ++i) /* scramble it */
61             {
62 0           mix(a,b,c,d,e,f,g,h);
63             }
64              
65 0 0         for (i=0; i<256; i+=8) /* fill in mm[] with messy stuff */
66             {
67 0           a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3];
68 0           e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7];
69 0           mix(a,b,c,d,e,f,g,h);
70 0           mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d;
71 0           mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h;
72             }
73              
74             { /* do a second pass to make all of the seed affect all of mm */
75 0 0         for (i=0; i<256; i+=8)
76             {
77 0           a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3];
78 0           e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7];
79 0           mix(a,b,c,d,e,f,g,h);
80 0           mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d;
81 0           mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h;
82             }
83             }
84              
85 0           isaac(); /* fill in the first set of results */
86 0           randcnt=256; /* first use will run isaac() again */
87 0           }
88              
89 0           int isaac_selftest(void) {
90 0           return 1;
91             }
92              
93             /*****************************************************************************/
94              
95 0           void isaac_seed(uint32_t bytes, const unsigned char* data)
96             {
97 0           memset(mm, 0, 4*256);
98 0           memset(randrsl, 0, 4*256);
99 0 0         if (bytes > 0 && data != 0) {
    0          
100 0           unsigned char* rdata = (unsigned char*) randrsl;
101 0 0         if (bytes > 1024) bytes = 1024;
102 0           memcpy(rdata, data, bytes);
103             }
104 0           randinit();
105 0           }
106              
107 0           void isaac_rand_bytes(uint32_t bytes, unsigned char* data)
108             {
109 0 0         if ( 4*(256-randcnt) >= bytes) {
110             /* We have enough data, just copy it and leave */
111 0           memcpy(data, (unsigned char*) (randrsl+randcnt), bytes);
112 0           randcnt += (bytes+3)/4;
113             } else {
114             /* Loop copying up to 1024 bytes at a time */
115             uint32_t n_rand_bytes, n_copy_bytes;
116 0 0         while (bytes > 0) {
117 0 0         if (randcnt > 255)
118 0           isaac();
119 0           n_rand_bytes = 4 * (256-randcnt);
120 0           n_copy_bytes = (n_rand_bytes > bytes) ? bytes : n_rand_bytes;
121 0           memcpy(data, (unsigned char*) (randrsl+randcnt), n_copy_bytes);
122 0           data += n_copy_bytes;
123 0           randcnt += (n_copy_bytes+3)/4;
124 0           bytes -= n_copy_bytes;
125             }
126             }
127 0           }
128              
129 0           uint32_t isaac_irand32(void)
130             {
131 0 0         if (randcnt > 255) isaac();
132 0           return randrsl[randcnt++];
133             }
134             #if BITS_PER_WORD == 64
135 0           UV isaac_irand64(void)
136             {
137             uint32_t a, b;
138 0 0         if (randcnt > 255) isaac();
139 0           a = randrsl[randcnt++];
140 0 0         if (randcnt > 255) isaac();
141 0           b = randrsl[randcnt++];
142 0           return (((UV)a) << 32) | b;
143             }
144             #else
145             UV isaac_irand64(void) { return isaac_irand32(); }
146             #endif