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