Bitcoin Core  26.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 void set_counting_callbacks(secp256k1_context *ctx0, int *ecount) {
15 }
16 
17 static void test_xonly_pubkey(void) {
19  secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
20  secp256k1_ge pk1;
21  secp256k1_ge pk2;
22  secp256k1_fe y;
23  unsigned char sk[32];
24  unsigned char xy_sk[32];
25  unsigned char buf32[32];
26  unsigned char ones32[32];
27  unsigned char zeros64[64] = { 0 };
28  int pk_parity;
29  int i;
30 
31  int ecount;
32 
33  set_counting_callbacks(CTX, &ecount);
34 
36  memset(ones32, 0xFF, 32);
37  secp256k1_testrand256(xy_sk);
39  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
40 
41  /* Test xonly_pubkey_from_pubkey */
42  ecount = 0;
43  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
44  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, NULL, &pk_parity, &pk) == 0);
45  CHECK(ecount == 1);
46  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1);
47  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, NULL) == 0);
48  CHECK(ecount == 2);
49  memset(&pk, 0, sizeof(pk));
50  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 0);
51  CHECK(ecount == 3);
52 
53  /* Choose a secret key such that the resulting pubkey and xonly_pubkey match. */
54  memset(sk, 0, sizeof(sk));
55  sk[0] = 1;
57  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
58  CHECK(secp256k1_memcmp_var(&pk, &xonly_pk, sizeof(pk)) == 0);
59  CHECK(pk_parity == 0);
60 
61  /* Choose a secret key such that pubkey and xonly_pubkey are each others
62  * negation. */
63  sk[0] = 2;
65  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
66  CHECK(secp256k1_memcmp_var(&xonly_pk, &pk, sizeof(xonly_pk)) != 0);
67  CHECK(pk_parity == 1);
68  secp256k1_pubkey_load(CTX, &pk1, &pk);
69  secp256k1_pubkey_load(CTX, &pk2, (secp256k1_pubkey *) &xonly_pk);
70  CHECK(secp256k1_fe_equal(&pk1.x, &pk2.x) == 1);
71  secp256k1_fe_negate(&y, &pk2.y, 1);
72  CHECK(secp256k1_fe_equal(&pk1.y, &y) == 1);
73 
74  /* Test xonly_pubkey_serialize and xonly_pubkey_parse */
75  ecount = 0;
76  CHECK(secp256k1_xonly_pubkey_serialize(CTX, NULL, &xonly_pk) == 0);
77  CHECK(ecount == 1);
78  CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, NULL) == 0);
79  CHECK(secp256k1_memcmp_var(buf32, zeros64, 32) == 0);
80  CHECK(ecount == 2);
81  {
82  /* A pubkey filled with 0s will fail to serialize due to pubkey_load
83  * special casing. */
85  memset(&pk_tmp, 0, sizeof(pk_tmp));
86  CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &pk_tmp) == 0);
87  }
88  /* pubkey_load called illegal callback */
89  CHECK(ecount == 3);
90 
91  CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1);
92  ecount = 0;
93  CHECK(secp256k1_xonly_pubkey_parse(CTX, NULL, buf32) == 0);
94  CHECK(ecount == 1);
95  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, NULL) == 0);
96  CHECK(ecount == 2);
97 
98  /* Serialization and parse roundtrip */
99  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1);
100  CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1);
101  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk_tmp, buf32) == 1);
102  CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(xonly_pk)) == 0);
103 
104  /* Test parsing invalid field elements */
105  memset(&xonly_pk, 1, sizeof(xonly_pk));
106  /* Overflowing field element */
107  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, ones32) == 0);
108  CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
109  memset(&xonly_pk, 1, sizeof(xonly_pk));
110  /* There's no point with x-coordinate 0 on secp256k1 */
111  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, zeros64) == 0);
112  CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
113  /* If a random 32-byte string can not be parsed with ec_pubkey_parse
114  * (because interpreted as X coordinate it does not correspond to a point on
115  * the curve) then xonly_pubkey_parse should fail as well. */
116  for (i = 0; i < COUNT; i++) {
117  unsigned char rand33[33];
118  secp256k1_testrand256(&rand33[1]);
119  rand33[0] = SECP256K1_TAG_PUBKEY_EVEN;
120  if (!secp256k1_ec_pubkey_parse(CTX, &pk, rand33, 33)) {
121  memset(&xonly_pk, 1, sizeof(xonly_pk));
122  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 0);
123  CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
124  } else {
125  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 1);
126  }
127  }
128  CHECK(ecount == 2);
129 }
130 
131 static void test_xonly_pubkey_comparison(void) {
132  unsigned char pk1_ser[32] = {
133  0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
134  0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
135  };
136  const unsigned char pk2_ser[32] = {
137  0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
138  0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
139  };
142  int ecount = 0;
143 
144  set_counting_callbacks(CTX, &ecount);
145 
146  CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk1, pk1_ser) == 1);
147  CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk2, pk2_ser) == 1);
148 
149  CHECK(secp256k1_xonly_pubkey_cmp(CTX, NULL, &pk2) < 0);
150  CHECK(ecount == 1);
151  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, NULL) > 0);
152  CHECK(ecount == 2);
153  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk2) < 0);
154  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk1) > 0);
155  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0);
156  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk2) == 0);
157  CHECK(ecount == 2);
158  memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */
159  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk2) < 0);
160  CHECK(ecount == 3);
161  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0);
162  CHECK(ecount == 5);
163  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk1) > 0);
164  CHECK(ecount == 6);
165 }
166 
167 static void test_xonly_pubkey_tweak(void) {
168  unsigned char zeros64[64] = { 0 };
169  unsigned char overflows[32];
170  unsigned char sk[32];
171  secp256k1_pubkey internal_pk;
172  secp256k1_xonly_pubkey internal_xonly_pk;
173  secp256k1_pubkey output_pk;
174  int pk_parity;
175  unsigned char tweak[32];
176  int i;
177 
178  int ecount;
179 
180  set_counting_callbacks(CTX, &ecount);
181 
182  memset(overflows, 0xff, sizeof(overflows));
183  secp256k1_testrand256(tweak);
185  CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1);
186  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
187 
188  ecount = 0;
189  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
190  CHECK(ecount == 0);
191  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
192  CHECK(ecount == 0);
193  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
194  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, NULL, &internal_xonly_pk, tweak) == 0);
195  CHECK(ecount == 1);
196  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, NULL, tweak) == 0);
197  CHECK(ecount == 2);
198  /* NULL internal_xonly_pk zeroes the output_pk */
199  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
200  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, NULL) == 0);
201  CHECK(ecount == 3);
202  /* NULL tweak zeroes the output_pk */
203  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
204 
205  /* Invalid tweak zeroes the output_pk */
206  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0);
207  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
208 
209  /* A zero tweak is fine */
210  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, zeros64) == 1);
211 
212  /* Fails if the resulting key was infinity */
213  for (i = 0; i < COUNT; i++) {
214  secp256k1_scalar scalar_tweak;
215  /* Because sk may be negated before adding, we need to try with tweak =
216  * sk as well as tweak = -sk. */
217  secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
218  secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
219  secp256k1_scalar_get_b32(tweak, &scalar_tweak);
220  CHECK((secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, sk) == 0)
221  || (secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 0));
222  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
223  }
224 
225  /* Invalid pk with a valid tweak */
226  memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk));
227  secp256k1_testrand256(tweak);
228  ecount = 0;
229  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 0);
230  CHECK(ecount == 1);
231  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
232 }
233 
234 static void test_xonly_pubkey_tweak_check(void) {
235  unsigned char zeros64[64] = { 0 };
236  unsigned char overflows[32];
237  unsigned char sk[32];
238  secp256k1_pubkey internal_pk;
239  secp256k1_xonly_pubkey internal_xonly_pk;
240  secp256k1_pubkey output_pk;
241  secp256k1_xonly_pubkey output_xonly_pk;
242  unsigned char output_pk32[32];
243  unsigned char buf32[32];
244  int pk_parity;
245  unsigned char tweak[32];
246 
247  int ecount;
248 
249  set_counting_callbacks(CTX, &ecount);
250 
251  memset(overflows, 0xff, sizeof(overflows));
252  secp256k1_testrand256(tweak);
254  CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1);
255  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
256 
257  ecount = 0;
258  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
259  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1);
260  CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &output_xonly_pk) == 1);
261  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
262  CHECK(ecount == 0);
263  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
264  CHECK(ecount == 0);
265  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
266  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, NULL, pk_parity, &internal_xonly_pk, tweak) == 0);
267  CHECK(ecount == 1);
268  /* invalid pk_parity value */
269  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, 2, &internal_xonly_pk, tweak) == 0);
270  CHECK(ecount == 1);
271  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, NULL, tweak) == 0);
272  CHECK(ecount == 2);
273  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, NULL) == 0);
274  CHECK(ecount == 3);
275 
276  memset(tweak, 1, sizeof(tweak));
277  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, NULL, &internal_pk) == 1);
278  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
279  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1);
280  CHECK(secp256k1_xonly_pubkey_serialize(CTX, output_pk32, &output_xonly_pk) == 1);
281  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, tweak) == 1);
282 
283  /* Wrong pk_parity */
284  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, !pk_parity, &internal_xonly_pk, tweak) == 0);
285  /* Wrong public key */
286  CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &internal_xonly_pk) == 1);
287  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
288 
289  /* Overflowing tweak not allowed */
290  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0);
291  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0);
292  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
293  CHECK(ecount == 3);
294 }
295 
296 /* Starts with an initial pubkey and recursively creates N_PUBKEYS - 1
297  * additional pubkeys by calling tweak_add. Then verifies every tweak starting
298  * from the last pubkey. */
299 #define N_PUBKEYS 32
301  unsigned char sk[32];
303  unsigned char pk_serialized[32];
304  unsigned char tweak[N_PUBKEYS - 1][32];
305  int i;
306 
308  CHECK(secp256k1_ec_pubkey_create(CTX, &pk[0], sk) == 1);
309  /* Add tweaks */
310  for (i = 0; i < N_PUBKEYS - 1; i++) {
311  secp256k1_xonly_pubkey xonly_pk;
312  memset(tweak[i], i + 1, sizeof(tweak[i]));
313  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i]) == 1);
314  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &pk[i + 1], &xonly_pk, tweak[i]) == 1);
315  }
316 
317  /* Verify tweaks */
318  for (i = N_PUBKEYS - 1; i > 0; i--) {
319  secp256k1_xonly_pubkey xonly_pk;
320  int pk_parity;
321  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk[i]) == 1);
322  CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk_serialized, &xonly_pk) == 1);
323  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i - 1]) == 1);
324  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, pk_serialized, pk_parity, &xonly_pk, tweak[i - 1]) == 1);
325  }
326 }
327 #undef N_PUBKEYS
328 
329 static void test_keypair(void) {
330  unsigned char sk[32];
331  unsigned char sk_tmp[32];
332  unsigned char zeros96[96] = { 0 };
333  unsigned char overflows[32];
334  secp256k1_keypair keypair;
335  secp256k1_pubkey pk, pk_tmp;
336  secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
337  int pk_parity, pk_parity_tmp;
338  int ecount;
339 
340  set_counting_callbacks(CTX, &ecount);
342 
343  CHECK(sizeof(zeros96) == sizeof(keypair));
344  memset(overflows, 0xFF, sizeof(overflows));
345 
346  /* Test keypair_create */
347  ecount = 0;
349  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
350  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
351  CHECK(ecount == 0);
352  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
353  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
354  CHECK(ecount == 0);
355  CHECK(secp256k1_keypair_create(CTX, NULL, sk) == 0);
356  CHECK(ecount == 1);
357  CHECK(secp256k1_keypair_create(CTX, &keypair, NULL) == 0);
358  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
359  CHECK(ecount == 2);
360  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
361  CHECK(ecount == 2);
362  CHECK(secp256k1_keypair_create(STATIC_CTX, &keypair, sk) == 0);
363  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
364  CHECK(ecount == 3);
365 
366  /* Invalid secret key */
367  CHECK(secp256k1_keypair_create(CTX, &keypair, zeros96) == 0);
368  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
369  CHECK(secp256k1_keypair_create(CTX, &keypair, overflows) == 0);
370  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
371 
372  /* Test keypair_pub */
373  ecount = 0;
375  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
376  CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1);
377  CHECK(secp256k1_keypair_pub(CTX, NULL, &keypair) == 0);
378  CHECK(ecount == 1);
379  CHECK(secp256k1_keypair_pub(CTX, &pk, NULL) == 0);
380  CHECK(ecount == 2);
381  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
382 
383  /* Using an invalid keypair is fine for keypair_pub */
384  memset(&keypair, 0, sizeof(keypair));
385  CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1);
386  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
387 
388  /* keypair holds the same pubkey as pubkey_create */
389  CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
390  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
391  CHECK(secp256k1_keypair_pub(CTX, &pk_tmp, &keypair) == 1);
392  CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
393 
395  ecount = 0;
397  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
398  CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1);
399  CHECK(secp256k1_keypair_xonly_pub(CTX, NULL, &pk_parity, &keypair) == 0);
400  CHECK(ecount == 1);
401  CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, NULL, &keypair) == 1);
402  CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, NULL) == 0);
403  CHECK(ecount == 2);
404  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
405  /* Using an invalid keypair will set the xonly_pk to 0 (first reset
406  * xonly_pk). */
407  CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1);
408  memset(&keypair, 0, sizeof(keypair));
409  CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 0);
410  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
411  CHECK(ecount == 3);
412 
414  CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
415  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
416  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
417  CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
418  CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
419  CHECK(pk_parity == pk_parity_tmp);
420 
421  /* Test keypair_seckey */
422  ecount = 0;
424  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
425  CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
426  CHECK(secp256k1_keypair_sec(CTX, NULL, &keypair) == 0);
427  CHECK(ecount == 1);
428  CHECK(secp256k1_keypair_sec(CTX, sk_tmp, NULL) == 0);
429  CHECK(ecount == 2);
430  CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
431 
432  /* keypair returns the same seckey it got */
433  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
434  CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
435  CHECK(secp256k1_memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0);
436 
437 
438  /* Using an invalid keypair is fine for keypair_seckey */
439  memset(&keypair, 0, sizeof(keypair));
440  CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
441  CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
442 
445 }
446 
447 static void test_keypair_add(void) {
448  unsigned char sk[32];
449  secp256k1_keypair keypair;
450  unsigned char overflows[32];
451  unsigned char zeros96[96] = { 0 };
452  unsigned char tweak[32];
453  int i;
454  int ecount = 0;
455 
456  set_counting_callbacks(CTX, &ecount);
457 
458  CHECK(sizeof(zeros96) == sizeof(keypair));
460  secp256k1_testrand256(tweak);
461  memset(overflows, 0xFF, 32);
462  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
463 
464  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
465  CHECK(ecount == 0);
466  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
467  CHECK(ecount == 0);
468  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
469  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, NULL, tweak) == 0);
470  CHECK(ecount == 1);
471  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, NULL) == 0);
472  CHECK(ecount == 2);
473  /* This does not set the keypair to zeroes */
474  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
475 
476  /* Invalid tweak zeroes the keypair */
477  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
478  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, overflows) == 0);
479  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
480 
481  /* A zero tweak is fine */
482  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
483  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, zeros96) == 1);
484 
485  /* Fails if the resulting keypair was (sk=0, pk=infinity) */
486  for (i = 0; i < COUNT; i++) {
487  secp256k1_scalar scalar_tweak;
488  secp256k1_keypair keypair_tmp;
490  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
491  memcpy(&keypair_tmp, &keypair, sizeof(keypair));
492  /* Because sk may be negated before adding, we need to try with tweak =
493  * sk as well as tweak = -sk. */
494  secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
495  secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
496  secp256k1_scalar_get_b32(tweak, &scalar_tweak);
497  CHECK((secp256k1_keypair_xonly_tweak_add(CTX, &keypair, sk) == 0)
498  || (secp256k1_keypair_xonly_tweak_add(CTX, &keypair_tmp, tweak) == 0));
499  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
500  || secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
501  }
502 
503  /* Invalid keypair with a valid tweak */
504  memset(&keypair, 0, sizeof(keypair));
505  secp256k1_testrand256(tweak);
506  ecount = 0;
507  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 0);
508  CHECK(ecount == 1);
509  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
510  /* Only seckey part of keypair invalid */
511  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
512  memset(&keypair, 0, 32);
513  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 0);
514  CHECK(ecount == 2);
515  /* Only pubkey part of keypair invalid */
516  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
517  memset(&keypair.data[32], 0, 64);
518  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 0);
519  CHECK(ecount == 3);
520 
521  /* Check that the keypair_tweak_add implementation is correct */
522  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
523  for (i = 0; i < COUNT; i++) {
524  secp256k1_xonly_pubkey internal_pk;
525  secp256k1_xonly_pubkey output_pk;
526  secp256k1_pubkey output_pk_xy;
527  secp256k1_pubkey output_pk_expected;
528  unsigned char pk32[32];
529  unsigned char sk32[32];
530  int pk_parity;
531 
532  secp256k1_testrand256(tweak);
533  CHECK(secp256k1_keypair_xonly_pub(CTX, &internal_pk, NULL, &keypair) == 1);
534  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
535  CHECK(secp256k1_keypair_xonly_pub(CTX, &output_pk, &pk_parity, &keypair) == 1);
536 
537  /* Check that it passes xonly_pubkey_tweak_add_check */
538  CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk32, &output_pk) == 1);
539  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, pk32, pk_parity, &internal_pk, tweak) == 1);
540 
541  /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
542  CHECK(secp256k1_keypair_pub(CTX, &output_pk_xy, &keypair) == 1);
543  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk_expected, &internal_pk, tweak) == 1);
544  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
545 
546  /* Check that the secret key in the keypair is tweaked correctly */
547  CHECK(secp256k1_keypair_sec(CTX, sk32, &keypair) == 1);
548  CHECK(secp256k1_ec_pubkey_create(CTX, &output_pk_expected, sk32) == 1);
549  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
550  }
551 }
552 
553 static void run_extrakeys_tests(void) {
554  /* xonly key test cases */
560 
561  /* keypair tests */
562  test_keypair();
564 }
565 
566 #endif
static void run_extrakeys_tests(void)
Definition: tests_impl.h:553
static void test_xonly_pubkey(void)
Definition: tests_impl.h:17
static void test_xonly_pubkey_tweak_check(void)
Definition: tests_impl.h:234
static void set_counting_callbacks(secp256k1_context *ctx0, int *ecount)
Definition: tests_impl.h:12
static void test_xonly_pubkey_comparison(void)
Definition: tests_impl.h:131
#define N_PUBKEYS
Definition: tests_impl.h:299
static void test_keypair_add(void)
Definition: tests_impl.h:447
static void test_keypair(void)
Definition: tests_impl.h:329
static void test_xonly_pubkey_tweak_recursive(void)
Definition: tests_impl.h:300
static void test_xonly_pubkey_tweak(void)
Definition: tests_impl.h:167
#define secp256k1_fe_negate(r, a, m)
Negate a field element.
Definition: field.h:215
static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Determine whether two field elements are equal.
#define CHECK(cond)
Unconditional failure on condition failure.
Definition: util.h:35
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow)
Set a scalar from a big endian byte array.
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
Convert a scalar to a byte array.
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
Compute the complement of a scalar (modulo the group order).
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
Definition: util.h:217
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition: secp256k1.c:239
#define SECP256K1_TAG_PUBKEY_EVEN
Prefix byte used to tag various encoded curvepoints for specific purposes.
Definition: secp256k1.h:219
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:210
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:198
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:272
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:595
SECP256K1_API int secp256k1_xonly_pubkey_cmp(const secp256k1_context *ctx, const secp256k1_xonly_pubkey *pk1, const secp256k1_xonly_pubkey *pk2) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compare two x-only public keys using lexicographic order.
Definition: main_impl.h:59
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_pub(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const secp256k1_keypair *keypair) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Get the public key from a keypair.
Definition: main_impl.h:224
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_sec(const secp256k1_context *ctx, unsigned char *seckey, const secp256k1_keypair *keypair) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Get the secret key from a keypair.
Definition: main_impl.h:214
SECP256K1_API int secp256k1_xonly_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output32, const secp256k1_xonly_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Serialize an xonly_pubkey object into a 32-byte sequence.
Definition: main_impl.h:44
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check(const secp256k1_context *ctx, const unsigned char *tweaked_pubkey32, int tweaked_pk_parity, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5)
Checks that a tweaked pubkey is the result of calling secp256k1_xonly_pubkey_tweak_add with internal_...
Definition: main_impl.h:135
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_create(const secp256k1_context *ctx, secp256k1_keypair *keypair, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the keypair for a secret key.
Definition: main_impl.h:196
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_from_pubkey(const secp256k1_context *ctx, secp256k1_xonly_pubkey *xonly_pubkey, int *pk_parity, const secp256k1_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4)
Converts a secp256k1_pubkey into a secp256k1_xonly_pubkey.
Definition: main_impl.h:99
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_tweak_add(const secp256k1_context *ctx, secp256k1_keypair *keypair, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Tweak a keypair by adding tweak32 to the secret key and updating the public key accordingly.
Definition: main_impl.h:255
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add(const secp256k1_context *ctx, secp256k1_pubkey *output_pubkey, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Tweak an x-only public key by adding the generator multiplied with tweak32 to it.
Definition: main_impl.h:118
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_keypair_xonly_pub(const secp256k1_context *ctx, secp256k1_xonly_pubkey *pubkey, int *pk_parity, const secp256k1_keypair *keypair) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4)
Get the x-only public key from a keypair.
Definition: main_impl.h:234
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(const secp256k1_context *ctx, secp256k1_xonly_pubkey *pubkey, const unsigned char *input32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a 32-byte sequence into a xonly_pubkey object.
Definition: main_impl.h:22
This field implementation represents the value as 10 uint32_t limbs in base 2^26.
Definition: field_10x26.h:14
A group element in affine coordinates on the secp256k1 curve, or occasionally on an isomorphic curve ...
Definition: group.h:16
secp256k1_fe x
Definition: group.h:17
secp256k1_fe y
Definition: group.h:18
Opaque data structure that holds a keypair consisting of a secret and a public key.
unsigned char data[96]
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:74
A scalar modulo the group order of the secp256k1 curve.
Definition: scalar_4x64.h:13
Opaque data structure that holds a parsed and valid "x-only" public key.
static void secp256k1_testrand256(unsigned char *b32)
Generate a pseudorandom 32-byte array.
static int COUNT
Definition: tests.c:39
static secp256k1_context * CTX
Definition: tests.c:40
static void counting_illegal_callback_fn(const char *str, void *data)
Definition: tests.c:74
static secp256k1_context * STATIC_CTX
Definition: tests.c:41