Bitcoin Core 28.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
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
11
12static void test_xonly_pubkey(void) {
14 secp256k1_xonly_pubkey xonly_pk, xonly_pk_tmp;
15 secp256k1_ge pk1;
16 secp256k1_ge pk2;
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
26 testrand256(sk);
27 memset(ones32, 0xFF, 32);
28 testrand256(xy_sk);
29 CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
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;
43 CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 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;
51 CHECK(secp256k1_ec_pubkey_create(CTX, &pk, sk) == 1);
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 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
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
143static 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 testrand256(tweak);
156 testrand256(sk);
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 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
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 testrand256(tweak);
213 testrand256(sk);
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
259 testrand256(sk);
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
281static 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 */
295 testrand256(sk);
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);
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 */
314 testrand256(sk);
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
333 testrand256(sk);
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 */
356 testrand256(sk);
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));
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
375static 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));
384 testrand256(sk);
385 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;
410 testrand256(sk);
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 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 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
470static 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:229
static int secp256k1_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_pubkey *pubkey)
Definition secp256k1.c:240
#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:199
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:262
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:613
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 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