Bitcoin Core 30.99.0
P2P Digital Currency
tests_impl.h
Go to the documentation of this file.
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#include "../../unit_test.h"
12
13static void test_xonly_pubkey(void) {
15 secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
16 secp256k1_ge pk1;
17 secp256k1_ge pk2;
19 unsigned char sk[32];
20 unsigned char xy_sk[32];
21 unsigned char buf32[32];
22 unsigned char ones32[32];
23 unsigned char zeros64[64] = { 0 };
24 int pk_parity;
25 int i;
26
28 memset(ones32, 0xFF, 32);
29 testrand256(xy_sk);
31 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
32
33 /* Test xonly_pubkey_from_pubkey */
34 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
36 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1);
37 CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, NULL));
38 memset(&pk, 0, sizeof(pk));
39 CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk));
40
41 /* Choose a secret key such that the resulting pubkey and xonly_pubkey match. */
42 memset(sk, 0, sizeof(sk));
43 sk[0] = 1;
45 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
46 CHECK(secp256k1_memcmp_var(&pk, &xonly_pk, sizeof(pk)) == 0);
47 CHECK(pk_parity == 0);
48
49 /* Choose a secret key such that pubkey and xonly_pubkey are each others
50 * negation. */
51 sk[0] = 2;
53 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
54 CHECK(secp256k1_memcmp_var(&xonly_pk, &pk, sizeof(xonly_pk)) != 0);
55 CHECK(pk_parity == 1);
57 secp256k1_pubkey_load(CTX, &pk2, (secp256k1_pubkey *) &xonly_pk);
58 CHECK(secp256k1_fe_equal(&pk1.x, &pk2.x) == 1);
59 secp256k1_fe_negate(&y, &pk2.y, 1);
60 CHECK(secp256k1_fe_equal(&pk1.y, &y) == 1);
61
62 /* Test xonly_pubkey_serialize and xonly_pubkey_parse */
65 CHECK(secp256k1_memcmp_var(buf32, zeros64, 32) == 0);
66 {
67 /* A pubkey filled with 0s will fail to serialize due to pubkey_load
68 * special casing. */
70 memset(&pk_tmp, 0, sizeof(pk_tmp));
71 /* pubkey_load calls illegal callback */
73 }
74
75 CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1);
78
79 /* Serialization and parse roundtrip */
80 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1);
81 CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1);
82 CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk_tmp, buf32) == 1);
83 CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(xonly_pk)) == 0);
84
85 /* Test parsing invalid field elements */
86 memset(&xonly_pk, 1, sizeof(xonly_pk));
87 /* Overflowing field element */
88 CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, ones32) == 0);
89 CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
90 memset(&xonly_pk, 1, sizeof(xonly_pk));
91 /* There's no point with x-coordinate 0 on secp256k1 */
92 CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, zeros64) == 0);
93 CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
94 /* If a random 32-byte string can not be parsed with ec_pubkey_parse
95 * (because interpreted as X coordinate it does not correspond to a point on
96 * the curve) then xonly_pubkey_parse should fail as well. */
97 for (i = 0; i < COUNT; i++) {
98 unsigned char rand33[33];
99 testrand256(&rand33[1]);
100 rand33[0] = SECP256K1_TAG_PUBKEY_EVEN;
101 if (!secp256k1_ec_pubkey_parse(CTX, &pk, rand33, 33)) {
102 memset(&xonly_pk, 1, sizeof(xonly_pk));
103 CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 0);
104 CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
105 } else {
106 CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 1);
107 }
108 }
109}
110
112 unsigned char pk1_ser[32] = {
113 0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
114 0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
115 };
116 const unsigned char pk2_ser[32] = {
117 0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
118 0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
119 };
122
123 CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk1, pk1_ser) == 1);
124 CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk2, pk2_ser) == 1);
125
128 CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk2) < 0);
129 CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk1) > 0);
130 CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0);
131 CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk2) == 0);
132 memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */
134 {
135 int32_t ecount = 0;
137 CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0);
138 CHECK(ecount == 2);
140 }
142}
143
144static void test_xonly_pubkey_tweak(void) {
145 unsigned char zeros64[64] = { 0 };
146 unsigned char overflows[32];
147 unsigned char sk[32];
148 secp256k1_pubkey internal_pk;
149 secp256k1_xonly_pubkey internal_xonly_pk;
150 secp256k1_pubkey output_pk;
151 int pk_parity;
152 unsigned char tweak[32];
153 int i;
154
155 memset(overflows, 0xff, sizeof(overflows));
158 CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1);
159 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
160
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(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
164 CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, NULL, &internal_xonly_pk, tweak));
166 /* NULL internal_xonly_pk zeroes the output_pk */
167 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
168 CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, NULL));
169 /* NULL tweak zeroes the output_pk */
170 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
171
172 /* Invalid tweak zeroes the output_pk */
173 CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0);
174 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
175
176 /* A zero tweak is fine */
177 CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, zeros64) == 1);
178
179 /* Fails if the resulting key was infinity */
180 for (i = 0; i < COUNT; i++) {
181 secp256k1_scalar scalar_tweak;
182 /* Because sk may be negated before adding, we need to try with tweak =
183 * sk as well as tweak = -sk. */
184 secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
185 secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
186 secp256k1_scalar_get_b32(tweak, &scalar_tweak);
187 CHECK((secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, sk) == 0)
188 || (secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 0));
189 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
190 }
191
192 /* Invalid pk with a valid tweak */
193 memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk));
195 CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak));
196 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
197}
198
200 unsigned char zeros64[64] = { 0 };
201 unsigned char overflows[32];
202 unsigned char sk[32];
203 secp256k1_pubkey internal_pk;
204 secp256k1_xonly_pubkey internal_xonly_pk;
205 secp256k1_pubkey output_pk;
206 secp256k1_xonly_pubkey output_xonly_pk;
207 unsigned char output_pk32[32];
208 unsigned char buf32[32];
209 int pk_parity;
210 unsigned char tweak[32];
211
212 memset(overflows, 0xff, sizeof(overflows));
215 CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1);
216 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
217
218 CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
219 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1);
220 CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &output_xonly_pk) == 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(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
224 CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, NULL, pk_parity, &internal_xonly_pk, tweak));
225 /* invalid pk_parity value */
226 CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, 2, &internal_xonly_pk, tweak) == 0);
228 CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, NULL));
229
230 memset(tweak, 1, sizeof(tweak));
231 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, NULL, &internal_pk) == 1);
232 CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
233 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1);
234 CHECK(secp256k1_xonly_pubkey_serialize(CTX, output_pk32, &output_xonly_pk) == 1);
235 CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, tweak) == 1);
236
237 /* Wrong pk_parity */
238 CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, !pk_parity, &internal_xonly_pk, tweak) == 0);
239 /* Wrong public key */
240 CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &internal_xonly_pk) == 1);
241 CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
242
243 /* Overflowing tweak not allowed */
244 CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0);
245 CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0);
246 CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
247}
248
249/* Starts with an initial pubkey and recursively creates N_PUBKEYS - 1
250 * additional pubkeys by calling tweak_add. Then verifies every tweak starting
251 * from the last pubkey. */
252#define N_PUBKEYS 32
254 unsigned char sk[32];
256 unsigned char pk_serialized[32];
257 unsigned char tweak[N_PUBKEYS - 1][32];
258 int i;
259
262 /* Add tweaks */
263 for (i = 0; i < N_PUBKEYS - 1; i++) {
264 secp256k1_xonly_pubkey xonly_pk;
265 memset(tweak[i], i + 1, sizeof(tweak[i]));
266 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i]) == 1);
267 CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &pk[i + 1], &xonly_pk, tweak[i]) == 1);
268 }
269
270 /* Verify tweaks */
271 for (i = N_PUBKEYS - 1; i > 0; i--) {
272 secp256k1_xonly_pubkey xonly_pk;
273 int pk_parity;
274 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk[i]) == 1);
275 CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk_serialized, &xonly_pk) == 1);
276 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i - 1]) == 1);
277 CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, pk_serialized, pk_parity, &xonly_pk, tweak[i - 1]) == 1);
278 }
279}
280#undef N_PUBKEYS
281
282static void test_keypair(void) {
283 unsigned char sk[32];
284 unsigned char sk_tmp[32];
285 unsigned char zeros96[96] = { 0 };
286 unsigned char overflows[32];
287 secp256k1_keypair keypair;
288 secp256k1_pubkey pk, pk_tmp;
289 secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
290 int pk_parity, pk_parity_tmp;
291
292 CHECK(sizeof(zeros96) == sizeof(keypair));
293 memset(overflows, 0xFF, sizeof(overflows));
294
295 /* Test keypair_create */
297 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
298 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
299 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
300 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
303 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
304 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
306 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
307
308 /* Invalid secret key */
309 CHECK(secp256k1_keypair_create(CTX, &keypair, zeros96) == 0);
310 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
311 CHECK(secp256k1_keypair_create(CTX, &keypair, overflows) == 0);
312 CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
313
314 /* Test keypair_pub */
316 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
317 CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1);
318 CHECK_ILLEGAL(CTX, secp256k1_keypair_pub(CTX, NULL, &keypair));
320 CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
321
322 /* Using an invalid keypair is fine for keypair_pub */
323 memset(&keypair, 0, sizeof(keypair));
324 CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1);
325 CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
326
327 /* keypair holds the same pubkey as pubkey_create */
329 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
330 CHECK(secp256k1_keypair_pub(CTX, &pk_tmp, &keypair) == 1);
331 CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
332
335 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
336 CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1);
337 CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, NULL, &pk_parity, &keypair));
338 CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, NULL, &keypair) == 1);
339 CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, NULL));
340 CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
341 /* Using an invalid keypair will set the xonly_pk to 0 (first reset
342 * xonly_pk). */
343 CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1);
344 memset(&keypair, 0, sizeof(keypair));
345 CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair));
346 CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
347
350 CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
351 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
352 CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
353 CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
354 CHECK(pk_parity == pk_parity_tmp);
355
356 /* Test keypair_seckey */
358 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
359 CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
360 CHECK_ILLEGAL(CTX, secp256k1_keypair_sec(CTX, NULL, &keypair));
362 CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
363
364 /* keypair returns the same seckey it got */
365 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
366 CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
367 CHECK(secp256k1_memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0);
368
369
370 /* Using an invalid keypair is fine for keypair_seckey */
371 memset(&keypair, 0, sizeof(keypair));
372 CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
373 CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
374}
375
376static void test_keypair_add(void) {
377 unsigned char sk[32];
378 secp256k1_keypair keypair;
379 unsigned char overflows[32];
380 unsigned char zeros96[96] = { 0 };
381 unsigned char tweak[32];
382 int i;
383
384 CHECK(sizeof(zeros96) == sizeof(keypair));
387 memset(overflows, 0xFF, 32);
388 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
389
395 /* This does not set the keypair to zeroes */
396 CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
397
398 /* Invalid tweak zeroes the keypair */
399 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
400 CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, overflows) == 0);
401 CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
402
403 /* A zero tweak is fine */
404 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
405 CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, zeros96) == 1);
406
407 /* Fails if the resulting keypair was (sk=0, pk=infinity) */
408 for (i = 0; i < COUNT; i++) {
409 secp256k1_scalar scalar_tweak;
410 secp256k1_keypair keypair_tmp;
412 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
413 memcpy(&keypair_tmp, &keypair, sizeof(keypair));
414 /* Because sk may be negated before adding, we need to try with tweak =
415 * sk as well as tweak = -sk. */
416 secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
417 secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
418 secp256k1_scalar_get_b32(tweak, &scalar_tweak);
420 || (secp256k1_keypair_xonly_tweak_add(CTX, &keypair_tmp, tweak) == 0));
421 CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
422 || secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
423 }
424
425 /* Invalid keypair with a valid tweak */
426 memset(&keypair, 0, sizeof(keypair));
429 CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
430 /* Only seckey part of keypair invalid */
431 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
432 memset(&keypair, 0, 32);
434 /* Only pubkey part of keypair invalid */
435 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
436 memset(&keypair.data[32], 0, 64);
438
439 /* Check that the keypair_tweak_add implementation is correct */
440 CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
441 for (i = 0; i < COUNT; i++) {
442 secp256k1_xonly_pubkey internal_pk;
443 secp256k1_xonly_pubkey output_pk;
444 secp256k1_pubkey output_pk_xy;
445 secp256k1_pubkey output_pk_expected;
446 unsigned char pk32[32];
447 unsigned char sk32[32];
448 int pk_parity;
449
451 CHECK(secp256k1_keypair_xonly_pub(CTX, &internal_pk, NULL, &keypair) == 1);
453 CHECK(secp256k1_keypair_xonly_pub(CTX, &output_pk, &pk_parity, &keypair) == 1);
454
455 /* Check that it passes xonly_pubkey_tweak_add_check */
456 CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk32, &output_pk) == 1);
457 CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, pk32, pk_parity, &internal_pk, tweak) == 1);
458
459 /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
460 CHECK(secp256k1_keypair_pub(CTX, &output_pk_xy, &keypair) == 1);
461 CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk_expected, &internal_pk, tweak) == 1);
462 CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
463
464 /* Check that the secret key in the keypair is tweaked correctly */
465 CHECK(secp256k1_keypair_sec(CTX, sk32, &keypair) == 1);
466 CHECK(secp256k1_ec_pubkey_create(CTX, &output_pk_expected, sk32) == 1);
467 CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
468 }
469}
470
471/* --- Test registry --- */
472static const struct tf_test_entry tests_extrakeys[] = {
473 /* xonly key test cases */
479 /* keypair tests */
482};
483
484#endif
static void test_xonly_pubkey(void)
Definition: tests_impl.h:13
static void test_xonly_pubkey_tweak_check(void)
Definition: tests_impl.h:199
static void test_xonly_pubkey_comparison(void)
Definition: tests_impl.h:111
static const struct tf_test_entry tests_extrakeys[]
Definition: tests_impl.h:472
#define N_PUBKEYS
Definition: tests_impl.h:252
static void test_keypair_add(void)
Definition: tests_impl.h:376
static void test_keypair(void)
Definition: tests_impl.h:282
static void test_xonly_pubkey_tweak_recursive(void)
Definition: tests_impl.h:253
static void test_xonly_pubkey_tweak(void)
Definition: tests_impl.h:144
#define secp256k1_fe_negate(r, a, m)
Negate a field element.
Definition: field.h:211
static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Determine whether two field elements are equal.
#define CHECK(cond)
Unconditional failure on condition failure.
Definition: util.h:35
static int tweak(const secp256k1_context *ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache)
Definition: musig.c:64
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow)
Set a scalar from a big endian byte array.
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
Convert a scalar to a byte array.
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the complement of a scalar (modulo the group order).
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition: util.h:268
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition: secp256k1.c:240
#define SECP256K1_TAG_PUBKEY_EVEN
Prefix byte used to tag various encoded curvepoints for specific purposes.
Definition: secp256k1.h:228
SECP256K1_API void secp256k1_context_set_illegal_callback(secp256k1_context *ctx, void(*fun)(const char *message, void *data), const void *data) SECP256K1_ARG_NONNULL(1)
Set a callback function to be called when an illegal argument is passed to an API call.
Definition: secp256k1.c:199
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *input, size_t inputlen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a variable-length public key into the pubkey object.
Definition: secp256k1.c:250
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the public key for a secret key.
Definition: secp256k1.c:604
SECP256K1_API int secp256k1_xonly_pubkey_cmp(const secp256k1_context *ctx, const secp256k1_xonly_pubkey *pk1, const secp256k1_xonly_pubkey *pk2) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compare two x-only public keys using lexicographic order.
Definition: main_impl.h:59
SECP256K1_API int secp256k1_xonly_pubkey_from_pubkey(const secp256k1_context *ctx, secp256k1_xonly_pubkey *xonly_pubkey, int *pk_parity, const secp256k1_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4)
Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
Definition: main_impl.h:99
SECP256K1_API int secp256k1_xonly_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output32, const secp256k1_xonly_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Serialize an xonly_pubkey object into a 32-byte sequence.
Definition: main_impl.h:44
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check(const secp256k1_context *ctx, const unsigned char *tweaked_pubkey32, int tweaked_pk_parity, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5)
Checks that a tweaked pubkey is the result of calling secp256k1_xonly_pubkey_tweak_add with internal_...
Definition: main_impl.h:135
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(const secp256k1_context *ctx, secp256k1_keypair *keypair, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the keypair for a valid secret key.
Definition: main_impl.h:196
SECP256K1_API int secp256k1_keypair_xonly_pub(const secp256k1_context *ctx, secp256k1_xonly_pubkey *pubkey, int *pk_parity, const secp256k1_keypair *keypair) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4)
Get the x-only public key from a keypair.
Definition: main_impl.h:234
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(const secp256k1_context *ctx, secp256k1_keypair *keypair, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Tweak a keypair by adding tweak32 to the secret key and updating the public key accordingly.
Definition: main_impl.h:255
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(const secp256k1_context *ctx, secp256k1_pubkey *output_pubkey, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Tweak an x-only public key by adding the generator multiplied with tweak32 to it.
Definition: main_impl.h:118
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(const secp256k1_context *ctx, secp256k1_xonly_pubkey *pubkey, const unsigned char *input32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a 32-byte sequence into a xonly_pubkey object.
Definition: main_impl.h:22
SECP256K1_API int secp256k1_keypair_pub(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const secp256k1_keypair *keypair) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Get the public key from a keypair.
Definition: main_impl.h:224
SECP256K1_API int secp256k1_keypair_sec(const secp256k1_context *ctx, unsigned char *seckey, const secp256k1_keypair *keypair) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Get the secret key from a keypair.
Definition: main_impl.h:214
This field implementation represents the value as 10 uint32_t limbs in base 2^26.
Definition: field_10x26.h:14
A group element in affine coordinates on the secp256k1 curve, or occasionally on an isomorphic curve ...
Definition: group.h:16
secp256k1_fe x
Definition: group.h:17
secp256k1_fe y
Definition: group.h:18
Opaque data structure that holds a keypair consisting of a secret and a public key.
unsigned char data[96]
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:61
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
Opaque data structure that holds a parsed and valid "x-only" public key.
Definition: unit_test.h:51
static void testrand256(unsigned char *b32)
Generate a pseudorandom 32-byte array.
#define CHECK_ILLEGAL_VOID(ctx, expr_or_stmt)
Definition: tests.c:71
static void counting_callback_fn(const char *str, void *data)
Definition: tests.c:82
#define CHECK_ILLEGAL(ctx, expr)
Definition: tests.c:79
static secp256k1_context * CTX
Definition: tests.c:42
static secp256k1_context * STATIC_CTX
Definition: tests.c:43
int COUNT
Definition: unit_test.c:23
#define CASE1(name)
Definition: unit_test.h:25