csecp256k1

Haskell FFI bindings to bitcoin-core/secp256k1 (docs.ppad.tech/csecp256k1).
git clone git://git.ppad.tech/csecp256k1.git
Log | Files | Refs | README | LICENSE

tests_impl.h (26830B)


      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     haskellsecp256k1_v0_1_0_pubkey pk;
     14     haskellsecp256k1_v0_1_0_xonly_pubkey xonly_pk, xonly_pk_tmp;
     15     haskellsecp256k1_v0_1_0_ge pk1;
     16     haskellsecp256k1_v0_1_0_ge pk2;
     17     haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_testrand256(sk);
     27     memset(ones32, 0xFF, 32);
     28     haskellsecp256k1_v0_1_0_testrand256(xy_sk);
     29     CHECK(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &pk, sk) == 1);
     30     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
     31 
     32     /* Test xonly_pubkey_from_pubkey */
     33     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
     34     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, NULL, &pk_parity, &pk));
     35     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1);
     36     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, NULL));
     37     memset(&pk, 0, sizeof(pk));
     38     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_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(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &pk, sk) == 1);
     44     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
     45     CHECK(haskellsecp256k1_v0_1_0_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(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &pk, sk) == 1);
     52     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
     53     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&xonly_pk, &pk, sizeof(xonly_pk)) != 0);
     54     CHECK(pk_parity == 1);
     55     haskellsecp256k1_v0_1_0_pubkey_load(CTX, &pk1, &pk);
     56     haskellsecp256k1_v0_1_0_pubkey_load(CTX, &pk2, (haskellsecp256k1_v0_1_0_pubkey *) &xonly_pk);
     57     CHECK(haskellsecp256k1_v0_1_0_fe_equal(&pk1.x, &pk2.x) == 1);
     58     haskellsecp256k1_v0_1_0_fe_negate(&y, &pk2.y, 1);
     59     CHECK(haskellsecp256k1_v0_1_0_fe_equal(&pk1.y, &y) == 1);
     60 
     61     /* Test xonly_pubkey_serialize and xonly_pubkey_parse */
     62     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(CTX, NULL, &xonly_pk));
     63     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(CTX, buf32, NULL));
     64     CHECK(haskellsecp256k1_v0_1_0_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         haskellsecp256k1_v0_1_0_xonly_pubkey pk_tmp;
     69         memset(&pk_tmp, 0, sizeof(pk_tmp));
     70         /* pubkey_load calls illegal callback */
     71         CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(CTX, buf32, &pk_tmp));
     72     }
     73 
     74     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1);
     75     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_parse(CTX, NULL, buf32));
     76     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_parse(CTX, &xonly_pk, NULL));
     77 
     78     /* Serialization and parse roundtrip */
     79     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1);
     80     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1);
     81     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_parse(CTX, &xonly_pk_tmp, buf32) == 1);
     82     CHECK(haskellsecp256k1_v0_1_0_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(haskellsecp256k1_v0_1_0_xonly_pubkey_parse(CTX, &xonly_pk, ones32) == 0);
     88     CHECK(haskellsecp256k1_v0_1_0_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(haskellsecp256k1_v0_1_0_xonly_pubkey_parse(CTX, &xonly_pk, zeros64) == 0);
     92     CHECK(haskellsecp256k1_v0_1_0_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         haskellsecp256k1_v0_1_0_testrand256(&rand33[1]);
     99         rand33[0] = SECP256K1_TAG_PUBKEY_EVEN;
    100         if (!haskellsecp256k1_v0_1_0_ec_pubkey_parse(CTX, &pk, rand33, 33)) {
    101             memset(&xonly_pk, 1, sizeof(xonly_pk));
    102             CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 0);
    103             CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
    104         } else {
    105             CHECK(haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_xonly_pubkey pk1;
    120     haskellsecp256k1_v0_1_0_xonly_pubkey pk2;
    121 
    122     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_parse(CTX, &pk1, pk1_ser) == 1);
    123     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_parse(CTX, &pk2, pk2_ser) == 1);
    124 
    125     CHECK_ILLEGAL_VOID(CTX, CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_cmp(CTX, NULL, &pk2) < 0));
    126     CHECK_ILLEGAL_VOID(CTX, CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_cmp(CTX, &pk1, NULL) > 0));
    127     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_cmp(CTX, &pk1, &pk2) < 0);
    128     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_cmp(CTX, &pk2, &pk1) > 0);
    129     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0);
    130     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_cmp(CTX, &pk2, &pk2) == 0);
    131     memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */
    132     CHECK_ILLEGAL_VOID(CTX, CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_cmp(CTX, &pk1, &pk2) < 0));
    133     {
    134         int32_t ecount = 0;
    135         haskellsecp256k1_v0_1_0_context_set_illegal_callback(CTX, counting_callback_fn, &ecount);
    136         CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0);
    137         CHECK(ecount == 2);
    138         haskellsecp256k1_v0_1_0_context_set_illegal_callback(CTX, NULL, NULL);
    139     }
    140     CHECK_ILLEGAL_VOID(CTX, CHECK(haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_pubkey internal_pk;
    148     haskellsecp256k1_v0_1_0_xonly_pubkey internal_xonly_pk;
    149     haskellsecp256k1_v0_1_0_pubkey output_pk;
    150     int pk_parity;
    151     unsigned char tweak[32];
    152     int i;
    153 
    154     memset(overflows, 0xff, sizeof(overflows));
    155     haskellsecp256k1_v0_1_0_testrand256(tweak);
    156     haskellsecp256k1_v0_1_0_testrand256(sk);
    157     CHECK(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &internal_pk, sk) == 1);
    158     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
    159 
    160     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
    161     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
    162     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
    163     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, NULL, &internal_xonly_pk, tweak));
    164     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, NULL, tweak));
    165     /* NULL internal_xonly_pk zeroes the output_pk */
    166     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
    167     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, NULL));
    168     /* NULL tweak zeroes the output_pk */
    169     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
    170 
    171     /* Invalid tweak zeroes the output_pk */
    172     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0);
    173     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&output_pk, zeros64, sizeof(output_pk))  == 0);
    174 
    175     /* A zero tweak is fine */
    176     CHECK(haskellsecp256k1_v0_1_0_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         haskellsecp256k1_v0_1_0_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         haskellsecp256k1_v0_1_0_scalar_set_b32(&scalar_tweak, sk, NULL);
    184         haskellsecp256k1_v0_1_0_scalar_negate(&scalar_tweak, &scalar_tweak);
    185         haskellsecp256k1_v0_1_0_scalar_get_b32(tweak, &scalar_tweak);
    186         CHECK((haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, sk) == 0)
    187               || (haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 0));
    188         CHECK(haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_testrand256(tweak);
    194     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak));
    195     CHECK(haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_pubkey internal_pk;
    203     haskellsecp256k1_v0_1_0_xonly_pubkey internal_xonly_pk;
    204     haskellsecp256k1_v0_1_0_pubkey output_pk;
    205     haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_testrand256(tweak);
    213     haskellsecp256k1_v0_1_0_testrand256(sk);
    214     CHECK(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &internal_pk, sk) == 1);
    215     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
    216 
    217     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
    218     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1);
    219     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(CTX, buf32, &output_xonly_pk) == 1);
    220     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
    221     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
    222     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
    223     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, NULL, pk_parity, &internal_xonly_pk, tweak));
    224     /* invalid pk_parity value */
    225     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, buf32, 2, &internal_xonly_pk, tweak) == 0);
    226     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, NULL, tweak));
    227     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, NULL));
    228 
    229     memset(tweak, 1, sizeof(tweak));
    230     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, NULL, &internal_pk) == 1);
    231     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
    232     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1);
    233     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(CTX, output_pk32, &output_xonly_pk) == 1);
    234     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, tweak) == 1);
    235 
    236     /* Wrong pk_parity */
    237     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, output_pk32, !pk_parity, &internal_xonly_pk, tweak) == 0);
    238     /* Wrong public key */
    239     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(CTX, buf32, &internal_xonly_pk) == 1);
    240     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
    241 
    242     /* Overflowing tweak not allowed */
    243     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0);
    244     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0);
    245     CHECK(haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_pubkey pk[N_PUBKEYS];
    255     unsigned char pk_serialized[32];
    256     unsigned char tweak[N_PUBKEYS - 1][32];
    257     int i;
    258 
    259     haskellsecp256k1_v0_1_0_testrand256(sk);
    260     CHECK(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &pk[0], sk) == 1);
    261     /* Add tweaks */
    262     for (i = 0; i < N_PUBKEYS - 1; i++) {
    263         haskellsecp256k1_v0_1_0_xonly_pubkey xonly_pk;
    264         memset(tweak[i], i + 1, sizeof(tweak[i]));
    265         CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i]) == 1);
    266         CHECK(haskellsecp256k1_v0_1_0_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         haskellsecp256k1_v0_1_0_xonly_pubkey xonly_pk;
    272         int pk_parity;
    273         CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk[i]) == 1);
    274         CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(CTX, pk_serialized, &xonly_pk) == 1);
    275         CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i - 1]) == 1);
    276         CHECK(haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_keypair keypair;
    287     haskellsecp256k1_v0_1_0_pubkey pk, pk_tmp;
    288     haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_testrand256(sk);
    296     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    297     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
    298     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    299     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
    300     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_create(CTX, NULL, sk));
    301     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, NULL));
    302     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
    303     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    304     CHECK_ILLEGAL(STATIC_CTX, haskellsecp256k1_v0_1_0_keypair_create(STATIC_CTX, &keypair, sk));
    305     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
    306 
    307     /* Invalid secret key */
    308     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, zeros96) == 0);
    309     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
    310     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, overflows) == 0);
    311     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
    312 
    313     /* Test keypair_pub */
    314     haskellsecp256k1_v0_1_0_testrand256(sk);
    315     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    316     CHECK(haskellsecp256k1_v0_1_0_keypair_pub(CTX, &pk, &keypair) == 1);
    317     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_pub(CTX, NULL, &keypair));
    318     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_pub(CTX, &pk, NULL));
    319     CHECK(haskellsecp256k1_v0_1_0_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(haskellsecp256k1_v0_1_0_keypair_pub(CTX, &pk, &keypair) == 1);
    324     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
    325 
    326     /* keypair holds the same pubkey as pubkey_create */
    327     CHECK(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &pk, sk) == 1);
    328     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    329     CHECK(haskellsecp256k1_v0_1_0_keypair_pub(CTX, &pk_tmp, &keypair) == 1);
    330     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
    331 
    332     /** Test keypair_xonly_pub **/
    333     haskellsecp256k1_v0_1_0_testrand256(sk);
    334     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    335     CHECK(haskellsecp256k1_v0_1_0_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1);
    336     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_xonly_pub(CTX, NULL, &pk_parity, &keypair));
    337     CHECK(haskellsecp256k1_v0_1_0_keypair_xonly_pub(CTX, &xonly_pk, NULL, &keypair) == 1);
    338     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, NULL));
    339     CHECK(haskellsecp256k1_v0_1_0_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(haskellsecp256k1_v0_1_0_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1);
    343     memset(&keypair, 0, sizeof(keypair));
    344     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair));
    345     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
    346 
    347     /** keypair holds the same xonly pubkey as pubkey_create **/
    348     CHECK(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &pk, sk) == 1);
    349     CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
    350     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    351     CHECK(haskellsecp256k1_v0_1_0_keypair_xonly_pub(CTX, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
    352     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
    353     CHECK(pk_parity == pk_parity_tmp);
    354 
    355     /* Test keypair_seckey */
    356     haskellsecp256k1_v0_1_0_testrand256(sk);
    357     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    358     CHECK(haskellsecp256k1_v0_1_0_keypair_sec(CTX, sk_tmp, &keypair) == 1);
    359     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_sec(CTX, NULL, &keypair));
    360     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_sec(CTX, sk_tmp, NULL));
    361     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
    362 
    363     /* keypair returns the same seckey it got */
    364     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    365     CHECK(haskellsecp256k1_v0_1_0_keypair_sec(CTX, sk_tmp, &keypair) == 1);
    366     CHECK(haskellsecp256k1_v0_1_0_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(haskellsecp256k1_v0_1_0_keypair_sec(CTX, sk_tmp, &keypair) == 1);
    372     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
    373 }
    374 
    375 static void test_keypair_add(void) {
    376     unsigned char sk[32];
    377     haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_testrand256(sk);
    385     haskellsecp256k1_v0_1_0_testrand256(tweak);
    386     memset(overflows, 0xFF, 32);
    387     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    388 
    389     CHECK(haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
    390     CHECK(haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
    391     CHECK(haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
    392     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, NULL, tweak));
    393     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair, NULL));
    394     /* This does not set the keypair to zeroes */
    395     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
    396 
    397     /* Invalid tweak zeroes the keypair */
    398     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    399     CHECK(haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair, overflows) == 0);
    400     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&keypair, zeros96, sizeof(keypair))  == 0);
    401 
    402     /* A zero tweak is fine */
    403     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    404     CHECK(haskellsecp256k1_v0_1_0_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         haskellsecp256k1_v0_1_0_scalar scalar_tweak;
    409         haskellsecp256k1_v0_1_0_keypair keypair_tmp;
    410         haskellsecp256k1_v0_1_0_testrand256(sk);
    411         CHECK(haskellsecp256k1_v0_1_0_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         haskellsecp256k1_v0_1_0_scalar_set_b32(&scalar_tweak, sk, NULL);
    416         haskellsecp256k1_v0_1_0_scalar_negate(&scalar_tweak, &scalar_tweak);
    417         haskellsecp256k1_v0_1_0_scalar_get_b32(tweak, &scalar_tweak);
    418         CHECK((haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair, sk) == 0)
    419               || (haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair_tmp, tweak) == 0));
    420         CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
    421               || haskellsecp256k1_v0_1_0_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     haskellsecp256k1_v0_1_0_testrand256(tweak);
    427     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair, tweak));
    428     CHECK(haskellsecp256k1_v0_1_0_memcmp_var(&keypair, zeros96, sizeof(keypair))  == 0);
    429     /* Only seckey part of keypair invalid */
    430     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    431     memset(&keypair, 0, 32);
    432     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair, tweak));
    433     /* Only pubkey part of keypair invalid */
    434     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    435     memset(&keypair.data[32], 0, 64);
    436     CHECK_ILLEGAL(CTX, haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair, tweak));
    437 
    438     /* Check that the keypair_tweak_add implementation is correct */
    439     CHECK(haskellsecp256k1_v0_1_0_keypair_create(CTX, &keypair, sk) == 1);
    440     for (i = 0; i < COUNT; i++) {
    441         haskellsecp256k1_v0_1_0_xonly_pubkey internal_pk;
    442         haskellsecp256k1_v0_1_0_xonly_pubkey output_pk;
    443         haskellsecp256k1_v0_1_0_pubkey output_pk_xy;
    444         haskellsecp256k1_v0_1_0_pubkey output_pk_expected;
    445         unsigned char pk32[32];
    446         unsigned char sk32[32];
    447         int pk_parity;
    448 
    449         haskellsecp256k1_v0_1_0_testrand256(tweak);
    450         CHECK(haskellsecp256k1_v0_1_0_keypair_xonly_pub(CTX, &internal_pk, NULL, &keypair) == 1);
    451         CHECK(haskellsecp256k1_v0_1_0_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
    452         CHECK(haskellsecp256k1_v0_1_0_keypair_xonly_pub(CTX, &output_pk, &pk_parity, &keypair) == 1);
    453 
    454         /* Check that it passes xonly_pubkey_tweak_add_check */
    455         CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_serialize(CTX, pk32, &output_pk) == 1);
    456         CHECK(haskellsecp256k1_v0_1_0_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(haskellsecp256k1_v0_1_0_keypair_pub(CTX, &output_pk_xy, &keypair) == 1);
    460         CHECK(haskellsecp256k1_v0_1_0_xonly_pubkey_tweak_add(CTX, &output_pk_expected, &internal_pk, tweak) == 1);
    461         CHECK(haskellsecp256k1_v0_1_0_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(haskellsecp256k1_v0_1_0_keypair_sec(CTX, sk32, &keypair) == 1);
    465         CHECK(haskellsecp256k1_v0_1_0_ec_pubkey_create(CTX, &output_pk_expected, sk32) == 1);
    466         CHECK(haskellsecp256k1_v0_1_0_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