Bitcoin Core  21.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 "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 sk_tmp[32];
315  unsigned char zeros96[96] = { 0 };
316  unsigned char overflows[32];
317  secp256k1_keypair keypair;
318  secp256k1_pubkey pk, pk_tmp;
319  secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
320  int pk_parity, pk_parity_tmp;
321  int ecount;
325 
326  CHECK(sizeof(zeros96) == sizeof(keypair));
327  memset(overflows, 0xFF, sizeof(overflows));
328 
329  /* Test keypair_create */
330  ecount = 0;
332  CHECK(secp256k1_keypair_create(none, &keypair, sk) == 0);
333  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
334  CHECK(ecount == 1);
335  CHECK(secp256k1_keypair_create(verify, &keypair, sk) == 0);
336  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
337  CHECK(ecount == 2);
338  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
339  CHECK(secp256k1_keypair_create(sign, NULL, sk) == 0);
340  CHECK(ecount == 3);
341  CHECK(secp256k1_keypair_create(sign, &keypair, NULL) == 0);
342  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
343  CHECK(ecount == 4);
344 
345  /* Invalid secret key */
346  CHECK(secp256k1_keypair_create(sign, &keypair, zeros96) == 0);
347  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
348  CHECK(secp256k1_keypair_create(sign, &keypair, overflows) == 0);
349  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
350 
351  /* Test keypair_pub */
352  ecount = 0;
354  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
355  CHECK(secp256k1_keypair_pub(none, &pk, &keypair) == 1);
356  CHECK(secp256k1_keypair_pub(none, NULL, &keypair) == 0);
357  CHECK(ecount == 1);
358  CHECK(secp256k1_keypair_pub(none, &pk, NULL) == 0);
359  CHECK(ecount == 2);
360  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
361 
362  /* Using an invalid keypair is fine for keypair_pub */
363  memset(&keypair, 0, sizeof(keypair));
364  CHECK(secp256k1_keypair_pub(none, &pk, &keypair) == 1);
365  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
366 
367  /* keypair holds the same pubkey as pubkey_create */
368  CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
369  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
370  CHECK(secp256k1_keypair_pub(none, &pk_tmp, &keypair) == 1);
371  CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
372 
374  ecount = 0;
376  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
377  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
378  CHECK(secp256k1_keypair_xonly_pub(none, NULL, &pk_parity, &keypair) == 0);
379  CHECK(ecount == 1);
380  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, NULL, &keypair) == 1);
381  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, NULL) == 0);
382  CHECK(ecount == 2);
383  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
384  /* Using an invalid keypair will set the xonly_pk to 0 (first reset
385  * xonly_pk). */
386  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
387  memset(&keypair, 0, sizeof(keypair));
388  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 0);
389  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
390  CHECK(ecount == 3);
391 
393  CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
394  CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
395  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
396  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
397  CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
398  CHECK(pk_parity == pk_parity_tmp);
399 
400  /* Test keypair_seckey */
401  ecount = 0;
403  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
404  CHECK(secp256k1_keypair_sec(none, sk_tmp, &keypair) == 1);
405  CHECK(secp256k1_keypair_sec(none, NULL, &keypair) == 0);
406  CHECK(ecount == 1);
407  CHECK(secp256k1_keypair_sec(none, sk_tmp, NULL) == 0);
408  CHECK(ecount == 2);
409  CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
410 
411  /* keypair returns the same seckey it got */
412  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
413  CHECK(secp256k1_keypair_sec(none, sk_tmp, &keypair) == 1);
414  CHECK(secp256k1_memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0);
415 
416 
417  /* Using an invalid keypair is fine for keypair_seckey */
418  memset(&keypair, 0, sizeof(keypair));
419  CHECK(secp256k1_keypair_sec(none, sk_tmp, &keypair) == 1);
420  CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
421 
425 }
426 
427 void test_keypair_add(void) {
428  unsigned char sk[32];
429  secp256k1_keypair keypair;
430  unsigned char overflows[32];
431  unsigned char zeros96[96] = { 0 };
432  unsigned char tweak[32];
433  int i;
434  int ecount = 0;
438 
439  CHECK(sizeof(zeros96) == sizeof(keypair));
441  secp256k1_testrand256(tweak);
442  memset(overflows, 0xFF, 32);
443  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
444 
445  CHECK(secp256k1_keypair_xonly_tweak_add(none, &keypair, tweak) == 0);
446  CHECK(ecount == 1);
447  CHECK(secp256k1_keypair_xonly_tweak_add(sign, &keypair, tweak) == 0);
448  CHECK(ecount == 2);
449  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 1);
450  CHECK(secp256k1_keypair_xonly_tweak_add(verify, NULL, tweak) == 0);
451  CHECK(ecount == 3);
452  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, NULL) == 0);
453  CHECK(ecount == 4);
454  /* This does not set the keypair to zeroes */
455  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
456 
457  /* Invalid tweak zeroes the keypair */
458  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
459  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, overflows) == 0);
460  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
461 
462  /* A zero tweak is fine */
463  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
464  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, zeros96) == 1);
465 
466  /* Fails if the resulting keypair was (sk=0, pk=infinity) */
467  for (i = 0; i < count; i++) {
468  secp256k1_scalar scalar_tweak;
469  secp256k1_keypair keypair_tmp;
471  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
472  memcpy(&keypair_tmp, &keypair, sizeof(keypair));
473  /* Because sk may be negated before adding, we need to try with tweak =
474  * sk as well as tweak = -sk. */
475  secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
476  secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
477  secp256k1_scalar_get_b32(tweak, &scalar_tweak);
478  CHECK((secp256k1_keypair_xonly_tweak_add(ctx, &keypair, sk) == 0)
479  || (secp256k1_keypair_xonly_tweak_add(ctx, &keypair_tmp, tweak) == 0));
480  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
481  || secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
482  }
483 
484  /* Invalid keypair with a valid tweak */
485  memset(&keypair, 0, sizeof(keypair));
486  secp256k1_testrand256(tweak);
487  ecount = 0;
488  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
489  CHECK(ecount == 1);
490  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
491  /* Only seckey part of keypair invalid */
492  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
493  memset(&keypair, 0, 32);
494  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
495  CHECK(ecount == 2);
496  /* Only pubkey part of keypair invalid */
497  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
498  memset(&keypair.data[32], 0, 64);
499  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
500  CHECK(ecount == 3);
501 
502  /* Check that the keypair_tweak_add implementation is correct */
503  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
504  for (i = 0; i < count; i++) {
505  secp256k1_xonly_pubkey internal_pk;
506  secp256k1_xonly_pubkey output_pk;
507  secp256k1_pubkey output_pk_xy;
508  secp256k1_pubkey output_pk_expected;
509  unsigned char pk32[32];
510  unsigned char sk32[32];
511  int pk_parity;
512 
513  secp256k1_testrand256(tweak);
514  CHECK(secp256k1_keypair_xonly_pub(ctx, &internal_pk, NULL, &keypair) == 1);
515  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 1);
516  CHECK(secp256k1_keypair_xonly_pub(ctx, &output_pk, &pk_parity, &keypair) == 1);
517 
518  /* Check that it passes xonly_pubkey_tweak_add_check */
519  CHECK(secp256k1_xonly_pubkey_serialize(ctx, pk32, &output_pk) == 1);
520  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, pk32, pk_parity, &internal_pk, tweak) == 1);
521 
522  /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
523  CHECK(secp256k1_keypair_pub(ctx, &output_pk_xy, &keypair) == 1);
524  CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk_expected, &internal_pk, tweak) == 1);
525  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
526 
527  /* Check that the secret key in the keypair is tweaked correctly */
528  CHECK(secp256k1_keypair_sec(none, sk32, &keypair) == 1);
529  CHECK(secp256k1_ec_pubkey_create(ctx, &output_pk_expected, sk32) == 1);
530  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
531  }
535 }
536 
538  /* xonly key test cases */
543 
544  /* keypair tests */
545  test_keypair();
547 }
548 
549 #endif
secp256k1_context_set_error_callback
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:212
test_xonly_pubkey
void test_xonly_pubkey(void)
Definition: tests_impl.h:19
secp256k1_scalar_negate
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the complement of a scalar (modulo the group order).
count
static int count
Definition: tests.c:41
SECP256K1_CONTEXT_VERIFY
#define SECP256K1_CONTEXT_VERIFY
Flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and secp256k1_context...
Definition: secp256k1.h:170
test_keypair_add
void test_keypair_add(void)
Definition: tests_impl.h:427
SECP256K1_TAG_PUBKEY_EVEN
#define SECP256K1_TAG_PUBKEY_EVEN
Prefix byte used to tag various encoded curvepoints for specific purposes.
Definition: secp256k1.h:180
secp256k1_ge::y
secp256k1_fe y
Definition: group.h:19
SECP256K1_CONTEXT_SIGN
#define SECP256K1_CONTEXT_SIGN
Definition: secp256k1.h:171
secp256k1_scalar_get_b32
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
Convert a scalar to a byte array.
secp256k1_testrand256
static void secp256k1_testrand256(unsigned char *b32)
Generate a pseudorandom 32-byte array.
flags
int flags
Definition: bitcoin-tx.cpp:512
secp256k1_pubkey_load
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition: secp256k1.c:245
secp256k1_context_struct
Definition: secp256k1.c:69
secp256k1_xonly_pubkey_from_pubkey
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
test_keypair
void test_keypair(void)
Definition: tests_impl.h:312
secp256k1_memcmp_var
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition: util.h:224
test_xonly_pubkey_tweak
void test_xonly_pubkey_tweak(void)
Definition: tests_impl.h:140
secp256k1_keypair_xonly_pub
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:209
secp256k1_keypair_sec
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:189
secp256k1_context_set_illegal_callback
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:203
secp256k1_context_destroy
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx)
Destroy a secp256k1 context object (created in dynamically allocated memory).
Definition: secp256k1.c:196
N_PUBKEYS
#define N_PUBKEYS
Definition: tests_impl.h:282
secp256k1_context_create
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:152
secp256k1_keypair
Opaque data structure that holds a keypair consisting of a secret and a public key.
Definition: secp256k1_extrakeys.h:33
secp256k1_scalar
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
counting_illegal_callback_fn
static void counting_illegal_callback_fn(const char *str, void *data)
Definition: tests.c:44
secp256k1_keypair_create
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
api_test_context
static secp256k1_context * api_test_context(int flags, int *ecount)
Definition: tests_impl.h:12
secp256k1_ec_pubkey_parse
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:278
secp256k1_fe
Definition: field_10x26.h:12
secp256k1_keypair_pub
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:199
secp256k1_xonly_pubkey_tweak_add_check
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_fe_equal
static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Compare two field elements.
test_xonly_pubkey_tweak_recursive
void test_xonly_pubkey_tweak_recursive(void)
Definition: tests_impl.h:283
secp256k1_xonly_pubkey_parse
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
SECP256K1_CONTEXT_NONE
#define SECP256K1_CONTEXT_NONE
Definition: secp256k1.h:173
test_xonly_pubkey_tweak_check
void test_xonly_pubkey_tweak_check(void)
Definition: tests_impl.h:212
secp256k1_xonly_pubkey_serialize
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
run_extrakeys_tests
void run_extrakeys_tests(void)
Definition: tests_impl.h:537
secp256k1_ec_pubkey_create
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:572
secp256k1_fe_negate
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.
secp256k1_keypair_xonly_tweak_add
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:230
secp256k1_keypair::data
unsigned char data[96]
Definition: secp256k1_extrakeys.h:34
secp256k1_ge::x
secp256k1_fe x
Definition: group.h:18
secp256k1_xonly_pubkey_tweak_add
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
secp256k1_extrakeys.h
CHECK
#define CHECK(cond)
Definition: util.h:53
secp256k1_scalar_set_b32
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow)
Set a scalar from a big endian byte array.
secp256k1_pubkey
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:67
secp256k1_ge
A group element of the secp256k1 curve, in affine coordinates.
Definition: group.h:13
ctx
static secp256k1_context * ctx
Definition: tests.c:42
secp256k1_xonly_pubkey
Opaque data structure that holds a parsed and valid "x-only" public key.
Definition: secp256k1_extrakeys.h:22