Skip to content

Commit

Permalink
Context isn't freed in the ECDH benchmark
Browse files Browse the repository at this point in the history
Summary:
 * free the ctx at the end of bench_ecdh

 * Pass num of iters to benchmarks as variable, and define envvar

 * Add running benchmarks regularly and under valgrind in travis

This is a backport of libsecp256k1 [[bitcoin-core/secp256k1#722 | PR722]]

Test Plan:
  ninja all check check-secp256k1 bench-secp256k1

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Subscribers: Fabien

Differential Revision: https://reviews.bitcoinabc.org/D6364
  • Loading branch information
elichai authored and deadalnix committed Jun 4, 2020
1 parent 0f15392 commit 270f319
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 133 deletions.
6 changes: 4 additions & 2 deletions src/secp256k1/.travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ env:
- OPENSSL_TESTS=auto
- MULTISET=no
- CTIMETEST=yes
- BENCH=yes
- SECP256K1_BENCH_ITERS=2
jobs:
- SCALAR=32bit RECOVERY=yes
- SCALAR=32bit FIELD=32bit ECDH=yes EXPERIMENTAL=yes MULTISET=yes
Expand All @@ -54,10 +56,10 @@ env:
- BIGNUM=no
- BIGNUM=no ENDOMORPHISM=yes RECOVERY=yes EXPERIMENTAL=yes MULTISET=yes
- BIGNUM=no STATICPRECOMPUTATION=no
- AUTOTOOLS_TARGET=distcheck CMAKE_TARGET=install CTIMETEST=
- AUTOTOOLS_TARGET=distcheck CMAKE_TARGET=install CTIMETEST= BENCH=
- AUTOTOOLS_EXTRA_FLAGS=CPPFLAGS=-DDETERMINISTIC CMAKE_EXTRA_FLAGS=-DCMAKE_C_FLAGS=-DDETERMINISTIC
- AUTOTOOLS_EXTRA_FLAGS=CFLAGS=-O0 CMAKE_EXTRA_FLAGS=-DCMAKE_BUILD_TYPE=Debug
- AUTOTOOLS_TARGET=check-java CMAKE_TARGET=check-secp256k1-java JNI=yes ECDH=yes EXPERIMENTAL=yes CTIMETEST=
- AUTOTOOLS_TARGET=check-java CMAKE_TARGET=check-secp256k1-java JNI=yes ECDH=yes EXPERIMENTAL=yes CTIMETEST= BENCH=
- ECMULTGENPRECISION=2
- ECMULTGENPRECISION=8
- SCHNORR=no
Expand Down
15 changes: 12 additions & 3 deletions src/secp256k1/src/bench.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ void print_number(const int64_t x) {
printf("%s", &buffer[ptr]);
}

void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) {
void run_benchmark(char *name, void (*benchmark)(void*, int), void (*setup)(void*), void (*teardown)(void*, int), void* data, int count, int iter) {
int i;
int64_t min = INT64_MAX;
int64_t sum = 0;
Expand All @@ -84,10 +84,10 @@ void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), v
setup(data);
}
begin = gettime_i64();
benchmark(data);
benchmark(data, iter);
total = gettime_i64() - begin;
if (teardown != NULL) {
teardown(data);
teardown(data, iter);
}
if (total < min) {
min = total;
Expand Down Expand Up @@ -121,4 +121,13 @@ int have_flag(int argc, char** argv, char *flag) {
return 0;
}

int get_iters(int default_iters) {
char* env = getenv("SECP256K1_BENCH_ITERS");
if (env) {
return strtol(env, NULL, 0);
} else {
return default_iters;
}
}

#endif /* SECP256K1_BENCH_H */
15 changes: 10 additions & 5 deletions src/secp256k1/src/bench_ecdh.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,32 @@ static void bench_ecdh_setup(void* arg) {
0xa2, 0xba, 0xd1, 0x84, 0xf8, 0x83, 0xc6, 0x9f
};

/* create a context with no capabilities */
data->ctx = secp256k1_context_create(SECP256K1_FLAGS_TYPE_CONTEXT);
for (i = 0; i < 32; i++) {
data->scalar[i] = i + 1;
}
CHECK(secp256k1_ec_pubkey_parse(data->ctx, &data->point, point, sizeof(point)) == 1);
}

static void bench_ecdh(void* arg) {
static void bench_ecdh(void* arg, int iters) {
int i;
unsigned char res[32];
bench_ecdh_data *data = (bench_ecdh_data*)arg;

for (i = 0; i < 20000; i++) {
for (i = 0; i < iters; i++) {
CHECK(secp256k1_ecdh(data->ctx, res, &data->point, data->scalar, NULL, NULL) == 1);
}
}

int main(void) {
bench_ecdh_data data;

run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, 20000);
int iters = get_iters(20000);

/* create a context with no capabilities */
data.ctx = secp256k1_context_create(SECP256K1_FLAGS_TYPE_CONTEXT);

run_benchmark("ecdh", bench_ecdh, bench_ecdh_setup, NULL, &data, 10, iters);

secp256k1_context_destroy(data.ctx);
return 0;
}
41 changes: 24 additions & 17 deletions src/secp256k1/src/bench_ecmult.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#include "secp256k1.c"

#define POINTS 32768
#define ITERS 10000

typedef struct {
/* Setup once in advance */
Expand Down Expand Up @@ -55,13 +54,13 @@ static int bench_callback(secp256k1_scalar* sc, secp256k1_ge* ge, size_t idx, vo
return 1;
}

static void bench_ecmult(void* arg) {
static void bench_ecmult(void* arg, int iters) {
bench_data* data = (bench_data*)arg;

size_t count = data->count;
int includes_g = data->includes_g;
size_t iters = 1 + ITERS / count;
size_t iter;
int iter;
int count = data->count;
iters = iters / data->count;

for (iter = 0; iter < iters; ++iter) {
data->ecmult_multi(&data->ctx->error_callback, &data->ctx->ecmult_ctx, data->scratch, &data->output[iter], data->includes_g ? &data->scalars[data->offset1] : NULL, bench_callback, arg, count - includes_g);
Expand All @@ -76,10 +75,10 @@ static void bench_ecmult_setup(void* arg) {
data->offset2 = (data->count * 0x7f6f537b + 0x6a1a8f49) % POINTS;
}

static void bench_ecmult_teardown(void* arg) {
static void bench_ecmult_teardown(void* arg, int iters) {
bench_data* data = (bench_data*)arg;
size_t iters = 1 + ITERS / data->count;
size_t iter;
int iter;
iters = iters / data->count;
/* Verify the results in teardown, to avoid doing comparisons while benchmarking. */
for (iter = 0; iter < iters; ++iter) {
secp256k1_gej tmp;
Expand All @@ -104,10 +103,10 @@ static void generate_scalar(uint32_t num, secp256k1_scalar* scalar) {
CHECK(!overflow);
}

static void run_test(bench_data* data, size_t count, int includes_g) {
static void run_test(bench_data* data, size_t count, int includes_g, int num_iters) {
char str[32];
static const secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
size_t iters = 1 + ITERS / count;
size_t iters = 1 + num_iters / count;
size_t iter;

data->count = count;
Expand All @@ -130,7 +129,7 @@ static void run_test(bench_data* data, size_t count, int includes_g) {

/* Run the benchmark. */
sprintf(str, includes_g ? "ecmult_%ig" : "ecmult_%i", (int)count);
run_benchmark(str, bench_ecmult, bench_ecmult_setup, bench_ecmult_teardown, data, 10, count * (1 + ITERS / count));
run_benchmark(str, bench_ecmult, bench_ecmult_setup, bench_ecmult_teardown, data, 10, count * iters);
}

int main(int argc, char **argv) {
Expand All @@ -139,6 +138,8 @@ int main(int argc, char **argv) {
secp256k1_gej* pubkeys_gej;
size_t scratch_size;

int iters = get_iters(10000);

data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
scratch_size = secp256k1_strauss_scratch_size(POINTS) + STRAUSS_SCRATCH_OBJECTS*16;
data.scratch = secp256k1_scratch_space_create(data.ctx, scratch_size);
Expand Down Expand Up @@ -167,8 +168,8 @@ int main(int argc, char **argv) {
data.scalars = malloc(sizeof(secp256k1_scalar) * POINTS);
data.seckeys = malloc(sizeof(secp256k1_scalar) * POINTS);
data.pubkeys = malloc(sizeof(secp256k1_ge) * POINTS);
data.expected_output = malloc(sizeof(secp256k1_gej) * (ITERS + 1));
data.output = malloc(sizeof(secp256k1_gej) * (ITERS + 1));
data.expected_output = malloc(sizeof(secp256k1_gej) * (iters + 1));
data.output = malloc(sizeof(secp256k1_gej) * (iters + 1));

/* Generate a set of scalars, and private/public keypairs. */
pubkeys_gej = malloc(sizeof(secp256k1_gej) * POINTS);
Expand All @@ -185,14 +186,20 @@ int main(int argc, char **argv) {
free(pubkeys_gej);

for (i = 1; i <= 8; ++i) {
run_test(&data, i, 1);
run_test(&data, i, 1, iters);
}

for (p = 0; p <= 11; ++p) {
for (i = 9; i <= 16; ++i) {
run_test(&data, i << p, 1);
/* This is disabled with low count of iterations because the loop runs 77 times even with iters=1
* and the higher it goes the longer the computation takes(more points)
* So we don't run this benchmark with low iterations to prevent slow down */
if (iters > 2) {
for (p = 0; p <= 11; ++p) {
for (i = 9; i <= 16; ++i) {
run_test(&data, i << p, 1, iters);
}
}
}

if (data.scratch != NULL) {
secp256k1_scratch_space_destroy(data.ctx, data.scratch);
}
Expand Down
Loading

0 comments on commit 270f319

Please sign in to comment.