1 /*	$NetBSD: test_bn.c,v 1.1.1.1 2011/04/13 18:14:51 elric 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 
38 #include <sys/types.h>
39 #include <limits.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 
44 #include <bn.h>
45 #include <rand.h>
46 
47 static int
48 set_get(unsigned long num)
49 {
50     BIGNUM *bn;
51 
52     bn = BN_new();
53     if (!BN_set_word(bn, num))
54 	return 1;
55 
56     if (BN_get_word(bn) != num)
57 	return 1;
58 
59     BN_free(bn);
60     return 0;
61 }
62 
63 #define CHECK(x) do { ret += x; } while(0)
64 
65 static int
66 test_BN_set_get(void)
67 {
68     int ret = 0;
69     CHECK(set_get(0));
70     CHECK(set_get(1));
71     CHECK(set_get(0xff));
72     CHECK(set_get(0x1ff));
73     CHECK(set_get(0xffff));
74     CHECK(set_get(0xf000));
75     CHECK(set_get(ULONG_MAX / 2));
76     CHECK(set_get(ULONG_MAX - 1));
77 
78     return ret;
79 }
80 
81 static int
82 test_BN_bit(void)
83 {
84     BIGNUM *bn;
85     int ret = 0;
86 
87     bn = BN_new();
88 
89     /* test setting and getting of "word" */
90     if (!BN_set_word(bn, 1))
91 	return 1;
92     if (!BN_is_bit_set(bn, 0))
93 	ret += 1;
94     if (!BN_is_bit_set(bn, 0))
95 	ret += 1;
96 
97     if (!BN_set_word(bn, 2))
98 	return 1;
99     if (!BN_is_bit_set(bn, 1))
100 	ret += 1;
101 
102     if (!BN_set_word(bn, 3))
103 	return 1;
104     if (!BN_is_bit_set(bn, 0))
105 	ret += 1;
106     if (!BN_is_bit_set(bn, 1))
107 	ret += 1;
108 
109     if (!BN_set_word(bn, 0x100))
110 	return 1;
111     if (!BN_is_bit_set(bn, 8))
112 	ret += 1;
113 
114     if (!BN_set_word(bn, 0x1000))
115 	return 1;
116     if (!BN_is_bit_set(bn, 12))
117 	ret += 1;
118 
119     /* test bitsetting */
120     if (!BN_set_word(bn, 1))
121 	return 1;
122     if (!BN_set_bit(bn, 1))
123 	return 1;
124     if (BN_get_word(bn) != 3)
125 	return 1;
126     if (!BN_clear_bit(bn, 0))
127 	return 1;
128     if (BN_get_word(bn) != 2)
129 	return 1;
130 
131     /* test bitsetting past end of current end */
132     BN_clear(bn);
133     if (!BN_set_bit(bn, 12))
134 	return 1;
135     if (BN_get_word(bn) != 0x1000)
136 	return 1;
137 
138     /* test bit and byte counting functions */
139     if (BN_num_bits(bn) != 13)
140 	return 1;
141     if (BN_num_bytes(bn) != 2)
142 	return 1;
143 
144     BN_free(bn);
145     return ret;
146 }
147 
148 struct ietest {
149     char *data;
150     size_t len;
151     unsigned long num;
152 } ietests[] = {
153     { "", 0, 0 },
154     { "\x01", 1, 1 },
155     { "\x02", 1, 2 },
156     { "\xf2", 1, 0xf2 },
157     { "\x01\x00", 2, 256 }
158 };
159 
160 static int
161 test_BN_import_export(void)
162 {
163     BIGNUM *bn;
164     int ret = 0;
165     int i;
166 
167     bn = BN_new();
168 
169     for (i = 0; i < sizeof(ietests)/sizeof(ietests[0]); i++) {
170 	size_t len;
171 	unsigned char *p;
172 	if (!BN_bin2bn((unsigned char*)ietests[i].data, ietests[i].len, bn))
173 	    return 1;
174 	if (BN_get_word(bn) != ietests[i].num)
175 	    return 1;
176 	len = BN_num_bytes(bn);
177 	if (len != ietests[i].len)
178 	    return 1;
179 	p = malloc(len + 1);
180 	p[len] = 0xf4;
181 	BN_bn2bin(bn, p);
182 	if (p[len] != 0xf4)
183 	    return 1;
184 	if (memcmp(p, ietests[i].data, ietests[i].len) != 0)
185 	    return 1;
186 	free(p);
187     }
188 
189     BN_free(bn);
190     return ret;
191 }
192 
193 static int
194 test_BN_uadd(void)
195 {
196     BIGNUM *a, *b, *c;
197     char *p;
198 
199     a = BN_new();
200     b = BN_new();
201     c = BN_new();
202 
203     BN_set_word(a, 1);
204     BN_set_word(b, 2);
205 
206     BN_uadd(c, a, b);
207 
208     if (BN_get_word(c) != 3)
209 	return 1;
210 
211     BN_uadd(c, b, a);
212 
213     if (BN_get_word(c) != 3)
214 	return 1;
215 
216     BN_set_word(b, 0xff);
217 
218     BN_uadd(c, a, b);
219     if (BN_get_word(c) != 0x100)
220 	return 1;
221 
222     BN_uadd(c, b, a);
223     if (BN_get_word(c) != 0x100)
224 	return 1;
225 
226     BN_set_word(a, 0xff);
227 
228     BN_uadd(c, a, b);
229     if (BN_get_word(c) != 0x1fe)
230 	return 1;
231 
232     BN_uadd(c, b, a);
233     if (BN_get_word(c) != 0x1fe)
234 	return 1;
235 
236 
237     BN_free(a);
238     BN_free(b);
239 
240     BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD2");
241     BN_hex2bn(&b, "84B6C7E8D28ACA1614954DA");
242 
243     BN_uadd(c, b, a);
244     p = BN_bn2hex(c);
245     if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) {
246 	free(p);
247 	return 1;
248     }
249     free(p);
250 
251     BN_uadd(c, a, b);
252     p = BN_bn2hex(c);
253     if (strcmp(p, "50212A3B611D466434CDC695307D7AB13621B2AC") != 0) {
254 	free(p);
255 	return 1;
256     }
257     free(p);
258 
259     BN_free(a);
260     BN_free(b);
261     BN_free(c);
262 
263     return 0;
264 }
265 
266 static int
267 test_BN_cmp(void)
268 {
269     BIGNUM *a, *b;
270 
271     a = BN_new();
272     b = BN_new();
273 
274     if (!BN_set_word(a, 1))
275 	return 1;
276     if (!BN_set_word(b, 1))
277 	return 1;
278 
279     if (BN_cmp(a, b) != 0)
280 	return 1;
281     if (BN_cmp(b, a) != 0)
282 	return 1;
283 
284     if (!BN_set_word(b, 2))
285 	return 1;
286 
287     if (BN_cmp(a, b) >= 0)
288 	return 1;
289     if (BN_cmp(b, a) <= 0)
290 	return 1;
291 
292     BN_set_negative(b, 1);
293 
294     if (BN_cmp(a, b) <= 0)
295 	return 1;
296     if (BN_cmp(b, a) >= 0)
297 	return 1;
298 
299     BN_free(a);
300     BN_free(b);
301 
302     BN_hex2bn(&a, "50212A3B611D46642C825A16A354CE0FD4D85DD1");
303     BN_hex2bn(&b, "50212A3B611D46642C825A16A354CE0FD4D85DD2");
304 
305     if (BN_cmp(a, b) >= 0)
306 	return 1;
307     if (BN_cmp(b, a) <= 0)
308 	return 1;
309 
310     BN_set_negative(b, 1);
311 
312     if (BN_cmp(a, b) <= 0)
313 	return 1;
314     if (BN_cmp(b, a) >= 0)
315 	return 1;
316 
317     BN_free(a);
318     BN_free(b);
319     return 0;
320 }
321 
322 static int
323 test_BN_rand(void)
324 {
325     BIGNUM *bn;
326 
327     if (RAND_status() != 1)
328 	return 0;
329 
330     bn = BN_new();
331     if (bn == NULL)
332 	return 1;
333 
334     if (!BN_rand(bn, 1024, 0, 0))
335 	return 1;
336 
337     BN_free(bn);
338     return 0;
339 }
340 
341 #define testnum 100
342 #define testnum2 10
343 
344 static int
345 test_BN_CTX(void)
346 {
347     unsigned int i, j;
348     BIGNUM *bn;
349     BN_CTX *c;
350 
351     if ((c = BN_CTX_new()) == NULL)
352 	return 1;
353 
354     for (i = 0; i < testnum; i++) {
355 	BN_CTX_start(c);
356 	BN_CTX_end(c);
357     }
358 
359     for (i = 0; i < testnum; i++)
360 	BN_CTX_start(c);
361     for (i = 0; i < testnum; i++)
362 	BN_CTX_end(c);
363 
364     for (i = 0; i < testnum; i++) {
365 	BN_CTX_start(c);
366 	if ((bn = BN_CTX_get(c)) == NULL)
367 	    return 1;
368 	BN_CTX_end(c);
369     }
370 
371     for (i = 0; i < testnum; i++) {
372 	BN_CTX_start(c);
373 	for (j = 0; j < testnum2; j++)
374 	    if ((bn = BN_CTX_get(c)) == NULL)
375 		return 1;
376     }
377     for (i = 0; i < testnum; i++)
378 	BN_CTX_end(c);
379 
380     BN_CTX_free(c);
381     return 0;
382 }
383 
384 
385 int
386 main(int argc, char **argv)
387 {
388     int ret = 0;
389 
390     ret += test_BN_set_get();
391     ret += test_BN_bit();
392     ret += test_BN_import_export();
393     ret += test_BN_uadd();
394     ret += test_BN_cmp();
395     ret += test_BN_rand();
396     ret += test_BN_CTX();
397 
398     return ret;
399 }
400