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

     1  /***********************************************************************
     2   * Copyright (c) 2020 Jonas Nick                                       *
     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_EXTRAKEYS_TESTS_H
     8  #define SECP256K1_MODULE_EXTRAKEYS_TESTS_H
     9  
    10  #include "../../../include/secp256k1_extrakeys.h"
    11  
    12  static void test_xonly_pubkey(void) {
    13      secp256k1_pubkey pk;
    14      secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
    15      secp256k1_ge pk1;
    16      secp256k1_ge pk2;
    17      secp256k1_fe y;
    18      unsigned char sk[32];
    19      unsigned char xy_sk[32];
    20      unsigned char buf32[32];
    21      unsigned char ones32[32];
    22      unsigned char zeros64[64] = { 0 };
    23      int pk_parity;
    24      int i;
    25  
    26      testrand256(sk);
    27      memset(ones32, 0xFF, 32);
    28      testrand256(xy_sk);
    29      CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
    30      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
    31  
    32      /* Test xonly_pubkey_from_pubkey */
    33      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
    34      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_from_pubkey(CTX, NULL, &pk_parity, &pk));
    35      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1);
    36      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, NULL));
    37      memset(&pk, 0, sizeof(pk));
    38      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk));
    39  
    40      /* Choose a secret key such that the resulting pubkey and xonly_pubkey match. */
    41      memset(sk, 0, sizeof(sk));
    42      sk[0] = 1;
    43      CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
    44      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
    45      CHECK(secp256k1_memcmp_var(&pk, &xonly_pk, sizeof(pk)) == 0);
    46      CHECK(pk_parity == 0);
    47  
    48      /* Choose a secret key such that pubkey and xonly_pubkey are each others
    49       * negation. */
    50      sk[0] = 2;
    51      CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
    52      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
    53      CHECK(secp256k1_memcmp_var(&xonly_pk, &pk, sizeof(xonly_pk)) != 0);
    54      CHECK(pk_parity == 1);
    55      secp256k1_pubkey_load(CTX, &pk1, &pk);
    56      secp256k1_pubkey_load(CTX, &pk2, (secp256k1_pubkey *) &xonly_pk);
    57      CHECK(secp256k1_fe_equal(&pk1.x, &pk2.x) == 1);
    58      secp256k1_fe_negate(&y, &pk2.y, 1);
    59      CHECK(secp256k1_fe_equal(&pk1.y, &y) == 1);
    60  
    61      /* Test xonly_pubkey_serialize and xonly_pubkey_parse */
    62      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_serialize(CTX, NULL, &xonly_pk));
    63      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_serialize(CTX, buf32, NULL));
    64      CHECK(secp256k1_memcmp_var(buf32, zeros64, 32) == 0);
    65      {
    66          /* A pubkey filled with 0s will fail to serialize due to pubkey_load
    67           * special casing. */
    68          secp256k1_xonly_pubkey pk_tmp;
    69          memset(&pk_tmp, 0, sizeof(pk_tmp));
    70          /* pubkey_load calls illegal callback */
    71          CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_serialize(CTX, buf32, &pk_tmp));
    72      }
    73  
    74      CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1);
    75      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_parse(CTX, NULL, buf32));
    76      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, NULL));
    77  
    78      /* Serialization and parse roundtrip */
    79      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1);
    80      CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1);
    81      CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk_tmp, buf32) == 1);
    82      CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(xonly_pk)) == 0);
    83  
    84      /* Test parsing invalid field elements */
    85      memset(&xonly_pk, 1, sizeof(xonly_pk));
    86      /* Overflowing field element */
    87      CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, ones32) == 0);
    88      CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
    89      memset(&xonly_pk, 1, sizeof(xonly_pk));
    90      /* There's no point with x-coordinate 0 on secp256k1 */
    91      CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, zeros64) == 0);
    92      CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
    93      /* If a random 32-byte string can not be parsed with ec_pubkey_parse
    94       * (because interpreted as X coordinate it does not correspond to a point on
    95       * the curve) then xonly_pubkey_parse should fail as well. */
    96      for (i = 0; i < COUNT; i++) {
    97          unsigned char rand33[33];
    98          testrand256(&rand33[1]);
    99          rand33[0] = SECP256K1_TAG_PUBKEY_EVEN;
   100          if (!secp256k1_ec_pubkey_parse(CTX, &pk, rand33, 33)) {
   101              memset(&xonly_pk, 1, sizeof(xonly_pk));
   102              CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 0);
   103              CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
   104          } else {
   105              CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 1);
   106          }
   107      }
   108  }
   109  
   110  static void test_xonly_pubkey_comparison(void) {
   111      unsigned char pk1_ser[32] = {
   112          0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
   113          0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
   114      };
   115      const unsigned char pk2_ser[32] = {
   116          0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
   117          0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
   118      };
   119      secp256k1_xonly_pubkey pk1;
   120      secp256k1_xonly_pubkey pk2;
   121  
   122      CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk1, pk1_ser) == 1);
   123      CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk2, pk2_ser) == 1);
   124  
   125      CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_xonly_pubkey_cmp(CTX, NULL, &pk2) < 0));
   126      CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, NULL) > 0));
   127      CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk2) < 0);
   128      CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk1) > 0);
   129      CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0);
   130      CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk2) == 0);
   131      memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */
   132      CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk2) < 0));
   133      {
   134          int32_t ecount = 0;
   135          secp256k1_context_set_illegal_callback(CTX, counting_callback_fn, &ecount);
   136          CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0);
   137          CHECK(ecount == 2);
   138          secp256k1_context_set_illegal_callback(CTX, NULL, NULL);
   139      }
   140      CHECK_ILLEGAL_VOID(CTX, CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk1) > 0));
   141  }
   142  
   143  static void test_xonly_pubkey_tweak(void) {
   144      unsigned char zeros64[64] = { 0 };
   145      unsigned char overflows[32];
   146      unsigned char sk[32];
   147      secp256k1_pubkey internal_pk;
   148      secp256k1_xonly_pubkey internal_xonly_pk;
   149      secp256k1_pubkey output_pk;
   150      int pk_parity;
   151      unsigned char tweak[32];
   152      int i;
   153  
   154      memset(overflows, 0xff, sizeof(overflows));
   155      testrand256(tweak);
   156      testrand256(sk);
   157      CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1);
   158      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
   159  
   160      CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
   161      CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
   162      CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
   163      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, NULL, &internal_xonly_pk, tweak));
   164      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, NULL, tweak));
   165      /* NULL internal_xonly_pk zeroes the output_pk */
   166      CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
   167      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, NULL));
   168      /* NULL tweak zeroes the output_pk */
   169      CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
   170  
   171      /* Invalid tweak zeroes the output_pk */
   172      CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0);
   173      CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk))  == 0);
   174  
   175      /* A zero tweak is fine */
   176      CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, zeros64) == 1);
   177  
   178      /* Fails if the resulting key was infinity */
   179      for (i = 0; i < COUNT; i++) {
   180          secp256k1_scalar scalar_tweak;
   181          /* Because sk may be negated before adding, we need to try with tweak =
   182           * sk as well as tweak = -sk. */
   183          secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
   184          secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
   185          secp256k1_scalar_get_b32(tweak, &scalar_tweak);
   186          CHECK((secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, sk) == 0)
   187                || (secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 0));
   188          CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
   189      }
   190  
   191      /* Invalid pk with a valid tweak */
   192      memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk));
   193      testrand256(tweak);
   194      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak));
   195      CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk))  == 0);
   196  }
   197  
   198  static void test_xonly_pubkey_tweak_check(void) {
   199      unsigned char zeros64[64] = { 0 };
   200      unsigned char overflows[32];
   201      unsigned char sk[32];
   202      secp256k1_pubkey internal_pk;
   203      secp256k1_xonly_pubkey internal_xonly_pk;
   204      secp256k1_pubkey output_pk;
   205      secp256k1_xonly_pubkey output_xonly_pk;
   206      unsigned char output_pk32[32];
   207      unsigned char buf32[32];
   208      int pk_parity;
   209      unsigned char tweak[32];
   210  
   211      memset(overflows, 0xff, sizeof(overflows));
   212      testrand256(tweak);
   213      testrand256(sk);
   214      CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1);
   215      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
   216  
   217      CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
   218      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1);
   219      CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &output_xonly_pk) == 1);
   220      CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
   221      CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
   222      CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
   223      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, NULL, pk_parity, &internal_xonly_pk, tweak));
   224      /* invalid pk_parity value */
   225      CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, 2, &internal_xonly_pk, tweak) == 0);
   226      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, NULL, tweak));
   227      CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, NULL));
   228  
   229      memset(tweak, 1, sizeof(tweak));
   230      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, NULL, &internal_pk) == 1);
   231      CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
   232      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1);
   233      CHECK(secp256k1_xonly_pubkey_serialize(CTX, output_pk32, &output_xonly_pk) == 1);
   234      CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, tweak) == 1);
   235  
   236      /* Wrong pk_parity */
   237      CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, !pk_parity, &internal_xonly_pk, tweak) == 0);
   238      /* Wrong public key */
   239      CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &internal_xonly_pk) == 1);
   240      CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
   241  
   242      /* Overflowing tweak not allowed */
   243      CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0);
   244      CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0);
   245      CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
   246  }
   247  
   248  /* Starts with an initial pubkey and recursively creates N_PUBKEYS - 1
   249   * additional pubkeys by calling tweak_add. Then verifies every tweak starting
   250   * from the last pubkey. */
   251  #define N_PUBKEYS 32
   252  static void test_xonly_pubkey_tweak_recursive(void) {
   253      unsigned char sk[32];
   254      secp256k1_pubkey pk[N_PUBKEYS];
   255      unsigned char pk_serialized[32];
   256      unsigned char tweak[N_PUBKEYS - 1][32];
   257      int i;
   258  
   259      testrand256(sk);
   260      CHECK(secp256k1_ec_pubkey_create(CTX, &pk[0], sk) == 1);
   261      /* Add tweaks */
   262      for (i = 0; i < N_PUBKEYS - 1; i++) {
   263          secp256k1_xonly_pubkey xonly_pk;
   264          memset(tweak[i], i + 1, sizeof(tweak[i]));
   265          CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i]) == 1);
   266          CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &pk[i + 1], &xonly_pk, tweak[i]) == 1);
   267      }
   268  
   269      /* Verify tweaks */
   270      for (i = N_PUBKEYS - 1; i > 0; i--) {
   271          secp256k1_xonly_pubkey xonly_pk;
   272          int pk_parity;
   273          CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk[i]) == 1);
   274          CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk_serialized, &xonly_pk) == 1);
   275          CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i - 1]) == 1);
   276          CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, pk_serialized, pk_parity, &xonly_pk, tweak[i - 1]) == 1);
   277      }
   278  }
   279  #undef N_PUBKEYS
   280  
   281  static void test_keypair(void) {
   282      unsigned char sk[32];
   283      unsigned char sk_tmp[32];
   284      unsigned char zeros96[96] = { 0 };
   285      unsigned char overflows[32];
   286      secp256k1_keypair keypair;
   287      secp256k1_pubkey pk, pk_tmp;
   288      secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
   289      int pk_parity, pk_parity_tmp;
   290  
   291      CHECK(sizeof(zeros96) == sizeof(keypair));
   292      memset(overflows, 0xFF, sizeof(overflows));
   293  
   294      /* Test keypair_create */
   295      testrand256(sk);
   296      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   297      CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
   298      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   299      CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
   300      CHECK_ILLEGAL(CTX, secp256k1_keypair_create(CTX, NULL, sk));
   301      CHECK_ILLEGAL(CTX, secp256k1_keypair_create(CTX, &keypair, NULL));
   302      CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
   303      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   304      CHECK_ILLEGAL(STATIC_CTX, secp256k1_keypair_create(STATIC_CTX, &keypair, sk));
   305      CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
   306  
   307      /* Invalid secret key */
   308      CHECK(secp256k1_keypair_create(CTX, &keypair, zeros96) == 0);
   309      CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
   310      CHECK(secp256k1_keypair_create(CTX, &keypair, overflows) == 0);
   311      CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
   312  
   313      /* Test keypair_pub */
   314      testrand256(sk);
   315      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   316      CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1);
   317      CHECK_ILLEGAL(CTX, secp256k1_keypair_pub(CTX, NULL, &keypair));
   318      CHECK_ILLEGAL(CTX, secp256k1_keypair_pub(CTX, &pk, NULL));
   319      CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
   320  
   321      /* Using an invalid keypair is fine for keypair_pub */
   322      memset(&keypair, 0, sizeof(keypair));
   323      CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1);
   324      CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
   325  
   326      /* keypair holds the same pubkey as pubkey_create */
   327      CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
   328      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   329      CHECK(secp256k1_keypair_pub(CTX, &pk_tmp, &keypair) == 1);
   330      CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
   331  
   332      /** Test keypair_xonly_pub **/
   333      testrand256(sk);
   334      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   335      CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1);
   336      CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, NULL, &pk_parity, &keypair));
   337      CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, NULL, &keypair) == 1);
   338      CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, NULL));
   339      CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
   340      /* Using an invalid keypair will set the xonly_pk to 0 (first reset
   341       * xonly_pk). */
   342      CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1);
   343      memset(&keypair, 0, sizeof(keypair));
   344      CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair));
   345      CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
   346  
   347      /** keypair holds the same xonly pubkey as pubkey_create **/
   348      CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
   349      CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
   350      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   351      CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
   352      CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
   353      CHECK(pk_parity == pk_parity_tmp);
   354  
   355      /* Test keypair_seckey */
   356      testrand256(sk);
   357      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   358      CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
   359      CHECK_ILLEGAL(CTX, secp256k1_keypair_sec(CTX, NULL, &keypair));
   360      CHECK_ILLEGAL(CTX, secp256k1_keypair_sec(CTX, sk_tmp, NULL));
   361      CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
   362  
   363      /* keypair returns the same seckey it got */
   364      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   365      CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
   366      CHECK(secp256k1_memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0);
   367  
   368  
   369      /* Using an invalid keypair is fine for keypair_seckey */
   370      memset(&keypair, 0, sizeof(keypair));
   371      CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
   372      CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
   373  }
   374  
   375  static void test_keypair_add(void) {
   376      unsigned char sk[32];
   377      secp256k1_keypair keypair;
   378      unsigned char overflows[32];
   379      unsigned char zeros96[96] = { 0 };
   380      unsigned char tweak[32];
   381      int i;
   382  
   383      CHECK(sizeof(zeros96) == sizeof(keypair));
   384      testrand256(sk);
   385      testrand256(tweak);
   386      memset(overflows, 0xFF, 32);
   387      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   388  
   389      CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
   390      CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
   391      CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
   392      CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, NULL, tweak));
   393      CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, &keypair, NULL));
   394      /* This does not set the keypair to zeroes */
   395      CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
   396  
   397      /* Invalid tweak zeroes the keypair */
   398      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   399      CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, overflows) == 0);
   400      CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair))  == 0);
   401  
   402      /* A zero tweak is fine */
   403      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   404      CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, zeros96) == 1);
   405  
   406      /* Fails if the resulting keypair was (sk=0, pk=infinity) */
   407      for (i = 0; i < COUNT; i++) {
   408          secp256k1_scalar scalar_tweak;
   409          secp256k1_keypair keypair_tmp;
   410          testrand256(sk);
   411          CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   412          memcpy(&keypair_tmp, &keypair, sizeof(keypair));
   413          /* Because sk may be negated before adding, we need to try with tweak =
   414           * sk as well as tweak = -sk. */
   415          secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
   416          secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
   417          secp256k1_scalar_get_b32(tweak, &scalar_tweak);
   418          CHECK((secp256k1_keypair_xonly_tweak_add(CTX, &keypair, sk) == 0)
   419                || (secp256k1_keypair_xonly_tweak_add(CTX, &keypair_tmp, tweak) == 0));
   420          CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
   421                || secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
   422      }
   423  
   424      /* Invalid keypair with a valid tweak */
   425      memset(&keypair, 0, sizeof(keypair));
   426      testrand256(tweak);
   427      CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak));
   428      CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair))  == 0);
   429      /* Only seckey part of keypair invalid */
   430      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   431      memset(&keypair, 0, 32);
   432      CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak));
   433      /* Only pubkey part of keypair invalid */
   434      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   435      memset(&keypair.data[32], 0, 64);
   436      CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak));
   437  
   438      /* Check that the keypair_tweak_add implementation is correct */
   439      CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
   440      for (i = 0; i < COUNT; i++) {
   441          secp256k1_xonly_pubkey internal_pk;
   442          secp256k1_xonly_pubkey output_pk;
   443          secp256k1_pubkey output_pk_xy;
   444          secp256k1_pubkey output_pk_expected;
   445          unsigned char pk32[32];
   446          unsigned char sk32[32];
   447          int pk_parity;
   448  
   449          testrand256(tweak);
   450          CHECK(secp256k1_keypair_xonly_pub(CTX, &internal_pk, NULL, &keypair) == 1);
   451          CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
   452          CHECK(secp256k1_keypair_xonly_pub(CTX, &output_pk, &pk_parity, &keypair) == 1);
   453  
   454          /* Check that it passes xonly_pubkey_tweak_add_check */
   455          CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk32, &output_pk) == 1);
   456          CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, pk32, pk_parity, &internal_pk, tweak) == 1);
   457  
   458          /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
   459          CHECK(secp256k1_keypair_pub(CTX, &output_pk_xy, &keypair) == 1);
   460          CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk_expected, &internal_pk, tweak) == 1);
   461          CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
   462  
   463          /* Check that the secret key in the keypair is tweaked correctly */
   464          CHECK(secp256k1_keypair_sec(CTX, sk32, &keypair) == 1);
   465          CHECK(secp256k1_ec_pubkey_create(CTX, &output_pk_expected, sk32) == 1);
   466          CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
   467      }
   468  }
   469  
   470  static void run_extrakeys_tests(void) {
   471      /* xonly key test cases */
   472      test_xonly_pubkey();
   473      test_xonly_pubkey_tweak();
   474      test_xonly_pubkey_tweak_check();
   475      test_xonly_pubkey_tweak_recursive();
   476      test_xonly_pubkey_comparison();
   477  
   478      /* keypair tests */
   479      test_keypair();
   480      test_keypair_add();
   481  }
   482  
   483  #endif