Bitcoin Core  24.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 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);
38  CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
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;
56  CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 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;
64  CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
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 
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 
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 
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 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;
340 
341  set_counting_callbacks(ctx, &ecount);
342  set_counting_callbacks(sttc, &ecount);
343 
344  CHECK(sizeof(zeros96) == sizeof(keypair));
345  memset(overflows, 0xFF, sizeof(overflows));
346 
347  /* Test keypair_create */
348  ecount = 0;
350  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
351  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
352  CHECK(ecount == 0);
353  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
354  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
355  CHECK(ecount == 0);
356  CHECK(secp256k1_keypair_create(ctx, NULL, sk) == 0);
357  CHECK(ecount == 1);
358  CHECK(secp256k1_keypair_create(ctx, &keypair, NULL) == 0);
359  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
360  CHECK(ecount == 2);
361  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
362  CHECK(ecount == 2);
363  CHECK(secp256k1_keypair_create(sttc, &keypair, sk) == 0);
364  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
365  CHECK(ecount == 3);
366 
367  /* Invalid secret key */
368  CHECK(secp256k1_keypair_create(ctx, &keypair, zeros96) == 0);
369  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
370  CHECK(secp256k1_keypair_create(ctx, &keypair, overflows) == 0);
371  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
372 
373  /* Test keypair_pub */
374  ecount = 0;
376  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
377  CHECK(secp256k1_keypair_pub(ctx, &pk, &keypair) == 1);
378  CHECK(secp256k1_keypair_pub(ctx, NULL, &keypair) == 0);
379  CHECK(ecount == 1);
380  CHECK(secp256k1_keypair_pub(ctx, &pk, NULL) == 0);
381  CHECK(ecount == 2);
382  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
383 
384  /* Using an invalid keypair is fine for keypair_pub */
385  memset(&keypair, 0, sizeof(keypair));
386  CHECK(secp256k1_keypair_pub(ctx, &pk, &keypair) == 1);
387  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
388 
389  /* keypair holds the same pubkey as pubkey_create */
390  CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
391  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
392  CHECK(secp256k1_keypair_pub(ctx, &pk_tmp, &keypair) == 1);
393  CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
394 
396  ecount = 0;
398  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
399  CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pk, &pk_parity, &keypair) == 1);
400  CHECK(secp256k1_keypair_xonly_pub(ctx, NULL, &pk_parity, &keypair) == 0);
401  CHECK(ecount == 1);
402  CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pk, NULL, &keypair) == 1);
403  CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pk, &pk_parity, NULL) == 0);
404  CHECK(ecount == 2);
405  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
406  /* Using an invalid keypair will set the xonly_pk to 0 (first reset
407  * xonly_pk). */
408  CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pk, &pk_parity, &keypair) == 1);
409  memset(&keypair, 0, sizeof(keypair));
410  CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pk, &pk_parity, &keypair) == 0);
411  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
412  CHECK(ecount == 3);
413 
415  CHECK(secp256k1_ec_pubkey_create(ctx, &pk, sk) == 1);
416  CHECK(secp256k1_xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk) == 1);
417  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
418  CHECK(secp256k1_keypair_xonly_pub(ctx, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
419  CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
420  CHECK(pk_parity == pk_parity_tmp);
421 
422  /* Test keypair_seckey */
423  ecount = 0;
425  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
426  CHECK(secp256k1_keypair_sec(ctx, sk_tmp, &keypair) == 1);
427  CHECK(secp256k1_keypair_sec(ctx, NULL, &keypair) == 0);
428  CHECK(ecount == 1);
429  CHECK(secp256k1_keypair_sec(ctx, sk_tmp, NULL) == 0);
430  CHECK(ecount == 2);
431  CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
432 
433  /* keypair returns the same seckey it got */
434  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
435  CHECK(secp256k1_keypair_sec(ctx, sk_tmp, &keypair) == 1);
436  CHECK(secp256k1_memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0);
437 
438 
439  /* Using an invalid keypair is fine for keypair_seckey */
440  memset(&keypair, 0, sizeof(keypair));
441  CHECK(secp256k1_keypair_sec(ctx, sk_tmp, &keypair) == 1);
442  CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
444 }
445 
446 void test_keypair_add(void) {
447  unsigned char sk[32];
448  secp256k1_keypair keypair;
449  unsigned char overflows[32];
450  unsigned char zeros96[96] = { 0 };
451  unsigned char tweak[32];
452  int i;
453  int ecount = 0;
454 
455  set_counting_callbacks(ctx, &ecount);
456 
457  CHECK(sizeof(zeros96) == sizeof(keypair));
459  secp256k1_testrand256(tweak);
460  memset(overflows, 0xFF, 32);
461  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
462 
463  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 1);
464  CHECK(ecount == 0);
465  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 1);
466  CHECK(ecount == 0);
467  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 1);
468  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, NULL, tweak) == 0);
469  CHECK(ecount == 1);
470  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, NULL) == 0);
471  CHECK(ecount == 2);
472  /* This does not set the keypair to zeroes */
473  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
474 
475  /* Invalid tweak zeroes the keypair */
476  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
477  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, overflows) == 0);
478  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
479 
480  /* A zero tweak is fine */
481  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
482  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, zeros96) == 1);
483 
484  /* Fails if the resulting keypair was (sk=0, pk=infinity) */
485  for (i = 0; i < count; i++) {
486  secp256k1_scalar scalar_tweak;
487  secp256k1_keypair keypair_tmp;
489  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
490  memcpy(&keypair_tmp, &keypair, sizeof(keypair));
491  /* Because sk may be negated before adding, we need to try with tweak =
492  * sk as well as tweak = -sk. */
493  secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
494  secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
495  secp256k1_scalar_get_b32(tweak, &scalar_tweak);
496  CHECK((secp256k1_keypair_xonly_tweak_add(ctx, &keypair, sk) == 0)
497  || (secp256k1_keypair_xonly_tweak_add(ctx, &keypair_tmp, tweak) == 0));
498  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
499  || secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
500  }
501 
502  /* Invalid keypair with a valid tweak */
503  memset(&keypair, 0, sizeof(keypair));
504  secp256k1_testrand256(tweak);
505  ecount = 0;
506  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 0);
507  CHECK(ecount == 1);
508  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
509  /* Only seckey part of keypair invalid */
510  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
511  memset(&keypair, 0, 32);
512  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 0);
513  CHECK(ecount == 2);
514  /* Only pubkey part of keypair invalid */
515  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
516  memset(&keypair.data[32], 0, 64);
517  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 0);
518  CHECK(ecount == 3);
519 
520  /* Check that the keypair_tweak_add implementation is correct */
521  CHECK(secp256k1_keypair_create(ctx, &keypair, sk) == 1);
522  for (i = 0; i < count; i++) {
523  secp256k1_xonly_pubkey internal_pk;
524  secp256k1_xonly_pubkey output_pk;
525  secp256k1_pubkey output_pk_xy;
526  secp256k1_pubkey output_pk_expected;
527  unsigned char pk32[32];
528  unsigned char sk32[32];
529  int pk_parity;
530 
531  secp256k1_testrand256(tweak);
532  CHECK(secp256k1_keypair_xonly_pub(ctx, &internal_pk, NULL, &keypair) == 1);
533  CHECK(secp256k1_keypair_xonly_tweak_add(ctx, &keypair, tweak) == 1);
534  CHECK(secp256k1_keypair_xonly_pub(ctx, &output_pk, &pk_parity, &keypair) == 1);
535 
536  /* Check that it passes xonly_pubkey_tweak_add_check */
537  CHECK(secp256k1_xonly_pubkey_serialize(ctx, pk32, &output_pk) == 1);
538  CHECK(secp256k1_xonly_pubkey_tweak_add_check(ctx, pk32, pk_parity, &internal_pk, tweak) == 1);
539 
540  /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
541  CHECK(secp256k1_keypair_pub(ctx, &output_pk_xy, &keypair) == 1);
542  CHECK(secp256k1_xonly_pubkey_tweak_add(ctx, &output_pk_expected, &internal_pk, tweak) == 1);
543  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
544 
545  /* Check that the secret key in the keypair is tweaked correctly */
546  CHECK(secp256k1_keypair_sec(ctx, sk32, &keypair) == 1);
547  CHECK(secp256k1_ec_pubkey_create(ctx, &output_pk_expected, sk32) == 1);
548  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
549  }
550 }
551 
553  /* xonly key test cases */
559 
560  /* keypair tests */
561  test_keypair();
563 }
564 
565 #endif
void test_xonly_pubkey(void)
Definition: tests_impl.h:17
void test_keypair_add(void)
Definition: tests_impl.h:446
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
void run_extrakeys_tests(void)
Definition: tests_impl.h:552
void test_xonly_pubkey_tweak(void)
Definition: tests_impl.h:167
void test_xonly_pubkey_tweak_recursive(void)
Definition: tests_impl.h:300
#define N_PUBKEYS
Definition: tests_impl.h:299
void test_xonly_pubkey_comparison(void)
Definition: tests_impl.h:131
void test_keypair(void)
Definition: tests_impl.h:329
static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m)
Set a field element equal to the additive inverse of another.
static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b)
Compare two field elements.
#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:201
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition: secp256k1.c:215
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx) SECP256K1_ARG_NONNULL(1)
Destroy a secp256k1 context object (created in dynamically allocated memory).
Definition: secp256k1.c:166
#define SECP256K1_TAG_PUBKEY_EVEN
Prefix byte used to tag various encoded curvepoints for specific purposes.
Definition: secp256k1.h:217
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:182
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:173
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:248
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the public key for a secret key.
Definition: secp256k1.c:571
SECP256K1_API secp256k1_context * secp256k1_context_clone(const secp256k1_context *ctx) SECP256K1_ARG_NONNULL(1) SECP256K1_WARN_UNUSED_RESULT
Copy a secp256k1 context object (into dynamically allocated memory).
Definition: secp256k1.c:148
SECP256K1_API const secp256k1_context * secp256k1_context_static
A built-in constant secp256k1 context object with static storage duration, to be used in conjunction ...
Definition: secp256k1.c:75
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
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:223
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:213
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
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:134
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:195
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
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:254
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
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:233
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
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 secp256k1_context * ctx
Definition: tests.c:35
static void counting_illegal_callback_fn(const char *str, void *data)
Definition: tests.c:37
static int count
Definition: tests.c:34