added RNG test vectors
[strongswan.git] / src / libstrongswan / plugins / test_vectors / test_vectors / rng.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the Licenseor (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be usefulbut
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <crypto/crypto_tester.h>
17
18 #include <debug.h>
19
20 /**
21 * Monobit test
22 */
23 typedef struct {
24 int lower;
25 int upper;
26 } monobit_t;
27
28 monobit_t monobit_all = {
29 .lower = 9654,
30 .upper = 10346
31 };
32
33 static bool test_monobit(monobit_t *param, chunk_t data)
34 {
35 int i, j, bits = 0;
36
37 for (i = 0; i < data.len; i++)
38 {
39 for (j = 0; j < 8; j++)
40 {
41 if (data.ptr[i] & (1<<j))
42 {
43 bits++;
44 }
45 }
46 }
47 DBG2(" Monobit: %d/%d bits set", bits, data.len * 8);
48 if (bits > param->lower && bits < param->upper)
49 {
50 return TRUE;
51 }
52 return FALSE;
53 }
54
55 rng_test_vector_t rng_monobit_1 = {
56 RNG_WEAK, .len = 2500,
57 .test = (void*)test_monobit,
58 .user = &monobit_all
59 };
60
61 rng_test_vector_t rng_monobit_2 = {
62 RNG_STRONG, .len = 2500,
63 .test = (void*)test_monobit,
64 .user = &monobit_all
65 };
66
67 rng_test_vector_t rng_monobit_3 = {
68 RNG_TRUE, .len = 2500,
69 .test = (void*)test_monobit,
70 .user = &monobit_all
71 };
72
73 /**
74 * Poker test
75 */
76 typedef struct {
77 double lower;
78 double upper;
79 } poker_t;
80
81 poker_t poker_all = {
82 .lower = 1.03,
83 .upper = 57.4
84 };
85
86 static bool test_poker(poker_t *param, chunk_t data)
87 {
88 int i, counter[16];
89 double sum = 0.0;
90
91 memset(counter, 0, sizeof(counter));
92
93 for (i = 0; i < data.len; i++)
94 {
95 counter[data.ptr[i] & 0x0F]++;
96 counter[(data.ptr[i] & 0xF0) >> 4]++;
97 }
98
99 for (i = 0; i < countof(counter); i++)
100 {
101 sum += (counter[i] * counter[i]) / 5000.0 * 16.0;
102 }
103 sum -= 5000.0;
104 DBG2(" Poker: %f", sum);
105 if (sum > param->lower && sum < param->upper)
106 {
107 return TRUE;
108 }
109 return FALSE;
110 }
111
112 rng_test_vector_t rng_poker_1 = {
113 RNG_WEAK, .len = 2500,
114 .test = (void*)test_poker,
115 .user = &poker_all
116 };
117
118 rng_test_vector_t rng_poker_2 = {
119 RNG_STRONG, .len = 2500,
120 .test = (void*)test_poker,
121 .user = &poker_all
122 };
123
124 rng_test_vector_t rng_poker_3 = {
125 RNG_TRUE, .len = 2500,
126 .test = (void*)test_poker,
127 .user = &poker_all
128 };
129
130 /**
131 * Runs test
132 */
133 typedef struct {
134 int longrun;
135 int lower[7];
136 int upper[7];
137 } runs_t;
138
139 runs_t runs_all = {
140 .longrun = 34,
141 .lower = {-1, 2267, 1079, 502, 223, 90, 90},
142 .upper = {-1, 2733, 1421, 748, 402, 223, 223},
143 };
144
145 static bool test_runs(runs_t *param, chunk_t data)
146 {
147 int i, j, zero_runs[7], one_runs[7], zero = 0, one = 0, longrun = 0;
148
149 memset(one_runs, 0, sizeof(zero_runs));
150 memset(zero_runs, 0, sizeof(one_runs));
151
152 for (i = 0; i < data.len; i++)
153 {
154 for (j = 0; j < 8; j++)
155 {
156 if (data.ptr[i] & (1<<j))
157 {
158 if (one)
159 {
160 if (++one >= param->longrun)
161 {
162 longrun++;
163 break;
164 }
165 }
166 else
167 {
168 zero_runs[min(6, zero)]++;
169 zero = 0;
170 one = 1;
171 }
172 }
173 else
174 {
175 if (zero)
176 {
177 if (++zero >= param->longrun)
178 {
179 longrun++;
180 break;
181 }
182 }
183 else
184 {
185 one_runs[min(6, one)]++;
186 one = 0;
187 zero = 1;
188 }
189 }
190 }
191 }
192
193 DBG2(" Runs: zero: %d/%d/%d/%d/%d/%d, one: %d/%d/%d/%d/%d/%d, "
194 "longruns: %d",
195 zero_runs[1], zero_runs[2], zero_runs[3],
196 zero_runs[4], zero_runs[5], zero_runs[6],
197 one_runs[1], one_runs[2], one_runs[3],
198 one_runs[4], one_runs[5], one_runs[6],
199 longrun);
200
201 if (longrun)
202 {
203 return FALSE;
204 }
205
206 for (i = 1; i < countof(zero_runs); i++)
207 {
208 if (zero_runs[i] <= param->lower[i] ||
209 zero_runs[i] >= param->upper[i] ||
210 one_runs[i] <= param->lower[i] ||
211 one_runs[i] >= param->upper[i])
212 {
213 return FALSE;
214 }
215 }
216 return TRUE;
217 }
218
219 rng_test_vector_t rng_runs_1 = {
220 RNG_WEAK, .len = 2500,
221 .test = (void*)test_runs,
222 .user = &runs_all
223 };
224
225 rng_test_vector_t rng_runs_2 = {
226 RNG_STRONG, .len = 2500,
227 .test = (void*)test_runs,
228 .user = &runs_all
229 };
230
231 rng_test_vector_t rng_runs_3 = {
232 RNG_TRUE, .len = 2500,
233 .test = (void*)test_runs,
234 .user = &runs_all
235 };
236