Bitcoin Core  27.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 test_xonly_pubkey(void) {
14  secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
15  secp256k1_ge pk1;
16  secp256k1_ge pk2;
17  secp256k1_fe y;
18  unsigned char sk[32];
19  unsigned char xy_sk[32];
20  unsigned char buf32[32];
21  unsigned char ones32[32];
22  unsigned char zeros64[64] = { 0 };
23  int pk_parity;
24  int i;
25 
27  memset(ones32, 0xFF, 32);
28  secp256k1_testrand256(xy_sk);
30  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
31 
32  /* Test xonly_pubkey_from_pubkey */
33  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
35  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1);
36  CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, NULL));
37  memset(&pk, 0, sizeof(pk));
38  CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk));
39 
40  /* Choose a secret key such that the resulting pubkey and xonly_pubkey match. */
41  memset(sk, 0, sizeof(sk));
42  sk[0] = 1;
44  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
45  CHECK(secp256k1_memcmp_var(&pk, &xonly_pk, sizeof(pk)) == 0);
46  CHECK(pk_parity == 0);
47 
48  /* Choose a secret key such that pubkey and xonly_pubkey are each others
49  * negation. */
50  sk[0] = 2;
52  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
53  CHECK(secp256k1_memcmp_var(&xonly_pk, &pk, sizeof(xonly_pk)) != 0);
54  CHECK(pk_parity == 1);
55  secp256k1_pubkey_load(CTX, &pk1, &pk);
56  secp256k1_pubkey_load(CTX, &pk2, (secp256k1_pubkey *) &xonly_pk);
57  CHECK(secp256k1_fe_equal(&pk1.x, &pk2.x) == 1);
58  secp256k1_fe_negate(&y, &pk2.y, 1);
59  CHECK(secp256k1_fe_equal(&pk1.y, &y) == 1);
60 
61  /* Test xonly_pubkey_serialize and xonly_pubkey_parse */
64  CHECK(secp256k1_memcmp_var(buf32, zeros64, 32) == 0);
65  {
66  /* A pubkey filled with 0s will fail to serialize due to pubkey_load
67  * special casing. */
69  memset(&pk_tmp, 0, sizeof(pk_tmp));
70  /* pubkey_load calls illegal callback */
72  }
73 
74  CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1);
77 
78  /* Serialization and parse roundtrip */
79  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk) == 1);
80  CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &xonly_pk) == 1);
81  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk_tmp, buf32) == 1);
82  CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(xonly_pk)) == 0);
83 
84  /* Test parsing invalid field elements */
85  memset(&xonly_pk, 1, sizeof(xonly_pk));
86  /* Overflowing field element */
87  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, ones32) == 0);
88  CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
89  memset(&xonly_pk, 1, sizeof(xonly_pk));
90  /* There's no point with x-coordinate 0 on secp256k1 */
91  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, zeros64) == 0);
92  CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
93  /* If a random 32-byte string can not be parsed with ec_pubkey_parse
94  * (because interpreted as X coordinate it does not correspond to a point on
95  * the curve) then xonly_pubkey_parse should fail as well. */
96  for (i = 0; i < COUNT; i++) {
97  unsigned char rand33[33];
98  secp256k1_testrand256(&rand33[1]);
99  rand33[0] = SECP256K1_TAG_PUBKEY_EVEN;
100  if (!secp256k1_ec_pubkey_parse(CTX, &pk, rand33, 33)) {
101  memset(&xonly_pk, 1, sizeof(xonly_pk));
102  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 0);
103  CHECK(secp256k1_memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
104  } else {
105  CHECK(secp256k1_xonly_pubkey_parse(CTX, &xonly_pk, &rand33[1]) == 1);
106  }
107  }
108 }
109 
110 static void test_xonly_pubkey_comparison(void) {
111  unsigned char pk1_ser[32] = {
112  0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
113  0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
114  };
115  const unsigned char pk2_ser[32] = {
116  0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
117  0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
118  };
121 
122  CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk1, pk1_ser) == 1);
123  CHECK(secp256k1_xonly_pubkey_parse(CTX, &pk2, pk2_ser) == 1);
124 
127  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk2) < 0);
128  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk1) > 0);
129  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0);
130  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk2, &pk2) == 0);
131  memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */
133  {
134  int32_t ecount = 0;
136  CHECK(secp256k1_xonly_pubkey_cmp(CTX, &pk1, &pk1) == 0);
137  CHECK(ecount == 2);
139  }
141 }
142 
143 static void test_xonly_pubkey_tweak(void) {
144  unsigned char zeros64[64] = { 0 };
145  unsigned char overflows[32];
146  unsigned char sk[32];
147  secp256k1_pubkey internal_pk;
148  secp256k1_xonly_pubkey internal_xonly_pk;
149  secp256k1_pubkey output_pk;
150  int pk_parity;
151  unsigned char tweak[32];
152  int i;
153 
154  memset(overflows, 0xff, sizeof(overflows));
155  secp256k1_testrand256(tweak);
157  CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1);
158  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
159 
160  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
161  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
162  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
163  CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, NULL, &internal_xonly_pk, tweak));
164  CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, NULL, tweak));
165  /* NULL internal_xonly_pk zeroes the output_pk */
166  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
167  CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, NULL));
168  /* NULL tweak zeroes the output_pk */
169  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
170 
171  /* Invalid tweak zeroes the output_pk */
172  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0);
173  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
174 
175  /* A zero tweak is fine */
176  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, zeros64) == 1);
177 
178  /* Fails if the resulting key was infinity */
179  for (i = 0; i < COUNT; i++) {
180  secp256k1_scalar scalar_tweak;
181  /* Because sk may be negated before adding, we need to try with tweak =
182  * sk as well as tweak = -sk. */
183  secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
184  secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
185  secp256k1_scalar_get_b32(tweak, &scalar_tweak);
186  CHECK((secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, sk) == 0)
187  || (secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 0));
188  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
189  }
190 
191  /* Invalid pk with a valid tweak */
192  memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk));
193  secp256k1_testrand256(tweak);
194  CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak));
195  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
196 }
197 
198 static void test_xonly_pubkey_tweak_check(void) {
199  unsigned char zeros64[64] = { 0 };
200  unsigned char overflows[32];
201  unsigned char sk[32];
202  secp256k1_pubkey internal_pk;
203  secp256k1_xonly_pubkey internal_xonly_pk;
204  secp256k1_pubkey output_pk;
205  secp256k1_xonly_pubkey output_xonly_pk;
206  unsigned char output_pk32[32];
207  unsigned char buf32[32];
208  int pk_parity;
209  unsigned char tweak[32];
210 
211  memset(overflows, 0xff, sizeof(overflows));
212  secp256k1_testrand256(tweak);
214  CHECK(secp256k1_ec_pubkey_create(CTX, &internal_pk, sk) == 1);
215  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
216 
217  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
218  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1);
219  CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &output_xonly_pk) == 1);
220  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
221  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
222  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
223  CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, NULL, pk_parity, &internal_xonly_pk, tweak));
224  /* invalid pk_parity value */
225  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, 2, &internal_xonly_pk, tweak) == 0);
226  CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, NULL, tweak));
227  CHECK_ILLEGAL(CTX, secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, NULL));
228 
229  memset(tweak, 1, sizeof(tweak));
230  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &internal_xonly_pk, NULL, &internal_pk) == 1);
231  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, tweak) == 1);
232  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &output_xonly_pk, &pk_parity, &output_pk) == 1);
233  CHECK(secp256k1_xonly_pubkey_serialize(CTX, output_pk32, &output_xonly_pk) == 1);
234  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, tweak) == 1);
235 
236  /* Wrong pk_parity */
237  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, !pk_parity, &internal_xonly_pk, tweak) == 0);
238  /* Wrong public key */
239  CHECK(secp256k1_xonly_pubkey_serialize(CTX, buf32, &internal_xonly_pk) == 1);
240  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
241 
242  /* Overflowing tweak not allowed */
243  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0);
244  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk, &internal_xonly_pk, overflows) == 0);
245  CHECK(secp256k1_memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
246 }
247 
248 /* Starts with an initial pubkey and recursively creates N_PUBKEYS - 1
249  * additional pubkeys by calling tweak_add. Then verifies every tweak starting
250  * from the last pubkey. */
251 #define N_PUBKEYS 32
253  unsigned char sk[32];
255  unsigned char pk_serialized[32];
256  unsigned char tweak[N_PUBKEYS - 1][32];
257  int i;
258 
260  CHECK(secp256k1_ec_pubkey_create(CTX, &pk[0], sk) == 1);
261  /* Add tweaks */
262  for (i = 0; i < N_PUBKEYS - 1; i++) {
263  secp256k1_xonly_pubkey xonly_pk;
264  memset(tweak[i], i + 1, sizeof(tweak[i]));
265  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i]) == 1);
266  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &pk[i + 1], &xonly_pk, tweak[i]) == 1);
267  }
268 
269  /* Verify tweaks */
270  for (i = N_PUBKEYS - 1; i > 0; i--) {
271  secp256k1_xonly_pubkey xonly_pk;
272  int pk_parity;
273  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk[i]) == 1);
274  CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk_serialized, &xonly_pk) == 1);
275  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, NULL, &pk[i - 1]) == 1);
276  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, pk_serialized, pk_parity, &xonly_pk, tweak[i - 1]) == 1);
277  }
278 }
279 #undef N_PUBKEYS
280 
281 static void test_keypair(void) {
282  unsigned char sk[32];
283  unsigned char sk_tmp[32];
284  unsigned char zeros96[96] = { 0 };
285  unsigned char overflows[32];
286  secp256k1_keypair keypair;
287  secp256k1_pubkey pk, pk_tmp;
288  secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
289  int pk_parity, pk_parity_tmp;
290 
291  CHECK(sizeof(zeros96) == sizeof(keypair));
292  memset(overflows, 0xFF, sizeof(overflows));
293 
294  /* Test keypair_create */
296  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
297  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
298  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
299  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) != 0);
301  CHECK_ILLEGAL(CTX, secp256k1_keypair_create(CTX, &keypair, NULL));
302  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
303  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
305  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
306 
307  /* Invalid secret key */
308  CHECK(secp256k1_keypair_create(CTX, &keypair, zeros96) == 0);
309  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
310  CHECK(secp256k1_keypair_create(CTX, &keypair, overflows) == 0);
311  CHECK(secp256k1_memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
312 
313  /* Test keypair_pub */
315  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
316  CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1);
317  CHECK_ILLEGAL(CTX, secp256k1_keypair_pub(CTX, NULL, &keypair));
319  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
320 
321  /* Using an invalid keypair is fine for keypair_pub */
322  memset(&keypair, 0, sizeof(keypair));
323  CHECK(secp256k1_keypair_pub(CTX, &pk, &keypair) == 1);
324  CHECK(secp256k1_memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
325 
326  /* keypair holds the same pubkey as pubkey_create */
327  CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
328  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
329  CHECK(secp256k1_keypair_pub(CTX, &pk_tmp, &keypair) == 1);
330  CHECK(secp256k1_memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
331 
334  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
335  CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1);
336  CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, NULL, &pk_parity, &keypair));
337  CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, NULL, &keypair) == 1);
338  CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, NULL));
339  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
340  /* Using an invalid keypair will set the xonly_pk to 0 (first reset
341  * xonly_pk). */
342  CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair) == 1);
343  memset(&keypair, 0, sizeof(keypair));
344  CHECK_ILLEGAL(CTX, secp256k1_keypair_xonly_pub(CTX, &xonly_pk, &pk_parity, &keypair));
345  CHECK(secp256k1_memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
346 
348  CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
349  CHECK(secp256k1_xonly_pubkey_from_pubkey(CTX, &xonly_pk, &pk_parity, &pk) == 1);
350  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
351  CHECK(secp256k1_keypair_xonly_pub(CTX, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
352  CHECK(secp256k1_memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
353  CHECK(pk_parity == pk_parity_tmp);
354 
355  /* Test keypair_seckey */
357  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
358  CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
359  CHECK_ILLEGAL(CTX, secp256k1_keypair_sec(CTX, NULL, &keypair));
360  CHECK_ILLEGAL(CTX, secp256k1_keypair_sec(CTX, sk_tmp, NULL));
361  CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
362 
363  /* keypair returns the same seckey it got */
364  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
365  CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
366  CHECK(secp256k1_memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0);
367 
368 
369  /* Using an invalid keypair is fine for keypair_seckey */
370  memset(&keypair, 0, sizeof(keypair));
371  CHECK(secp256k1_keypair_sec(CTX, sk_tmp, &keypair) == 1);
372  CHECK(secp256k1_memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
373 }
374 
375 static void test_keypair_add(void) {
376  unsigned char sk[32];
377  secp256k1_keypair keypair;
378  unsigned char overflows[32];
379  unsigned char zeros96[96] = { 0 };
380  unsigned char tweak[32];
381  int i;
382 
383  CHECK(sizeof(zeros96) == sizeof(keypair));
385  secp256k1_testrand256(tweak);
386  memset(overflows, 0xFF, 32);
387  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
388 
389  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
390  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
391  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
394  /* This does not set the keypair to zeroes */
395  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
396 
397  /* Invalid tweak zeroes the keypair */
398  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
399  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, overflows) == 0);
400  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
401 
402  /* A zero tweak is fine */
403  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
404  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, zeros96) == 1);
405 
406  /* Fails if the resulting keypair was (sk=0, pk=infinity) */
407  for (i = 0; i < COUNT; i++) {
408  secp256k1_scalar scalar_tweak;
409  secp256k1_keypair keypair_tmp;
411  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
412  memcpy(&keypair_tmp, &keypair, sizeof(keypair));
413  /* Because sk may be negated before adding, we need to try with tweak =
414  * sk as well as tweak = -sk. */
415  secp256k1_scalar_set_b32(&scalar_tweak, sk, NULL);
416  secp256k1_scalar_negate(&scalar_tweak, &scalar_tweak);
417  secp256k1_scalar_get_b32(tweak, &scalar_tweak);
418  CHECK((secp256k1_keypair_xonly_tweak_add(CTX, &keypair, sk) == 0)
419  || (secp256k1_keypair_xonly_tweak_add(CTX, &keypair_tmp, tweak) == 0));
420  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
421  || secp256k1_memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
422  }
423 
424  /* Invalid keypair with a valid tweak */
425  memset(&keypair, 0, sizeof(keypair));
426  secp256k1_testrand256(tweak);
428  CHECK(secp256k1_memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
429  /* Only seckey part of keypair invalid */
430  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
431  memset(&keypair, 0, 32);
433  /* Only pubkey part of keypair invalid */
434  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
435  memset(&keypair.data[32], 0, 64);
437 
438  /* Check that the keypair_tweak_add implementation is correct */
439  CHECK(secp256k1_keypair_create(CTX, &keypair, sk) == 1);
440  for (i = 0; i < COUNT; i++) {
441  secp256k1_xonly_pubkey internal_pk;
442  secp256k1_xonly_pubkey output_pk;
443  secp256k1_pubkey output_pk_xy;
444  secp256k1_pubkey output_pk_expected;
445  unsigned char pk32[32];
446  unsigned char sk32[32];
447  int pk_parity;
448 
449  secp256k1_testrand256(tweak);
450  CHECK(secp256k1_keypair_xonly_pub(CTX, &internal_pk, NULL, &keypair) == 1);
451  CHECK(secp256k1_keypair_xonly_tweak_add(CTX, &keypair, tweak) == 1);
452  CHECK(secp256k1_keypair_xonly_pub(CTX, &output_pk, &pk_parity, &keypair) == 1);
453 
454  /* Check that it passes xonly_pubkey_tweak_add_check */
455  CHECK(secp256k1_xonly_pubkey_serialize(CTX, pk32, &output_pk) == 1);
456  CHECK(secp256k1_xonly_pubkey_tweak_add_check(CTX, pk32, pk_parity, &internal_pk, tweak) == 1);
457 
458  /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
459  CHECK(secp256k1_keypair_pub(CTX, &output_pk_xy, &keypair) == 1);
460  CHECK(secp256k1_xonly_pubkey_tweak_add(CTX, &output_pk_expected, &internal_pk, tweak) == 1);
461  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
462 
463  /* Check that the secret key in the keypair is tweaked correctly */
464  CHECK(secp256k1_keypair_sec(CTX, sk32, &keypair) == 1);
465  CHECK(secp256k1_ec_pubkey_create(CTX, &output_pk_expected, sk32) == 1);
466  CHECK(secp256k1_memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
467  }
468 }
469 
470 static void run_extrakeys_tests(void) {
471  /* xonly key test cases */
477 
478  /* keypair tests */
479  test_keypair();
481 }
482 
483 #endif
static void run_extrakeys_tests(void)
Definition: tests_impl.h:470
static void test_xonly_pubkey(void)
Definition: tests_impl.h:12
static void test_xonly_pubkey_tweak_check(void)
Definition: tests_impl.h:198
static void test_xonly_pubkey_comparison(void)
Definition: tests_impl.h:110
#define N_PUBKEYS
Definition: tests_impl.h:251
static void test_keypair_add(void)
Definition: tests_impl.h:375
static void test_keypair(void)
Definition: tests_impl.h:281
static void test_xonly_pubkey_tweak_recursive(void)
Definition: tests_impl.h:252
static void test_xonly_pubkey_tweak(void)
Definition: tests_impl.h:143
#define secp256k1_fe_negate(r, a, m)
Negate a field element.
Definition: field.h:216
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:226
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_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:261
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:584
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.
#define CHECK_ILLEGAL_VOID(ctx, expr_or_stmt)
Definition: tests.c:70
static void counting_callback_fn(const char *str, void *data)
Definition: tests.c:81
static int COUNT
Definition: tests.c:40
#define CHECK_ILLEGAL(ctx, expr)
Definition: tests.c:78
static secp256k1_context * CTX
Definition: tests.c:41
static secp256k1_context * STATIC_CTX
Definition: tests.c:42