Bitcoin Core  0.20.99
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 http://www.opensource.org/licenses/mit-license.php.*
5  **********************************************************************/
6 
7 #ifndef _SECP256K1_MODULE_EXTRAKEYS_TESTS_
8 #define _SECP256K1_MODULE_EXTRAKEYS_TESTS_
9 
10 #include "secp256k1_extrakeys.h"
11 
12 static secp256k1_context* api_test_context(int flags, int *ecount) {
16  return ctx0;
17 }
18 
19 void test_xonly_pubkey(void) {
21  secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
22  secp256k1_ge pk1;
23  secp256k1_ge pk2;
24  secp256k1_fe y;
25  unsigned char sk[32];
26  unsigned char xy_sk[32];
27  unsigned char buf32[32];
28  unsigned char ones32[32];
29  unsigned char zeros64[64] = { 0 };
30  int pk_parity;
31  int i;
32 
33  int ecount;
37 
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);
43 
44  /* Test xonly_pubkey_from_pubkey */
45  ecount = 0;
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);
50  CHECK(ecount == 1);
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);
53  CHECK(ecount == 2);
54  memset(&pk, 0, sizeof(pk));
55  CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 0);
56  CHECK(ecount == 3);
57 
58  /* Choose a secret key such that the resulting pubkey and xonly_pubkey match. */
59  memset(sk, 0, sizeof(sk));
60  sk[0] = 1;
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);
65 
66  /* Choose a secret key such that pubkey and xonly_pubkey are each others
67  * negation. */
68  sk[0] = 2;
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);
78 
79  /* Test xonly_pubkey_serialize and xonly_pubkey_parse */
80  ecount = 0;
81  CHECK(secp256k1_xonly_pubkey_serialize(none, NULL, &xonly_pk) == 0);
82  CHECK(ecount == 1);
83  CHECK(secp256k1_xonly_pubkey_serialize(none, buf32, NULL) == 0);
84  CHECK(secp256k1_memcmp_var(buf32, zeros64, 32) == 0);
85  CHECK(ecount == 2);
86  {
87  /* A pubkey filled with 0s will fail to serialize due to pubkey_load
88  * special casing. */
90  memset(&pk_tmp, 0, sizeof(pk_tmp));
91  CHECK(secp256k1_xonly_pubkey_serialize(none, buf32, &pk_tmp) == 0);
92  }
93  /* pubkey_load called illegal callback */
94  CHECK(ecount == 3);
95 
96  CHECK(secp256k1_xonly_pubkey_serialize(none, buf32, &xonly_pk) == 1);
97  ecount = 0;
98  CHECK(secp256k1_xonly_pubkey_parse(none, NULL, buf32) == 0);
99  CHECK(ecount == 1);
100  CHECK(secp256k1_xonly_pubkey_parse(none, &xonly_pk, NULL) == 0);
101  CHECK(ecount == 2);
102 
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);
108 
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);
129  } else {
130  CHECK(secp256k1_xonly_pubkey_parse(ctx, &xonly_pk, &rand33[1]) == 1);
131  }
132  }
133  CHECK(ecount == 2);
134 
138 }
139 
141  unsigned char zeros64[64] = { 0 };
142  unsigned char overflows[32];
143  unsigned char sk[32];
144  secp256k1_pubkey internal_pk;
145  secp256k1_xonly_pubkey internal_xonly_pk;
146  secp256k1_pubkey output_pk;
147  int pk_parity;
148  unsigned char tweak[32];
149  int i;
150 
151  int ecount;
155 
156  memset(overflows, 0xff, sizeof(overflows));
157  secp256k1_testrand256(tweak);
159  CHECK(secp256k1_ec_pubkey_create(ctx, &internal_pk, sk) == 1);
160  CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
161 
162  ecount = 0;
163  CHECK(secp256k1_xonly_pubkey_tweak_add(none, &output_pk, &internal_xonly_pk, tweak) == 0);
164  CHECK(ecount == 1);
165  CHECK(secp256k1_xonly_pubkey_tweak_add(sign, &output_pk, &internal_xonly_pk, tweak) == 0);
166  CHECK(ecount == 2);
167  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 1);
168  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, NULL, &internal_xonly_pk, tweak) == 0);
169  CHECK(ecount == 3);
170  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, NULL, tweak) == 0);
171  CHECK(ecount == 4);
172  /* NULL internal_xonly_pk zeroes the output_pk */
173  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
174  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, NULL) == 0);
175  CHECK(ecount == 5);
176  /* NULL tweak zeroes the output_pk */
177  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
178 
179  /* Invalid tweak zeroes the output_pk */
180  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, overflows) == 0);
181  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
182 
183  /* A zero tweak is fine */
184  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, zeros64) == 1);
185 
186  /* Fails if the resulting key was infinity */
187  for (i = 0; i < count; i++) {
188  secp256k1_scalar scalar_tweak;
189  /* Because sk may be negated before adding, we need to try with tweak =
190  * sk as well as tweak = -sk. */
191  secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
192  secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
193  secp256k1_scalar_get_b32(tweak, &scalar_tweak);
194  CHECK((secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, sk) == 0)
195  || (secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 0));
196  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
197  }
198 
199  /* Invalid pk with a valid tweak */
200  memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk));
201  secp256k1_testrand256(tweak);
202  ecount = 0;
203  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 0);
204  CHECK(ecount == 1);
205  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
206 
210 }
211 
213  unsigned char zeros64[64] = { 0 };
214  unsigned char overflows[32];
215  unsigned char sk[32];
216  secp256k1_pubkey internal_pk;
217  secp256k1_xonly_pubkey internal_xonly_pk;
218  secp256k1_pubkey output_pk;
219  secp256k1_xonly_pubkey output_xonly_pk;
220  unsigned char output_pk32[32];
221  unsigned char buf32[32];
222  int pk_parity;
223  unsigned char tweak[32];
224 
225  int ecount;
229 
230  memset(overflows, 0xff, sizeof(overflows));
231  secp256k1_testrand256(tweak);
233  CHECK(secp256k1_ec_pubkey_create(ctx, &internal_pk, sk) == 1);
234  CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
235 
236  ecount = 0;
237  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 1);
238  CHECK(secp256k1_xonly_pubkey_from_pubkey(verify, &output_xonly_pk, &pk_parity, &output_pk) == 1);
239  CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf32, &output_xonly_pk) == 1);
240  CHECK(secp256k1_xonly_pubkey_tweak_add_check(none, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
241  CHECK(ecount == 1);
242  CHECK(secp256k1_xonly_pubkey_tweak_add_check(sign, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
243  CHECK(ecount == 2);
244  CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
245  CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, NULL, pk_parity, &internal_xonly_pk, tweak) == 0);
246  CHECK(ecount == 3);
247  /* invalid pk_parity value */
248  CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, 2, &internal_xonly_pk, tweak) == 0);
249  CHECK(ecount == 3);
250  CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, NULL, tweak) == 0);
251  CHECK(ecount == 4);
252  CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, &internal_xonly_pk, NULL) == 0);
253  CHECK(ecount == 5);
254 
255  memset(tweak, 1, sizeof(tweak));
256  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &internal_xonly_pk, NULL, &internal_pk) == 1);
257  CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk, &internal_xonly_pk, tweak) == 1);
258  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &output_xonly_pk, &pk_parity, &output_pk) == 1);
259  CHECK(secp256k1_xonly_pubkey_serialize(ctx, output_pk32, &output_xonly_pk) == 1);
260  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, output_pk32, pk_parity, &internal_xonly_pk, tweak) == 1);
261 
262  /* Wrong pk_parity */
263  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, output_pk32, !pk_parity, &internal_xonly_pk, tweak) == 0);
264  /* Wrong public key */
265  CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf32, &internal_xonly_pk) == 1);
266  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
267 
268  /* Overflowing tweak not allowed */
269  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0);
270  CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk, &internal_xonly_pk, overflows) == 0);
271  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
272  CHECK(ecount == 5);
273 
277 }
278 
279 /* Starts with an initial pubkey and recursively creates N_PUBKEYS - 1
280  * additional pubkeys by calling tweak_add. Then verifies every tweak starting
281  * from the last pubkey. */
282 #define N_PUBKEYS 32
284  unsigned char sk[32];
286  unsigned char pk_serialized[32];
287  unsigned char tweak[N_PUBKEYS - 1][32];
288  int i;
289 
291  CHECK(secp256k1_ec_pubkey_create(ctx, &pk[0], sk) == 1);
292  /* Add tweaks */
293  for (i = 0; i < N_PUBKEYS - 1; i++) {
294  secp256k1_xonly_pubkey xonly_pk;
295  memset(tweak[i], i + 1, sizeof(tweak[i]));
296  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, NULL, &pk[i]) == 1);
297  CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &pk[i + 1], &xonly_pk, tweak[i]) == 1);
298  }
299 
300  /* Verify tweaks */
301  for (i = N_PUBKEYS - 1; i > 0; i--) {
302  secp256k1_xonly_pubkey xonly_pk;
303  int pk_parity;
304  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk[i]) == 1);
305  CHECK(secp256k1_xonly_pubkey_serialize(ctx, pk_serialized, &xonly_pk) == 1);
306  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, NULL, &pk[i - 1]) == 1);
307  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, pk_serialized, pk_parity, &xonly_pk, tweak[i - 1]) == 1);
308  }
309 }
310 #undef N_PUBKEYS
311 
312 void test_keypair(void) {
313  unsigned char sk[32];
314  unsigned char zeros96[96] = { 0 };
315  unsigned char overflows[32];
316  secp256k1_keypair keypair;
317  secp256k1_pubkey pk, pk_tmp;
318  secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
319  int pk_parity, pk_parity_tmp;
320  int ecount;
324 
325  CHECK(sizeof(zeros96) == sizeof(keypair));
326  memset(overflows, 0xFF, sizeof(overflows));
327 
328  /* Test keypair_create */
329  ecount = 0;
331  CHECK(secp256k1_keypair_create(none, &keypair, sk) == 0);
332  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
333  CHECK(ecount == 1);
334  CHECK(secp256k1_keypair_create(verify, &keypair, sk) == 0);
335  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
336  CHECK(ecount == 2);
337  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
338  CHECK(secp256k1_keypair_create(sign, NULL, sk) == 0);
339  CHECK(ecount == 3);
340  CHECK(secp256k1_keypair_create(sign, &keypair, NULL) == 0);
341  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
342  CHECK(ecount == 4);
343 
344  /* Invalid secret key */
345  CHECK(secp256k1_keypair_create(sign, &keypair, zeros96) == 0);
346  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
347  CHECK(secp256k1_keypair_create(sign, &keypair, overflows) == 0);
348  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
349 
350  /* Test keypair_pub */
351  ecount = 0;
353  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
354  CHECK(secp256k1_keypair_pub(none, &pk, &keypair) == 1);
355  CHECK(secp256k1_keypair_pub(none, NULL, &keypair) == 0);
356  CHECK(ecount == 1);
357  CHECK(secp256k1_keypair_pub(none, &pk, NULL) == 0);
358  CHECK(ecount == 2);
359  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
360 
361  /* Using an invalid keypair is fine for keypair_pub */
362  memset(&keypair, 0, sizeof(keypair));
363  CHECK(secp256k1_keypair_pub(none, &pk, &keypair) == 1);
364  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
365 
366  /* keypair holds the same pubkey as pubkey_create */
367  CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
368  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
369  CHECK(secp256k1_keypair_pub(none, &pk_tmp, &keypair) == 1);
370  CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
371 
373  ecount = 0;
375  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
376  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
377  CHECK(secp256k1_keypair_xonly_pub(none, NULL, &pk_parity, &keypair) == 0);
378  CHECK(ecount == 1);
379  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, NULL, &keypair) == 1);
380  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, NULL) == 0);
381  CHECK(ecount == 2);
382  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
383  /* Using an invalid keypair will set the xonly_pk to 0 (first reset
384  * xonly_pk). */
385  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
386  memset(&keypair, 0, sizeof(keypair));
387  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 0);
388  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
389  CHECK(ecount == 3);
390 
392  CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
393  CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
394  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
395  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
396  CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
397  CHECK(pk_parity == pk_parity_tmp);
398 
402 }
403 
404 void test_keypair_add(void) {
405  unsigned char sk[32];
406  secp256k1_keypair keypair;
407  unsigned char overflows[32];
408  unsigned char zeros96[96] = { 0 };
409  unsigned char tweak[32];
410  int i;
411  int ecount = 0;
415 
416  CHECK(sizeof(zeros96) == sizeof(keypair));
418  secp256k1_testrand256(tweak);
419  memset(overflows, 0xFF, 32);
420  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
421 
422  CHECK(secp256k1_keypair_xonly_tweak_add(none, &keypair, tweak) == 0);
423  CHECK(ecount == 1);
424  CHECK(secp256k1_keypair_xonly_tweak_add(sign, &keypair, tweak) == 0);
425  CHECK(ecount == 2);
426  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 1);
427  CHECK(secp256k1_keypair_xonly_tweak_add(verify, NULL, tweak) == 0);
428  CHECK(ecount == 3);
429  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, NULL) == 0);
430  CHECK(ecount == 4);
431  /* This does not set the keypair to zeroes */
432  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
433 
434  /* Invalid tweak zeroes the keypair */
435  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
436  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, overflows) == 0);
437  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
438 
439  /* A zero tweak is fine */
440  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
441  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, zeros96) == 1);
442 
443  /* Fails if the resulting keypair was (sk=0, pk=infinity) */
444  for (i = 0; i < count; i++) {
445  secp256k1_scalar scalar_tweak;
446  secp256k1_keypair keypair_tmp;
448  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
449  memcpy(&keypair_tmp, &keypair, sizeof(keypair));
450  /* Because sk may be negated before adding, we need to try with tweak =
451  * sk as well as tweak = -sk. */
452  secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
453  secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
454  secp256k1_scalar_get_b32(tweak, &scalar_tweak);
455  CHECK((secp256k1_keypair_xonly_tweak_add(ctx, &keypair, sk) == 0)
456  || (secp256k1_keypair_xonly_tweak_add(ctx, &keypair_tmp, tweak) == 0));
457  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
458  || secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
459  }
460 
461  /* Invalid keypair with a valid tweak */
462  memset(&keypair, 0, sizeof(keypair));
463  secp256k1_testrand256(tweak);
464  ecount = 0;
465  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
466  CHECK(ecount == 1);
467  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
468  /* Only seckey part of keypair invalid */
469  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
470  memset(&keypair, 0, 32);
471  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
472  CHECK(ecount == 2);
473  /* Only pubkey part of keypair invalid */
474  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
475  memset(&keypair.data[32], 0, 64);
476  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
477  CHECK(ecount == 3);
478 
479  /* Check that the keypair_tweak_add implementation is correct */
480  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
481  for (i = 0; i < count; i++) {
482  secp256k1_xonly_pubkey internal_pk;
483  secp256k1_xonly_pubkey output_pk;
484  secp256k1_pubkey output_pk_xy;
485  secp256k1_pubkey output_pk_expected;
486  unsigned char pk32[32];
487  int pk_parity;
488 
489  secp256k1_testrand256(tweak);
490  CHECK(secp256k1_keypair_xonly_pub(ctx, &internal_pk, NULL, &keypair) == 1);
491  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 1);
492  CHECK(secp256k1_keypair_xonly_pub(ctx, &output_pk, &pk_parity, &keypair) == 1);
493 
494  /* Check that it passes xonly_pubkey_tweak_add_check */
495  CHECK(secp256k1_xonly_pubkey_serialize(ctx, pk32, &output_pk) == 1);
496  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, pk32, pk_parity, &internal_pk, tweak) == 1);
497 
498  /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
499  CHECK(secp256k1_keypair_pub(ctx, &output_pk_xy, &keypair) == 1);
500  CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk_expected, &internal_pk, tweak) == 1);
501  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
502 
503  /* Check that the secret key in the keypair is tweaked correctly */
504  CHECK(secp256k1_ec_pubkey_create(ctx, &output_pk_expected, &keypair.data[0]) == 1);
505  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
506  }
510 }
511 
513  /* xonly key test cases */
518 
519  /* keypair tests */
520  test_keypair();
522 }
523 
524 #endif
void test_keypair_add(void)
Definition: tests_impl.h:404
static void secp256k1_testrand256(unsigned char *b32)
Generate a pseudorandom 32-byte array.
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:202
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 secret key.
Definition: main_impl.h:171
void test_xonly_pubkey_tweak(void)
Definition: tests_impl.h:140
static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Compare two field elements.
static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m)
Set a field element equal to the additive inverse of another.
static secp256k1_context * api_test_context(int flags, int *ecount)
Definition: tests_impl.h:12
#define SECP256K1_CONTEXT_NONE
Definition: secp256k1.h:173
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:189
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the complement of a scalar (modulo the group order).
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:220
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow)
Set a scalar from a big endian byte array.
#define SECP256K1_CONTEXT_SIGN
Definition: secp256k1.h:171
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx)
Destroy a secp256k1 context object (created in dynamically allocated memory).
Definition: secp256k1.c:195
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:571
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:72
void run_extrakeys_tests(void)
Definition: tests_impl.h:512
void test_keypair(void)
Definition: tests_impl.h:312
Opaque data structure that holds a parsed and valid "x-only" public key.
#define N_PUBKEYS
Definition: tests_impl.h:282
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:21
static secp256k1_context * ctx
Definition: tests.c:36
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:109
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:277
A group element of the secp256k1 curve, in affine coordinates.
Definition: group.h:14
secp256k1_fe x
Definition: group.h:15
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:199
#define CHECK(cond)
Definition: util.h:53
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
SECP256K1_API void secp256k1_context_set_error_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 internal consistency check fails.
Definition: secp256k1.c:211
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.
void test_xonly_pubkey_tweak_check(void)
Definition: tests_impl.h:212
#define SECP256K1_CONTEXT_VERIFY
Flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and secp256k1_context...
Definition: secp256k1.h:170
int flags
Definition: bitcoin-tx.cpp:506
void test_xonly_pubkey_tweak_recursive(void)
Definition: tests_impl.h:283
void * memcpy(void *a, const void *b, size_t c)
void test_xonly_pubkey(void)
Definition: tests_impl.h:19
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition: util.h:224
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:43
static int count
Definition: tests.c:35
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition: secp256k1.c:244
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:91
static void counting_illegal_callback_fn(const char *str, void *data)
Definition: tests.c:38
secp256k1_fe y
Definition: group.h:16
SECP256K1_API secp256k1_context * secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Create a secp256k1 context object (in dynamically allocated memory).
Definition: secp256k1.c:151
unsigned char data[96]
#define SECP256K1_TAG_PUBKEY_EVEN
Prefix byte used to tag various encoded curvepoints for specific purposes.
Definition: secp256k1.h:180
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:67