diff options
| author | jsing <> | 2025-08-03 08:29:39 +0000 |
|---|---|---|
| committer | jsing <> | 2025-08-03 08:29:39 +0000 |
| commit | 814ef81f3e7fc1744717c0de4deaf1c916dfad4f (patch) | |
| tree | 49e203eb318d932a65b978cee8757d2a26a4fbb2 /src | |
| parent | 39d33c1bb185014e05def87e04f21103d92dc455 (diff) | |
| download | openbsd-814ef81f3e7fc1744717c0de4deaf1c916dfad4f.tar.gz openbsd-814ef81f3e7fc1744717c0de4deaf1c916dfad4f.tar.bz2 openbsd-814ef81f3e7fc1744717c0de4deaf1c916dfad4f.zip | |
Provide benchmarks for EC arithmetic.
This provides benchmarking for EC_POINT_add(), EC_POINT_dbl() and
EC_POINT_mul()'s scalar * generator path.
Diffstat (limited to 'src')
| -rw-r--r-- | src/regress/lib/libcrypto/ec/Makefile | 3 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/ec/ec_arithmetic.c | 210 |
2 files changed, 212 insertions, 1 deletions
diff --git a/src/regress/lib/libcrypto/ec/Makefile b/src/regress/lib/libcrypto/ec/Makefile index 3595a88608..1d976c77d0 100644 --- a/src/regress/lib/libcrypto/ec/Makefile +++ b/src/regress/lib/libcrypto/ec/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # $OpenBSD: Makefile,v 1.12 2025/07/23 07:43:14 tb Exp $ | 1 | # $OpenBSD: Makefile,v 1.13 2025/08/03 08:29:39 jsing Exp $ |
| 2 | 2 | ||
| 3 | .ifdef EOPENSSL35 | 3 | .ifdef EOPENSSL35 |
| 4 | LDADD += -Wl,-rpath,/usr/local/lib/eopenssl35 -L/usr/local/lib/eopenssl35 | 4 | LDADD += -Wl,-rpath,/usr/local/lib/eopenssl35 -L/usr/local/lib/eopenssl35 |
| @@ -7,6 +7,7 @@ CFLAGS += -DOPENSSL_SUPPRESS_DEPRECATED | |||
| 7 | .endif | 7 | .endif |
| 8 | 8 | ||
| 9 | PROGS += ectest | 9 | PROGS += ectest |
| 10 | PROGS += ec_arithmetic | ||
| 10 | PROGS += ec_asn1_test | 11 | PROGS += ec_asn1_test |
| 11 | PROGS += ec_point_conversion | 12 | PROGS += ec_point_conversion |
| 12 | 13 | ||
diff --git a/src/regress/lib/libcrypto/ec/ec_arithmetic.c b/src/regress/lib/libcrypto/ec/ec_arithmetic.c new file mode 100644 index 0000000000..c6f7cd4f8c --- /dev/null +++ b/src/regress/lib/libcrypto/ec/ec_arithmetic.c | |||
| @@ -0,0 +1,210 @@ | |||
| 1 | /* $OpenBSD: ec_arithmetic.c,v 1.1 2025/08/03 08:29:39 jsing Exp $ */ | ||
| 2 | /* | ||
| 3 | * Copyright (c) 2022,2025 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 | #include <openssl/ec.h> | ||
| 29 | #include <openssl/objects.h> | ||
| 30 | |||
| 31 | static void | ||
| 32 | benchmark_ec_point_add(const EC_GROUP *group, EC_POINT *result, | ||
| 33 | const BIGNUM *scalar, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
| 34 | { | ||
| 35 | if (!EC_POINT_add(group, result, a, b, ctx)) | ||
| 36 | errx(1, "EC_POINT_add"); | ||
| 37 | } | ||
| 38 | |||
| 39 | static void | ||
| 40 | benchmark_ec_point_dbl(const EC_GROUP *group, EC_POINT *result, | ||
| 41 | const BIGNUM *scalar, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
| 42 | { | ||
| 43 | if (!EC_POINT_dbl(group, result, a, ctx)) | ||
| 44 | errx(1, "EC_POINT_dbl"); | ||
| 45 | } | ||
| 46 | |||
| 47 | static void | ||
| 48 | benchmark_ec_point_mul_generator(const EC_GROUP *group, EC_POINT *result, | ||
| 49 | const BIGNUM *scalar, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx) | ||
| 50 | { | ||
| 51 | if (!EC_POINT_mul(group, result, scalar, NULL, NULL, ctx)) | ||
| 52 | errx(1, "EC_POINT_mul"); | ||
| 53 | } | ||
| 54 | |||
| 55 | struct benchmark { | ||
| 56 | int curve; | ||
| 57 | const char *desc; | ||
| 58 | void (*func)(const EC_GROUP *, EC_POINT *, const BIGNUM *, | ||
| 59 | const EC_POINT *, const EC_POINT *, BN_CTX *); | ||
| 60 | }; | ||
| 61 | |||
| 62 | static const struct benchmark benchmarks[] = { | ||
| 63 | { | ||
| 64 | .curve = NID_X9_62_prime256v1, | ||
| 65 | .desc = "EC_POINT_add() p256", | ||
| 66 | .func = benchmark_ec_point_add, | ||
| 67 | }, | ||
| 68 | { | ||
| 69 | .curve = NID_secp384r1, | ||
| 70 | .desc = "EC_POINT_add() p384", | ||
| 71 | .func = benchmark_ec_point_add, | ||
| 72 | }, | ||
| 73 | { | ||
| 74 | .curve = NID_secp521r1, | ||
| 75 | .desc = "EC_POINT_add() p521", | ||
| 76 | .func = benchmark_ec_point_add, | ||
| 77 | }, | ||
| 78 | { | ||
| 79 | .curve = NID_X9_62_prime256v1, | ||
| 80 | .desc = "EC_POINT_dbl() p256", | ||
| 81 | .func = benchmark_ec_point_dbl, | ||
| 82 | }, | ||
| 83 | { | ||
| 84 | .curve = NID_secp384r1, | ||
| 85 | .desc = "EC_POINT_dbl() p384", | ||
| 86 | .func = benchmark_ec_point_dbl, | ||
| 87 | }, | ||
| 88 | { | ||
| 89 | .curve = NID_secp521r1, | ||
| 90 | .desc = "EC_POINT_dbl() p521", | ||
| 91 | .func = benchmark_ec_point_dbl, | ||
| 92 | }, | ||
| 93 | { | ||
| 94 | .curve = NID_X9_62_prime256v1, | ||
| 95 | .desc = "EC_POINT_mul() generator p256", | ||
| 96 | .func = benchmark_ec_point_mul_generator, | ||
| 97 | }, | ||
| 98 | { | ||
| 99 | .curve = NID_secp384r1, | ||
| 100 | .desc = "EC_POINT_mul() generator p384", | ||
| 101 | .func = benchmark_ec_point_mul_generator, | ||
| 102 | }, | ||
| 103 | { | ||
| 104 | .curve = NID_secp521r1, | ||
| 105 | .desc = "EC_POINT_mul() generator p521", | ||
| 106 | .func = benchmark_ec_point_mul_generator, | ||
| 107 | }, | ||
| 108 | }; | ||
| 109 | |||
| 110 | #define N_BENCHMARKS (sizeof(benchmarks) / sizeof(benchmarks[0])) | ||
| 111 | |||
| 112 | static volatile sig_atomic_t benchmark_stop; | ||
| 113 | |||
| 114 | static void | ||
| 115 | benchmark_sig_alarm(int sig) | ||
| 116 | { | ||
| 117 | benchmark_stop = 1; | ||
| 118 | } | ||
| 119 | |||
| 120 | static void | ||
| 121 | benchmark_run(const struct benchmark *bm, int seconds) | ||
| 122 | { | ||
| 123 | struct timespec start, end, duration; | ||
| 124 | EC_GROUP *group = NULL; | ||
| 125 | EC_POINT *a = NULL, *b = NULL, *result = NULL; | ||
| 126 | BIGNUM *order = NULL, *scalar = NULL; | ||
| 127 | BN_CTX *ctx = NULL; | ||
| 128 | int i; | ||
| 129 | |||
| 130 | signal(SIGALRM, benchmark_sig_alarm); | ||
| 131 | |||
| 132 | if ((ctx = BN_CTX_new()) == NULL) | ||
| 133 | errx(1, "BN_CTX_new"); | ||
| 134 | |||
| 135 | if ((group = EC_GROUP_new_by_curve_name(bm->curve)) == NULL) | ||
| 136 | errx(1, "EC_GROUP_new_by_curve_name"); | ||
| 137 | if ((order = BN_new()) == NULL) | ||
| 138 | errx(1, "BN_new"); | ||
| 139 | if (!EC_GROUP_get_order(group, order, ctx)) | ||
| 140 | errx(1, "EC_GROUP_get_order"); | ||
| 141 | |||
| 142 | if ((scalar = BN_new()) == NULL) | ||
| 143 | errx(1, "BN_new"); | ||
| 144 | if (!BN_rand_range(scalar, order)) | ||
| 145 | errx(1, "BN_rand_range"); | ||
| 146 | if (!BN_set_bit(scalar, EC_GROUP_order_bits(group) - 1)) | ||
| 147 | errx(1, "BN_set_bit"); | ||
| 148 | |||
| 149 | if ((result = EC_POINT_new(group)) == NULL) | ||
| 150 | errx(1, "EC_POINT_new"); | ||
| 151 | if ((a = EC_POINT_new(group)) == NULL) | ||
| 152 | errx(1, "EC_POINT_new"); | ||
| 153 | if ((b = EC_POINT_new(group)) == NULL) | ||
| 154 | errx(1, "EC_POINT_new"); | ||
| 155 | |||
| 156 | if (!EC_POINT_mul(group, a, scalar, NULL, NULL, ctx)) | ||
| 157 | errx(1, "EC_POINT_mul"); | ||
| 158 | if (!EC_POINT_mul(group, b, scalar, NULL, NULL, ctx)) | ||
| 159 | errx(1, "EC_POINT_mul"); | ||
| 160 | |||
| 161 | benchmark_stop = 0; | ||
| 162 | i = 0; | ||
| 163 | alarm(seconds); | ||
| 164 | |||
| 165 | clock_gettime(CLOCK_MONOTONIC, &start); | ||
| 166 | |||
| 167 | fprintf(stderr, "Benchmarking %s for %ds: ", bm->desc, seconds); | ||
| 168 | while (!benchmark_stop) { | ||
| 169 | bm->func(group, result, scalar, a, b, ctx); | ||
| 170 | i++; | ||
| 171 | } | ||
| 172 | clock_gettime(CLOCK_MONOTONIC, &end); | ||
| 173 | timespecsub(&end, &start, &duration); | ||
| 174 | fprintf(stderr, "%d iterations in %f seconds\n", i, | ||
| 175 | duration.tv_sec + duration.tv_nsec / 1000000000.0); | ||
| 176 | |||
| 177 | EC_GROUP_free(group); | ||
| 178 | EC_POINT_free(result); | ||
| 179 | EC_POINT_free(a); | ||
| 180 | EC_POINT_free(b); | ||
| 181 | BN_free(order); | ||
| 182 | BN_free(scalar); | ||
| 183 | BN_CTX_free(ctx); | ||
| 184 | } | ||
| 185 | |||
| 186 | static void | ||
| 187 | benchmark_ec_mul_single(void) | ||
| 188 | { | ||
| 189 | const struct benchmark *bm; | ||
| 190 | size_t i; | ||
| 191 | |||
| 192 | for (i = 0; i < N_BENCHMARKS; i++) { | ||
| 193 | bm = &benchmarks[i]; | ||
| 194 | benchmark_run(bm, 5); | ||
| 195 | } | ||
| 196 | } | ||
| 197 | |||
| 198 | int | ||
| 199 | main(int argc, char **argv) | ||
| 200 | { | ||
| 201 | int benchmark = 0, failed = 0; | ||
| 202 | |||
| 203 | if (argc == 2 && strcmp(argv[1], "--benchmark") == 0) | ||
| 204 | benchmark = 1; | ||
| 205 | |||
| 206 | if (benchmark && !failed) | ||
| 207 | benchmark_ec_mul_single(); | ||
| 208 | |||
| 209 | return failed; | ||
| 210 | } | ||
