From e79df2fb4880f5044b78ea35aeed91750da9217b Mon Sep 17 00:00:00 2001 From: jsing Date: Mon, 10 Apr 2023 19:02:30 +0000 Subject: [PATCH] Provide benchmarks for BN_copy() --- regress/lib/libcrypto/bn/Makefile | 3 +- regress/lib/libcrypto/bn/bn_general.c | 182 ++++++++++++++++++++++++++ 2 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 regress/lib/libcrypto/bn/bn_general.c diff --git a/regress/lib/libcrypto/bn/Makefile b/regress/lib/libcrypto/bn/Makefile index 71909edc61e..5df30379a4f 100644 --- a/regress/lib/libcrypto/bn/Makefile +++ b/regress/lib/libcrypto/bn/Makefile @@ -1,8 +1,9 @@ -# $OpenBSD: Makefile,v 1.28 2023/04/10 13:57:57 tb Exp $ +# $OpenBSD: Makefile,v 1.29 2023/04/10 19:02:30 jsing Exp $ PROGS += bn_add_sub PROGS += bn_cmp PROGS += bn_gcd +PROGS += bn_general PROGS += bn_isqrt PROGS += bn_mod_exp PROGS += bn_mod_sqrt diff --git a/regress/lib/libcrypto/bn/bn_general.c b/regress/lib/libcrypto/bn/bn_general.c new file mode 100644 index 00000000000..94f7af19efe --- /dev/null +++ b/regress/lib/libcrypto/bn/bn_general.c @@ -0,0 +1,182 @@ +/* $OpenBSD: bn_general.c,v 1.1 2023/04/10 19:02:30 jsing Exp $ */ +/* + * Copyright (c) 2022, 2023 Joel Sing + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +static void +benchmark_bn_copy_setup(BIGNUM *dst, BIGNUM *src, int n) +{ + if (!BN_set_bit(dst, n - 1)) + errx(1, "BN_set_bit"); + if (!BN_set_bit(src, n - 1)) + errx(1, "BN_set_bit"); +} + +static void +benchmark_bn_copy_run_once(BIGNUM *dst, BIGNUM *src) +{ + if (BN_copy(dst, src) == NULL) + errx(1, "BN_copy"); +} + +struct benchmark { + const char *desc; + void (*setup)(BIGNUM *, BIGNUM *, int); + void (*run_once)(BIGNUM *, BIGNUM *); + int bits; +}; + +struct benchmark benchmarks[] = { + { + .desc = "BN_copy() 32 bits", + .setup = benchmark_bn_copy_setup, + .run_once = benchmark_bn_copy_run_once, + .bits = 32, + }, + { + .desc = "BN_copy() 256 bits", + .setup = benchmark_bn_copy_setup, + .run_once = benchmark_bn_copy_run_once, + .bits = 256, + }, + { + .desc = "BN_copy() 320 bits", + .setup = benchmark_bn_copy_setup, + .run_once = benchmark_bn_copy_run_once, + .bits = 320, + }, + { + .desc = "BN_copy() 512 bits", + .setup = benchmark_bn_copy_setup, + .run_once = benchmark_bn_copy_run_once, + .bits = 512, + }, + { + .desc = "BN_copy() 1024 bits", + .setup = benchmark_bn_copy_setup, + .run_once = benchmark_bn_copy_run_once, + .bits = 1024, + }, + { + .desc = "BN_copy() 2048 bits", + .setup = benchmark_bn_copy_setup, + .run_once = benchmark_bn_copy_run_once, + .bits = 2048, + }, + { + .desc = "BN_copy() 4096 bits", + .setup = benchmark_bn_copy_setup, + .run_once = benchmark_bn_copy_run_once, + .bits = 4096, + }, + { + .desc = "BN_copy() 16384 bits", + .setup = benchmark_bn_copy_setup, + .run_once = benchmark_bn_copy_run_once, + .bits = 16384, + }, +}; + +#define N_BENCHMARKS (sizeof(benchmarks) / sizeof(benchmarks[0])) + +static int benchmark_stop; + +static void +benchmark_sig_alarm(int sig) +{ + benchmark_stop = 1; +} + +static void +benchmark_run(const struct benchmark *bm, int seconds) +{ + struct timespec start, end, duration; + struct rusage rusage; + BIGNUM *dst, *src; + int i; + + signal(SIGALRM, benchmark_sig_alarm); + + if ((src = BN_new()) == NULL) + errx(1, "BN_new"); + if ((dst = BN_new()) == NULL) + errx(1, "BN_new"); + + bm->setup(dst, src, bm->bits); + + benchmark_stop = 0; + i = 0; + alarm(seconds); + + if (getrusage(RUSAGE_SELF, &rusage) == -1) + err(1, "getrusage failed"); + TIMEVAL_TO_TIMESPEC(&rusage.ru_utime, &start); + + fprintf(stderr, "Benchmarking %s for %ds: ", bm->desc, seconds); + while (!benchmark_stop) { + bm->run_once(dst, src); + i++; + } + if (getrusage(RUSAGE_SELF, &rusage) == -1) + err(1, "getrusage failed"); + TIMEVAL_TO_TIMESPEC(&rusage.ru_utime, &end); + + timespecsub(&end, &start, &duration); + fprintf(stderr, "%d iterations in %f seconds - %llu op/s\n", i, + duration.tv_sec + duration.tv_nsec / 1000000000.0, + (size_t)i * 1000000000 / + (duration.tv_sec * 1000000000 + duration.tv_nsec)); + + BN_free(src); + BN_free(dst); +} + +static void +benchmark_bn_general(void) +{ + const struct benchmark *bm; + size_t i; + + for (i = 0; i < N_BENCHMARKS; i++) { + bm = &benchmarks[i]; + benchmark_run(bm, 5); + } +} + +int +main(int argc, char **argv) +{ + int benchmark = 0, failed = 0; + + if (argc == 2 && strcmp(argv[1], "--benchmark") == 0) + benchmark = 1; + + if (benchmark && !failed) + benchmark_bn_general(); + + return failed; +} -- 2.20.1