Bitcoin Core  31.0.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 
13 static void test_xonly_pubkey(void) {
15  secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
16  secp256k1_ge pk1;
17  secp256k1_ge pk2;
18  secp256k1_fe y;
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 
27  testrand256(sk);
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);
56  secp256k1_pubkey_load(CTX, &pk1, &pk);
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 
111 static void test_xonly_pubkey_comparison(void) {
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 
144 static 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));
157  testrand256(sk);
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 
199 static void test_xonly_pubkey_tweak_check(void) {
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));
214  testrand256(sk);
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 
260  testrand256(sk);
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 
282 static 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 */
296  testrand256(sk);
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);
302  CHECK_ILLEGAL(CTX, secp256k1_keypair_create(CTX, &keypair, NULL));
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 */
315  testrand256(sk);
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 
334  testrand256(sk);
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 */
357  testrand256(sk);
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));
361  CHECK_ILLEGAL(CTX, secp256k1_keypair_sec(CTX, sk_tmp, NULL));
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 
376 static 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));
385  testrand256(sk);
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;
411  testrand256(sk);
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);
419  CHECK((secp256k1_keypair_xonly_tweak_add(CTX, &keypair, sk) == 0)
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 --- */
472 static const struct tf_test_entry tests_extrakeys[] = {
473  /* xonly key test cases */
479  /* keypair tests */
482 };
483 
484 #endif
static void test_xonly_pubkey_comparison(void)
Definition: tests_impl.h:111
static void test_keypair(void)
Definition: tests_impl.h:282
This field implementation represents the value as 10 uint32_t limbs in base 2^26. ...
Definition: field_10x26.h:14
#define CASE1(name)
Definition: unit_test.h:25
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_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
static void counting_callback_fn(const char *str, void *data)
Definition: tests.c:82
static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Determine whether two field elements are equal.
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
#define CHECK_ILLEGAL_VOID(ctx, expr_or_stmt)
Definition: tests.c:71
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the complement of a scalar (modulo the group order).
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
static void test_xonly_pubkey_tweak(void)
Definition: tests_impl.h:144
static void test_keypair_add(void)
Definition: tests_impl.h:376
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
memcpy(result.begin(), stream.data(), stream.size())
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 testrand256(unsigned char *b32)
Generate a pseudorandom 32-byte array.
static int tweak(const secp256k1_context *ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache)
Definition: musig.c:64
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:612
static secp256k1_context * STATIC_CTX
Definition: tests.c:43
Opaque data structure that holds a parsed and valid "x-only" public key.
#define N_PUBKEYS
Definition: tests_impl.h:252
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
Definition: unit_test.h:51
static secp256k1_context * CTX
Definition: tests.c:42
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
static void test_xonly_pubkey(void)
Definition: tests_impl.h:13
#define CHECK(cond)
Unconditional failure on condition failure.
Definition: util.h:35
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
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
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
Opaque data structure that holds a keypair consisting of a secret and a public key.
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
Convert a scalar to a byte array.
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition: util.h:269
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
#define secp256k1_fe_negate(r, a, m)
Negate a field element.
Definition: field.h:211
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition: secp256k1.c:240
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 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_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
#define CHECK_ILLEGAL(ctx, expr)
Definition: tests.c:79
static void test_xonly_pubkey_tweak_check(void)
Definition: tests_impl.h:199
secp256k1_fe y
Definition: group.h:18
static const struct tf_test_entry tests_extrakeys[]
Definition: tests_impl.h:472
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
unsigned char data[96]
static void test_xonly_pubkey_tweak_recursive(void)
Definition: tests_impl.h:253
#define SECP256K1_TAG_PUBKEY_EVEN
Prefix byte used to tag various encoded curvepoints for specific purposes.
Definition: secp256k1.h:228
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:61
int COUNT
Definition: unit_test.c:23