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 ***********************************************************************/
7 #ifndef SECP256K1_MODULE_EXTRAKEYS_TESTS_H
8 #define SECP256K1_MODULE_EXTRAKEYS_TESTS_H
10 #include "secp256k1_extrakeys.h"
12 static secp256k1_context* api_test_context(int flags, int *ecount) {
13 secp256k1_context *ctx0 = secp256k1_context_create(flags);
14 secp256k1_context_set_error_callback(ctx0, counting_illegal_callback_fn, ecount);
15 secp256k1_context_set_illegal_callback(ctx0, counting_illegal_callback_fn, ecount);
19 void test_xonly_pubkey(void) {
21 secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
26 unsigned char xy_sk[32];
27 unsigned char buf32[32];
28 unsigned char ones32[32];
29 unsigned char zeros64[64] = { 0 };
34 secp256k1_context *none = api_test_context(SECP256K1_CONTEXT_NONE, &ecount);
35 secp256k1_context *sign = api_test_context(SECP256K1_CONTEXT_SIGN, &ecount);
36 secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount);
38 secp256k1_testrand256(sk);
39 memset(ones32, 0xFF, 32);
40 secp256k1_testrand256(xy_sk);
41 CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
42 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
44 /* Test xonly_pubkey_from_pubkey */
46 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
47 CHECK(secp256k1_xonly_pubkey_from_pubkey(sign, &xonly_pk, &pk_parity, &pk) == 1);
48 CHECK(secp256k1_xonly_pubkey_from_pubkey(verify, &xonly_pk, &pk_parity, &pk) == 1);
49 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, NULL, &pk_parity, &pk) == 0);
51 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, NULL, &pk) == 1);
52 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, NULL) == 0);
54 memset(&pk, 0, sizeof(pk));
55 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 0);
58 /* Choose a secret key such that the resulting pubkey and xonly_pubkey match. */
59 memset(sk, 0, sizeof(sk));
61 CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
62 CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk) == 1);
63 CHECK(secp256k1_memcmp_var(&pk, &xonly_pk, sizeof(pk)) == 0);
64 CHECK(pk_parity == 0);
66 /* Choose a secret key such that pubkey and xonly_pubkey are each others
69 CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
70 CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk) == 1);
71 CHECK(secp256k1_memcmp_var(&xonly_pk, &pk, sizeof(xonly_pk)) != 0);
72 CHECK(pk_parity == 1);
73 secp256k1_pubkey_load(ctx, &pk1, &pk);
74 secp256k1_pubkey_load(ctx, &pk2, (secp256k1_pubkey *) &xonly_pk);
75 CHECK(secp256k1_fe_equal(&pk1.x, &pk2.x) == 1);
76 secp256k1_fe_negate(&y, &pk2.y, 1);
77 CHECK(secp256k1_fe_equal(&pk1.y, &y) == 1);
79 /* Test xonly_pubkey_serialize and xonly_pubkey_parse */
81 CHECK(secp256k1_xonly_pubkey_serialize(none, NULL, &xonly_pk) == 0);
83 CHECK(secp256k1_xonly_pubkey_serialize(none, buf32, NULL) == 0);
84 CHECK(secp256k1_memcmp_var(buf32, zeros64, 32) == 0);
87 /* A pubkey filled with 0s will fail to serialize due to pubkey_load
89 secp256k1_xonly_pubkey pk_tmp;
90 memset(&pk_tmp, 0, sizeof(pk_tmp));
91 CHECK(secp256k1_xonly_pubkey_serialize(none, buf32, &pk_tmp) == 0);
93 /* pubkey_load called illegal callback */
96 CHECK(secp256k1_xonly_pubkey_serialize(none, buf32, &xonly_pk) == 1);
98 CHECK(secp256k1_xonly_pubkey_parse(none, NULL, buf32) == 0);
100 CHECK(secp256k1_xonly_pubkey_parse(none, &xonly_pk, NULL) == 0);
103 /* Serialization and parse roundtrip */
104 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, NULL, &pk) == 1);
105 CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf32, &xonly_pk) == 1);
106 CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pk_tmp, buf32) == 1);
107 CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(xonly_pk)) == 0);
109 /* Test parsing invalid field elements */
110 memset(&xonly_pk, 1, sizeof(xonly_pk));
111 /* Overflowing field element */
112 CHECK(secp256k1_xonly_pubkey_parse(none, &xonly_pk, ones32) == 0);
113 CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
114 memset(&xonly_pk, 1, sizeof(xonly_pk));
115 /* There's no point with x-coordinate 0 on secp256k1 */
116 CHECK(secp256k1_xonly_pubkey_parse(none, &xonly_pk, zeros64) == 0);
117 CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
118 /* If a random 32-byte string can not be parsed with ec_pubkey_parse
119 * (because interpreted as X coordinate it does not correspond to a point on
120 * the curve) then xonly_pubkey_parse should fail as well. */
121 for (i = 0; i < count; i++) {
122 unsigned char rand33[33];
123 secp256k1_testrand256(&rand33[1]);
124 rand33[0] = SECP256K1_TAG_PUBKEY_EVEN;
125 if (!secp256k1_ec_pubkey_parse(ctx, &pk, rand33, 33)) {
126 memset(&xonly_pk, 1, sizeof(xonly_pk));
127 CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pk, &rand33[1]) == 0);
128 CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
130 CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pk, &rand33[1]) == 1);
135 secp256k1_context_destroy(none);
136 secp256k1_context_destroy(sign);
137 secp256k1_context_destroy(verify);
140 void test_xonly_pubkey_comparison(void) {
141 unsigned char pk1_ser[32] = {
142 0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
143 0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
145 const unsigned char pk2_ser[32] = {
146 0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
147 0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
149 secp256k1_xonly_pubkey pk1;
150 secp256k1_xonly_pubkey pk2;
152 secp256k1_context *none = api_test_context(SECP256K1_CONTEXT_NONE, &ecount);
154 CHECK(secp256k1_xonly_pubkey_parse(none, &pk1, pk1_ser) == 1);
155 CHECK(secp256k1_xonly_pubkey_parse(none, &pk2, pk2_ser) == 1);
157 CHECK(secp256k1_xonly_pubkey_cmp(none, NULL, &pk2) < 0);
159 CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, NULL) > 0);
161 CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk2) < 0);
162 CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk1) > 0);
163 CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk1) == 0);
164 CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk2) == 0);
166 memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */
167 CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk2) < 0);
169 CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk1) == 0);
171 CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk1) > 0);
174 secp256k1_context_destroy(none);
177 void test_xonly_pubkey_tweak(void) {
178 unsigned char zeros64[64] = { 0 };
179 unsigned char overflows[32];
180 unsigned char sk[32];
181 secp256k1_pubkey internal_pk;
182 secp256k1_xonly_pubkey internal_xonly_pk;
183 secp256k1_pubkey output_pk;
185 unsigned char tweak[32];
189 secp256k1_context *none = api_test_context(SECP256K1_CONTEXT_NONE, &ecount);
190 secp256k1_context *sign = api_test_context(SECP256K1_CONTEXT_SIGN, &ecount);
191 secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount);
193 memset(overflows, 0xff, sizeof(overflows));
194 secp256k1_testrand256(tweak);
195 secp256k1_testrand256(sk);
196 CHECK(secp256k1_ec_pubkey_create(ctx, &internal_pk, sk) == 1);
197 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
200 CHECK(secp256k1_xonly_pubkey_tweak_add(none, &output_pk, &internal_xonly_pk, tweak) == 0);
202 CHECK(secp256k1_xonly_pubkey_tweak_add(sign, &output_pk, &internal_xonly_pk, tweak) == 0);
204 CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 1);
205 CHECK(secp256k1_xonly_pubkey_tweak_add(verify, NULL, &internal_xonly_pk, tweak) == 0);
207 CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, NULL, tweak) == 0);
209 /* NULL internal_xonly_pk zeroes the output_pk */
210 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
211 CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, NULL) == 0);
213 /* NULL tweak zeroes the output_pk */
214 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
216 /* Invalid tweak zeroes the output_pk */
217 CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, overflows) == 0);
218 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
220 /* A zero tweak is fine */
221 CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, zeros64) == 1);
223 /* Fails if the resulting key was infinity */
224 for (i = 0; i < count; i++) {
225 secp256k1_scalar scalar_tweak;
226 /* Because sk may be negated before adding, we need to try with tweak =
227 * sk as well as tweak = -sk. */
228 secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
229 secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
230 secp256k1_scalar_get_b32(tweak, &scalar_tweak);
231 CHECK((secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, sk) == 0)
232 || (secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 0));
233 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
236 /* Invalid pk with a valid tweak */
237 memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk));
238 secp256k1_testrand256(tweak);
240 CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 0);
242 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
244 secp256k1_context_destroy(none);
245 secp256k1_context_destroy(sign);
246 secp256k1_context_destroy(verify);
249 void test_xonly_pubkey_tweak_check(void) {
250 unsigned char zeros64[64] = { 0 };
251 unsigned char overflows[32];
252 unsigned char sk[32];
253 secp256k1_pubkey internal_pk;
254 secp256k1_xonly_pubkey internal_xonly_pk;
255 secp256k1_pubkey output_pk;
256 secp256k1_xonly_pubkey output_xonly_pk;
257 unsigned char output_pk32[32];
258 unsigned char buf32[32];
260 unsigned char tweak[32];
263 secp256k1_context *none = api_test_context(SECP256K1_CONTEXT_NONE, &ecount);
264 secp256k1_context *sign = api_test_context(SECP256K1_CONTEXT_SIGN, &ecount);
265 secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount);
267 memset(overflows, 0xff, sizeof(overflows));
268 secp256k1_testrand256(tweak);
269 secp256k1_testrand256(sk);
270 CHECK(secp256k1_ec_pubkey_create(ctx, &internal_pk, sk) == 1);
271 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
274 CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 1);
275 CHECK(secp256k1_xonly_pubkey_from_pubkey(verify, &output_xonly_pk, &pk_parity, &output_pk) == 1);
276 CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf32, &output_xonly_pk) == 1);
277 CHECK(secp256k1_xonly_pubkey_tweak_add_check(none, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
279 CHECK(secp256k1_xonly_pubkey_tweak_add_check(sign, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
281 CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
282 CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, NULL, pk_parity, &internal_xonly_pk, tweak) == 0);
284 /* invalid pk_parity value */
285 CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, 2, &internal_xonly_pk, tweak) == 0);
287 CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, NULL, tweak) == 0);
289 CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, &internal_xonly_pk, NULL) == 0);
292 memset(tweak, 1, sizeof(tweak));
293 CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &internal_xonly_pk, NULL, &internal_pk) == 1);
294 CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk, &internal_xonly_pk, tweak) == 1);
295 CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &output_xonly_pk, &pk_parity, &output_pk) == 1);
296 CHECK(secp256k1_xonly_pubkey_serialize(ctx, output_pk32, &output_xonly_pk) == 1);
297 CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, output_pk32, pk_parity, &internal_xonly_pk, tweak) == 1);
299 /* Wrong pk_parity */
300 CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, output_pk32, !pk_parity, &internal_xonly_pk, tweak) == 0);
301 /* Wrong public key */
302 CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf32, &internal_xonly_pk) == 1);
303 CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
305 /* Overflowing tweak not allowed */
306 CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0);
307 CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk, &internal_xonly_pk, overflows) == 0);
308 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
311 secp256k1_context_destroy(none);
312 secp256k1_context_destroy(sign);
313 secp256k1_context_destroy(verify);
316 /* Starts with an initial pubkey and recursively creates N_PUBKEYS - 1
317 * additional pubkeys by calling tweak_add. Then verifies every tweak starting
318 * from the last pubkey. */
320 void test_xonly_pubkey_tweak_recursive(void) {
321 unsigned char sk[32];
322 secp256k1_pubkey pk[N_PUBKEYS];
323 unsigned char pk_serialized[32];
324 unsigned char tweak[N_PUBKEYS - 1][32];
327 secp256k1_testrand256(sk);
328 CHECK(secp256k1_ec_pubkey_create(ctx, &pk[0], sk) == 1);
330 for (i = 0; i < N_PUBKEYS - 1; i++) {
331 secp256k1_xonly_pubkey xonly_pk;
332 memset(tweak[i], i + 1, sizeof(tweak[i]));
333 CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, NULL, &pk[i]) == 1);
334 CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &pk[i + 1], &xonly_pk, tweak[i]) == 1);
338 for (i = N_PUBKEYS - 1; i > 0; i--) {
339 secp256k1_xonly_pubkey xonly_pk;
341 CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk[i]) == 1);
342 CHECK(secp256k1_xonly_pubkey_serialize(ctx, pk_serialized, &xonly_pk) == 1);
343 CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, NULL, &pk[i - 1]) == 1);
344 CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, pk_serialized, pk_parity, &xonly_pk, tweak[i - 1]) == 1);
349 void test_keypair(void) {
350 unsigned char sk[32];
351 unsigned char sk_tmp[32];
352 unsigned char zeros96[96] = { 0 };
353 unsigned char overflows[32];
354 secp256k1_keypair keypair;
355 secp256k1_pubkey pk, pk_tmp;
356 secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
357 int pk_parity, pk_parity_tmp;
359 secp256k1_context *none = api_test_context(SECP256K1_CONTEXT_NONE, &ecount);
360 secp256k1_context *sign = api_test_context(SECP256K1_CONTEXT_SIGN, &ecount);
361 secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount);
363 CHECK(sizeof(zeros96) == sizeof(keypair));
364 memset(overflows, 0xFF, sizeof(overflows));
366 /* Test keypair_create */
368 secp256k1_testrand256(sk);
369 CHECK(secp256k1_keypair_create(none, &keypair, sk) == 0);
370 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
372 CHECK(secp256k1_keypair_create(verify, &keypair, sk) == 0);
373 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
375 CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
376 CHECK(secp256k1_keypair_create(sign, NULL, sk) == 0);
378 CHECK(secp256k1_keypair_create(sign, &keypair, NULL) == 0);
379 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
382 /* Invalid secret key */
383 CHECK(secp256k1_keypair_create(sign, &keypair, zeros96) == 0);
384 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
385 CHECK(secp256k1_keypair_create(sign, &keypair, overflows) == 0);
386 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
388 /* Test keypair_pub */
390 secp256k1_testrand256(sk);
391 CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
392 CHECK(secp256k1_keypair_pub(none, &pk, &keypair) == 1);
393 CHECK(secp256k1_keypair_pub(none, NULL, &keypair) == 0);
395 CHECK(secp256k1_keypair_pub(none, &pk, NULL) == 0);
397 CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
399 /* Using an invalid keypair is fine for keypair_pub */
400 memset(&keypair, 0, sizeof(keypair));
401 CHECK(secp256k1_keypair_pub(none, &pk, &keypair) == 1);
402 CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
404 /* keypair holds the same pubkey as pubkey_create */
405 CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
406 CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
407 CHECK(secp256k1_keypair_pub(none, &pk_tmp, &keypair) == 1);
408 CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
410 /** Test keypair_xonly_pub **/
412 secp256k1_testrand256(sk);
413 CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
414 CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
415 CHECK(secp256k1_keypair_xonly_pub(none, NULL, &pk_parity, &keypair) == 0);
417 CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, NULL, &keypair) == 1);
418 CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, NULL) == 0);
420 CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
421 /* Using an invalid keypair will set the xonly_pk to 0 (first reset
423 CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
424 memset(&keypair, 0, sizeof(keypair));
425 CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 0);
426 CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
429 /** keypair holds the same xonly pubkey as pubkey_create **/
430 CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
431 CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
432 CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
433 CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
434 CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
435 CHECK(pk_parity == pk_parity_tmp);
437 /* Test keypair_seckey */
439 secp256k1_testrand256(sk);
440 CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
441 CHECK(secp256k1_keypair_sec(none, sk_tmp, &keypair) == 1);
442 CHECK(secp256k1_keypair_sec(none, NULL, &keypair) == 0);
444 CHECK(secp256k1_keypair_sec(none, sk_tmp, NULL) == 0);
446 CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
448 /* keypair returns the same seckey it got */
449 CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
450 CHECK(secp256k1_keypair_sec(none, sk_tmp, &keypair) == 1);
451 CHECK(secp256k1_memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0);
454 /* Using an invalid keypair is fine for keypair_seckey */
455 memset(&keypair, 0, sizeof(keypair));
456 CHECK(secp256k1_keypair_sec(none, sk_tmp, &keypair) == 1);
457 CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
459 secp256k1_context_destroy(none);
460 secp256k1_context_destroy(sign);
461 secp256k1_context_destroy(verify);
464 void test_keypair_add(void) {
465 unsigned char sk[32];
466 secp256k1_keypair keypair;
467 unsigned char overflows[32];
468 unsigned char zeros96[96] = { 0 };
469 unsigned char tweak[32];
472 secp256k1_context *none = api_test_context(SECP256K1_CONTEXT_NONE, &ecount);
473 secp256k1_context *sign = api_test_context(SECP256K1_CONTEXT_SIGN, &ecount);
474 secp256k1_context *verify = api_test_context(SECP256K1_CONTEXT_VERIFY, &ecount);
476 CHECK(sizeof(zeros96) == sizeof(keypair));
477 secp256k1_testrand256(sk);
478 secp256k1_testrand256(tweak);
479 memset(overflows, 0xFF, 32);
480 CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
482 CHECK(secp256k1_keypair_xonly_tweak_add(none, &keypair, tweak) == 0);
484 CHECK(secp256k1_keypair_xonly_tweak_add(sign, &keypair, tweak) == 0);
486 CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 1);
487 CHECK(secp256k1_keypair_xonly_tweak_add(verify, NULL, tweak) == 0);
489 CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, NULL) == 0);
491 /* This does not set the keypair to zeroes */
492 CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
494 /* Invalid tweak zeroes the keypair */
495 CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
496 CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, overflows) == 0);
497 CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
499 /* A zero tweak is fine */
500 CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
501 CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, zeros96) == 1);
503 /* Fails if the resulting keypair was (sk=0, pk=infinity) */
504 for (i = 0; i < count; i++) {
505 secp256k1_scalar scalar_tweak;
506 secp256k1_keypair keypair_tmp;
507 secp256k1_testrand256(sk);
508 CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
509 memcpy(&keypair_tmp, &keypair, sizeof(keypair));
510 /* Because sk may be negated before adding, we need to try with tweak =
511 * sk as well as tweak = -sk. */
512 secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
513 secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
514 secp256k1_scalar_get_b32(tweak, &scalar_tweak);
515 CHECK((secp256k1_keypair_xonly_tweak_add(ctx, &keypair, sk) == 0)
516 || (secp256k1_keypair_xonly_tweak_add(ctx, &keypair_tmp, tweak) == 0));
517 CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
518 || secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
521 /* Invalid keypair with a valid tweak */
522 memset(&keypair, 0, sizeof(keypair));
523 secp256k1_testrand256(tweak);
525 CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
527 CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
528 /* Only seckey part of keypair invalid */
529 CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
530 memset(&keypair, 0, 32);
531 CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
533 /* Only pubkey part of keypair invalid */
534 CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
535 memset(&keypair.data[32], 0, 64);
536 CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
539 /* Check that the keypair_tweak_add implementation is correct */
540 CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
541 for (i = 0; i < count; i++) {
542 secp256k1_xonly_pubkey internal_pk;
543 secp256k1_xonly_pubkey output_pk;
544 secp256k1_pubkey output_pk_xy;
545 secp256k1_pubkey output_pk_expected;
546 unsigned char pk32[32];
547 unsigned char sk32[32];
550 secp256k1_testrand256(tweak);
551 CHECK(secp256k1_keypair_xonly_pub(ctx, &internal_pk, NULL, &keypair) == 1);
552 CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 1);
553 CHECK(secp256k1_keypair_xonly_pub(ctx, &output_pk, &pk_parity, &keypair) == 1);
555 /* Check that it passes xonly_pubkey_tweak_add_check */
556 CHECK(secp256k1_xonly_pubkey_serialize(ctx, pk32, &output_pk) == 1);
557 CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, pk32, pk_parity, &internal_pk, tweak) == 1);
559 /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
560 CHECK(secp256k1_keypair_pub(ctx, &output_pk_xy, &keypair) == 1);
561 CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk_expected, &internal_pk, tweak) == 1);
562 CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
564 /* Check that the secret key in the keypair is tweaked correctly */
565 CHECK(secp256k1_keypair_sec(none, sk32, &keypair) == 1);
566 CHECK(secp256k1_ec_pubkey_create(ctx, &output_pk_expected, sk32) == 1);
567 CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
569 secp256k1_context_destroy(none);
570 secp256k1_context_destroy(sign);
571 secp256k1_context_destroy(verify);
574 void run_extrakeys_tests(void) {
575 /* xonly key test cases */
577 test_xonly_pubkey_tweak();
578 test_xonly_pubkey_tweak_check();
579 test_xonly_pubkey_tweak_recursive();
580 test_xonly_pubkey_comparison();