summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/regress/lib/libcrypto/bn/Makefile3
-rw-r--r--src/regress/lib/libcrypto/bn/bn_word.c617
2 files changed, 619 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/bn/Makefile b/src/regress/lib/libcrypto/bn/Makefile
index 2852b2e469..bcdfe3ed4f 100644
--- a/src/regress/lib/libcrypto/bn/Makefile
+++ b/src/regress/lib/libcrypto/bn/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.21 2023/01/31 05:13:28 jsing Exp $ 1# $OpenBSD: Makefile,v 1.22 2023/03/11 14:04:21 jsing Exp $
2 2
3PROGS += bn_add_sub 3PROGS += bn_add_sub
4PROGS += bn_cmp 4PROGS += bn_cmp
@@ -15,6 +15,7 @@ PROGS += bn_shift
15PROGS += bn_test 15PROGS += bn_test
16PROGS += bn_to_string 16PROGS += bn_to_string
17PROGS += bn_unit 17PROGS += bn_unit
18PROGS += bn_word
18 19
19STATIC_LINK += bn_isqrt 20STATIC_LINK += bn_isqrt
20STATIC_LINK += bn_mod_exp 21STATIC_LINK += bn_mod_exp
diff --git a/src/regress/lib/libcrypto/bn/bn_word.c b/src/regress/lib/libcrypto/bn/bn_word.c
new file mode 100644
index 0000000000..0a543add97
--- /dev/null
+++ b/src/regress/lib/libcrypto/bn/bn_word.c
@@ -0,0 +1,617 @@
1/* $OpenBSD: bn_word.c,v 1.1 2023/03/11 14:04:21 jsing Exp $ */
2/*
3 * Copyright (c) 2023 Joel Sing <jsing@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <err.h>
19#include <string.h>
20
21#include <openssl/bn.h>
22
23struct bn_word_test {
24 const char *in_hex;
25 BN_ULONG in_word;
26 BN_ULONG mod_word;
27 BN_ULONG out_word;
28 const char *out_hex;
29 int out_is_negative;
30};
31
32static int
33check_bn_word_test(const char *op_name, const BIGNUM *bn,
34 const struct bn_word_test *bwt)
35{
36 char *out_hex = NULL;
37 BN_ULONG out_word;
38 int failed = 1;
39
40 if ((out_word = BN_get_word(bn)) != bwt->out_word) {
41 fprintf(stderr, "FAIL %s: Got word %lx, want %lx\n",
42 op_name, (unsigned long)out_word,
43 (unsigned long)bwt->out_word);
44 goto failure;
45 }
46
47 if (BN_is_negative(bn) != bwt->out_is_negative) {
48 fprintf(stderr, "FAIL %s: Got is negative %d, want %d\n",
49 op_name, BN_is_negative(bn), bwt->out_is_negative);
50 goto failure;
51 }
52
53 if ((out_hex = BN_bn2hex(bn)) == NULL)
54 errx(1, "BN_bn2hex() failed\n");
55
56 if (strcmp(out_hex, bwt->out_hex) != 0) {
57 fprintf(stderr, "FAIL %s: Got hex %s, want %s\n",
58 op_name, out_hex, bwt->out_hex);
59 goto failure;
60 }
61
62 if (BN_is_zero(bn) && BN_is_negative(bn) != 0) {
63 fprintf(stderr, "FAIL %s: Got negative zero\n", op_name);
64 goto failure;
65 }
66
67 failed = 0;
68
69 failure:
70 free(out_hex);
71
72 return failed;
73}
74
75static int
76test_bn_word(int (*bn_word_op)(BIGNUM *, BN_ULONG), const char *op_name,
77 const struct bn_word_test *bwts, size_t num_tests)
78{
79 const struct bn_word_test *bwt;
80 BIGNUM *bn;
81 size_t i;
82 int failed = 0;
83
84 if ((bn = BN_new()) == NULL)
85 errx(1, "BN_new() failed\n");
86
87 for (i = 0; i < num_tests; i++) {
88 bwt = &bwts[i];
89
90 if (!BN_hex2bn(&bn, bwt->in_hex)) {
91 fprintf(stderr, "FAIL: BN_hex2bn(\"%s\") failed\n",
92 bwt->in_hex);
93 failed = 1;
94 continue;
95 }
96
97 if (!bn_word_op(bn, bwt->in_word)) {
98 fprintf(stderr, "FAIL: %s(%lx) failed\n", op_name,
99 (unsigned long)bwt->in_word);
100 failed = 1;
101 continue;
102 }
103
104 failed |= check_bn_word_test(op_name, bn, bwt);
105 }
106
107 BN_free(bn);
108
109 return failed;
110}
111
112static const struct bn_word_test bn_add_word_tests[] = {
113 {
114 .in_hex = "1",
115 .in_word = 0,
116 .out_word = 1,
117 .out_hex = "01",
118 },
119 {
120 .in_hex = "0",
121 .in_word = 1,
122 .out_word = 1,
123 .out_hex = "01",
124 },
125 {
126 .in_hex = "1",
127 .in_word = 1,
128 .out_word = 2,
129 .out_hex = "02",
130 },
131 {
132 .in_hex = "-1",
133 .in_word = 2,
134 .out_word = 1,
135 .out_hex = "01",
136 },
137 {
138 .in_hex = "-1",
139 .in_word = 1,
140 .out_word = 0,
141 .out_hex = "0",
142 },
143 {
144 .in_hex = "-3",
145 .in_word = 2,
146 .out_word = 1,
147 .out_hex = "-01",
148 .out_is_negative = 1,
149 },
150 {
151 .in_hex = "1",
152 .in_word = 0xfffffffeUL,
153 .out_word = 0xffffffffUL,
154 .out_hex = "FFFFFFFF",
155 },
156 {
157 .in_hex = "FFFFFFFFFFFFFFFF",
158 .in_word = 1,
159 .out_word = BN_MASK2,
160 .out_hex = "010000000000000000",
161 },
162};
163
164#define N_BN_ADD_WORD_TESTS \
165 (sizeof(bn_add_word_tests) / sizeof(bn_add_word_tests[0]))
166
167static int
168test_bn_add_word(void)
169{
170 return test_bn_word(BN_add_word, "BN_add_word", bn_add_word_tests,
171 N_BN_ADD_WORD_TESTS);
172}
173
174static const struct bn_word_test bn_sub_word_tests[] = {
175 {
176 .in_hex = "1",
177 .in_word = 0,
178 .out_word = 1,
179 .out_hex = "01",
180 },
181 {
182 .in_hex = "0",
183 .in_word = 1,
184 .out_word = 1,
185 .out_hex = "-01",
186 .out_is_negative = 1,
187 },
188 {
189 .in_hex = "1",
190 .in_word = 1,
191 .out_word = 0,
192 .out_hex = "0",
193 },
194 {
195 .in_hex = "2",
196 .in_word = 1,
197 .out_word = 1,
198 .out_hex = "01",
199 },
200 {
201 .in_hex = "-1",
202 .in_word = 2,
203 .out_word = 3,
204 .out_hex = "-03",
205 .out_is_negative = 1,
206 },
207 {
208 .in_hex = "1",
209 .in_word = 1,
210 .out_word = 0,
211 .out_hex = "0",
212 },
213 {
214 .in_hex = "3",
215 .in_word = 2,
216 .out_word = 1,
217 .out_hex = "01",
218 },
219 {
220 .in_hex = "-3",
221 .in_word = 2,
222 .out_word = 5,
223 .out_hex = "-05",
224 .out_is_negative = 1,
225 },
226 {
227 .in_hex = "-1",
228 .in_word = 0xfffffffeUL,
229 .out_word = 0xffffffffUL,
230 .out_hex = "-FFFFFFFF",
231 .out_is_negative = 1,
232 },
233 {
234 .in_hex = "010000000000000000",
235 .in_word = 1,
236 .out_word = BN_MASK2,
237 .out_hex = "FFFFFFFFFFFFFFFF",
238 },
239};
240
241#define N_BN_SUB_WORD_TESTS \
242 (sizeof(bn_sub_word_tests) / sizeof(bn_sub_word_tests[0]))
243
244static int
245test_bn_sub_word(void)
246{
247 return test_bn_word(BN_sub_word, "BN_sub_word", bn_sub_word_tests,
248 N_BN_SUB_WORD_TESTS);
249}
250
251static const struct bn_word_test bn_mul_word_tests[] = {
252 {
253 .in_hex = "1",
254 .in_word = 0,
255 .out_word = 0,
256 .out_hex = "0",
257 },
258 {
259 .in_hex = "0",
260 .in_word = 1,
261 .out_word = 0,
262 .out_hex = "0",
263 },
264 {
265 .in_hex = "1",
266 .in_word = 1,
267 .out_word = 1,
268 .out_hex = "01",
269 },
270 {
271 .in_hex = "-1",
272 .in_word = 0,
273 .out_word = 0,
274 .out_hex = "0",
275 },
276 {
277 .in_hex = "-1",
278 .in_word = 1,
279 .out_word = 1,
280 .out_hex = "-01",
281 .out_is_negative = 1,
282 },
283 {
284 .in_hex = "-3",
285 .in_word = 2,
286 .out_word = 6,
287 .out_hex = "-06",
288 .out_is_negative = 1,
289 },
290 {
291 .in_hex = "1",
292 .in_word = 0xfffffffeUL,
293 .out_word = 0xfffffffeUL,
294 .out_hex = "FFFFFFFE",
295 },
296 {
297 .in_hex = "010000000000000000",
298 .in_word = 2,
299 .out_word = BN_MASK2,
300 .out_hex = "020000000000000000",
301 },
302};
303
304#define N_BN_MUL_WORD_TESTS \
305 (sizeof(bn_mul_word_tests) / sizeof(bn_mul_word_tests[0]))
306
307static int
308test_bn_mul_word(void)
309{
310 return test_bn_word(BN_mul_word, "BN_mul_word", bn_mul_word_tests,
311 N_BN_MUL_WORD_TESTS);
312}
313
314static const struct bn_word_test bn_div_word_tests[] = {
315 {
316 .in_hex = "1",
317 .in_word = 0,
318 .mod_word = BN_MASK2,
319 .out_word = 1,
320 .out_hex = "01",
321 },
322 {
323 .in_hex = "0",
324 .in_word = 1,
325 .mod_word = 0,
326 .out_word = 0,
327 .out_hex = "0",
328 },
329 {
330 .in_hex = "4",
331 .in_word = 2,
332 .mod_word = 0,
333 .out_word = 2,
334 .out_hex = "02",
335 },
336 {
337 .in_hex = "7",
338 .in_word = 3,
339 .mod_word = 1,
340 .out_word = 2,
341 .out_hex = "02",
342 },
343 {
344 .in_hex = "1",
345 .in_word = 1,
346 .mod_word = 0,
347 .out_word = 1,
348 .out_hex = "01",
349 },
350 {
351 .in_hex = "-2",
352 .in_word = 1,
353 .mod_word = 0,
354 .out_word = 2,
355 .out_hex = "-02",
356 .out_is_negative = 1,
357 },
358 {
359 .in_hex = "-1",
360 .in_word = 2,
361 .mod_word = 1,
362 .out_word = 0,
363 .out_hex = "0",
364 },
365 {
366 .in_hex = "-3",
367 .in_word = 2,
368 .mod_word = 1,
369 .out_word = 1,
370 .out_hex = "-01",
371 .out_is_negative = 1,
372 },
373 {
374 .in_hex = "1",
375 .in_word = 0xffffffffUL,
376 .mod_word = 1,
377 .out_word = 0,
378 .out_hex = "0",
379 },
380 {
381 .in_hex = "FFFFFFFF",
382 .in_word = 1,
383 .mod_word = 0,
384 .out_word = 0xffffffffUL,
385 .out_hex = "FFFFFFFF",
386 },
387 {
388 .in_hex = "FFFFFFFE",
389 .in_word = 0xffffffffUL,
390 .mod_word = 0xfffffffeUL,
391 .out_word = 0,
392 .out_hex = "0",
393 },
394 {
395 .in_hex = "FFFFFFFFFFFFFFFF",
396 .in_word = 1,
397 .mod_word = 0,
398 .out_word = BN_MASK2,
399 .out_hex = "FFFFFFFFFFFFFFFF",
400 },
401 {
402 .in_hex = "FFFFFFFF",
403 .in_word = 0xff,
404 .mod_word = 0,
405 .out_word = 0x1010101UL,
406 .out_hex = "01010101",
407 },
408 {
409 .in_hex = "FFFFFFFF",
410 .in_word = 0x10,
411 .mod_word = 0xf,
412 .out_word = 0xfffffffUL,
413 .out_hex = "0FFFFFFF",
414 },
415};
416
417#define N_BN_DIV_WORD_TESTS \
418 (sizeof(bn_div_word_tests) / sizeof(bn_div_word_tests[0]))
419
420static int
421test_bn_div_word(void)
422{
423 const char *op_name = "BN_div_word";
424 const struct bn_word_test *bwt;
425 BN_ULONG mod_word;
426 BIGNUM *bn;
427 size_t i;
428 int failed = 0;
429
430 if ((bn = BN_new()) == NULL)
431 errx(1, "BN_new() failed\n");
432
433 for (i = 0; i < N_BN_DIV_WORD_TESTS; i++) {
434 bwt = &bn_div_word_tests[i];
435
436 if (!BN_hex2bn(&bn, bwt->in_hex)) {
437 fprintf(stderr, "FAIL: BN_hex2bn(\"%s\") failed\n",
438 bwt->in_hex);
439 failed = 1;
440 continue;
441 }
442
443 if ((mod_word = BN_div_word(bn, bwt->in_word)) != bwt->mod_word) {
444 fprintf(stderr, "FAIL %s: Got mod word %lx, want %lx\n",
445 op_name, (unsigned long)mod_word,
446 (unsigned long)bwt->mod_word);
447 failed = 1;
448 continue;
449 }
450
451 failed |= check_bn_word_test(op_name, bn, bwt);
452 }
453
454 BN_free(bn);
455
456 return failed;
457}
458
459static const struct bn_word_test bn_mod_word_tests[] = {
460 {
461 .in_hex = "1",
462 .in_word = 0,
463 .mod_word = BN_MASK2,
464 .out_word = 1,
465 .out_hex = "01",
466 },
467 {
468 .in_hex = "0",
469 .in_word = 1,
470 .mod_word = 0,
471 .out_word = 0,
472 .out_hex = "0",
473 },
474 {
475 .in_hex = "4",
476 .in_word = 2,
477 .mod_word = 0,
478 .out_word = 4,
479 .out_hex = "04",
480 },
481 {
482 .in_hex = "7",
483 .in_word = 3,
484 .mod_word = 1,
485 .out_word = 7,
486 .out_hex = "07",
487 },
488 {
489 .in_hex = "1",
490 .in_word = 1,
491 .mod_word = 0,
492 .out_word = 1,
493 .out_hex = "01",
494 },
495 {
496 .in_hex = "-2",
497 .in_word = 1,
498 .mod_word = 0,
499 .out_word = 2,
500 .out_hex = "-02",
501 .out_is_negative = 1,
502 },
503 {
504 .in_hex = "-1",
505 .in_word = 2,
506 .mod_word = 1,
507 .out_word = 1,
508 .out_hex = "-01",
509 .out_is_negative = 1,
510 },
511 {
512 .in_hex = "-3",
513 .in_word = 2,
514 .mod_word = 1,
515 .out_word = 3,
516 .out_hex = "-03",
517 .out_is_negative = 1,
518 },
519 {
520 .in_hex = "1",
521 .in_word = 0xffffffffUL,
522 .mod_word = 1,
523 .out_word = 1,
524 .out_hex = "01",
525 },
526 {
527 .in_hex = "FFFFFFFF",
528 .in_word = 1,
529 .mod_word = 0,
530 .out_word = 0xffffffffUL,
531 .out_hex = "FFFFFFFF",
532 },
533 {
534 .in_hex = "FFFFFFFE",
535 .in_word = 0xffffffffUL,
536 .mod_word = 0xfffffffeUL,
537 .out_word = 0xfffffffeUL,
538 .out_hex = "FFFFFFFE",
539 },
540 {
541 .in_hex = "FFFFFFFFFFFFFFFF",
542 .in_word = 1,
543 .mod_word = 0,
544 .out_word = BN_MASK2,
545 .out_hex = "FFFFFFFFFFFFFFFF",
546 },
547 {
548 .in_hex = "FFFFFFFF",
549 .in_word = 0xff,
550 .mod_word = 0,
551 .out_word = 0xffffffff,
552 .out_hex = "FFFFFFFF",
553 },
554 {
555 .in_hex = "FFFFFFFF",
556 .in_word = 0x10,
557 .mod_word = 0xf,
558 .out_word = 0xffffffffUL,
559 .out_hex = "FFFFFFFF",
560 },
561};
562
563#define N_BN_MOD_WORD_TESTS \
564 (sizeof(bn_mod_word_tests) / sizeof(bn_mod_word_tests[0]))
565
566static int
567test_bn_mod_word(void)
568{
569 const char *op_name = "BN_mod_word";
570 const struct bn_word_test *bwt;
571 BN_ULONG mod_word;
572 BIGNUM *bn;
573 size_t i;
574 int failed = 0;
575
576 if ((bn = BN_new()) == NULL)
577 errx(1, "BN_new() failed\n");
578
579 for (i = 0; i < N_BN_MOD_WORD_TESTS; i++) {
580 bwt = &bn_mod_word_tests[i];
581
582 if (!BN_hex2bn(&bn, bwt->in_hex)) {
583 fprintf(stderr, "FAIL: BN_hex2bn(\"%s\") failed\n",
584 bwt->in_hex);
585 failed = 1;
586 continue;
587 }
588
589 if ((mod_word = BN_mod_word(bn, bwt->in_word)) != bwt->mod_word) {
590 fprintf(stderr, "FAIL %s: Got mod word %lx, want %lx\n",
591 op_name, (unsigned long)mod_word,
592 (unsigned long)bwt->mod_word);
593 failed = 1;
594 continue;
595 }
596
597 failed |= check_bn_word_test(op_name, bn, bwt);
598 }
599
600 BN_free(bn);
601
602 return failed;
603}
604
605int
606main(int argc, char **argv)
607{
608 int failed = 0;
609
610 failed |= test_bn_add_word();
611 failed |= test_bn_sub_word();
612 failed |= test_bn_mul_word();
613 failed |= test_bn_div_word();
614 failed |= test_bn_mod_word();
615
616 return failed;
617}