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