Skip to content

Commit 67cbdf0

Browse files
committed
Merge pull request bitcoin#207
039723d Benchmarks for all internal operations (Pieter Wuille)
2 parents f88343f + 039723d commit 67cbdf0

File tree

8 files changed

+346
-59
lines changed

8 files changed

+346
-59
lines changed

Makefile.am

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ libsecp256k1_la_LIBADD = $(SECP_LIBS)
4949

5050
noinst_PROGRAMS =
5151
if USE_BENCHMARK
52-
noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_inv
52+
noinst_PROGRAMS += bench_verify bench_recover bench_sign bench_internal
5353
bench_verify_SOURCES = src/bench_verify.c
5454
bench_verify_LDADD = libsecp256k1.la $(SECP_LIBS)
5555
bench_verify_LDFLAGS = -static
@@ -59,10 +59,10 @@ bench_recover_LDFLAGS = -static
5959
bench_sign_SOURCES = src/bench_sign.c
6060
bench_sign_LDADD = libsecp256k1.la $(SECP_LIBS)
6161
bench_sign_LDFLAGS = -static
62-
bench_inv_SOURCES = src/bench_inv.c
63-
bench_inv_LDADD = $(SECP_LIBS)
64-
bench_inv_LDFLAGS = -static
65-
bench_inv_CPPFLAGS = $(SECP_INCLUDES)
62+
bench_internal_SOURCES = src/bench_internal.c
63+
bench_internal_LDADD = $(SECP_LIBS)
64+
bench_internal_LDFLAGS = -static
65+
bench_internal_CPPFLAGS = $(SECP_INCLUDES)
6666
endif
6767

6868
if USE_TESTS

src/bench.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,18 @@ static double gettimedouble(void) {
1717
return tv.tv_usec * 0.000001 + tv.tv_sec;
1818
}
1919

