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