github.com/ethereum/go-ethereum@v1.16.1/crypto/secp256k1/libsecp256k1/src/ctime_tests.c (about)

     1  /***********************************************************************
     2   * Copyright (c) 2020 Gregory Maxwell                                  *
     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 "assumptions.h"
    13  #include "checkmem.h"
    14  
    15  #if !SECP256K1_CHECKMEM_ENABLED
    16  #  error "This tool cannot be compiled without memory-checking interface (valgrind or msan)"
    17  #endif
    18  
    19  #ifdef ENABLE_MODULE_ECDH
    20  # include "../include/secp256k1_ecdh.h"
    21  #endif
    22  
    23  #ifdef ENABLE_MODULE_RECOVERY
    24  # include "../include/secp256k1_recovery.h"
    25  #endif
    26  
    27  #ifdef ENABLE_MODULE_EXTRAKEYS
    28  # include "../include/secp256k1_extrakeys.h"
    29  #endif
    30  
    31  #ifdef ENABLE_MODULE_SCHNORRSIG
    32  #include "../include/secp256k1_schnorrsig.h"
    33  #endif
    34  
    35  #ifdef ENABLE_MODULE_MUSIG
    36  #include "../include/secp256k1_musig.h"
    37  #endif
    38  
    39  #ifdef ENABLE_MODULE_ELLSWIFT
    40  #include "../include/secp256k1_ellswift.h"
    41  #endif
    42  
    43  static void run_tests(secp256k1_context *ctx, unsigned char *key);
    44  
    45  int main(void) {
    46      secp256k1_context* ctx;
    47      unsigned char key[32];
    48      int ret, i;
    49  
    50      if (!SECP256K1_CHECKMEM_RUNNING()) {
    51          fprintf(stderr, "This test can only usefully be run inside valgrind because it was not compiled under msan.\n");
    52          fprintf(stderr, "Usage: libtool --mode=execute valgrind ./ctime_tests\n");
    53          return EXIT_FAILURE;
    54      }
    55      ctx = secp256k1_context_create(SECP256K1_CONTEXT_DECLASSIFY);
    56      /** In theory, testing with a single secret input should be sufficient:
    57       *  If control flow depended on secrets the tool would generate an error.
    58       */
    59      for (i = 0; i < 32; i++) {
    60          key[i] = i + 65;
    61      }
    62  
    63      run_tests(ctx, key);
    64  
    65      /* Test context randomisation. Do this last because it leaves the context
    66       * tainted. */
    67      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
    68      ret = secp256k1_context_randomize(ctx, key);
    69      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
    70      CHECK(ret);
    71  
    72      secp256k1_context_destroy(ctx);
    73      return EXIT_SUCCESS;
    74  }
    75  
    76  static void run_tests(secp256k1_context *ctx, unsigned char *key) {
    77      secp256k1_ecdsa_signature signature;
    78      secp256k1_pubkey pubkey;
    79      size_t siglen = 74;
    80      size_t outputlen = 33;
    81      int i;
    82      int ret;
    83      unsigned char msg[32];
    84      unsigned char sig[74];
    85      unsigned char spubkey[33];
    86  #ifdef ENABLE_MODULE_RECOVERY
    87      secp256k1_ecdsa_recoverable_signature recoverable_signature;
    88      int recid;
    89  #endif
    90  #ifdef ENABLE_MODULE_EXTRAKEYS
    91      secp256k1_keypair keypair;
    92  #endif
    93  #ifdef ENABLE_MODULE_ELLSWIFT
    94      unsigned char ellswift[64];
    95      static const unsigned char prefix[64] = {'t', 'e', 's', 't'};
    96  #endif
    97  
    98      for (i = 0; i < 32; i++) {
    99          msg[i] = i + 1;
   100      }
   101  
   102      /* Test keygen. */
   103      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   104      ret = secp256k1_ec_pubkey_create(ctx, &pubkey, key);
   105      SECP256K1_CHECKMEM_DEFINE(&pubkey, sizeof(secp256k1_pubkey));
   106      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   107      CHECK(ret);
   108      CHECK(secp256k1_ec_pubkey_serialize(ctx, spubkey, &outputlen, &pubkey, SECP256K1_EC_COMPRESSED) == 1);
   109  
   110      /* Test signing. */
   111      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   112      ret = secp256k1_ecdsa_sign(ctx, &signature, msg, key, NULL, NULL);
   113      SECP256K1_CHECKMEM_DEFINE(&signature, sizeof(secp256k1_ecdsa_signature));
   114      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   115      CHECK(ret);
   116      CHECK(secp256k1_ecdsa_signature_serialize_der(ctx, sig, &siglen, &signature));
   117  
   118  #ifdef ENABLE_MODULE_ECDH
   119      /* Test ECDH. */
   120      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   121      ret = secp256k1_ecdh(ctx, msg, &pubkey, key, NULL, NULL);
   122      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   123      CHECK(ret == 1);
   124  #endif
   125  
   126  #ifdef ENABLE_MODULE_RECOVERY
   127      /* Test signing a recoverable signature. */
   128      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   129      ret = secp256k1_ecdsa_sign_recoverable(ctx, &recoverable_signature, msg, key, NULL, NULL);
   130      SECP256K1_CHECKMEM_DEFINE(&recoverable_signature, sizeof(recoverable_signature));
   131      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   132      CHECK(ret);
   133      CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &recoverable_signature));
   134      CHECK(recid >= 0 && recid <= 3);
   135  #endif
   136  
   137      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   138      ret = secp256k1_ec_seckey_verify(ctx, key);
   139      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   140      CHECK(ret == 1);
   141  
   142      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   143      ret = secp256k1_ec_seckey_negate(ctx, key);
   144      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   145      CHECK(ret == 1);
   146  
   147      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   148      SECP256K1_CHECKMEM_UNDEFINE(msg, 32);
   149      ret = secp256k1_ec_seckey_tweak_add(ctx, key, msg);
   150      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   151      CHECK(ret == 1);
   152  
   153      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   154      SECP256K1_CHECKMEM_UNDEFINE(msg, 32);
   155      ret = secp256k1_ec_seckey_tweak_mul(ctx, key, msg);
   156      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   157      CHECK(ret == 1);
   158  
   159      /* Test keypair_create and keypair_xonly_tweak_add. */
   160  #ifdef ENABLE_MODULE_EXTRAKEYS
   161      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   162      ret = secp256k1_keypair_create(ctx, &keypair, key);
   163      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   164      CHECK(ret == 1);
   165  
   166      /* The tweak is not treated as a secret in keypair_tweak_add */
   167      SECP256K1_CHECKMEM_DEFINE(msg, 32);
   168      ret = secp256k1_keypair_xonly_tweak_add(ctx, &keypair, msg);
   169      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   170      CHECK(ret == 1);
   171  
   172      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   173      SECP256K1_CHECKMEM_UNDEFINE(&keypair, sizeof(keypair));
   174      ret = secp256k1_keypair_sec(ctx, key, &keypair);
   175      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   176      CHECK(ret == 1);
   177  #endif
   178  
   179  #ifdef ENABLE_MODULE_SCHNORRSIG
   180      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   181      ret = secp256k1_keypair_create(ctx, &keypair, key);
   182      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   183      CHECK(ret == 1);
   184      ret = secp256k1_schnorrsig_sign32(ctx, sig, msg, &keypair, NULL);
   185      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   186      CHECK(ret == 1);
   187  #endif
   188  
   189  #ifdef ENABLE_MODULE_MUSIG
   190      {
   191          secp256k1_pubkey pk;
   192          const secp256k1_pubkey *pk_ptr[1];
   193          secp256k1_xonly_pubkey agg_pk;
   194          unsigned char session_secrand[32];
   195          uint64_t nonrepeating_cnt = 0;
   196          secp256k1_musig_secnonce secnonce;
   197          secp256k1_musig_pubnonce pubnonce;
   198          const secp256k1_musig_pubnonce *pubnonce_ptr[1];
   199          secp256k1_musig_aggnonce aggnonce;
   200          secp256k1_musig_keyagg_cache cache;
   201          secp256k1_musig_session session;
   202          secp256k1_musig_partial_sig partial_sig;
   203          unsigned char extra_input[32];
   204  
   205          pk_ptr[0] = &pk;
   206          pubnonce_ptr[0] = &pubnonce;
   207          SECP256K1_CHECKMEM_DEFINE(key, 32);
   208          memcpy(session_secrand, key, sizeof(session_secrand));
   209          session_secrand[0] = session_secrand[0] + 1;
   210          memcpy(extra_input, key, sizeof(extra_input));
   211          extra_input[0] = extra_input[0] + 2;
   212  
   213          CHECK(secp256k1_keypair_create(ctx, &keypair, key));
   214          CHECK(secp256k1_keypair_pub(ctx, &pk, &keypair));
   215          CHECK(secp256k1_musig_pubkey_agg(ctx, &agg_pk, &cache, pk_ptr, 1));
   216  
   217          SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   218          SECP256K1_CHECKMEM_UNDEFINE(session_secrand, sizeof(session_secrand));
   219          SECP256K1_CHECKMEM_UNDEFINE(extra_input, sizeof(extra_input));
   220          ret = secp256k1_musig_nonce_gen(ctx, &secnonce, &pubnonce, session_secrand, key, &pk, msg, &cache, extra_input);
   221          SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   222          CHECK(ret == 1);
   223          ret = secp256k1_musig_nonce_gen_counter(ctx, &secnonce, &pubnonce, nonrepeating_cnt, &keypair, msg, &cache, extra_input);
   224          SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   225          CHECK(ret == 1);
   226  
   227          CHECK(secp256k1_musig_nonce_agg(ctx, &aggnonce, pubnonce_ptr, 1));
   228          /* Make sure that previous tests don't undefine msg. It's not used as a secret here. */
   229          SECP256K1_CHECKMEM_DEFINE(msg, sizeof(msg));
   230          CHECK(secp256k1_musig_nonce_process(ctx, &session, &aggnonce, msg, &cache) == 1);
   231  
   232          ret = secp256k1_keypair_create(ctx, &keypair, key);
   233          SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   234          CHECK(ret == 1);
   235          ret = secp256k1_musig_partial_sign(ctx, &partial_sig, &secnonce, &keypair, &cache, &session);
   236          SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   237          CHECK(ret == 1);
   238      }
   239  #endif
   240  
   241  #ifdef ENABLE_MODULE_ELLSWIFT
   242      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   243      ret = secp256k1_ellswift_create(ctx, ellswift, key, NULL);
   244      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   245      CHECK(ret == 1);
   246  
   247      SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   248      ret = secp256k1_ellswift_create(ctx, ellswift, key, ellswift);
   249      SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   250      CHECK(ret == 1);
   251  
   252      for (i = 0; i < 2; i++) {
   253          SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   254          SECP256K1_CHECKMEM_DEFINE(&ellswift, sizeof(ellswift));
   255          ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_bip324, NULL);
   256          SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   257          CHECK(ret == 1);
   258  
   259          SECP256K1_CHECKMEM_UNDEFINE(key, 32);
   260          SECP256K1_CHECKMEM_DEFINE(&ellswift, sizeof(ellswift));
   261          ret = secp256k1_ellswift_xdh(ctx, msg, ellswift, ellswift, key, i, secp256k1_ellswift_xdh_hash_function_prefix, (void *)prefix);
   262          SECP256K1_CHECKMEM_DEFINE(&ret, sizeof(ret));
   263          CHECK(ret == 1);
   264      }
   265  
   266  #endif
   267  }