github.com/ethereum/go-ethereum@v1.16.1/crypto/secp256k1/libsecp256k1/src/modules/recovery/tests_impl.h (about)

     1  /***********************************************************************
     2   * Copyright (c) 2013-2015 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  #ifndef SECP256K1_MODULE_RECOVERY_TESTS_H
     8  #define SECP256K1_MODULE_RECOVERY_TESTS_H
     9  
    10  static int recovery_test_nonce_function(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, void *data, unsigned int counter) {
    11      (void) msg32;
    12      (void) key32;
    13      (void) algo16;
    14      (void) data;
    15  
    16      /* On the first run, return 0 to force a second run */
    17      if (counter == 0) {
    18          memset(nonce32, 0, 32);
    19          return 1;
    20      }
    21      /* On the second run, return an overflow to force a third run */
    22      if (counter == 1) {
    23          memset(nonce32, 0xff, 32);
    24          return 1;
    25      }
    26      /* On the next run, return a valid nonce, but flip a coin as to whether or not to fail signing. */
    27      memset(nonce32, 1, 32);
    28      return testrand_bits(1);
    29  }
    30  
    31  static void test_ecdsa_recovery_api(void) {
    32      /* Setup contexts that just count errors */
    33      secp256k1_pubkey pubkey;
    34      secp256k1_pubkey recpubkey;
    35      secp256k1_ecdsa_signature normal_sig;
    36      secp256k1_ecdsa_recoverable_signature recsig;
    37      unsigned char privkey[32] = { 1 };
    38      unsigned char message[32] = { 2 };
    39      int recid = 0;
    40      unsigned char sig[74];
    41      unsigned char zero_privkey[32] = { 0 };
    42      unsigned char over_privkey[32] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    43                                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    44                                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    45                                         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
    46  
    47      /* Construct and verify corresponding public key. */
    48      CHECK(secp256k1_ec_seckey_verify(CTX, privkey) == 1);
    49      CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, privkey) == 1);
    50  
    51      /* Check bad contexts and NULLs for signing */
    52      CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, NULL, NULL) == 1);
    53      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_sign_recoverable(CTX, NULL, message, privkey, NULL, NULL));
    54      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_sign_recoverable(CTX, &recsig, NULL, privkey, NULL, NULL));
    55      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, NULL, NULL, NULL));
    56      CHECK_ILLEGAL(STATIC_CTX, secp256k1_ecdsa_sign_recoverable(STATIC_CTX, &recsig, message, privkey, NULL, NULL));
    57      /* This will fail or succeed randomly, and in either case will not ARG_CHECK failure */
    58      secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, recovery_test_nonce_function, NULL);
    59      /* These will all fail, but not in ARG_CHECK way */
    60      CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, zero_privkey, NULL, NULL) == 0);
    61      CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, over_privkey, NULL, NULL) == 0);
    62      /* This one will succeed. */
    63      CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, NULL, NULL) == 1);
    64  
    65      /* Check signing with a goofy nonce function */
    66  
    67      /* Check bad contexts and NULLs for recovery */
    68      CHECK(secp256k1_ecdsa_recover(CTX, &recpubkey, &recsig, message) == 1);
    69      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recover(CTX, NULL, &recsig, message));
    70      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recover(CTX, &recpubkey, NULL, message));
    71      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recover(CTX, &recpubkey, &recsig, NULL));
    72  
    73      /* Check NULLs for conversion */
    74      CHECK(secp256k1_ecdsa_sign(CTX, &normal_sig, message, privkey, NULL, NULL) == 1);
    75      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_convert(CTX, NULL, &recsig));
    76      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_convert(CTX, &normal_sig, NULL));
    77      CHECK(secp256k1_ecdsa_recoverable_signature_convert(CTX, &normal_sig, &recsig) == 1);
    78  
    79      /* Check NULLs for de/serialization */
    80      CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &recsig, message, privkey, NULL, NULL) == 1);
    81      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, NULL, &recid, &recsig));
    82      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, NULL, &recsig));
    83      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, NULL));
    84      CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, &recsig) == 1);
    85  
    86      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, NULL, sig, recid));
    87      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, NULL, recid));
    88      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, sig, -1));
    89      CHECK_ILLEGAL(CTX, secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, sig, 5));
    90      /* overflow in signature will not result in calling illegal_callback */
    91      memcpy(sig, over_privkey, 32);
    92      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &recsig, sig, recid) == 0);
    93  }
    94  
    95  static void test_ecdsa_recovery_end_to_end(void) {
    96      unsigned char extra[32] = {0x00};
    97      unsigned char privkey[32];
    98      unsigned char message[32];
    99      secp256k1_ecdsa_signature signature[5];
   100      secp256k1_ecdsa_recoverable_signature rsignature[5];
   101      unsigned char sig[74];
   102      secp256k1_pubkey pubkey;
   103      secp256k1_pubkey recpubkey;
   104      int recid = 0;
   105  
   106      /* Generate a random key and message. */
   107      {
   108          secp256k1_scalar msg, key;
   109          testutil_random_scalar_order_test(&msg);
   110          testutil_random_scalar_order_test(&key);
   111          secp256k1_scalar_get_b32(privkey, &key);
   112          secp256k1_scalar_get_b32(message, &msg);
   113      }
   114  
   115      /* Construct and verify corresponding public key. */
   116      CHECK(secp256k1_ec_seckey_verify(CTX, privkey) == 1);
   117      CHECK(secp256k1_ec_pubkey_create(CTX, &pubkey, privkey) == 1);
   118  
   119      /* Serialize/parse compact and verify/recover. */
   120      extra[0] = 0;
   121      CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &rsignature[0], message, privkey, NULL, NULL) == 1);
   122      CHECK(secp256k1_ecdsa_sign(CTX, &signature[0], message, privkey, NULL, NULL) == 1);
   123      CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &rsignature[4], message, privkey, NULL, NULL) == 1);
   124      CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &rsignature[1], message, privkey, NULL, extra) == 1);
   125      extra[31] = 1;
   126      CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &rsignature[2], message, privkey, NULL, extra) == 1);
   127      extra[31] = 0;
   128      extra[0] = 1;
   129      CHECK(secp256k1_ecdsa_sign_recoverable(CTX, &rsignature[3], message, privkey, NULL, extra) == 1);
   130      CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, &rsignature[4]) == 1);
   131      CHECK(secp256k1_ecdsa_recoverable_signature_convert(CTX, &signature[4], &rsignature[4]) == 1);
   132      CHECK(secp256k1_memcmp_var(&signature[4], &signature[0], 64) == 0);
   133      CHECK(secp256k1_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 1);
   134      memset(&rsignature[4], 0, sizeof(rsignature[4]));
   135      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsignature[4], sig, recid) == 1);
   136      CHECK(secp256k1_ecdsa_recoverable_signature_convert(CTX, &signature[4], &rsignature[4]) == 1);
   137      CHECK(secp256k1_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 1);
   138      /* Parse compact (with recovery id) and recover. */
   139      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsignature[4], sig, recid) == 1);
   140      CHECK(secp256k1_ecdsa_recover(CTX, &recpubkey, &rsignature[4], message) == 1);
   141      CHECK(secp256k1_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) == 0);
   142      /* Serialize/destroy/parse signature and verify again. */
   143      CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(CTX, sig, &recid, &rsignature[4]) == 1);
   144      sig[testrand_bits(6)] += 1 + testrand_int(255);
   145      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsignature[4], sig, recid) == 1);
   146      CHECK(secp256k1_ecdsa_recoverable_signature_convert(CTX, &signature[4], &rsignature[4]) == 1);
   147      CHECK(secp256k1_ecdsa_verify(CTX, &signature[4], message, &pubkey) == 0);
   148      /* Recover again */
   149      CHECK(secp256k1_ecdsa_recover(CTX, &recpubkey, &rsignature[4], message) == 0 ||
   150            secp256k1_memcmp_var(&pubkey, &recpubkey, sizeof(pubkey)) != 0);
   151  }
   152  
   153  /* Tests several edge cases. */
   154  static void test_ecdsa_recovery_edge_cases(void) {
   155      const unsigned char msg32[32] = {
   156          'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
   157          'a', ' ', 'v', 'e', 'r', 'y', ' ', 's',
   158          'e', 'c', 'r', 'e', 't', ' ', 'm', 'e',
   159          's', 's', 'a', 'g', 'e', '.', '.', '.'
   160      };
   161      const unsigned char sig64[64] = {
   162          /* Generated by signing the above message with nonce 'This is the nonce we will use...'
   163           * and secret key 0 (which is not valid), resulting in recid 1. */
   164          0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8,
   165          0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96,
   166          0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63,
   167          0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32,
   168          0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E,
   169          0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD,
   170          0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86,
   171          0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57
   172      };
   173      secp256k1_pubkey pubkey;
   174      /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */
   175      const unsigned char sigb64[64] = {
   176          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   177          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   178          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   179          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
   180          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   181          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   182          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   183          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
   184      };
   185      secp256k1_pubkey pubkeyb;
   186      secp256k1_ecdsa_recoverable_signature rsig;
   187      secp256k1_ecdsa_signature sig;
   188      int recid;
   189  
   190      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 0));
   191      CHECK(!secp256k1_ecdsa_recover(CTX, &pubkey, &rsig, msg32));
   192      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 1));
   193      CHECK(secp256k1_ecdsa_recover(CTX, &pubkey, &rsig, msg32));
   194      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 2));
   195      CHECK(!secp256k1_ecdsa_recover(CTX, &pubkey, &rsig, msg32));
   196      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sig64, 3));
   197      CHECK(!secp256k1_ecdsa_recover(CTX, &pubkey, &rsig, msg32));
   198  
   199      for (recid = 0; recid < 4; recid++) {
   200          int i;
   201          int recid2;
   202          /* (4,4) encoded in DER. */
   203          unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04};
   204          unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01};
   205          unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00};
   206          unsigned char sigbderalt1[39] = {
   207              0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
   208              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   209              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   210              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   211              0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
   212          };
   213          unsigned char sigbderalt2[39] = {
   214              0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00,
   215              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   216              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   217              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   218              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
   219          };
   220          unsigned char sigbderalt3[40] = {
   221              0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00,
   222              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   223              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   224              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   225              0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
   226          };
   227          unsigned char sigbderalt4[40] = {
   228              0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00,
   229              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   230              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   231              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   232              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
   233          };
   234          /* (order + r,4) encoded in DER. */
   235          unsigned char sigbderlong[40] = {
   236              0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF,
   237              0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   238              0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC,
   239              0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E,
   240              0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04
   241          };
   242          CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigb64, recid) == 1);
   243          CHECK(secp256k1_ecdsa_recover(CTX, &pubkeyb, &rsig, msg32) == 1);
   244          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder)) == 1);
   245          CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 1);
   246          for (recid2 = 0; recid2 < 4; recid2++) {
   247              secp256k1_pubkey pubkey2b;
   248              CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigb64, recid2) == 1);
   249              CHECK(secp256k1_ecdsa_recover(CTX, &pubkey2b, &rsig, msg32) == 1);
   250              /* Verifying with (order + r,4) should always fail. */
   251              CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderlong, sizeof(sigbderlong)) == 1);
   252              CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0);
   253          }
   254          /* DER parsing tests. */
   255          /* Zero length r/s. */
   256          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigcder_zr, sizeof(sigcder_zr)) == 0);
   257          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0);
   258          /* Leading zeros. */
   259          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt1, sizeof(sigbderalt1)) == 0);
   260          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt2, sizeof(sigbderalt2)) == 0);
   261          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0);
   262          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt4, sizeof(sigbderalt4)) == 0);
   263          sigbderalt3[4] = 1;
   264          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1);
   265          CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0);
   266          sigbderalt4[7] = 1;
   267          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1);
   268          CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0);
   269          /* Damage signature. */
   270          sigbder[7]++;
   271          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder)) == 1);
   272          CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0);
   273          sigbder[7]--;
   274          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbder, 6) == 0);
   275          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder) - 1) == 0);
   276          for(i = 0; i < 8; i++) {
   277              int c;
   278              unsigned char orig = sigbder[i];
   279              /*Try every single-byte change.*/
   280              for (c = 0; c < 256; c++) {
   281                  if (c == orig ) {
   282                      continue;
   283                  }
   284                  sigbder[i] = c;
   285                  CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyb) == 0);
   286              }
   287              sigbder[i] = orig;
   288          }
   289      }
   290  
   291      /* Test r/s equal to zero */
   292      {
   293          /* (1,1) encoded in DER. */
   294          unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01};
   295          unsigned char sigc64[64] = {
   296              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   297              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   298              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   299              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
   300              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   301              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   302              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   303              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
   304          };
   305          secp256k1_pubkey pubkeyc;
   306          CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigc64, 0) == 1);
   307          CHECK(secp256k1_ecdsa_recover(CTX, &pubkeyc, &rsig, msg32) == 1);
   308          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigcder, sizeof(sigcder)) == 1);
   309          CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyc) == 1);
   310          sigcder[4] = 0;
   311          sigc64[31] = 0;
   312          CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigc64, 0) == 1);
   313          CHECK(secp256k1_ecdsa_recover(CTX, &pubkeyb, &rsig, msg32) == 0);
   314          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigcder, sizeof(sigcder)) == 1);
   315          CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyc) == 0);
   316          sigcder[4] = 1;
   317          sigcder[7] = 0;
   318          sigc64[31] = 1;
   319          sigc64[63] = 0;
   320          CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(CTX, &rsig, sigc64, 0) == 1);
   321          CHECK(secp256k1_ecdsa_recover(CTX, &pubkeyb, &rsig, msg32) == 0);
   322          CHECK(secp256k1_ecdsa_signature_parse_der(CTX, &sig, sigcder, sizeof(sigcder)) == 1);
   323          CHECK(secp256k1_ecdsa_verify(CTX, &sig, msg32, &pubkeyc) == 0);
   324      }
   325  }
   326  
   327  static void run_recovery_tests(void) {
   328      int i;
   329      for (i = 0; i < COUNT; i++) {
   330          test_ecdsa_recovery_api();
   331      }
   332      for (i = 0; i < 64*COUNT; i++) {
   333          test_ecdsa_recovery_end_to_end();
   334      }
   335      test_ecdsa_recovery_edge_cases();
   336  }
   337  
   338  #endif /* SECP256K1_MODULE_RECOVERY_TESTS_H */