Add benchmark for DH handshake and ECDH-P-224/56 handshake

This commit is contained in:
Nick Mathewson 2012-11-28 14:14:35 -05:00
parent 175b2678d7
commit 2f8fd53750
2 changed files with 102 additions and 0 deletions

3
changes/dh_benchmarks Normal file
View File

@ -0,0 +1,3 @@
o Minor features (testing):
- Add benchmarks for DH (1024-bit multiplicative group) and ECDH
(P-256) diffie-hellman handshakes to src/or/bench.

View File

@ -18,6 +18,15 @@ const char tor_git_revision[] = "";
#include "or.h"
#include "relay.h"
#include <openssl/opensslv.h>
#include <openssl/evp.h>
#if OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,0)
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#include <openssl/ecdh.h>
#include <openssl/obj_mac.h>
#endif
#endif
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_PROCESS_CPUTIME_ID)
static uint64_t nanostart;
@ -248,6 +257,91 @@ bench_cell_ops(void)
tor_free(cell);
}
static void
bench_dh(void)
{
const int iters = 1<<10;
int i;
uint64_t start, end;
reset_perftime();
start = perftime();
for (i = 0; i < iters; ++i) {
char dh_pubkey_a[DH_BYTES], dh_pubkey_b[DH_BYTES];
char secret_a[DH_BYTES], secret_b[DH_BYTES];
ssize_t slen_a, slen_b;
crypto_dh_t *dh_a = crypto_dh_new(DH_TYPE_TLS);
crypto_dh_t *dh_b = crypto_dh_new(DH_TYPE_TLS);
crypto_dh_generate_public(dh_a);
crypto_dh_generate_public(dh_b);
crypto_dh_get_public(dh_a, dh_pubkey_a, sizeof(dh_pubkey_a));
crypto_dh_get_public(dh_b, dh_pubkey_b, sizeof(dh_pubkey_b));
slen_a = crypto_dh_compute_secret(LOG_NOTICE,
dh_a, dh_pubkey_b, sizeof(dh_pubkey_b),
secret_a, sizeof(secret_a));
slen_b = crypto_dh_compute_secret(LOG_NOTICE,
dh_b, dh_pubkey_a, sizeof(dh_pubkey_a),
secret_b, sizeof(secret_b));
tor_assert(slen_a == slen_b);
tor_assert(!memcmp(secret_a, secret_b, slen_a));
crypto_dh_free(dh_a);
crypto_dh_free(dh_b);
}
end = perftime();
printf("Complete DH handshakes (1024 bit, public and private ops):\n"
" %f millisec each.\n", NANOCOUNT(start, end, iters)/1e6);
}
#if (!defined(OPENSSL_NO_EC) \
&& OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,0,0))
#define HAVE_EC_BENCHMARKS
static void
bench_ecdh_impl(int nid, const char *name)
{
const int iters = 1<<10;
int i;
uint64_t start, end;
reset_perftime();
start = perftime();
for (i = 0; i < iters; ++i) {
char secret_a[DH_BYTES], secret_b[DH_BYTES];
ssize_t slen_a, slen_b;
EC_KEY *dh_a = EC_KEY_new_by_curve_name(nid);
EC_KEY *dh_b = EC_KEY_new_by_curve_name(nid);
EC_KEY_generate_key(dh_a);
EC_KEY_generate_key(dh_b);
slen_a = ECDH_compute_key(secret_a, DH_BYTES,
EC_KEY_get0_public_key(dh_b), dh_a,
NULL);
slen_b = ECDH_compute_key(secret_b, DH_BYTES,
EC_KEY_get0_public_key(dh_a), dh_b,
NULL);
tor_assert(slen_a == slen_b);
tor_assert(!memcmp(secret_a, secret_b, slen_a));
EC_KEY_free(dh_a);
EC_KEY_free(dh_b);
}
end = perftime();
printf("Complete ECDH %s handshakes (2 public and 2 private ops):\n"
" %f millisec each.\n", name, NANOCOUNT(start, end, iters)/1e6);
}
static void
bench_ecdh_p256(void)
{
bench_ecdh_impl(NID_X9_62_prime256v1, "P-256");
}
static void
bench_ecdh_p224(void)
{
bench_ecdh_impl(NID_secp224r1, "P-224");
}
#endif
typedef void (*bench_fn)(void);
typedef struct benchmark_t {
@ -263,6 +357,11 @@ static struct benchmark_t benchmarks[] = {
ENT(aes),
ENT(cell_aes),
ENT(cell_ops),
ENT(dh),
#ifdef HAVE_EC_BENCHMARKS
ENT(ecdh_p256),
ENT(ecdh_p224),
#endif
{NULL,NULL,0}
};