github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/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  void test_ecdsa_recovery_end_to_end(void) {
    11      unsigned char extra[32] = {0x00};
    12      unsigned char privkey[32];
    13      unsigned char message[32];
    14      secp256k1_ecdsa_signature signature[5];
    15      secp256k1_ecdsa_recoverable_signature rsignature[5];
    16      unsigned char sig[74];
    17      secp256k1_pubkey pubkey;
    18      secp256k1_pubkey recpubkey;
    19      int recid = 0;
    20  
    21      /* Generate a random key and message. */
    22      {
    23          secp256k1_scalar msg, key;
    24          random_scalar_order_test(&msg);
    25          random_scalar_order_test(&key);
    26          secp256k1_scalar_get_b32(privkey, &key);
    27          secp256k1_scalar_get_b32(message, &msg);
    28      }
    29  
    30      /* Construct and verify corresponding public key. */
    31      CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1);
    32      CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1);
    33  
    34      /* Serialize/parse compact and verify/recover. */
    35      extra[0] = 0;
    36      CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[0], message, privkey, NULL, NULL) == 1);
    37      CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[4], message, privkey, NULL, NULL) == 1);
    38      CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[1], message, privkey, NULL, extra) == 1);
    39      extra[31] = 1;
    40      CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[2], message, privkey, NULL, extra) == 1);
    41      extra[31] = 0;
    42      extra[0] = 1;
    43      CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[3], message, privkey, NULL, extra) == 1);
    44      CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1);
    45      CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
    46      CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1);
    47      memset(&rsignature[4], 0, sizeof(rsignature[4]));
    48      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
    49      CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
    50      CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1);
    51      /* Parse compact (with recovery id) and recover. */
    52      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
    53      CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 1);
    54      CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0);
    55      /* Serialize/destroy/parse signature and verify again. */
    56      CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1);
    57      sig[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255);
    58      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
    59      CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
    60      CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 0);
    61      /* Recover again */
    62      CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 0 ||
    63            memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0);
    64  }
    65  
    66  /* Tests several edge cases. */
    67  void test_ecdsa_recovery_edge_cases(void) {
    68      const unsigned char msg32[32] = {
    69          'T', 'h', 'i', 's', ' ', 'i', 's', ' ',
    70          'a', ' ', 'v', 'e', 'r', 'y', ' ', 's',
    71          'e', 'c', 'r', 'e', 't', ' ', 'm', 'e',
    72          's', 's', 'a', 'g', 'e', '.', '.', '.'
    73      };
    74      const unsigned char sig64[64] = {
    75          /* Generated by signing the above message with nonce 'This is the nonce we will use...'
    76           * and secret key 0 (which is not valid), resulting in recid 0. */
    77          0x67, 0xCB, 0x28, 0x5F, 0x9C, 0xD1, 0x94, 0xE8,
    78          0x40, 0xD6, 0x29, 0x39, 0x7A, 0xF5, 0x56, 0x96,
    79          0x62, 0xFD, 0xE4, 0x46, 0x49, 0x99, 0x59, 0x63,
    80          0x17, 0x9A, 0x7D, 0xD1, 0x7B, 0xD2, 0x35, 0x32,
    81          0x4B, 0x1B, 0x7D, 0xF3, 0x4C, 0xE1, 0xF6, 0x8E,
    82          0x69, 0x4F, 0xF6, 0xF1, 0x1A, 0xC7, 0x51, 0xDD,
    83          0x7D, 0xD7, 0x3E, 0x38, 0x7E, 0xE4, 0xFC, 0x86,
    84          0x6E, 0x1B, 0xE8, 0xEC, 0xC7, 0xDD, 0x95, 0x57
    85      };
    86      secp256k1_pubkey pubkey;
    87      /* signature (r,s) = (4,4), which can be recovered with all 4 recids. */
    88      const unsigned char sigb64[64] = {
    89          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    90          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    91          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    92          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
    93          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    94          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    95          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    96          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
    97      };
    98      secp256k1_pubkey pubkeyb;
    99      secp256k1_ecdsa_recoverable_signature rsig;
   100      secp256k1_ecdsa_signature sig;
   101      int recid;
   102  
   103      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 0));
   104      CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
   105      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 1));
   106      CHECK(secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
   107      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 2));
   108      CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
   109      CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 3));
   110      CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
   111  
   112      for (recid = 0; recid < 4; recid++) {
   113          int i;
   114          int recid2;
   115          /* (4,4) encoded in DER. */
   116          unsigned char sigbder[8] = {0x30, 0x06, 0x02, 0x01, 0x04, 0x02, 0x01, 0x04};
   117          unsigned char sigcder_zr[7] = {0x30, 0x05, 0x02, 0x00, 0x02, 0x01, 0x01};
   118          unsigned char sigcder_zs[7] = {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x00};
   119          unsigned char sigbderalt1[39] = {
   120              0x30, 0x25, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
   121              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   122              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   123              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   124              0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
   125          };
   126          unsigned char sigbderalt2[39] = {
   127              0x30, 0x25, 0x02, 0x01, 0x04, 0x02, 0x20, 0x00,
   128              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   129              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   130              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   131              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
   132          };
   133          unsigned char sigbderalt3[40] = {
   134              0x30, 0x26, 0x02, 0x21, 0x00, 0x00, 0x00, 0x00,
   135              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   136              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   137              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   138              0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x01, 0x04,
   139          };
   140          unsigned char sigbderalt4[40] = {
   141              0x30, 0x26, 0x02, 0x01, 0x04, 0x02, 0x21, 0x00,
   142              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   143              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   144              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   145              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
   146          };
   147          /* (order + r,4) encoded in DER. */
   148          unsigned char sigbderlong[40] = {
   149              0x30, 0x26, 0x02, 0x21, 0x00, 0xFF, 0xFF, 0xFF,
   150              0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
   151              0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC,
   152              0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E,
   153              0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04
   154          };
   155          CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid) == 1);
   156          CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 1);
   157          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1);
   158          CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
   159          for (recid2 = 0; recid2 < 4; recid2++) {
   160              secp256k1_pubkey pubkey2b;
   161              CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid2) == 1);
   162              CHECK(secp256k1_ecdsa_recover(ctx, &pubkey2b, &rsig, msg32) == 1);
   163              /* Verifying with (order + r,4) should always fail. */
   164              CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderlong, sizeof(sigbderlong)) == 0);
   165          }
   166          /* DER parsing tests. */
   167          /* Zero length r/s. */
   168          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zr, sizeof(sigcder_zr)) == 0);
   169          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0);
   170          /* Leading zeros. */
   171          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt1, sizeof(sigbderalt1)) == 1);
   172          CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
   173          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt2, sizeof(sigbderalt2)) == 1);
   174          CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
   175          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1);
   176          CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
   177          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1);
   178          CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
   179          sigbderalt3[4] = 1;
   180          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0);
   181          sigbderalt4[7] = 1;
   182          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 0);
   183          /* Damage signature. */
   184          sigbder[7]++;
   185          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1);
   186          CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0);
   187          sigbder[7]--;
   188          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, 6) == 0);
   189          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder) - 1) == 0);
   190          for(i = 0; i < 8; i++) {
   191              int c;
   192              unsigned char orig = sigbder[i];
   193              /*Try every single-byte change.*/
   194              for (c = 0; c < 256; c++) {
   195                  if (c == orig ) {
   196                      continue;
   197                  }
   198                  sigbder[i] = c;
   199                  CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0);
   200              }
   201              sigbder[i] = orig;
   202          }
   203      }
   204  
   205      /* Test r/s equal to zero */
   206      {
   207          /* (1,1) encoded in DER. */
   208          unsigned char sigcder[8] = {0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x01};
   209          unsigned char sigc64[64] = {
   210              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   211              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   212              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   213              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
   214              0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x01,
   218          };
   219          secp256k1_pubkey pubkeyc;
   220          CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1);
   221          CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyc, &rsig, msg32) == 1);
   222          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1);
   223          CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 1);
   224          sigcder[4] = 0;
   225          sigc64[31] = 0;
   226          CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1);
   227          CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0);
   228          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1);
   229          CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0);
   230          sigcder[4] = 1;
   231          sigcder[7] = 0;
   232          sigc64[31] = 1;
   233          sigc64[63] = 0;
   234          CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1);
   235          CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0);
   236          CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1);
   237          CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0);
   238      }
   239  }
   240  
   241  void run_recovery_tests(void) {
   242      int i;
   243      for (i = 0; i < 64*count; i++) {
   244          test_ecdsa_recovery_end_to_end();
   245      }
   246      test_ecdsa_recovery_edge_cases();
   247  }
   248  
   249  #endif