133965Sjdp/*	$NetBSD: test_bn.c,v 1.2 2017/01/28 21:31:47 christos Exp $	*/
233965Sjdp
333965Sjdp/*
433965Sjdp * Copyright (c) 2006 - 2007 Kungliga Tekniska H��gskolan
533965Sjdp * (Royal Institute of Technology, Stockholm, Sweden).
689857Sobrien * All rights reserved.
733965Sjdp *
889857Sobrien * Redistribution and use in source and binary forms, with or without
989857Sobrien * modification, are permitted provided that the following conditions
1089857Sobrien * are met:
1189857Sobrien *
1289857Sobrien * 1. Redistributions of source code must retain the above copyright
1389857Sobrien *    notice, this list of conditions and the following disclaimer.
1489857Sobrien *
1533965Sjdp * 2. Redistributions in binary form must reproduce the above copyright
1689857Sobrien *    notice, this list of conditions and the following disclaimer in the
1760484Sobrien *    documentation and/or other materials provided with the distribution.
1833965Sjdp *
1933965Sjdp * 3. Neither the name of the Institute nor the names of its contributors
2060484Sobrien *    may be used to endorse or promote products derived from this software
2160484Sobrien *    without specific prior written permission.
2260484Sobrien *
2333965Sjdp * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
2433965Sjdp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2533965Sjdp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2677298Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
2777298Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2877298Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2977298Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3077298Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3177298Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3233965Sjdp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3333965Sjdp * SUCH DAMAGE.
3433965Sjdp */
3533965Sjdp
3633965Sjdp#include <config.h>
3733965Sjdp#include <krb5/roken.h>
3833965Sjdp
3933965Sjdp#include <bn.h>
4033965Sjdp#include <rand.h>
41218822Sdim
4233965Sjdpstatic int
4333965Sjdpset_get(unsigned long num)
4433965Sjdp{
4533965Sjdp    BIGNUM *bn;
4633965Sjdp
4733965Sjdp    bn = BN_new();
4833965Sjdp    if (!BN_set_word(bn, num))
4933965Sjdp	return 1;
5033965Sjdp
5133965Sjdp    if (BN_get_word(bn) != num)
5260484Sobrien	return 1;
5360484Sobrien
5460484Sobrien    BN_free(bn);
5560484Sobrien    return 0;
5660484Sobrien}
5760484Sobrien
5860484Sobrien#define CHECK(x) do { ret += x; } while(0)
5933965Sjdp
6033965Sjdpstatic int
6133965Sjdptest_BN_set_get(void)
6233965Sjdp{
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
76static int
77test_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
143struct 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
155static int
156test_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
188static int
189test_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
261static int
262test_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
317static int
318test_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
339static int
340test_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
380int
381main(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