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