Created
May 1, 2021 15:55
-
-
Save raycoll/cf89b622387056083df3a6fcc6e6a12d to your computer and use it in GitHub Desktop.
ecdhe + ec_key_check_key microbenchmark
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <openssl/opensslv.h> | |
#include <openssl/ecdh.h> | |
#include <openssl/evp.h> | |
#include <sys/time.h> | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <sys/utsname.h> | |
#include <time.h> | |
struct curve_testcase | |
{ | |
int nid; | |
const char *name; | |
}; | |
const struct curve_testcase testcases[] = { | |
{ .nid = NID_X9_62_prime256v1, .name = "secp256r1" }, | |
{ .nid = NID_secp384r1, .name = "secp384r1" }, | |
{ .nid = NID_secp521r1, .name = "secp521r1" }, | |
// too lazy to write the conditional to support the keygen implementation for this curve. | |
//{ .nid = NID_X25519, .name = "x25519" }, | |
}; | |
const int NUM_ITERS=10000; | |
const unsigned int USECS_IN_SEC=1000000; | |
static void print_summary(const struct curve_testcase *testcase, double avg_usecs_keygen, double avg_usecs_key_check) | |
{ | |
printf("%s: %f avg usecs for ECDH key generation %f avg usecs for EC_KEY_check_key in %d iterations \n", testcase->name, avg_usecs_keygen, avg_usecs_key_check, NUM_ITERS); | |
} | |
static void microbenchmark_ec_key_check_key(const struct curve_testcase *testcase) | |
{ | |
double usecs_elapsed_keygen = 0; | |
double usecs_elapsed_key_check = 0; | |
for (int i = 0; i < NUM_ITERS; i++) { | |
// Benchmark the ephemeral key generation for the curve | |
double begin = clock(); | |
EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); | |
EVP_PKEY_paramgen_init(pctx); | |
EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, testcase->nid); | |
EVP_PKEY *params = NULL; | |
EVP_PKEY_paramgen(pctx, ¶ms); | |
EVP_PKEY_CTX *kctx = EVP_PKEY_CTX_new(params, NULL); | |
EVP_PKEY_keygen_init(kctx); | |
EVP_PKEY *pkey = NULL; | |
EVP_PKEY_keygen(kctx, &pkey); | |
EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(pkey); | |
double end = clock(); | |
usecs_elapsed_keygen += ((end - begin) / CLOCKS_PER_SEC) * USECS_IN_SEC; | |
// Benchmark key check for the curve. | |
begin = clock(); | |
const int rc = EC_KEY_check_key(ec_key); | |
end = clock(); | |
usecs_elapsed_key_check += ((end - begin) / CLOCKS_PER_SEC) * USECS_IN_SEC; | |
EVP_PKEY_free(params); | |
EVP_PKEY_CTX_free(kctx); | |
EVP_PKEY_free(pkey); | |
} | |
print_summary(testcase, (double) usecs_elapsed_keygen / (double) NUM_ITERS, (double) usecs_elapsed_key_check / (double) | |
NUM_ITERS); | |
} | |
int main(void) | |
{ | |
struct utsname name; | |
uname(&name); | |
printf("starting ECC microbenchmark. Platform: %s %s, Openssl version: %s\n", | |
name.sysname, | |
name.machine, | |
OPENSSL_VERSION_TEXT); | |
for (int i = 0; i < (sizeof(testcases) / sizeof(testcases[0])) ; | |
i++) { | |
microbenchmark_ec_key_check_key(&testcases[i]); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note:
EC_KEY_check_key
validation check is unnecessary for Curve x25519, so the line 20-21 can be safely removed.