diff options
author | jsing <> | 2022-12-17 17:18:46 +0000 |
---|---|---|
committer | jsing <> | 2022-12-17 17:18:46 +0000 |
commit | 3badb2f37b0b6599d1adea20cfe176f262924ddc (patch) | |
tree | 584200d07b15a79d4fe9b0e386517da7c173569c | |
parent | df2ca82e06a75275e3bc983f48d1bb6f80cefdc5 (diff) | |
download | openbsd-3badb2f37b0b6599d1adea20cfe176f262924ddc.tar.gz openbsd-3badb2f37b0b6599d1adea20cfe176f262924ddc.tar.bz2 openbsd-3badb2f37b0b6599d1adea20cfe176f262924ddc.zip |
Provide regress coverage for BN shift functions.
Provide regress coverage for BN_lshift1(), BN_rshift1(), BN_lshift() and
BN_rshift(), along with basic benchmarking functionality (run via
'make benchmark').
-rw-r--r-- | src/regress/lib/libcrypto/bn/Makefile | 6 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/bn/bn_shift.c | 538 |
2 files changed, 543 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/bn/Makefile b/src/regress/lib/libcrypto/bn/Makefile index e95091aeb5..8a51a2ccad 100644 --- a/src/regress/lib/libcrypto/bn/Makefile +++ b/src/regress/lib/libcrypto/bn/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: Makefile,v 1.16 2022/12/09 09:56:41 tb Exp $ | 1 | # $OpenBSD: Makefile,v 1.17 2022/12/17 17:18:46 jsing Exp $ |
2 | 2 | ||
3 | PROGS += bn_add_sub | 3 | PROGS += bn_add_sub |
4 | PROGS += bn_cmp | 4 | PROGS += bn_cmp |
@@ -10,6 +10,7 @@ PROGS += bn_mod_sqrt | |||
10 | PROGS += bn_mont | 10 | PROGS += bn_mont |
11 | PROGS += bn_primes | 11 | PROGS += bn_primes |
12 | PROGS += bn_rand_interval | 12 | PROGS += bn_rand_interval |
13 | PROGS += bn_shift | ||
13 | PROGS += bn_test | 14 | PROGS += bn_test |
14 | PROGS += bn_to_string | 15 | PROGS += bn_to_string |
15 | PROGS += bn_unit | 16 | PROGS += bn_unit |
@@ -63,4 +64,7 @@ CLEANFILES += bn_test.out bc.out | |||
63 | LDADD_$p += ${CRYPTO_INT} | 64 | LDADD_$p += ${CRYPTO_INT} |
64 | .endfor | 65 | .endfor |
65 | 66 | ||
67 | benchmark: bn_shift | ||
68 | ./bn_shift --benchmark | ||
69 | |||
66 | .include <bsd.regress.mk> | 70 | .include <bsd.regress.mk> |
diff --git a/src/regress/lib/libcrypto/bn/bn_shift.c b/src/regress/lib/libcrypto/bn/bn_shift.c new file mode 100644 index 0000000000..c8f9d3ad1c --- /dev/null +++ b/src/regress/lib/libcrypto/bn/bn_shift.c | |||
@@ -0,0 +1,538 @@ | |||
1 | /* $OpenBSD: bn_shift.c,v 1.1 2022/12/17 17:18:46 jsing Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2022 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 <sys/time.h> | ||
19 | |||
20 | #include <err.h> | ||
21 | #include <signal.h> | ||
22 | #include <stdio.h> | ||
23 | #include <string.h> | ||
24 | #include <time.h> | ||
25 | #include <unistd.h> | ||
26 | |||
27 | #include <openssl/bn.h> | ||
28 | |||
29 | static const char *bn_shift_want_hex = \ | ||
30 | "02AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \ | ||
31 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8"; | ||
32 | |||
33 | static int | ||
34 | check_shift_result(BIGNUM *bn1) | ||
35 | { | ||
36 | BIGNUM *bn2 = NULL; | ||
37 | char *s = NULL; | ||
38 | int ret = 0; | ||
39 | |||
40 | if (!BN_hex2bn(&bn2, bn_shift_want_hex)) { | ||
41 | fprintf(stderr, "FAIL: BN_hex2bn() failed\n"); | ||
42 | goto failure; | ||
43 | } | ||
44 | if (BN_cmp(bn1, bn2) != 0) { | ||
45 | fprintf(stderr, "FAIL: shifted result differs\n"); | ||
46 | if ((s = BN_bn2hex(bn1)) == NULL) { | ||
47 | fprintf(stderr, "FAIL: BN_bn2hex()\n"); | ||
48 | goto failure; | ||
49 | } | ||
50 | fprintf(stderr, "Got: %s\n", s); | ||
51 | free(s); | ||
52 | if ((s = BN_bn2hex(bn2)) == NULL) { | ||
53 | fprintf(stderr, "FAIL: BN_bn2hex()\n"); | ||
54 | goto failure; | ||
55 | } | ||
56 | fprintf(stderr, "Want: %s\n", s); | ||
57 | } | ||
58 | |||
59 | ret = 1; | ||
60 | |||
61 | failure: | ||
62 | BN_free(bn2); | ||
63 | free(s); | ||
64 | |||
65 | return ret; | ||
66 | } | ||
67 | |||
68 | static int | ||
69 | test_bn_shift1(void) | ||
70 | { | ||
71 | BIGNUM *bn1 = NULL, *bn2 = NULL; | ||
72 | int i; | ||
73 | int failed = 1; | ||
74 | |||
75 | if ((bn1 = BN_new()) == NULL) { | ||
76 | fprintf(stderr, "FAIL: failed to create BN\n"); | ||
77 | goto failure; | ||
78 | } | ||
79 | if ((bn2 = BN_new()) == NULL) { | ||
80 | fprintf(stderr, "FAIL: failed to create BN\n"); | ||
81 | goto failure; | ||
82 | } | ||
83 | |||
84 | for (i = 1; i <= 256; i++) { | ||
85 | if (!BN_set_bit(bn1, 1)) { | ||
86 | fprintf(stderr, "FAIL: failed to set bit\n"); | ||
87 | goto failure; | ||
88 | } | ||
89 | if (!BN_lshift1(bn1, bn1)) { | ||
90 | fprintf(stderr, "FAIL: failed to BN_lshift1()\n"); | ||
91 | goto failure; | ||
92 | } | ||
93 | if (!BN_lshift1(bn1, bn1)) { | ||
94 | fprintf(stderr, "FAIL: failed to BN_lshift1()\n"); | ||
95 | goto failure; | ||
96 | } | ||
97 | if (!BN_rshift1(bn1, bn1)) { | ||
98 | fprintf(stderr, "FAIL: failed to BN_rshift1()\n"); | ||
99 | goto failure; | ||
100 | } | ||
101 | if (!BN_lshift1(bn1, bn1)) { | ||
102 | fprintf(stderr, "FAIL: failed to BN_lshift1()\n"); | ||
103 | goto failure; | ||
104 | } | ||
105 | } | ||
106 | |||
107 | if (!check_shift_result(bn1)) | ||
108 | goto failure; | ||
109 | |||
110 | /* | ||
111 | * Shift result into a different BN. | ||
112 | */ | ||
113 | if (!BN_lshift1(bn1, bn1)) { | ||
114 | fprintf(stderr, "FAIL: failed to BN_lshift1()\n"); | ||
115 | goto failure; | ||
116 | } | ||
117 | if (!BN_rshift1(bn2, bn1)) { | ||
118 | fprintf(stderr, "FAIL: failed to BN_rshift1()\n"); | ||
119 | goto failure; | ||
120 | } | ||
121 | |||
122 | if (!check_shift_result(bn2)) | ||
123 | goto failure; | ||
124 | |||
125 | if (!BN_rshift1(bn2, bn2)) { | ||
126 | fprintf(stderr, "FAIL: failed to BN_rshift1()\n"); | ||
127 | goto failure; | ||
128 | } | ||
129 | if (!BN_lshift1(bn1, bn2)) { | ||
130 | fprintf(stderr, "FAIL: failed to BN_lshift1()\n"); | ||
131 | goto failure; | ||
132 | } | ||
133 | |||
134 | if (!check_shift_result(bn1)) | ||
135 | goto failure; | ||
136 | |||
137 | failed = 0; | ||
138 | |||
139 | failure: | ||
140 | BN_free(bn1); | ||
141 | BN_free(bn2); | ||
142 | |||
143 | return failed; | ||
144 | } | ||
145 | |||
146 | static int | ||
147 | test_bn_shift(void) | ||
148 | { | ||
149 | BIGNUM *bn1 = NULL, *bn2 = NULL; | ||
150 | int i; | ||
151 | int failed = 1; | ||
152 | |||
153 | if ((bn1 = BN_new()) == NULL) { | ||
154 | fprintf(stderr, "FAIL: failed to create BN 1\n"); | ||
155 | goto failure; | ||
156 | } | ||
157 | if ((bn2 = BN_new()) == NULL) { | ||
158 | fprintf(stderr, "FAIL: failed to create BN 2\n"); | ||
159 | goto failure; | ||
160 | } | ||
161 | |||
162 | for (i = 1; i <= 256; i++) { | ||
163 | if (!BN_set_bit(bn1, 1)) { | ||
164 | fprintf(stderr, "FAIL: failed to set bit\n"); | ||
165 | goto failure; | ||
166 | } | ||
167 | if (!BN_lshift(bn1, bn1, i + 1)) { | ||
168 | fprintf(stderr, "FAIL: failed to BN_lshift()\n"); | ||
169 | goto failure; | ||
170 | } | ||
171 | if (!BN_rshift(bn1, bn1, i - 1)) { | ||
172 | fprintf(stderr, "FAIL: failed to BN_rshift()\n"); | ||
173 | goto failure; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | if (!check_shift_result(bn1)) | ||
178 | goto failure; | ||
179 | |||
180 | for (i = 0; i <= 256; i++) { | ||
181 | if (!BN_lshift(bn1, bn1, i)) { | ||
182 | fprintf(stderr, "FAIL: failed to BN_lshift()\n"); | ||
183 | goto failure; | ||
184 | } | ||
185 | if (i > 1) { | ||
186 | if (!BN_set_bit(bn1, 1)) { | ||
187 | fprintf(stderr, "FAIL: failed to set bit\n"); | ||
188 | goto failure; | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | |||
193 | if (BN_num_bytes(bn1) != 4177) { | ||
194 | fprintf(stderr, "FAIL: BN has %d bytes, want 4177\n", | ||
195 | BN_num_bytes(bn1)); | ||
196 | goto failure; | ||
197 | } | ||
198 | |||
199 | for (i = 0; i <= 256; i++) { | ||
200 | if (!BN_rshift(bn1, bn1, i)) { | ||
201 | fprintf(stderr, "FAIL: failed to BN_rshift()\n"); | ||
202 | goto failure; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | if (!check_shift_result(bn1)) | ||
207 | goto failure; | ||
208 | |||
209 | /* | ||
210 | * Shift result into a different BN. | ||
211 | */ | ||
212 | if (!BN_lshift(bn1, bn1, BN_BITS2 + 1)) { | ||
213 | fprintf(stderr, "FAIL: failed to BN_lshift()\n"); | ||
214 | goto failure; | ||
215 | } | ||
216 | if (!BN_rshift(bn2, bn1, BN_BITS2 + 1)) { | ||
217 | fprintf(stderr, "FAIL: failed to BN_rshift()\n"); | ||
218 | goto failure; | ||
219 | } | ||
220 | |||
221 | if (!check_shift_result(bn2)) | ||
222 | goto failure; | ||
223 | |||
224 | if (!BN_rshift(bn2, bn2, 3)) { | ||
225 | fprintf(stderr, "FAIL: failed to BN_rshift()\n"); | ||
226 | goto failure; | ||
227 | } | ||
228 | if (!BN_lshift(bn1, bn2, 3)) { | ||
229 | fprintf(stderr, "FAIL: failed to BN_lshift()\n"); | ||
230 | goto failure; | ||
231 | } | ||
232 | |||
233 | if (!check_shift_result(bn1)) | ||
234 | goto failure; | ||
235 | |||
236 | failed = 0; | ||
237 | |||
238 | failure: | ||
239 | BN_free(bn1); | ||
240 | BN_free(bn2); | ||
241 | |||
242 | return failed; | ||
243 | } | ||
244 | |||
245 | static int | ||
246 | test_bn_rshift_to_zero(void) | ||
247 | { | ||
248 | BIGNUM *bn1 = NULL, *bn2 = NULL; | ||
249 | int failed = 1; | ||
250 | |||
251 | if (!BN_hex2bn(&bn1, "ffff")) { | ||
252 | fprintf(stderr, "FAIL: BN_hex2bn() failed\n"); | ||
253 | goto failure; | ||
254 | } | ||
255 | if (!BN_lshift(bn1, bn1, BN_BITS2)) { | ||
256 | fprintf(stderr, "FAIL: BN_lshift() failed\n"); | ||
257 | goto failure; | ||
258 | } | ||
259 | |||
260 | if ((bn2 = BN_new()) == NULL) { | ||
261 | fprintf(stderr, "FAIL: BN_new() failed\n"); | ||
262 | goto failure; | ||
263 | } | ||
264 | |||
265 | /* Shift all words. */ | ||
266 | if (!BN_rshift(bn2, bn1, BN_BITS2 * 2)) { | ||
267 | fprintf(stderr, "FAIL: BN_rshift() failed\n"); | ||
268 | goto failure; | ||
269 | } | ||
270 | if (BN_is_zero(bn1)) { | ||
271 | fprintf(stderr, "FAIL: BN is zero\n"); | ||
272 | goto failure; | ||
273 | } | ||
274 | if (!BN_is_zero(bn2)) { | ||
275 | fprintf(stderr, "FAIL: BN is not zero\n"); | ||
276 | goto failure; | ||
277 | } | ||
278 | |||
279 | /* Shift to zero, with partial shift for top most word. */ | ||
280 | if (!BN_rshift(bn2, bn1, BN_BITS2 + 16)) { | ||
281 | fprintf(stderr, "FAIL: BN_rshift() failed\n"); | ||
282 | goto failure; | ||
283 | } | ||
284 | if (BN_is_zero(bn1)) { | ||
285 | fprintf(stderr, "FAIL: BN is zero\n"); | ||
286 | goto failure; | ||
287 | } | ||
288 | if (!BN_is_zero(bn2)) { | ||
289 | fprintf(stderr, "FAIL: BN is not zero\n"); | ||
290 | goto failure; | ||
291 | } | ||
292 | |||
293 | /* Shift to zero of negative value. */ | ||
294 | if (!BN_one(bn1)) { | ||
295 | fprintf(stderr, "FAIL: BN_one() failed\n"); | ||
296 | goto failure; | ||
297 | } | ||
298 | BN_set_negative(bn1, 1); | ||
299 | if (!BN_rshift(bn1, bn1, 1)) { | ||
300 | fprintf(stderr, "FAIL: BN_rshift() failed\n"); | ||
301 | goto failure; | ||
302 | } | ||
303 | if (!BN_is_zero(bn1)) { | ||
304 | fprintf(stderr, "FAIL: BN is not zero\n"); | ||
305 | goto failure; | ||
306 | } | ||
307 | |||
308 | failed = 0; | ||
309 | |||
310 | failure: | ||
311 | BN_free(bn1); | ||
312 | BN_free(bn2); | ||
313 | |||
314 | return failed; | ||
315 | } | ||
316 | |||
317 | static void | ||
318 | benchmark_bn_lshift1(BIGNUM *bn) | ||
319 | { | ||
320 | int i; | ||
321 | |||
322 | if (!BN_one(bn)) | ||
323 | errx(1, "BN_one"); | ||
324 | |||
325 | for (i = 0; i < 8192; i++) { | ||
326 | if (!BN_lshift1(bn, bn)) | ||
327 | errx(1, "BN_lshift1"); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | static void | ||
332 | benchmark_bn_lshift(BIGNUM *bn, int n) | ||
333 | { | ||
334 | int i; | ||
335 | |||
336 | if (!BN_one(bn)) | ||
337 | errx(1, "BN_one"); | ||
338 | |||
339 | for (i = 0; i < 8192; i++) { | ||
340 | if (!BN_lshift(bn, bn, n)) | ||
341 | errx(1, "BN_lshift"); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | static void | ||
346 | benchmark_bn_lshift_1(BIGNUM *bn) | ||
347 | { | ||
348 | benchmark_bn_lshift(bn, 1); | ||
349 | } | ||
350 | |||
351 | static void | ||
352 | benchmark_bn_lshift_32(BIGNUM *bn) | ||
353 | { | ||
354 | benchmark_bn_lshift(bn, 32); | ||
355 | } | ||
356 | |||
357 | static void | ||
358 | benchmark_bn_lshift_64(BIGNUM *bn) | ||
359 | { | ||
360 | benchmark_bn_lshift(bn, 64); | ||
361 | } | ||
362 | |||
363 | static void | ||
364 | benchmark_bn_lshift_127(BIGNUM *bn) | ||
365 | { | ||
366 | benchmark_bn_lshift(bn, 127); | ||
367 | } | ||
368 | |||
369 | static void | ||
370 | benchmark_bn_rshift1(BIGNUM *bn) | ||
371 | { | ||
372 | int i; | ||
373 | |||
374 | if (!BN_set_bit(bn, 8192)) | ||
375 | errx(1, "BN_set_bit"); | ||
376 | |||
377 | for (i = 0; i < 8192; i++) { | ||
378 | if (!BN_rshift1(bn, bn)) | ||
379 | errx(1, "BN_rshift1"); | ||
380 | } | ||
381 | } | ||
382 | |||
383 | static void | ||
384 | benchmark_bn_rshift(BIGNUM *bn, int n) | ||
385 | { | ||
386 | int i; | ||
387 | |||
388 | if (!BN_set_bit(bn, 8192 * n)) | ||
389 | errx(1, "BN_set_bit"); | ||
390 | |||
391 | for (i = 0; i < 8192; i++) { | ||
392 | if (!BN_rshift(bn, bn, n)) | ||
393 | errx(1, "BN_rshift"); | ||
394 | } | ||
395 | } | ||
396 | |||
397 | static void | ||
398 | benchmark_bn_rshift_1(BIGNUM *bn) | ||
399 | { | ||
400 | benchmark_bn_rshift(bn, 1); | ||
401 | } | ||
402 | |||
403 | static void | ||
404 | benchmark_bn_rshift_32(BIGNUM *bn) | ||
405 | { | ||
406 | benchmark_bn_rshift(bn, 32); | ||
407 | } | ||
408 | |||
409 | static void | ||
410 | benchmark_bn_rshift_64(BIGNUM *bn) | ||
411 | { | ||
412 | benchmark_bn_rshift(bn, 64); | ||
413 | } | ||
414 | |||
415 | static void | ||
416 | benchmark_bn_rshift_127(BIGNUM *bn) | ||
417 | { | ||
418 | benchmark_bn_rshift(bn, 127); | ||
419 | } | ||
420 | |||
421 | struct benchmark { | ||
422 | const char *desc; | ||
423 | void (*func)(BIGNUM *); | ||
424 | }; | ||
425 | |||
426 | struct benchmark benchmarks[] = { | ||
427 | { | ||
428 | .desc = "BN_lshift1()", | ||
429 | .func = benchmark_bn_lshift1, | ||
430 | }, | ||
431 | { | ||
432 | .desc = "BN_lshift(_, _, 1)", | ||
433 | .func = benchmark_bn_lshift_1, | ||
434 | }, | ||
435 | { | ||
436 | .desc = "BN_lshift(_, _, 32)", | ||
437 | .func = benchmark_bn_lshift_32, | ||
438 | }, | ||
439 | { | ||
440 | .desc = "BN_lshift(_, _, 64)", | ||
441 | .func = benchmark_bn_lshift_64, | ||
442 | }, | ||
443 | { | ||
444 | .desc = "BN_lshift(_, _, 127)", | ||
445 | .func = benchmark_bn_lshift_127, | ||
446 | }, | ||
447 | { | ||
448 | .desc = "BN_rshift1()", | ||
449 | .func = benchmark_bn_rshift1, | ||
450 | }, | ||
451 | { | ||
452 | .desc = "BN_rshift(_, _, 1)", | ||
453 | .func = benchmark_bn_rshift_1, | ||
454 | }, | ||
455 | { | ||
456 | .desc = "BN_rshift(_, _, 32)", | ||
457 | .func = benchmark_bn_rshift_32, | ||
458 | }, | ||
459 | { | ||
460 | .desc = "BN_rshift(_, _, 64)", | ||
461 | .func = benchmark_bn_rshift_64, | ||
462 | }, | ||
463 | { | ||
464 | .desc = "BN_rshift(_, _, 127)", | ||
465 | .func = benchmark_bn_rshift_127, | ||
466 | }, | ||
467 | }; | ||
468 | |||
469 | #define N_BENCHMARKS (sizeof(benchmarks) / sizeof(benchmarks[0])) | ||
470 | |||
471 | static int benchmark_stop; | ||
472 | |||
473 | static void | ||
474 | benchmark_sig_alarm(int sig) | ||
475 | { | ||
476 | benchmark_stop = 1; | ||
477 | } | ||
478 | |||
479 | static void | ||
480 | benchmark_run(const struct benchmark *bm, int seconds) | ||
481 | { | ||
482 | struct timespec start, end, duration; | ||
483 | BIGNUM *bn; | ||
484 | int i; | ||
485 | |||
486 | signal(SIGALRM, benchmark_sig_alarm); | ||
487 | |||
488 | if ((bn = BN_new()) == NULL) | ||
489 | errx(1, "BN_new"); | ||
490 | |||
491 | benchmark_stop = 0; | ||
492 | i = 0; | ||
493 | alarm(seconds); | ||
494 | |||
495 | clock_gettime(CLOCK_MONOTONIC, &start); | ||
496 | |||
497 | fprintf(stderr, "Benchmarking %s for %ds: ", bm->desc, seconds); | ||
498 | while (!benchmark_stop) { | ||
499 | bm->func(bn); | ||
500 | i++; | ||
501 | } | ||
502 | clock_gettime(CLOCK_MONOTONIC, &end); | ||
503 | timespecsub(&end, &start, &duration); | ||
504 | fprintf(stderr, "%d iterations in %f seconds\n", i, | ||
505 | duration.tv_sec + duration.tv_nsec / 1000000000.0); | ||
506 | |||
507 | BN_free(bn); | ||
508 | } | ||
509 | |||
510 | static void | ||
511 | benchmark_bn_shift(void) | ||
512 | { | ||
513 | const struct benchmark *bm; | ||
514 | size_t i; | ||
515 | |||
516 | for (i = 0; i < N_BENCHMARKS; i++) { | ||
517 | bm = &benchmarks[i]; | ||
518 | benchmark_run(bm, 5); | ||
519 | } | ||
520 | } | ||
521 | |||
522 | int | ||
523 | main(int argc, char **argv) | ||
524 | { | ||
525 | int benchmark = 0, failed = 0; | ||
526 | |||
527 | if (argc == 2 && strcmp(argv[1], "--benchmark") == 0) | ||
528 | benchmark = 1; | ||
529 | |||
530 | failed |= test_bn_shift1(); | ||
531 | failed |= test_bn_shift(); | ||
532 | failed |= test_bn_rshift_to_zero(); | ||
533 | |||
534 | if (benchmark && !failed) | ||
535 | benchmark_bn_shift(); | ||
536 | |||
537 | return failed; | ||
538 | } | ||