Bitcoin ABC 0.32.10
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
12static void set_counting_callbacks(secp256k1_context *ctx0, int *ecount) {
15}
16
19 secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
20 secp256k1_ge pk1;
21 secp256k1_ge pk2;
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
34
36 memset(ones32, 0xFF, 32);
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));
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));
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));
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
329void 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
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));
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));
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
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
554 /* xonly key test cases */
560
561 /* keypair tests */
562 test_keypair();
564}
565
566#endif
void test_xonly_pubkey(void)
Definition: tests_impl.h:17
void test_keypair_add(void)
Definition: tests_impl.h:447
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:553
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.
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:197
#define CHECK(cond)
Definition: util.h:81
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition: secp256k1.c:231
#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:195
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:183
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:264
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:588
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 int COUNT
Definition: tests.c:30
static secp256k1_context * CTX
Definition: tests.c:31
static void counting_illegal_callback_fn(const char *str, void *data)
Definition: tests.c:34
static secp256k1_context * STATIC_CTX
Definition: tests.c:32