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