csecp256k1

Haskell FFI bindings to bitcoin-core/secp256k1 (docs.ppad.tech/csecp256k1).
git clone git://git.ppad.tech/csecp256k1.git
Log | Files | Refs | README | LICENSE

bench.c (10170B)


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