github.com/ethereum/go-ethereum@v1.16.1/crypto/secp256k1/libsecp256k1/src/bench.c (about) 1 /*********************************************************************** 2 * Copyright (c) 2014 Pieter Wuille * 3 * Distributed under the MIT software license, see the accompanying * 4 * file COPYING or https://www.opensource.org/licenses/mit-license.php.* 5 ***********************************************************************/ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 #include "../include/secp256k1.h" 12 #include "util.h" 13 #include "bench.h" 14 15 static void help(int default_iters) { 16 printf("Benchmarks the following algorithms:\n"); 17 printf(" - ECDSA signing/verification\n"); 18 19 #ifdef ENABLE_MODULE_ECDH 20 printf(" - ECDH key exchange (optional module)\n"); 21 #endif 22 23 #ifdef ENABLE_MODULE_RECOVERY 24 printf(" - Public key recovery (optional module)\n"); 25 #endif 26 27 #ifdef ENABLE_MODULE_SCHNORRSIG 28 printf(" - Schnorr signatures (optional module)\n"); 29 #endif 30 31 printf("\n"); 32 printf("The default number of iterations for each benchmark is %d. This can be\n", default_iters); 33 printf("customized using the SECP256K1_BENCH_ITERS environment variable.\n"); 34 printf("\n"); 35 printf("Usage: ./bench [args]\n"); 36 printf("By default, all benchmarks will be run.\n"); 37 printf("args:\n"); 38 printf(" help : display this help and exit\n"); 39 printf(" ecdsa : all ECDSA algorithms--sign, verify, recovery (if enabled)\n"); 40 printf(" ecdsa_sign : ECDSA siging algorithm\n"); 41 printf(" ecdsa_verify : ECDSA verification algorithm\n"); 42 printf(" ec : all EC public key algorithms (keygen)\n"); 43 printf(" ec_keygen : EC public key generation\n"); 44 45 #ifdef ENABLE_MODULE_RECOVERY 46 printf(" ecdsa_recover : ECDSA public key recovery algorithm\n"); 47 #endif 48 49 #ifdef ENABLE_MODULE_ECDH 50 printf(" ecdh : ECDH key exchange algorithm\n"); 51 #endif 52 53 #ifdef ENABLE_MODULE_SCHNORRSIG 54 printf(" schnorrsig : all Schnorr signature algorithms (sign, verify)\n"); 55 printf(" schnorrsig_sign : Schnorr sigining algorithm\n"); 56 printf(" schnorrsig_verify : Schnorr verification algorithm\n"); 57 #endif 58 59 #ifdef ENABLE_MODULE_ELLSWIFT 60 printf(" ellswift : all ElligatorSwift benchmarks (encode, decode, keygen, ecdh)\n"); 61 printf(" ellswift_encode : ElligatorSwift encoding\n"); 62 printf(" ellswift_decode : ElligatorSwift decoding\n"); 63 printf(" ellswift_keygen : ElligatorSwift key generation\n"); 64 printf(" ellswift_ecdh : ECDH on ElligatorSwift keys\n"); 65 #endif 66 67 printf("\n"); 68 } 69 70 typedef struct { 71 secp256k1_context *ctx; 72 unsigned char msg[32]; 73 unsigned char key[32]; 74 unsigned char sig[72]; 75 size_t siglen; 76 unsigned char pubkey[33]; 77 size_t pubkeylen; 78 } bench_data; 79 80 static void bench_verify(void* arg, int iters) { 81 int i; 82 bench_data* data = (bench_data*)arg; 83 84 for (i = 0; i < iters; i++) { 85 secp256k1_pubkey pubkey; 86 secp256k1_ecdsa_signature sig; 87 data->sig[data->siglen - 1] ^= (i & 0xFF); 88 data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); 89 data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); 90 CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1); 91 CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1); 92 CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0)); 93 data->sig[data->siglen - 1] ^= (i & 0xFF); 94 data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF); 95 data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF); 96 } 97 } 98 99 static void bench_sign_setup(void* arg) { 100 int i; 101 bench_data *data = (bench_data*)arg; 102 103 for (i = 0; i < 32; i++) { 104 data->msg[i] = i + 1; 105 } 106 for (i = 0; i < 32; i++) { 107 data->key[i] = i + 65; 108 } 109 } 110 111 static void bench_sign_run(void* arg, int iters) { 112 int i; 113 bench_data *data = (bench_data*)arg; 114 115 unsigned char sig[74]; 116 for (i = 0; i < iters; i++) { 117 size_t siglen = 74; 118 int j; 119 secp256k1_ecdsa_signature signature; 120 CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL)); 121 CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature)); 122 for (j = 0; j < 32; j++) { 123 data->msg[j] = sig[j]; 124 data->key[j] = sig[j + 32]; 125 } 126 } 127 } 128 129 static void bench_keygen_setup(void* arg) { 130 int i; 131 bench_data *data = (bench_data*)arg; 132 133 for (i = 0; i < 32; i++) { 134 data->key[i] = i + 65; 135 } 136 } 137 138 static void bench_keygen_run(void *arg, int iters) { 139 int i; 140 bench_data *data = (bench_data*)arg; 141 142 for (i = 0; i < iters; i++) { 143 unsigned char pub33[33]; 144 size_t len = 33; 145 secp256k1_pubkey pubkey; 146 CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->key)); 147 CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pub33, &len, &pubkey, SECP256K1_EC_COMPRESSED)); 148 memcpy(data->key, pub33 + 1, 32); 149 } 150 } 151 152 153 #ifdef ENABLE_MODULE_ECDH 154 # include "modules/ecdh/bench_impl.h" 155 #endif 156 157 #ifdef ENABLE_MODULE_RECOVERY 158 # include "modules/recovery/bench_impl.h" 159 #endif 160 161 #ifdef ENABLE_MODULE_SCHNORRSIG 162 # include "modules/schnorrsig/bench_impl.h" 163 #endif 164 165 #ifdef ENABLE_MODULE_ELLSWIFT 166 # include "modules/ellswift/bench_impl.h" 167 #endif 168 169 int main(int argc, char** argv) { 170 int i; 171 secp256k1_pubkey pubkey; 172 secp256k1_ecdsa_signature sig; 173 bench_data data; 174 175 int d = argc == 1; 176 int default_iters = 20000; 177 int iters = get_iters(default_iters); 178 179 /* Check for invalid user arguments */ 180 char* valid_args[] = {"ecdsa", "verify", "ecdsa_verify", "sign", "ecdsa_sign", "ecdh", "recover", 181 "ecdsa_recover", "schnorrsig", "schnorrsig_verify", "schnorrsig_sign", "ec", 182 "keygen", "ec_keygen", "ellswift", "encode", "ellswift_encode", "decode", 183 "ellswift_decode", "ellswift_keygen", "ellswift_ecdh"}; 184 size_t valid_args_size = sizeof(valid_args)/sizeof(valid_args[0]); 185 int invalid_args = have_invalid_args(argc, argv, valid_args, valid_args_size); 186 187 if (argc > 1) { 188 if (have_flag(argc, argv, "-h") 189 || have_flag(argc, argv, "--help") 190 || have_flag(argc, argv, "help")) { 191 help(default_iters); 192 return EXIT_SUCCESS; 193 } else if (invalid_args) { 194 fprintf(stderr, "./bench: unrecognized argument.\n\n"); 195 help(default_iters); 196 return EXIT_FAILURE; 197 } 198 } 199 200 /* Check if the user tries to benchmark optional module without building it */ 201 #ifndef ENABLE_MODULE_ECDH 202 if (have_flag(argc, argv, "ecdh")) { 203 fprintf(stderr, "./bench: ECDH module not enabled.\n"); 204 fprintf(stderr, "Use ./configure --enable-module-ecdh.\n\n"); 205 return EXIT_FAILURE; 206 } 207 #endif 208 209 #ifndef ENABLE_MODULE_RECOVERY 210 if (have_flag(argc, argv, "recover") || have_flag(argc, argv, "ecdsa_recover")) { 211 fprintf(stderr, "./bench: Public key recovery module not enabled.\n"); 212 fprintf(stderr, "Use ./configure --enable-module-recovery.\n\n"); 213 return EXIT_FAILURE; 214 } 215 #endif 216 217 #ifndef ENABLE_MODULE_SCHNORRSIG 218 if (have_flag(argc, argv, "schnorrsig") || have_flag(argc, argv, "schnorrsig_sign") || have_flag(argc, argv, "schnorrsig_verify")) { 219 fprintf(stderr, "./bench: Schnorr signatures module not enabled.\n"); 220 fprintf(stderr, "Use ./configure --enable-module-schnorrsig.\n\n"); 221 return EXIT_FAILURE; 222 } 223 #endif 224 225 #ifndef ENABLE_MODULE_ELLSWIFT 226 if (have_flag(argc, argv, "ellswift") || have_flag(argc, argv, "ellswift_encode") || have_flag(argc, argv, "ellswift_decode") || 227 have_flag(argc, argv, "encode") || have_flag(argc, argv, "decode") || have_flag(argc, argv, "ellswift_keygen") || 228 have_flag(argc, argv, "ellswift_ecdh")) { 229 fprintf(stderr, "./bench: ElligatorSwift module not enabled.\n"); 230 fprintf(stderr, "Use ./configure --enable-module-ellswift.\n\n"); 231 return EXIT_FAILURE; 232 } 233 #endif 234 235 /* ECDSA benchmark */ 236 data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_NONE); 237 238 for (i = 0; i < 32; i++) { 239 data.msg[i] = 1 + i; 240 } 241 for (i = 0; i < 32; i++) { 242 data.key[i] = 33 + i; 243 } 244 data.siglen = 72; 245 CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL)); 246 CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig)); 247 CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key)); 248 data.pubkeylen = 33; 249 CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED) == 1); 250 251 print_output_table_header_row(); 252 if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "verify") || have_flag(argc, argv, "ecdsa_verify")) run_benchmark("ecdsa_verify", bench_verify, NULL, NULL, &data, 10, iters); 253 254 if (d || have_flag(argc, argv, "ecdsa") || have_flag(argc, argv, "sign") || have_flag(argc, argv, "ecdsa_sign")) run_benchmark("ecdsa_sign", bench_sign_run, bench_sign_setup, NULL, &data, 10, iters); 255 if (d || have_flag(argc, argv, "ec") || have_flag(argc, argv, "keygen") || have_flag(argc, argv, "ec_keygen")) run_benchmark("ec_keygen", bench_keygen_run, bench_keygen_setup, NULL, &data, 10, iters); 256 257 secp256k1_context_destroy(data.ctx); 258 259 #ifdef ENABLE_MODULE_ECDH 260 /* ECDH benchmarks */ 261 run_ecdh_bench(iters, argc, argv); 262 #endif 263 264 #ifdef ENABLE_MODULE_RECOVERY 265 /* ECDSA recovery benchmarks */ 266 run_recovery_bench(iters, argc, argv); 267 #endif 268 269 #ifdef ENABLE_MODULE_SCHNORRSIG 270 /* Schnorr signature benchmarks */ 271 run_schnorrsig_bench(iters, argc, argv); 272 #endif 273 274 #ifdef ENABLE_MODULE_ELLSWIFT 275 /* ElligatorSwift benchmarks */ 276 run_ellswift_bench(iters, argc, argv); 277 #endif 278 279 return EXIT_SUCCESS; 280 }