Bitcoin Core  22.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 
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 pk1_ser[32] = {
142  0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
143  0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
144  };
145  const unsigned char pk2_ser[32] = {
146  0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
147  0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
148  };
151  int ecount = 0;
153 
154  CHECK(secp256k1_xonly_pubkey_parse(none, &pk1, pk1_ser) == 1);
155  CHECK(secp256k1_xonly_pubkey_parse(none, &pk2, pk2_ser) == 1);
156 
157  CHECK(secp256k1_xonly_pubkey_cmp(none, NULL, &pk2) < 0);
158  CHECK(ecount == 1);
159  CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, NULL) > 0);
160  CHECK(ecount == 2);
161  CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk2) < 0);
162  CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk1) > 0);
163  CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk1) == 0);
164  CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk2) == 0);
165  CHECK(ecount == 2);
166  memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */
167  CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk2) < 0);
168  CHECK(ecount == 3);
169  CHECK(secp256k1_xonly_pubkey_cmp(none, &pk1, &pk1) == 0);
170  CHECK(ecount == 5);
171  CHECK(secp256k1_xonly_pubkey_cmp(none, &pk2, &pk1) > 0);
172  CHECK(ecount == 6);
173 
175 }
176 
178  unsigned char zeros64[64] = { 0 };
179  unsigned char overflows[32];
180  unsigned char sk[32];
181  secp256k1_pubkey internal_pk;
182  secp256k1_xonly_pubkey internal_xonly_pk;
183  secp256k1_pubkey output_pk;
184  int pk_parity;
185  unsigned char tweak[32];
186  int i;
187 
188  int ecount;
192 
193  memset(overflows, 0xff, sizeof(overflows));
194  secp256k1_testrand256(tweak);
196  CHECK(secp256k1_ec_pubkey_create(ctx, &internal_pk, sk) == 1);
197  CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
198 
199  ecount = 0;
200  CHECK(secp256k1_xonly_pubkey_tweak_add(none, &output_pk, &internal_xonly_pk, tweak) == 0);
201  CHECK(ecount == 1);
202  CHECK(secp256k1_xonly_pubkey_tweak_add(sign, &output_pk, &internal_xonly_pk, tweak) == 0);
203  CHECK(ecount == 2);
204  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 1);
205  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, NULL, &internal_xonly_pk, tweak) == 0);
206  CHECK(ecount == 3);
207  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, NULL, tweak) == 0);
208  CHECK(ecount == 4);
209  /* NULL internal_xonly_pk zeroes the output_pk */
210  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
211  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, NULL) == 0);
212  CHECK(ecount == 5);
213  /* NULL tweak zeroes the output_pk */
214  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
215 
216  /* Invalid tweak zeroes the output_pk */
217  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, overflows) == 0);
218  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
219 
220  /* A zero tweak is fine */
221  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, zeros64) == 1);
222 
223  /* Fails if the resulting key was infinity */
224  for (i = 0; i < count; i++) {
225  secp256k1_scalar scalar_tweak;
226  /* Because sk may be negated before adding, we need to try with tweak =
227  * sk as well as tweak = -sk. */
228  secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
229  secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
230  secp256k1_scalar_get_b32(tweak, &scalar_tweak);
231  CHECK((secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, sk) == 0)
232  || (secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 0));
233  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
234  }
235 
236  /* Invalid pk with a valid tweak */
237  memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk));
238  secp256k1_testrand256(tweak);
239  ecount = 0;
240  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 0);
241  CHECK(ecount == 1);
242  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
243 
247 }
248 
250  unsigned char zeros64[64] = { 0 };
251  unsigned char overflows[32];
252  unsigned char sk[32];
253  secp256k1_pubkey internal_pk;
254  secp256k1_xonly_pubkey internal_xonly_pk;
255  secp256k1_pubkey output_pk;
256  secp256k1_xonly_pubkey output_xonly_pk;
257  unsigned char output_pk32[32];
258  unsigned char buf32[32];
259  int pk_parity;
260  unsigned char tweak[32];
261 
262  int ecount;
266 
267  memset(overflows, 0xff, sizeof(overflows));
268  secp256k1_testrand256(tweak);
270  CHECK(secp256k1_ec_pubkey_create(ctx, &internal_pk, sk) == 1);
271  CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
272 
273  ecount = 0;
274  CHECK(secp256k1_xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 1);
275  CHECK(secp256k1_xonly_pubkey_from_pubkey(verify, &output_xonly_pk, &pk_parity, &output_pk) == 1);
276  CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf32, &output_xonly_pk) == 1);
277  CHECK(secp256k1_xonly_pubkey_tweak_add_check(none, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
278  CHECK(ecount == 1);
279  CHECK(secp256k1_xonly_pubkey_tweak_add_check(sign, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
280  CHECK(ecount == 2);
281  CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
282  CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, NULL, pk_parity, &internal_xonly_pk, tweak) == 0);
283  CHECK(ecount == 3);
284  /* invalid pk_parity value */
285  CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, 2, &internal_xonly_pk, tweak) == 0);
286  CHECK(ecount == 3);
287  CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, NULL, tweak) == 0);
288  CHECK(ecount == 4);
289  CHECK(secp256k1_xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, &internal_xonly_pk, NULL) == 0);
290  CHECK(ecount == 5);
291 
292  memset(tweak, 1, sizeof(tweak));
293  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &internal_xonly_pk, NULL, &internal_pk) == 1);
294  CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk, &internal_xonly_pk, tweak) == 1);
295  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &output_xonly_pk, &pk_parity, &output_pk) == 1);
296  CHECK(secp256k1_xonly_pubkey_serialize(ctx, output_pk32, &output_xonly_pk) == 1);
297  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, output_pk32, pk_parity, &internal_xonly_pk, tweak) == 1);
298 
299  /* Wrong pk_parity */
300  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, output_pk32, !pk_parity, &internal_xonly_pk, tweak) == 0);
301  /* Wrong public key */
302  CHECK(secp256k1_xonly_pubkey_serialize(ctx, buf32, &internal_xonly_pk) == 1);
303  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
304 
305  /* Overflowing tweak not allowed */
306  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0);
307  CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk, &internal_xonly_pk, overflows) == 0);
308  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
309  CHECK(ecount == 5);
310 
314 }
315 
316 /* Starts with an initial pubkey and recursively creates N_PUBKEYS - 1
317  * additional pubkeys by calling tweak_add. Then verifies every tweak starting
318  * from the last pubkey. */
319 #define N_PUBKEYS 32
321  unsigned char sk[32];
323  unsigned char pk_serialized[32];
324  unsigned char tweak[N_PUBKEYS - 1][32];
325  int i;
326 
328  CHECK(secp256k1_ec_pubkey_create(ctx, &pk[0], sk) == 1);
329  /* Add tweaks */
330  for (i = 0; i < N_PUBKEYS - 1; i++) {
331  secp256k1_xonly_pubkey xonly_pk;
332  memset(tweak[i], i + 1, sizeof(tweak[i]));
333  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, NULL, &pk[i]) == 1);
334  CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &pk[i + 1], &xonly_pk, tweak[i]) == 1);
335  }
336 
337  /* Verify tweaks */
338  for (i = N_PUBKEYS - 1; i > 0; i--) {
339  secp256k1_xonly_pubkey xonly_pk;
340  int pk_parity;
341  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk[i]) == 1);
342  CHECK(secp256k1_xonly_pubkey_serialize(ctx, pk_serialized, &xonly_pk) == 1);
343  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, NULL, &pk[i - 1]) == 1);
344  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, pk_serialized, pk_parity, &xonly_pk, tweak[i - 1]) == 1);
345  }
346 }
347 #undef N_PUBKEYS
348 
349 void test_keypair(void) {
350  unsigned char sk[32];
351  unsigned char sk_tmp[32];
352  unsigned char zeros96[96] = { 0 };
353  unsigned char overflows[32];
354  secp256k1_keypair keypair;
355  secp256k1_pubkey pk, pk_tmp;
356  secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
357  int pk_parity, pk_parity_tmp;
358  int ecount;
362 
363  CHECK(sizeof(zeros96) == sizeof(keypair));
364  memset(overflows, 0xFF, sizeof(overflows));
365 
366  /* Test keypair_create */
367  ecount = 0;
369  CHECK(secp256k1_keypair_create(none, &keypair, sk) == 0);
370  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
371  CHECK(ecount == 1);
372  CHECK(secp256k1_keypair_create(verify, &keypair, sk) == 0);
373  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
374  CHECK(ecount == 2);
375  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
376  CHECK(secp256k1_keypair_create(sign, NULL, sk) == 0);
377  CHECK(ecount == 3);
378  CHECK(secp256k1_keypair_create(sign, &keypair, NULL) == 0);
379  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
380  CHECK(ecount == 4);
381 
382  /* Invalid secret key */
383  CHECK(secp256k1_keypair_create(sign, &keypair, zeros96) == 0);
384  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
385  CHECK(secp256k1_keypair_create(sign, &keypair, overflows) == 0);
386  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
387 
388  /* Test keypair_pub */
389  ecount = 0;
391  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
392  CHECK(secp256k1_keypair_pub(none, &pk, &keypair) == 1);
393  CHECK(secp256k1_keypair_pub(none, NULL, &keypair) == 0);
394  CHECK(ecount == 1);
395  CHECK(secp256k1_keypair_pub(none, &pk, NULL) == 0);
396  CHECK(ecount == 2);
397  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
398 
399  /* Using an invalid keypair is fine for keypair_pub */
400  memset(&keypair, 0, sizeof(keypair));
401  CHECK(secp256k1_keypair_pub(none, &pk, &keypair) == 1);
402  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
403 
404  /* keypair holds the same pubkey as pubkey_create */
405  CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
406  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
407  CHECK(secp256k1_keypair_pub(none, &pk_tmp, &keypair) == 1);
408  CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
409 
411  ecount = 0;
413  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
414  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
415  CHECK(secp256k1_keypair_xonly_pub(none, NULL, &pk_parity, &keypair) == 0);
416  CHECK(ecount == 1);
417  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, NULL, &keypair) == 1);
418  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, NULL) == 0);
419  CHECK(ecount == 2);
420  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
421  /* Using an invalid keypair will set the xonly_pk to 0 (first reset
422  * xonly_pk). */
423  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
424  memset(&keypair, 0, sizeof(keypair));
425  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 0);
426  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
427  CHECK(ecount == 3);
428 
430  CHECK(secp256k1_ec_pubkey_create(sign, &pk, sk) == 1);
431  CHECK(secp256k1_xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
432  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
433  CHECK(secp256k1_keypair_xonly_pub(none, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
434  CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
435  CHECK(pk_parity == pk_parity_tmp);
436 
437  /* Test keypair_seckey */
438  ecount = 0;
440  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
441  CHECK(secp256k1_keypair_sec(none, sk_tmp, &keypair) == 1);
442  CHECK(secp256k1_keypair_sec(none, NULL, &keypair) == 0);
443  CHECK(ecount == 1);
444  CHECK(secp256k1_keypair_sec(none, sk_tmp, NULL) == 0);
445  CHECK(ecount == 2);
446  CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
447 
448  /* keypair returns the same seckey it got */
449  CHECK(secp256k1_keypair_create(sign, &keypair, sk) == 1);
450  CHECK(secp256k1_keypair_sec(none, sk_tmp, &keypair) == 1);
451  CHECK(secp256k1_memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0);
452 
453 
454  /* Using an invalid keypair is fine for keypair_seckey */
455  memset(&keypair, 0, sizeof(keypair));
456  CHECK(secp256k1_keypair_sec(none, sk_tmp, &keypair) == 1);
457  CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
458 
462 }
463 
464 void test_keypair_add(void) {
465  unsigned char sk[32];
466  secp256k1_keypair keypair;
467  unsigned char overflows[32];
468  unsigned char zeros96[96] = { 0 };
469  unsigned char tweak[32];
470  int i;
471  int ecount = 0;
475 
476  CHECK(sizeof(zeros96) == sizeof(keypair));
478  secp256k1_testrand256(tweak);
479  memset(overflows, 0xFF, 32);
480  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
481 
482  CHECK(secp256k1_keypair_xonly_tweak_add(none, &keypair, tweak) == 0);
483  CHECK(ecount == 1);
484  CHECK(secp256k1_keypair_xonly_tweak_add(sign, &keypair, tweak) == 0);
485  CHECK(ecount == 2);
486  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 1);
487  CHECK(secp256k1_keypair_xonly_tweak_add(verify, NULL, tweak) == 0);
488  CHECK(ecount == 3);
489  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, NULL) == 0);
490  CHECK(ecount == 4);
491  /* This does not set the keypair to zeroes */
492  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
493 
494  /* Invalid tweak zeroes the keypair */
495  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
496  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, overflows) == 0);
497  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
498 
499  /* A zero tweak is fine */
500  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
501  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, zeros96) == 1);
502 
503  /* Fails if the resulting keypair was (sk=0, pk=infinity) */
504  for (i = 0; i < count; i++) {
505  secp256k1_scalar scalar_tweak;
506  secp256k1_keypair keypair_tmp;
508  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
509  memcpy(&keypair_tmp, &keypair, sizeof(keypair));
510  /* Because sk may be negated before adding, we need to try with tweak =
511  * sk as well as tweak = -sk. */
512  secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
513  secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
514  secp256k1_scalar_get_b32(tweak, &scalar_tweak);
515  CHECK((secp256k1_keypair_xonly_tweak_add(ctx, &keypair, sk) == 0)
516  || (secp256k1_keypair_xonly_tweak_add(ctx, &keypair_tmp, tweak) == 0));
517  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
518  || secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
519  }
520 
521  /* Invalid keypair with a valid tweak */
522  memset(&keypair, 0, sizeof(keypair));
523  secp256k1_testrand256(tweak);
524  ecount = 0;
525  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
526  CHECK(ecount == 1);
527  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
528  /* Only seckey part of keypair invalid */
529  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
530  memset(&keypair, 0, 32);
531  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
532  CHECK(ecount == 2);
533  /* Only pubkey part of keypair invalid */
534  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
535  memset(&keypair.data[32], 0, 64);
536  CHECK(secp256k1_keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
537  CHECK(ecount == 3);
538 
539  /* Check that the keypair_tweak_add implementation is correct */
540  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
541  for (i = 0; i < count; i++) {
542  secp256k1_xonly_pubkey internal_pk;
543  secp256k1_xonly_pubkey output_pk;
544  secp256k1_pubkey output_pk_xy;
545  secp256k1_pubkey output_pk_expected;
546  unsigned char pk32[32];
547  unsigned char sk32[32];
548  int pk_parity;
549 
550  secp256k1_testrand256(tweak);
551  CHECK(secp256k1_keypair_xonly_pub(ctx, &internal_pk, NULL, &keypair) == 1);
552  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 1);
553  CHECK(secp256k1_keypair_xonly_pub(ctx, &output_pk, &pk_parity, &keypair) == 1);
554 
555  /* Check that it passes xonly_pubkey_tweak_add_check */
556  CHECK(secp256k1_xonly_pubkey_serialize(ctx, pk32, &output_pk) == 1);
557  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, pk32, pk_parity, &internal_pk, tweak) == 1);
558 
559  /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
560  CHECK(secp256k1_keypair_pub(ctx, &output_pk_xy, &keypair) == 1);
561  CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk_expected, &internal_pk, tweak) == 1);
562  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
563 
564  /* Check that the secret key in the keypair is tweaked correctly */
565  CHECK(secp256k1_keypair_sec(none, sk32, &keypair) == 1);
566  CHECK(secp256k1_ec_pubkey_create(ctx, &output_pk_expected, sk32) == 1);
567  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
568  }
572 }
573 
575  /* xonly key test cases */
581 
582  /* keypair tests */
583  test_keypair();
585 }
586 
587 #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:218
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).
secp256k1_xonly_pubkey_cmp
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:58
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:184
test_keypair_add
void test_keypair_add(void)
Definition: tests_impl.h:464
SECP256K1_TAG_PUBKEY_EVEN
#define SECP256K1_TAG_PUBKEY_EVEN
Prefix byte used to tag various encoded curvepoints for specific purposes.
Definition: secp256k1.h:194
secp256k1_ge::y
secp256k1_fe y
Definition: group.h:19
SECP256K1_CONTEXT_SIGN
#define SECP256K1_CONTEXT_SIGN
Definition: secp256k1.h:185
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:513
secp256k1_pubkey_load
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition: secp256k1.c:251
secp256k1_context_struct
Definition: secp256k1.c:75
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:98
test_keypair
void test_keypair(void)
Definition: tests_impl.h:349
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:177
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:235
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:215
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:209
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:202
N_PUBKEYS
#define N_PUBKEYS
Definition: tests_impl.h:319
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:158
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:197
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:284
secp256k1_fe
Definition: field_10x26.h:12
verify
static bool verify(const CScriptNum10 &bignum, const CScriptNum &scriptnum)
Definition: scriptnum_tests.cpp:21
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:225
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:135
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:320
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:187
test_xonly_pubkey_tweak_check
void test_xonly_pubkey_tweak_check(void)
Definition: tests_impl.h:249
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:574
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:604
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:256
secp256k1_keypair::data
unsigned char data[96]
Definition: secp256k1_extrakeys.h:34
secp256k1_ge::x
secp256k1_fe x
Definition: group.h:18
test_xonly_pubkey_comparison
void test_xonly_pubkey_comparison(void)
Definition: tests_impl.h:140
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:117
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:70
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