1 /* $NetBSD: test_bn.c,v 1.2 2017/01/28 21:31:47 christos Exp $ */
2
3 /*
4 * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
5 * (Royal Institute of Technology, Stockholm, Sweden).
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36 #include <config.h>
37 #include <krb5/roken.h>
38
39 #include <bn.h>
40 #include <rand.h>
41
42 static int
set_get(unsigned long num)43 set_get(unsigned long num)
44 {
45 BIGNUM *bn;
46
47 bn = BN_new();
48 if (!BN_set_word(bn, num))
49 return 1;
50
51 if (BN_get_word(bn) != num)
52 return 1;
53
54 BN_free(bn);
55 return 0;
56 }
57
58 #define CHECK(x) do { ret += x; } while(0)
59
60 static int
test_BN_set_get(void)61 test_BN_set_get(void)
62 {
63 int ret = 0;
64 CHECK(set_get(0));
65 CHECK(set_get(1));
66 CHECK(set_get(0xff));
67 CHECK(set_get(0x1ff));
68 CHECK(set_get(0xffff));
69 CHECK(set_get(0xf000));
70 CHECK(set_get(ULONG_MAX / 2));
71 CHECK(set_get(ULONG_MAX - 1));
72
73 return ret;
74 }
75
76 static int
test_BN_bit(void)77 test_BN_bit(void)
78 {
79 BIGNUM *bn;
80 int ret = 0;
81
82 bn = BN_new();
83
84 /* test setting and getting of "word" */
85 if (!BN_set_word(bn, 1))
86 return 1;
87 if (!BN_is_bit_set(bn, 0))
88 ret += 1;
89 if (!BN_is_bit_set(bn, 0))
90 ret += 1;
91
92 if (!BN_set_word(bn, 2))
93 return 1;
94 if (!BN_is_bit_set(bn, 1))
95 ret += 1;
96
97 if (!BN_set_word(bn, 3))
98 return 1;
99 if (!BN_is_bit_set(bn, 0))
100 ret += 1;
101 if (!BN_is_bit_set(bn, 1))
102 ret += 1;
103
104 if (!BN_set_word(bn, 0x100))
105 return 1;
106 if (!BN_is_bit_set(bn, 8))
107 ret += 1;
108
109 if (!BN_set_word(bn, 0x1000))
110 return 1;
111 if (!BN_is_bit_set(bn, 12))
112 ret += 1;
113
114 /* test bitsetting */
115 if (!BN_set_word(bn, 1))
116 return 1;
117 if (!BN_set_bit(bn, 1))
118 return 1;
119 if (BN_get_word(bn) != 3)
120 return 1;
121 if (!BN_clear_bit(bn, 0))
122 return 1;
123 if (BN_get_word(bn) != 2)
124 return 1;
125
126 /* test bitsetting past end of current end */
127 BN_clear(bn);
128 if (!BN_set_bit(bn, 12))
129 return 1;
130 if (BN_get_word(bn) != 0x1000)
131 return 1;
132
133 /* test bit and byte counting functions */
134 if (BN_num_bits(bn) != 13)
135 return 1;
136 if (BN_num_bytes(bn) != 2)
137 return 1;
138
139 BN_free(bn);
140 return ret;
141 }
142
143 struct ietest {
144 char *data;
145 size_t len;
146 unsigned long num;
147 } ietests[] = {
148 { "", 0, 0 },
149 { "\x01", 1, 1 },
150 { "\x02", 1, 2 },
151 { "\xf2", 1, 0xf2 },
152 { "\x01\x00", 2, 256 }
153 };
154
155 static int
test_BN_import_export(void)156 test_BN_import_export(void)
157 {
158 BIGNUM *bn;
159 int ret = 0;
160 int i;
161
162 bn = BN_new();
163
164 for (i = 0; i < sizeof(ietests)/sizeof(ietests[0]); i++) {
165 size_t len;
166 unsigned char *p;
167 if (!BN_bin2bn((unsigned char*)ietests[i].data, ietests[i].len, bn))
168 return 1;
169 if (BN_get_word(bn) != ietests[i].num)
170 return 1;
171 len = BN_num_bytes(bn);
172 if (len != ietests[i].len)
173 return 1;
174 p = malloc(len + 1);
175 p[len] = 0xf4;
176 BN_bn2bin(bn, p);
177 if (p[len] != 0xf4)
178 return 1;
179 if (memcmp(p, ietests[i].data, ietests[i].len) != 0)
180 return 1;
181 free(p);
182 }
183
184 BN_free(bn);
185 return ret;
186 }
187
188 static int
test_BN_uadd(void)189 test_BN_uadd(void)
190 {
191 BIGNUM *a, *b, *c;
192 char *p;
193
194 a = BN_new();
195 b = BN_new();
196 c = BN_new();
197
198 BN_set_word(a, 1);
199 BN_set_word(b, 2);
200
201 BN_uadd(c, a, b);
202
203 if (BN_get_word(c) != 3)
204 return 1;
205
206 BN_uadd(c, b, a);
207
208 if (BN_get_word(c) != 3)
209 return 1;
210
211 BN_set_word(b, 0xff);
212
213 BN_uadd(c, a, b);
214 if (BN_get_word(c) != 0x100)
215 return 1;
216
217 BN_uadd(c, b, a);
218 if (BN_get_word(c) != 0x100)
219 return 1;
220
221 BN_set_word(a, 0xff);
222
223 BN_uadd(c, a, b);
224 if (BN_get_word(c) != 0x1fe)
225 return 1;
226
227 BN_uadd(c, b, a);
228 if (BN_get_word(c) != 0x1fe)
229 return 1;
230
231
232 BN_free(a);
233 BN_free(b);
234
235 BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD2");
236 BN_hex2bn(&b, "84B6C7E8D28ACA1614954DA");
237
238 BN_uadd(c, b, a);
239 p = BN_bn2hex(c);
240 if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) {
241 free(p);
242 return 1;
243 }
244 free(p);
245
246 BN_uadd(c, a, b);
247 p = BN_bn2hex(c);
248 if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) {
249 free(p);
250 return 1;
251 }
252 free(p);
253
254 BN_free(a);
255 BN_free(b);
256 BN_free(c);
257
258 return 0;
259 }
260
261 static int
test_BN_cmp(void)262 test_BN_cmp(void)
263 {
264 BIGNUM *a, *b;
265
266 a = BN_new();
267 b = BN_new();
268
269 if (!BN_set_word(a, 1))
270 return 1;
271 if (!BN_set_word(b, 1))
272 return 1;
273
274 if (BN_cmp(a, b) != 0)
275 return 1;
276 if (BN_cmp(b, a) != 0)
277 return 1;
278
279 if (!BN_set_word(b, 2))
280 return 1;
281
282 if (BN_cmp(a, b) >= 0)
283 return 1;
284 if (BN_cmp(b, a) <= 0)
285 return 1;
286
287 BN_set_negative(b, 1);
288
289 if (BN_cmp(a, b) <= 0)
290 return 1;
291 if (BN_cmp(b, a) >= 0)
292 return 1;
293
294 BN_free(a);
295 BN_free(b);
296
297 BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD1");
298 BN_hex2bn(&b, "50212A3B611D46642C825A16A354CE0FD4D85DD2");
299
300 if (BN_cmp(a, b) >= 0)
301 return 1;
302 if (BN_cmp(b, a) <= 0)
303 return 1;
304
305 BN_set_negative(b, 1);
306
307 if (BN_cmp(a, b) <= 0)
308 return 1;
309 if (BN_cmp(b, a) >= 0)
310 return 1;
311
312 BN_free(a);
313 BN_free(b);
314 return 0;
315 }
316
317 static int
test_BN_rand(void)318 test_BN_rand(void)
319 {
320 BIGNUM *bn;
321
322 if (RAND_status() != 1)
323 return 0;
324
325 bn = BN_new();
326 if (bn == NULL)
327 return 1;
328
329 if (!BN_rand(bn, 1024, 0, 0))
330 return 1;
331
332 BN_free(bn);
333 return 0;
334 }
335
336 #define testnum 100
337 #define testnum2 10
338
339 static int
test_BN_CTX(void)340 test_BN_CTX(void)
341 {
342 unsigned int i, j;
343 BIGNUM *bn;
344 BN_CTX *c;
345
346 if ((c = BN_CTX_new()) == NULL)
347 return 1;
348
349 for (i = 0; i < testnum; i++) {
350 BN_CTX_start(c);
351 BN_CTX_end(c);
352 }
353
354 for (i = 0; i < testnum; i++)
355 BN_CTX_start(c);
356 for (i = 0; i < testnum; i++)
357 BN_CTX_end(c);
358
359 for (i = 0; i < testnum; i++) {
360 BN_CTX_start(c);
361 if ((bn = BN_CTX_get(c)) == NULL)
362 return 1;
363 BN_CTX_end(c);
364 }
365
366 for (i = 0; i < testnum; i++) {
367 BN_CTX_start(c);
368 for (j = 0; j < testnum2; j++)
369 if ((bn = BN_CTX_get(c)) == NULL)
370 return 1;
371 }
372 for (i = 0; i < testnum; i++)
373 BN_CTX_end(c);
374
375 BN_CTX_free(c);
376 return 0;
377 }
378
379
380 int
main(int argc,char ** argv)381 main(int argc, char **argv)
382 {
383 int ret = 0;
384
385 ret += test_BN_set_get();
386 ret += test_BN_bit();
387 ret += test_BN_import_export();
388 ret += test_BN_uadd();
389 ret += test_BN_cmp();
390 ret += test_BN_rand();
391 ret += test_BN_CTX();
392
393 return ret;
394 }
395