9#include "../include/secp256k1.h"
20static void help(
int default_iters) {
21 printf(
"Benchmarks various internal routines.\n");
23 printf(
"The default number of iterations for each benchmark is %d. This can be\n", default_iters);
24 printf(
"customized using the SECP256K1_BENCH_ITERS environment variable.\n");
26 printf(
"Usage: ./bench_internal [args]\n");
27 printf(
"By default, all benchmarks will be run.\n");
29 printf(
" help : display this help and exit\n");
30 printf(
" scalar : all scalar operations (add, half, inverse, mul, negate, split)\n");
31 printf(
" field : all field operations (half, inverse, issquare, mul, normalize, sqr, sqrt)\n");
32 printf(
" group : all group operations (add, double, to_affine)\n");
33 printf(
" ecmult : all point multiplication operations (ecmult_wnaf) \n");
34 printf(
" hash : all hash algorithms (hmac, rng6979, sha256)\n");
35 printf(
" context : all context object operations (context_create)\n");
51 static const unsigned char init[4][32] = {
55 0x02, 0x03, 0x05, 0x07, 0x0b, 0x0d, 0x11, 0x13,
56 0x17, 0x1d, 0x1f, 0x25, 0x29, 0x2b, 0x2f, 0x35,
57 0x3b, 0x3d, 0x43, 0x47, 0x49, 0x4f, 0x53, 0x59,
58 0x61, 0x65, 0x67, 0x6b, 0x6d, 0x71, 0x7f, 0x83
63 0x82, 0x83, 0x85, 0x87, 0x8b, 0x8d, 0x81, 0x83,
64 0x97, 0xad, 0xaf, 0xb5, 0xb9, 0xbb, 0xbf, 0xc5,
65 0xdb, 0xdd, 0xe3, 0xe7, 0xe9, 0xef, 0xf3, 0xf9,
66 0x11, 0x15, 0x17, 0x1b, 0x1d, 0xb1, 0xbf, 0xd3
70 0x3d, 0x2d, 0xef, 0xf4, 0x25, 0x98, 0x4f, 0x5d,
71 0xe2, 0xca, 0x5f, 0x41, 0x3f, 0x3f, 0xce, 0x44,
72 0xaa, 0x2c, 0x53, 0x8a, 0xc6, 0x59, 0x1f, 0x38,
73 0x38, 0x23, 0xe4, 0x11, 0x27, 0xc6, 0xa0, 0xe7
77 0xbd, 0x21, 0xa5, 0xe1, 0x13, 0x50, 0x73, 0x2e,
78 0x52, 0x98, 0xc8, 0x9e, 0xab, 0x00, 0xa2, 0x68,
79 0x43, 0xf5, 0xd7, 0x49, 0x80, 0x72, 0xa7, 0xf3,
80 0xd7, 0x60, 0xe6, 0xab, 0x90, 0x92, 0xdf, 0xc5
97 memcpy(
data->data + 32,
init[1], 32);
104 for (i = 0; i < iters; i++) {
114 for (i = 0; i < iters; i++) {
124 for (i = 0; i < iters; i++) {
135 for (i = 0; i < iters; i++) {
145 for (i = 0; i < iters; i++) {
156 for (i = 0; i < iters; i++) {
167 for (i = 0; i < iters; i++) {
178 for (i = 0; i < iters; i++) {
187 for (i = 0; i < iters; i++) {
196 for (i = 0; i < iters; i++) {
205 for (i = 0; i < iters; i++) {
214 for (i = 0; i < iters; i++) {
223 for (i = 0; i < iters; i++) {
233 for (i = 0; i < iters; i++) {
244 for (i = 0; i < iters; i++) {
257 for (i = 0; i < iters; i++) {
269 for (i = 0; i < iters; i++) {
278 for (i = 0; i < iters; i++) {
287 for (i = 0; i < iters; i++) {
296 for (i = 0; i < iters; i++) {
305 for (i = 0; i < iters; i++) {
314 for (i = 0; i < iters; ++i) {
331 int i, bits = 0, overflow = 0;
334 for (i = 0; i < iters; i++) {
338 CHECK(overflow >= 0);
339 CHECK(bits <= 256*iters);
347 for (i = 0; i < iters; i++) {
359 for (i = 0; i < iters; i++) {
371 for (i = 0; i < iters; i++) {
380 for (i = 0; i < iters; i++) {
385int main(
int argc,
char **argv) {
387 int default_iters = 20000;
402 if (d ||
have_flag(argc, argv,
"scalar") ||
have_flag(argc, argv,
"half"))
run_benchmark(
"scalar_half",
bench_scalar_half,
bench_setup, NULL, &
data, 10, iters*100);
403 if (d ||
have_flag(argc, argv,
"scalar") ||
have_flag(argc, argv,
"add"))
run_benchmark(
"scalar_add",
bench_scalar_add,
bench_setup, NULL, &
data, 10, iters*100);
404 if (d ||
have_flag(argc, argv,
"scalar") ||
have_flag(argc, argv,
"negate"))
run_benchmark(
"scalar_negate",
bench_scalar_negate,
bench_setup, NULL, &
data, 10, iters*100);
405 if (d ||
have_flag(argc, argv,
"scalar") ||
have_flag(argc, argv,
"mul"))
run_benchmark(
"scalar_mul",
bench_scalar_mul,
bench_setup, NULL, &
data, 10, iters*10);
406 if (d ||
have_flag(argc, argv,
"scalar") ||
have_flag(argc, argv,
"split"))
run_benchmark(
"scalar_split",
bench_scalar_split,
bench_setup, NULL, &
data, 10, iters);
407 if (d ||
have_flag(argc, argv,
"scalar") ||
have_flag(argc, argv,
"inverse"))
run_benchmark(
"scalar_inverse",
bench_scalar_inverse,
bench_setup, NULL, &
data, 10, iters);
408 if (d ||
have_flag(argc, argv,
"scalar") ||
have_flag(argc, argv,
"inverse"))
run_benchmark(
"scalar_inverse_var",
bench_scalar_inverse_var,
bench_setup, NULL, &
data, 10, iters);
410 if (d ||
have_flag(argc, argv,
"field") ||
have_flag(argc, argv,
"half"))
run_benchmark(
"field_half",
bench_field_half,
bench_setup, NULL, &
data, 10, iters*100);
411 if (d ||
have_flag(argc, argv,
"field") ||
have_flag(argc, argv,
"normalize"))
run_benchmark(
"field_normalize",
bench_field_normalize,
bench_setup, NULL, &
data, 10, iters*100);
412 if (d ||
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);
413 if (d ||
have_flag(argc, argv,
"field") ||
have_flag(argc, argv,
"sqr"))
run_benchmark(
"field_sqr",
bench_field_sqr,
bench_setup, NULL, &
data, 10, iters*10);
414 if (d ||
have_flag(argc, argv,
"field") ||
have_flag(argc, argv,
"mul"))
run_benchmark(
"field_mul",
bench_field_mul,
bench_setup, NULL, &
data, 10, iters*10);
415 if (d ||
have_flag(argc, argv,
"field") ||
have_flag(argc, argv,
"inverse"))
run_benchmark(
"field_inverse",
bench_field_inverse,
bench_setup, NULL, &
data, 10, iters);
416 if (d ||
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);
417 if (d ||
have_flag(argc, argv,
"field") ||
have_flag(argc, argv,
"issquare"))
run_benchmark(
"field_is_square_var",
bench_field_is_square_var,
bench_setup, NULL, &
data, 10, iters);
418 if (d ||
have_flag(argc, argv,
"field") ||
have_flag(argc, argv,
"sqrt"))
run_benchmark(
"field_sqrt",
bench_field_sqrt,
bench_setup, NULL, &
data, 10, iters);
420 if (d ||
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);
421 if (d ||
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);
422 if (d ||
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);
423 if (d ||
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);
424 if (d ||
have_flag(argc, argv,
"group") ||
have_flag(argc, argv,
"add"))
run_benchmark(
"group_add_zinv_var",
bench_group_add_zinv_var,
bench_setup, NULL, &
data, 10, iters*10);
425 if (d ||
have_flag(argc, argv,
"group") ||
have_flag(argc, argv,
"to_affine"))
run_benchmark(
"group_to_affine_var",
bench_group_to_affine_var,
bench_setup, NULL, &
data, 10, iters);
427 if (d ||
have_flag(argc, argv,
"ecmult") ||
have_flag(argc, argv,
"wnaf"))
run_benchmark(
"ecmult_wnaf",
bench_ecmult_wnaf,
bench_setup, NULL, &
data, 10, iters);
429 if (d ||
have_flag(argc, argv,
"hash") ||
have_flag(argc, argv,
"sha256"))
run_benchmark(
"hash_sha256",
bench_sha256,
bench_setup, NULL, &
data, 10, iters);
430 if (d ||
have_flag(argc, argv,
"hash") ||
have_flag(argc, argv,
"hmac"))
run_benchmark(
"hash_hmac_sha256",
bench_hmac_sha256,
bench_setup, NULL, &
data, 10, iters);
431 if (d ||
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);
static void bench_setup(void *arg)
static void bench_scalar_inverse(void *arg, int iters)
static void bench_scalar_inverse_var(void *arg, int iters)
static void bench_field_mul(void *arg, int iters)
static void bench_sha256(void *arg, int iters)
static void bench_rfc6979_hmac_sha256(void *arg, int iters)
static void bench_scalar_negate(void *arg, int iters)
static void bench_scalar_split(void *arg, int iters)
static void bench_scalar_add(void *arg, int iters)
int main(int argc, char **argv)
static void help(int default_iters)
static void bench_field_normalize(void *arg, int iters)
static void bench_ecmult_wnaf(void *arg, int iters)
static void bench_group_add_zinv_var(void *arg, int iters)
static void bench_group_double_var(void *arg, int iters)
static void bench_field_inverse(void *arg, int iters)
static void bench_group_to_affine_var(void *arg, int iters)
static void bench_field_sqr(void *arg, int iters)
static void bench_scalar_mul(void *arg, int iters)
static void bench_field_normalize_weak(void *arg, int iters)
static void bench_group_add_affine_var(void *arg, int iters)
static void bench_field_is_square_var(void *arg, int iters)
static void bench_group_add_affine(void *arg, int iters)
static void bench_context(void *arg, int iters)
static void bench_field_half(void *arg, int iters)
static void bench_group_add_var(void *arg, int iters)
static void bench_field_inverse_var(void *arg, int iters)
static void bench_hmac_sha256(void *arg, int iters)
static void bench_field_sqrt(void *arg, int iters)
static void bench_scalar_half(void *arg, int iters)
static void run_benchmark(char *name, void(*benchmark)(void *), void(*setup)(void *), void(*teardown)(void *), void *data, int count, int iter)
static int secp256k1_ecmult_wnaf(int *wnaf, int len, const secp256k1_scalar *a, int w)
Convert a number to WNAF notation.
#define secp256k1_fe_normalize_weak
static int secp256k1_fe_sqrt(secp256k1_fe *SECP256K1_RESTRICT r, const secp256k1_fe *SECP256K1_RESTRICT a)
Compute a square root of a field element.
#define secp256k1_fe_normalize_var
#define secp256k1_fe_half
#define secp256k1_fe_inv_var
#define secp256k1_fe_set_b32_limit
#define secp256k1_fe_is_square_var
#define secp256k1_fe_normalize
static void secp256k1_gej_double_var(secp256k1_gej *r, const secp256k1_gej *a, secp256k1_fe *rzr)
Set r equal to the double of a.
static void secp256k1_gej_add_zinv_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, const secp256k1_fe *bzinv)
Set r equal to the sum of a and b (with the inverse of b's Z coordinate passed as bzinv).
static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd)
Set a group element (affine) equal to the point with the given X coordinate, and given oddness for Y.
static void secp256k1_gej_add_ge_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b, secp256k1_fe *rzr)
Set r equal to the sum of a and b (with b given in affine coordinates).
static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b)
Set r equal to the sum of a and b (with b given in affine coordinates, and not infinity).
static void secp256k1_gej_add_var(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_gej *b, secp256k1_fe *rzr)
Set r equal to the sum of a and b.
static void secp256k1_gej_rescale(secp256k1_gej *r, const secp256k1_fe *b)
Rescale a jacobian point by b which must be non-zero.
static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a)
Set a group element (jacobian) equal to another which is given in affine coordinates.
static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a)
Set a group element equal to another which is given in jacobian coordinates.
#define CHECK(cond)
Unconditional failure on condition failure.
static void secp256k1_scalar_half(secp256k1_scalar *r, const secp256k1_scalar *a)
Multiply a scalar with the multiplicative inverse of 2.
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow)
Set a scalar from a big endian byte array.
static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the inverse of a scalar (modulo the group order), without constant-time guarantee.
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
Add two scalars together (modulo the group order).
static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
Multiply two scalars (modulo the group order).
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the complement of a scalar (modulo the group order).
static void secp256k1_scalar_split_lambda(secp256k1_scalar *SECP256K1_RESTRICT r1, secp256k1_scalar *SECP256K1_RESTRICT r2, const secp256k1_scalar *SECP256K1_RESTRICT k)
Find r1 and r2 such that r1+r2*lambda = k, where r1 and r2 or their negations are maximum 128 bits lo...
static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the inverse of a scalar (modulo the group order).
static int get_iters(int default_iters)
static void print_output_table_header_row(void)
static int have_flag(int argc, char **argv, char *flag)
static void secp256k1_sha256_initialize(secp256k1_sha256 *hash)
static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen)
static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32)
static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size)
static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32)
static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen)
static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size)
static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size)
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx) SECP256K1_ARG_NONNULL(1)
Destroy a secp256k1 context object (created in dynamically allocated memory).
SECP256K1_API secp256k1_context * secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Create a secp256k1 context object (in dynamically allocated memory).
#define SECP256K1_CONTEXT_NONE
Context flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size,...
This field implementation represents the value as 10 uint32_t limbs in base 2^26.
A group element in affine coordinates on the secp256k1 curve, or occasionally on an isomorphic curve ...
A group element of the secp256k1 curve, in jacobian coordinates.
A scalar modulo the group order of the secp256k1 curve.