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 **********************************************************************/
8 #include "include/secp256k1.h"
10 #include "assumptions.h"
12 #include "hash_impl.h"
14 #include "field_impl.h"
15 #include "group_impl.h"
16 #include "scalar_impl.h"
17 #include "ecmult_const_impl.h"
18 #include "ecmult_impl.h"
20 #include "secp256k1.c"
23 secp256k1_scalar scalar_x, scalar_y;
24 secp256k1_fe fe_x, fe_y;
25 secp256k1_ge ge_x, ge_y;
26 secp256k1_gej gej_x, gej_y;
27 unsigned char data[64];
31 void bench_setup(void* arg) {
32 bench_inv *data = (bench_inv*)arg;
34 static const unsigned char init_x[32] = {
35 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13,
36 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35,
37 0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59,
38 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83
41 static const unsigned char init_y[32] = {
42 0x82, 0x83, 0x85, 0x87, 0x8b, 0x8d, 0x81, 0x83,
43 0x97, 0xad, 0xaf, 0xb5, 0xb9, 0xbb, 0xbf, 0xc5,
44 0xdb, 0xdd, 0xe3, 0xe7, 0xe9, 0xef, 0xf3, 0xf9,
45 0x11, 0x15, 0x17, 0x1b, 0x1d, 0xb1, 0xbf, 0xd3
48 secp256k1_scalar_set_b32(&data->scalar_x, init_x, NULL);
49 secp256k1_scalar_set_b32(&data->scalar_y, init_y, NULL);
50 secp256k1_fe_set_b32(&data->fe_x, init_x);
51 secp256k1_fe_set_b32(&data->fe_y, init_y);
52 CHECK(secp256k1_ge_set_xo_var(&data->ge_x, &data->fe_x, 0));
53 CHECK(secp256k1_ge_set_xo_var(&data->ge_y, &data->fe_y, 1));
54 secp256k1_gej_set_ge(&data->gej_x, &data->ge_x);
55 secp256k1_gej_set_ge(&data->gej_y, &data->ge_y);
56 memcpy(data->data, init_x, 32);
57 memcpy(data->data + 32, init_y, 32);
60 void bench_scalar_add(void* arg, int iters) {
62 bench_inv *data = (bench_inv*)arg;
64 for (i = 0; i < iters; i++) {
65 j += secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
70 void bench_scalar_negate(void* arg, int iters) {
72 bench_inv *data = (bench_inv*)arg;
74 for (i = 0; i < iters; i++) {
75 secp256k1_scalar_negate(&data->scalar_x, &data->scalar_x);
79 void bench_scalar_sqr(void* arg, int iters) {
81 bench_inv *data = (bench_inv*)arg;
83 for (i = 0; i < iters; i++) {
84 secp256k1_scalar_sqr(&data->scalar_x, &data->scalar_x);
88 void bench_scalar_mul(void* arg, int iters) {
90 bench_inv *data = (bench_inv*)arg;
92 for (i = 0; i < iters; i++) {
93 secp256k1_scalar_mul(&data->scalar_x, &data->scalar_x, &data->scalar_y);
97 #ifdef USE_ENDOMORPHISM
98 void bench_scalar_split(void* arg, int iters) {
100 bench_inv *data = (bench_inv*)arg;
102 for (i = 0; i < iters; i++) {
103 secp256k1_scalar_split_lambda(&data->scalar_x, &data->scalar_y, &data->scalar_x);
104 j += secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
110 void bench_scalar_inverse(void* arg, int iters) {
112 bench_inv *data = (bench_inv*)arg;
114 for (i = 0; i < iters; i++) {
115 secp256k1_scalar_inverse(&data->scalar_x, &data->scalar_x);
116 j += secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
121 void bench_scalar_inverse_var(void* arg, int iters) {
123 bench_inv *data = (bench_inv*)arg;
125 for (i = 0; i < iters; i++) {
126 secp256k1_scalar_inverse_var(&data->scalar_x, &data->scalar_x);
127 j += secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
132 void bench_field_normalize(void* arg, int iters) {
134 bench_inv *data = (bench_inv*)arg;
136 for (i = 0; i < iters; i++) {
137 secp256k1_fe_normalize(&data->fe_x);
141 void bench_field_normalize_weak(void* arg, int iters) {
143 bench_inv *data = (bench_inv*)arg;
145 for (i = 0; i < iters; i++) {
146 secp256k1_fe_normalize_weak(&data->fe_x);
150 void bench_field_mul(void* arg, int iters) {
152 bench_inv *data = (bench_inv*)arg;
154 for (i = 0; i < iters; i++) {
155 secp256k1_fe_mul(&data->fe_x, &data->fe_x, &data->fe_y);
159 void bench_field_sqr(void* arg, int iters) {
161 bench_inv *data = (bench_inv*)arg;
163 for (i = 0; i < iters; i++) {
164 secp256k1_fe_sqr(&data->fe_x, &data->fe_x);
168 void bench_field_inverse(void* arg, int iters) {
170 bench_inv *data = (bench_inv*)arg;
172 for (i = 0; i < iters; i++) {
173 secp256k1_fe_inv(&data->fe_x, &data->fe_x);
174 secp256k1_fe_add(&data->fe_x, &data->fe_y);
178 void bench_field_inverse_var(void* arg, int iters) {
180 bench_inv *data = (bench_inv*)arg;
182 for (i = 0; i < iters; i++) {
183 secp256k1_fe_inv_var(&data->fe_x, &data->fe_x);
184 secp256k1_fe_add(&data->fe_x, &data->fe_y);
188 void bench_field_sqrt(void* arg, int iters) {
190 bench_inv *data = (bench_inv*)arg;
193 for (i = 0; i < iters; i++) {
195 j += secp256k1_fe_sqrt(&data->fe_x, &t);
196 secp256k1_fe_add(&data->fe_x, &data->fe_y);
201 void bench_group_double_var(void* arg, int iters) {
203 bench_inv *data = (bench_inv*)arg;
205 for (i = 0; i < iters; i++) {
206 secp256k1_gej_double_var(&data->gej_x, &data->gej_x, NULL);
210 void bench_group_add_var(void* arg, int iters) {
212 bench_inv *data = (bench_inv*)arg;
214 for (i = 0; i < iters; i++) {
215 secp256k1_gej_add_var(&data->gej_x, &data->gej_x, &data->gej_y, NULL);
219 void bench_group_add_affine(void* arg, int iters) {
221 bench_inv *data = (bench_inv*)arg;
223 for (i = 0; i < iters; i++) {
224 secp256k1_gej_add_ge(&data->gej_x, &data->gej_x, &data->ge_y);
228 void bench_group_add_affine_var(void* arg, int iters) {
230 bench_inv *data = (bench_inv*)arg;
232 for (i = 0; i < iters; i++) {
233 secp256k1_gej_add_ge_var(&data->gej_x, &data->gej_x, &data->ge_y, NULL);
237 void bench_group_jacobi_var(void* arg, int iters) {
239 bench_inv *data = (bench_inv*)arg;
241 for (i = 0; i < iters; i++) {
242 j += secp256k1_gej_has_quad_y_var(&data->gej_x);
247 void bench_ecmult_wnaf(void* arg, int iters) {
248 int i, bits = 0, overflow = 0;
249 bench_inv *data = (bench_inv*)arg;
251 for (i = 0; i < iters; i++) {
252 bits += secp256k1_ecmult_wnaf(data->wnaf, 256, &data->scalar_x, WINDOW_A);
253 overflow += secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
255 CHECK(overflow >= 0);
256 CHECK(bits <= 256*iters);
259 void bench_wnaf_const(void* arg, int iters) {
260 int i, bits = 0, overflow = 0;
261 bench_inv *data = (bench_inv*)arg;
263 for (i = 0; i < iters; i++) {
264 bits += secp256k1_wnaf_const(data->wnaf, &data->scalar_x, WINDOW_A, 256);
265 overflow += secp256k1_scalar_add(&data->scalar_x, &data->scalar_x, &data->scalar_y);
267 CHECK(overflow >= 0);
268 CHECK(bits <= 256*iters);
272 void bench_sha256(void* arg, int iters) {
274 bench_inv *data = (bench_inv*)arg;
275 secp256k1_sha256 sha;
277 for (i = 0; i < iters; i++) {
278 secp256k1_sha256_initialize(&sha);
279 secp256k1_sha256_write(&sha, data->data, 32);
280 secp256k1_sha256_finalize(&sha, data->data);
284 void bench_hmac_sha256(void* arg, int iters) {
286 bench_inv *data = (bench_inv*)arg;
287 secp256k1_hmac_sha256 hmac;
289 for (i = 0; i < iters; i++) {
290 secp256k1_hmac_sha256_initialize(&hmac, data->data, 32);
291 secp256k1_hmac_sha256_write(&hmac, data->data, 32);
292 secp256k1_hmac_sha256_finalize(&hmac, data->data);
296 void bench_rfc6979_hmac_sha256(void* arg, int iters) {
298 bench_inv *data = (bench_inv*)arg;
299 secp256k1_rfc6979_hmac_sha256 rng;
301 for (i = 0; i < iters; i++) {
302 secp256k1_rfc6979_hmac_sha256_initialize(&rng, data->data, 64);
303 secp256k1_rfc6979_hmac_sha256_generate(&rng, data->data, 32);
307 void bench_context_verify(void* arg, int iters) {
310 for (i = 0; i < iters; i++) {
311 secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_VERIFY));
315 void bench_context_sign(void* arg, int iters) {
318 for (i = 0; i < iters; i++) {
319 secp256k1_context_destroy(secp256k1_context_create(SECP256K1_CONTEXT_SIGN));
324 void bench_num_jacobi(void* arg, int iters) {
326 bench_inv *data = (bench_inv*)arg;
327 secp256k1_num nx, norder;
329 secp256k1_scalar_get_num(&nx, &data->scalar_x);
330 secp256k1_scalar_order_get_num(&norder);
331 secp256k1_scalar_get_num(&norder, &data->scalar_y);
333 for (i = 0; i < iters; i++) {
334 j += secp256k1_num_jacobi(&nx, &norder);
340 int main(int argc, char **argv) {
342 int iters = get_iters(20000);
344 if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "add")) run_benchmark("scalar_add", bench_scalar_add, bench_setup, NULL, &data, 10, iters*100);
345 if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "negate")) run_benchmark("scalar_negate", bench_scalar_negate, bench_setup, NULL, &data, 10, iters*100);
346 if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "sqr")) run_benchmark("scalar_sqr", bench_scalar_sqr, bench_setup, NULL, &data, 10, iters*10);
347 if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "mul")) run_benchmark("scalar_mul", bench_scalar_mul, bench_setup, NULL, &data, 10, iters*10);
348 #ifdef USE_ENDOMORPHISM
349 if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "split")) run_benchmark("scalar_split", bench_scalar_split, bench_setup, NULL, &data, 10, iters);
351 if (have_flag(argc, argv, "scalar") || have_flag(argc, argv, "inverse")) run_benchmark("scalar_inverse", bench_scalar_inverse, bench_setup, NULL, &data, 10, 2000);
352 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);
354 if (have_flag(argc, argv, "field") || have_flag(argc, argv, "normalize")) run_benchmark("field_normalize", bench_field_normalize, bench_setup, NULL, &data, 10, iters*100);
355 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, iters*100);
356 if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqr")) run_benchmark("field_sqr", bench_field_sqr, bench_setup, NULL, &data, 10, iters*10);
357 if (have_flag(argc, argv, "field") || have_flag(argc, argv, "mul")) run_benchmark("field_mul", bench_field_mul, bench_setup, NULL, &data, 10, iters*10);
358 if (have_flag(argc, argv, "field") || have_flag(argc, argv, "inverse")) run_benchmark("field_inverse", bench_field_inverse, bench_setup, NULL, &data, 10, iters);
359 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, iters);
360 if (have_flag(argc, argv, "field") || have_flag(argc, argv, "sqrt")) run_benchmark("field_sqrt", bench_field_sqrt, bench_setup, NULL, &data, 10, iters);
362 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, iters*10);
363 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, iters*10);
364 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, iters*10);
365 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, iters*10);
366 if (have_flag(argc, argv, "group") || have_flag(argc, argv, "jacobi")) run_benchmark("group_jacobi_var", bench_group_jacobi_var, bench_setup, NULL, &data, 10, iters);
368 if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("wnaf_const", bench_wnaf_const, bench_setup, NULL, &data, 10, iters);
369 if (have_flag(argc, argv, "ecmult") || have_flag(argc, argv, "wnaf")) run_benchmark("ecmult_wnaf", bench_ecmult_wnaf, bench_setup, NULL, &data, 10, iters);
371 if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "sha256")) run_benchmark("hash_sha256", bench_sha256, bench_setup, NULL, &data, 10, iters);
372 if (have_flag(argc, argv, "hash") || have_flag(argc, argv, "hmac")) run_benchmark("hash_hmac_sha256", bench_hmac_sha256, bench_setup, NULL, &data, 10, iters);
373 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, iters);
375 if (have_flag(argc, argv, "context") || have_flag(argc, argv, "verify")) run_benchmark("context_verify", bench_context_verify, bench_setup, NULL, &data, 10, 1 + iters/1000);
376 if (have_flag(argc, argv, "context") || have_flag(argc, argv, "sign")) run_benchmark("context_sign", bench_context_sign, bench_setup, NULL, &data, 10, 1 + iters/100);
379 if (have_flag(argc, argv, "num") || have_flag(argc, argv, "jacobi")) run_benchmark("num_jacobi", bench_num_jacobi, bench_setup, NULL, &data, 10, iters*10);