20-
void run_benchmark(void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) {
20+
void print_number(double x) {
21+
double y = x;
22+
int c = 0;
23+
if (y < 0.0) y = -y;
24+
while (y < 100.0) {
25+
y *= 10.0;
26+
c++;
27+
}
28+
printf("%.*f", c, x);
29+
}
30+
31+
void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) {
2132
int i;
2233
double min = HUGE_VAL;
2334
double sum = 0.0;
@@ -33,7 +44,13 @@ void run_benchmark(void (*benchmark)(void*), void (*setup)(void*), void (*teardo
3344
if (total > max) max = total;
3445
sum += total;
3546
}
36-
printf("min %.3fus / avg %.3fus / max %.3fus\n", min * 1000000.0 / iter, (sum / count) * 1000000.0 / iter, max * 1000000.0 / iter);
47+
printf("%s: min ", name);
48+
print_number(min * 1000000.0 / iter);
49+
printf("us / avg ");
50+
print_number((sum / count) * 1000000.0 / iter);
51+
printf("us / avg ");
52+
print_number(max * 1000000.0 / iter);
53+
printf("us\n");
3754
}
3855

3956
#endif

src/bench_internal.c

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
/**********************************************************************
2+
* Copyright (c) 2014-2015 Pieter Wuille *
3+
* Distributed under the MIT software license, see the accompanying *
4+
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
5+
**********************************************************************/
6+
#include <stdio.h>
7+
8+
#include "include/secp256k1.h"
9+
10+
#include "util.h"
11+
#include "hash_impl.h"
12+
#include "num_impl.h"
13+
#include "field_impl.h"
14+
#include "group_impl.h"
15+
#include "scalar_impl.h"
16+
#include "ecmult_impl.h"
17+
#include "bench.h"
18+
19+
typedef struct {
20+
secp256k1_scalar_t scalar_x, scalar_y;
21+
secp256k1_fe_t fe_x, fe_y;
22+
secp256k1_ge_t ge_x, ge_y;
23+
secp256k1_gej_t gej_x, gej_y;
24+
unsigned char data[32];
25+
int wnaf[256];
26+
} bench_inv_t;
27+
28+
void bench_setup(void* arg) {
29+
bench_inv_t *data = (bench_inv_t*)arg;
30+
31+
static const unsigned char init_x[32] = {
32+
0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13,
33+
0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35,
34+
0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59,
35+
0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83
36+
};
37+
38+
static const unsigned char init_y[32] = {
39+
0x82, 0x83, 0x85, 0x87, 0x8b, 0x8d, 0x81, 0x83,
40+
0x97, 0xad, 0xaf, 0xb5, 0xb9, 0xbb, 0xbf, 0xc5,
41+
0xdb, 0xdd, 0xe3, 0xe7, 0xe9, 0xef, 0xf3, 0xf9,
42+
0x11, 0x15, 0x17, 0x1b, 0x1d, 0xb1, 0xbf, 0xd3
43+
};
44+
45+
secp256k1_scalar_set_b32(&data->scalar_x, init_x, NULL);
46+
secp256k1_scalar_set_b32(&data->scalar_y, init_y, NULL);
47+
secp256k1_fe_set_b32(&data->fe_x, init_x);
48+
secp256k1_fe_set_b32(&data->fe_y, init_y);
49+
CHECK(secp256k1_ge_set_xo_var(&data->ge_x, &data->fe_x, 0));
50+
CHECK(secp256k1_ge_set_xo_var(&data->ge_y, &data->fe_y, 1));
51+
secp256k1_gej_set_ge(&data->gej_x, &data->ge_x);
52+
secp256k1_gej_set_ge(&data->gej_y, &data->ge_y);
53+
memcpy(data->data, init_x, 32);
54+
}
55+
56+
void bench_scalar_add(void* arg) {
57+
int i;
58+
bench_inv_t *data = (bench_inv_t*)arg;
59+
60+
for (i = 0; i < 2000000; i++) {
61+
secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
62+
}
63+
}
64+
65+
void bench_scalar_negate(void* arg) {
66+
int i;
67+
bench_inv_t *data = (bench_inv_t*)arg;
68+
69+
for (i = 0; i < 2000000; i++) {
70+
secp256k1_scalar_negate(&data->scalar_x, &data->scalar_x);
71+
}
72+
}
73+
74+
void bench_scalar_sqr(void* arg) {
75+
int i;
76+
bench_inv_t *data = (bench_inv_t*)arg;
77+
78+
for (i = 0; i < 200000; i++) {
79+
secp256k1_scalar_sqr(&data->scalar_x, &data->scalar_x);
80+
}
81+
}
82+
83+
void bench_scalar_mul(void* arg) {
84+
int i;
85+
bench_inv_t *data = (bench_inv_t*)arg;
86+
87+
for (i = 0; i < 200000; i++) {
88+
secp256k1_scalar_mul(&data->scalar_x, &data->scalar_x, &data->scalar_y);
89+
}
90+
}
91+
92+
#ifdef USE_ENDOMORPHISM
93+
void bench_scalar_split(void* arg) {
94+
int i;
95+
bench_inv_t *data = (bench_inv_t*)arg;
96+
97+
for (i = 0; i < 20000; i++) {
98+
secp256k1_scalar_t l, r;
99+
secp256k1_scalar_split_lambda_var(&l, &r, &data->scalar_x);
100+
secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
101+
}
102+
}
103+
#endif
104+
105+
void bench_scalar_inverse(void* arg) {
106+
int i;
107+
bench_inv_t *data = (bench_inv_t*)arg;
108+
109+
for (i = 0; i < 2000; i++) {
110+
secp256k1_scalar_inverse(&data->scalar_x, &data->scalar_x);
111+
secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
112+
}
113+
}
114+
115+
void bench_scalar_inverse_var(void* arg) {
116+
int i;
117+
bench_inv_t *data = (bench_inv_t*)arg;
118+
119+
for (i = 0; i < 2000; i++) {
120+
secp256k1_scalar_inverse_var(&data->scalar_x, &data->scalar_x);
121+
secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
122+
}
123+
}
124+
125+
void bench_field_normalize(void* arg) {
126+
int i;
127+
bench_inv_t *data = (bench_inv_t*)arg;
128+
129+
for (i = 0; i < 2000000; i++) {
130+
secp256k1_fe_normalize(&data->fe_x);
131+
}
132+
}
133+
134+
void bench_field_normalize_weak(void* arg) {
135+
int i;
136+
bench_inv_t *data = (bench_inv_t*)arg;
137+
138+
for (i = 0; i < 2000000; i++) {
139+
secp256k1_fe_normalize_weak(&data->fe_x);
140+
}
141+
}
142+
143+
void bench_field_mul(void* arg) {
144+
int i;
145+
bench_inv_t *data = (bench_inv_t*)arg;
146+
147+
for (i = 0; i < 200000; i++) {
148+
secp256k1_fe_mul(&data->fe_x, &data->fe_x, &data->fe_y);
149+
}
150+
}
151+
152+
void bench_field_sqr(void* arg) {
153+
int i;
154+
bench_inv_t *data = (bench_inv_t*)arg;
155+
156+
for (i = 0; i < 200000; i++) {
157+
secp256k1_fe_sqr(&data->fe_x, &data->fe_x);
158+
}
159+
}
160+
161+
void bench_field_inverse(void* arg) {
162+
int i;
163+
bench_inv_t *data = (bench_inv_t*)arg;
164+
165+
for (i = 0; i < 20000; i++) {
166+
secp256k1_fe_inv(&data->fe_x, &data->fe_x);
167+
secp256k1_fe_add(&data->fe_x, &data->fe_y);
168+
}
169+
}
170+
171+
void bench_field_inverse_var(void* arg) {
172+
int i;
173+
bench_inv_t *data = (bench_inv_t*)arg;
174+
175+
for (i = 0; i < 20000; i++) {
176+
secp256k1_fe_inv_var(&data->fe_x, &data->fe_x);
177+
secp256k1_fe_add(&data->fe_x, &data->fe_y);
178+
}
179+
}
180+
181+
void bench_field_sqrt_var(void* arg) {
182+
int i;
183+
bench_inv_t *data = (bench_inv_t*)arg;
184+
185+
for (i = 0; i < 20000; i++) {
186+
secp256k1_fe_sqrt_var(&data->fe_x, &data->fe_x);
187+
secp256k1_fe_add(&data->fe_x, &data->fe_y);
188+
}
189+
}
190+
191+
void bench_group_double_var(void* arg) {
192+
int i;
193+
bench_inv_t *data = (bench_inv_t*)arg;
194+
195+
for (i = 0; i < 200000; i++) {
196+
secp256k1_gej_double_var(&data->gej_x, &data->gej_x);
197+
}
198+
}
199+
200+
void bench_group_add_var(void* arg) {
201+
int i;
202+
bench_inv_t *data = (bench_inv_t*)arg;
203+
204+
for (i = 0; i < 200000; i++) {
205+
secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y);
206+
}
207+
}
208+
209+
void bench_group_add_affine(void* arg) {
210+
int i;
211+
bench_inv_t *data = (bench_inv_t*)arg;
212+
213+
for (i = 0; i < 200000; i++) {
214+
secp256k1_gej_add_ge(&data->gej_x, &data->gej_x, &data->ge_y);
215+
}
216+
}
217+
218+
void bench_group_add_affine_var(void* arg) {
219+
int i;
220+
bench_inv_t *data = (bench_inv_t*)arg;
221+
222+
for (i = 0; i < 200000; i++) {
223+
secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y);
224+
}
225+
}
226+
227+
void bench_ecmult_wnaf(void* arg) {
228+
int i;
229+
bench_inv_t *data = (bench_inv_t*)arg;
230+
231+
for (i = 0; i < 20000; i++) {
232+
secp256k1_ecmult_wnaf(data->wnaf, &data->scalar_x, WINDOW_A);
233+
secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
234+
}
235+
}
236+
237+
238+
void bench_sha256(void* arg) {
239+
int i;
240+
bench_inv_t *data = (bench_inv_t*)arg;
241+
secp256k1_sha256_t sha;
242+
243+
for (i = 0; i < 20000; i++) {
244+
secp256k1_sha256_initialize(&sha);
245+
secp256k1_sha256_write(&sha, data->data, 32);
246+
secp256k1_sha256_finalize(&sha, data->data);
247+
}
248+
}
249+
250+
void bench_hmac_sha256(void* arg) {
251+
int i;
252+
bench_inv_t *data = (bench_inv_t*)arg;
253+
secp256k1_hmac_sha256_t hmac;
254+
255+
for (i = 0; i < 20000; i++) {
256+
secp256k1_hmac_sha256_initialize(&hmac, data->data, 32);
257+
secp256k1_hmac_sha256_write(&hmac, data->data, 32);
258+
secp256k1_hmac_sha256_finalize(&hmac, data->data);
259+
}
260+
}
261+
262+
void bench_rfc6979_hmac_sha256(void* arg) {
263+
int i;
264+
bench_inv_t *data = (bench_inv_t*)arg;
265+
secp256k1_rfc6979_hmac_sha256_t rng;
266+
267+
for (i = 0; i < 20000; i++) {
268+
secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 32, data->data, 32);
269+
secp256k1_rfc6979_hmac_sha256_generate(&rng, data->data, 32);
270+
}
271+
}
272+
273+
274+
int have_flag(int argc, char** argv, char *flag) {
275+
char** argm = argv + argc;
276+
argv++;
277+
if (argv == argm) {
278+
return 1;
279+
}
280+
while (argv != NULL && argv != argm) {
281+
if (strcmp(*argv, flag) == 0) return 1;
282+
argv++;
283+
}
284+
return 0;
285+
}
286+
287+
int main(int argc, char **argv) {
288+
bench_inv_t data;
289+
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, 2000000);
290+
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, 2000000);
291+
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, 200000);
292+
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, 200000);
293+
#ifdef USE_ENDOMORPHISM
294+
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, 20000);
295+
#endif
296+
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, 2000);
297+
if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse_var", bench_scalar_inverse_var, bench_setup, NULL, &data, 10, 2000);
298+
299+
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, 2000000);
300+
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize_weak", bench_field_normalize_weak, bench_setup, NULL, &data, 10, 2000000);
301+
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, 200000);
302+
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, 200000);
303+
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, 20000);
304+
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse_var", bench_field_inverse_var, bench_setup, NULL, &data, 10, 20000);
305+
if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt_var", bench_field_sqrt_var, bench_setup, NULL, &data, 10, 20000);
306+
307+
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "double")) run_benchmark("group_double_var", bench_group_double_var, bench_setup, NULL, &data, 10, 200000);
308+
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_var", bench_group_add_var, bench_setup, NULL, &data, 10, 200000);
309+
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine", bench_group_add_affine, bench_setup, NULL, &data, 10, 200000);
310+
if (have_flag(argc, argv, "group") || have_flag(argc, argv, "add")) run_benchmark("group_add_affine_var", bench_group_add_affine_var, bench_setup, NULL, &data, 10, 200000);
311+
312+
if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, 20000);
313+
314+
if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, 20000);
315+
if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, 20000);
316+
if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "rng6979")) run_benchmark("hash_rfc6979_hmac_sha256", bench_rfc6979_hmac_sha256, bench_setup, NULL, &data, 10, 20000);
317+
return 0;
318+
}

0 commit comments

Comments
 (0)