bitcoinsecp256k1_keys/extrakeys.rs
1crate::ix!();
2
3//-------------------------------------------[.cpp/bitcoin/src/secp256k1/include/extrakeys.h]
4
5/**
6 | Opaque data structure that holds a parsed
7 | and valid "x-only" public key.
8 |
9 | An x-only pubkey encodes a point whose
10 | Y coordinate is even. It is serialized
11 | using only its X coordinate (32 bytes).
12 | See BIP-340 for more information about
13 | x-only pubkeys.
14 |
15 | The exact representation of data inside
16 | is implementation defined and not guaranteed
17 | to be portable between different platforms
18 | or versions. It is however guaranteed
19 | to be 64 bytes in size, and can be safely
20 | copied/moved.
21 |
22 | If you need to convert to a format suitable
23 | for storage, transmission, use use
24 | xonly_pubkey_serialize and xonly_pubkey_parse.
25 | To compare keys, use xonly_pubkey_cmp.
26 |
27 */
28pub struct XOnlyPubKey {
29 data: [u8; 64],
30}
31
32/**
33 | Opaque data structure that holds a keypair
34 | consisting of a secret and a public key.
35 |
36 | The exact representation of data inside
37 | is implementation defined and not guaranteed
38 | to be portable between different platforms
39 | or versions. It is however guaranteed
40 | to be 96 bytes in size, and can be safely
41 | copied/moved.
42 |
43 */
44pub struct KeyPair {
45 data: [u8; 96],
46}
47
48/**
49 | Parse a 32-byte sequence into a xonly_pubkey
50 | object.
51 |
52 | Returns: 1 if the public key was fully valid.
53 |
54 | 0 if the public key could not be
55 | parsed or is invalid.
56 |
57 | Args: ctx: a secp256k1 context object
58 | (cannot be NULL).
59 |
60 | Out: pubkey: pointer to a pubkey object. If
61 | 1 is returned, it is set to
62 | a parsed version of input. If
63 | not, it's set to an invalid
64 | value. (cannot be NULL).
65 |
66 | In: input32: pointer to a serialized
67 | xonly_pubkey (cannot be NULL)
68 */
69lazy_static!{
70 /*
71 API WARN_UNUSED_RESULT int xonly_pubkey_parse(
72 const context* ctx,
73 xonly_pubkey* pubkey,
74 const unsigned char *input32
75 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(3);
76 */
77}
78
79/**
80 | Serialize an xonly_pubkey object into a 32-byte
81 | sequence.
82 |
83 | Returns: 1 always.
84 |
85 | Args: ctx: a secp256k1 context object
86 | (cannot be NULL).
87 |
88 | Out: output32: a pointer to a 32-byte array to
89 | place the serialized key in
90 | (cannot be NULL).
91 |
92 | In: pubkey: a pointer to a xonly_pubkey
93 | containing an initialized
94 | public key (cannot be NULL).
95 */
96lazy_static!{
97 /*
98 API int xonly_pubkey_serialize(
99 const context* ctx,
100 unsigned char *output32,
101 const xonly_pubkey* pubkey
102 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(3);
103 */
104}
105
106/**
107 | Compare two x-only public keys using
108 | lexicographic order
109 |
110 | Returns: <0 if the first public key is less
111 | than the second
112 |
113 | >0 if the first public key is greater
114 | than the second
115 |
116 | 0 if the two public keys are equal
117 |
118 | Args: ctx: a secp256k1 context object.
119 | In: pubkey1: first public key to compare
120 | pubkey2: second public key to compare
121 */
122lazy_static!{
123 /*
124 API int xonly_pubkey_cmp(
125 const context* ctx,
126 const xonly_pubkey* pk1,
127 const xonly_pubkey* pk2
128 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(3);
129 */
130}
131
132/**
133 | Converts a pubkey into a xonly_pubkey.
134 |
135 | Returns: 1 if the public key was successfully
136 | converted
137 |
138 | 0 otherwise
139 |
140 | Args: ctx: pointer to a context object
141 | (cannot be NULL)
142 |
143 | Out: xonly_pubkey: pointer to an x-only public
144 | key object for placing the
145 | converted public key
146 | (cannot be NULL)
147 |
148 | pk_parity: pointer to an integer that
149 | will be set to 1 if the
150 | point encoded by
151 | xonly_pubkey is the
152 | negation of the pubkey and
153 | set to 0 otherwise. (can be
154 | NULL)
155 |
156 | In: pubkey: pointer to a public key
157 | that is converted (cannot
158 | be NULL)
159 |
160 */
161lazy_static!{
162 /*
163 API WARN_UNUSED_RESULT int xonly_pubkey_from_pubkey(
164 const context* ctx,
165 xonly_pubkey *xonly_pubkey,
166 int *pk_parity,
167 const pubkey *pubkey
168 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(4);
169 */
170}
171
172/**
173 | Tweak an x-only public key by adding the
174 | generator multiplied with tweak32 to it.
175 |
176 | Note that the resulting point can not in
177 | general be represented by an x-only pubkey
178 | because it may have an odd
179 | Y coordinate. Instead, the output_pubkey is
180 | a normal pubkey.
181 |
182 | Returns: 0 if the arguments are invalid or the
183 | resulting public key would be invalid
184 | (only when the tweak is the negation
185 | of the corresponding secret
186 | key). 1 otherwise.
187 |
188 | Args: ctx: pointer to a context
189 | object initialized for
190 | verification (cannot be
191 | NULL)
192 |
193 | Out: output_pubkey: pointer to a public key
194 | to store the result. Will
195 | be set to an invalid
196 | value if this function
197 | returns 0 (cannot be
198 | NULL)
199 |
200 | In: internal_pubkey: pointer to an x-only
201 | pubkey to apply the tweak
202 | to. (cannot be NULL).
203 |
204 | tweak32: pointer to a 32-byte
205 | tweak. If the tweak is
206 | invalid according to
207 | ec_seckey_verify, this
208 | function returns 0. For
209 | uniformly random 32-byte
210 | arrays the chance of
211 | being invalid is
212 | negligible (around 1 in
213 | 2^128) (cannot be NULL).
214 */
215lazy_static!{
216 /*
217 API WARN_UNUSED_RESULT int xonly_pubkey_tweak_add(
218 const context* ctx,
219 pubkey *output_pubkey,
220 const xonly_pubkey *internal_pubkey,
221 const unsigned char *tweak32
222 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(3) ARG_NONNULL(4);
223 */
224}
225
226/**
227 | Checks that a tweaked pubkey is the result of
228 | calling xonly_pubkey_tweak_add with
229 | internal_pubkey and tweak32.
230 |
231 | The tweaked pubkey is represented by its
232 | 32-byte x-only serialization and its
233 | pk_parity, which can both be obtained by
234 | converting the result of tweak_add to
235 | a xonly_pubkey.
236 |
237 | Note that this alone does _not_ verify that
238 | the tweaked pubkey is a commitment. If the
239 | tweak is not chosen in a specific way, the
240 | tweaked pubkey can easily be the result of
241 | a different internal_pubkey and tweak.
242 |
243 | Returns: 0 if the arguments are invalid or the
244 | tweaked pubkey is not the result of
245 | tweaking the internal_pubkey with
246 | tweak32. 1 otherwise.
247 |
248 | Args: ctx: pointer to a context
249 | object initialized for
250 | verification (cannot be
251 | NULL)
252 |
253 | In: tweaked_pubkey32: pointer to a serialized
254 | xonly_pubkey (cannot be
255 | NULL)
256 |
257 | tweaked_pk_parity: the parity of the
258 | tweaked pubkey (whose
259 | serialization is passed
260 | in as tweaked_pubkey32).
261 | This must match the
262 | pk_parity value that is
263 | returned when calling
264 | xonly_pubkey with the
265 | tweaked pubkey, or this
266 | function will fail.
267 |
268 | internal_pubkey: pointer to an x-only
269 | public key object to
270 | apply the tweak to
271 | (cannot be NULL)
272 |
273 | tweak32: pointer to a 32-byte
274 | tweak (cannot be NULL)
275 |
276 */
277lazy_static!{
278 /*
279 API WARN_UNUSED_RESULT int xonly_pubkey_tweak_add_check(
280 const context* ctx,
281 const unsigned char *tweaked_pubkey32,
282 int tweaked_pk_parity,
283 const xonly_pubkey *internal_pubkey,
284 const unsigned char *tweak32
285 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(4) ARG_NONNULL(5);
286 */
287}
288
289/**
290 | Compute the keypair for a secret key.
291 |
292 | Returns: 1: secret was valid, keypair is ready
293 | to use
294 |
295 | 0: secret was invalid, try again with
296 | a different secret
297 |
298 | Args: ctx: pointer to a context object,
299 | initialized for signing (cannot
300 | be NULL)
301 |
302 | Out: keypair: pointer to the created keypair
303 | (cannot be NULL)
304 |
305 | In: seckey: pointer to a 32-byte secret key
306 | (cannot be NULL)
307 */
308lazy_static!{
309 /*
310 API WARN_UNUSED_RESULT int keypair_create(
311 const context* ctx,
312 keypair *keypair,
313 const unsigned char *seckey
314 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(3);
315 */
316}
317
318/**
319 | Get the secret key from a keypair.
320 |
321 | Returns: 0 if the arguments are
322 | invalid. 1 otherwise.
323 |
324 | Args: ctx: pointer to a context object
325 | (cannot be NULL)
326 |
327 | Out: seckey: pointer to a 32-byte buffer for
328 | the secret key (cannot be NULL)
329 |
330 | In: keypair: pointer to a keypair (cannot be
331 | NULL)
332 */
333lazy_static!{
334 /*
335 API WARN_UNUSED_RESULT int keypair_sec(
336 const context* ctx,
337 unsigned char *seckey,
338 const keypair *keypair
339 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(3);
340 */
341}
342
343/**
344 | Get the public key from a keypair.
345 |
346 | Returns: 0 if the arguments are
347 | invalid. 1 otherwise.
348 |
349 | Args: ctx: pointer to a context object
350 | (cannot be NULL)
351 |
352 | Out: pubkey: pointer to a pubkey object. If
353 | 1 is returned, it is set to the
354 | keypair public key. If not, it's
355 | set to an invalid value. (cannot
356 | be NULL)
357 |
358 | In: keypair: pointer to a keypair (cannot be
359 | NULL)
360 |
361 */
362lazy_static!{
363 /*
364 API WARN_UNUSED_RESULT int keypair_pub(
365 const context* ctx,
366 pubkey *pubkey,
367 const keypair *keypair
368 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(3);
369 */
370}
371
372/**
373 | Get the x-only public key from a keypair.
374 |
375 | This is the same as calling keypair_pub and
376 | then xonly_pubkey_from_pubkey.
377 |
378 | Returns: 0 if the arguments are
379 | invalid. 1 otherwise.
380 |
381 | Args: ctx: pointer to a context object
382 | (cannot be NULL)
383 |
384 | Out: pubkey: pointer to an xonly_pubkey
385 | object. If 1 is returned, it is
386 | set to the keypair public key
387 | after converting it to an
388 | xonly_pubkey. If not, it's set to
389 | an invalid value (cannot be
390 | NULL).
391 |
392 | pk_parity: pointer to an integer that will
393 | be set to the pk_parity argument
394 | of xonly_pubkey_from_pubkey (can
395 | be NULL).
396 |
397 | In: keypair: pointer to a keypair (cannot be
398 | NULL)
399 |
400 */
401lazy_static!{
402 /*
403 API WARN_UNUSED_RESULT int keypair_xonly_pub(
404 const context* ctx,
405 xonly_pubkey *pubkey,
406 int *pk_parity,
407 const keypair *keypair
408 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(4);
409 */
410}
411
412/**
413 | Tweak a keypair by adding tweak32 to the secret
414 | key and updating the public key accordingly.
415 |
416 | Calling this function and then keypair_pub
417 | results in the same public key as calling
418 | keypair_xonly_pub and then
419 | xonly_pubkey_tweak_add.
420 |
421 | Returns: 0 if the arguments are invalid or the
422 | resulting keypair would be invalid
423 | (only when the tweak is the negation
424 | of the keypair's secret
425 | key). 1 otherwise.
426 |
427 | Args: ctx: pointer to a context object
428 | initialized for verification
429 | (cannot be NULL)
430 |
431 | In/Out: keypair: pointer to a keypair to apply
432 | the tweak to. Will be set to
433 | an invalid value if this
434 | function returns 0 (cannot be
435 | NULL).
436 |
437 | In: tweak32: pointer to a 32-byte
438 | tweak. If the tweak is
439 | invalid according to
440 | ec_seckey_verify, this
441 | function returns 0. For
442 | uniformly random 32-byte
443 | arrays the chance of being
444 | invalid is negligible (around
445 | 1 in 2^128) (cannot be NULL).
446 |
447 */
448lazy_static!{
449 /*
450 API WARN_UNUSED_RESULT int keypair_xonly_tweak_add(
451 const context* ctx,
452 keypair *keypair,
453 const unsigned char *tweak32
454 ) ARG_NONNULL(1) ARG_NONNULL(2) ARG_NONNULL(3);
455 */
456}
457
458//-------------------------------------------[.cpp/bitcoin/src/secp256k1/src/modules/extrakeys/main_impl.h]
459
460#[inline] pub fn xonly_pubkey_load(
461 ctx: *const Secp256k1Context,
462 ge: *mut Ge,
463 pubkey: *const XOnlyPubKey) -> i32 {
464
465 todo!();
466 /*
467 return pubkey_load(ctx, ge, (const pubkey *) pubkey);
468 */
469}
470
471#[inline] pub fn xonly_pubkey_save(
472 pubkey: *mut XOnlyPubKey,
473 ge: *mut Ge) {
474
475 todo!();
476 /*
477 pubkey_save((pubkey *) pubkey, ge);
478 */
479}
480
481pub fn xonly_pubkey_parse(
482 ctx: *const Secp256k1Context,
483 pubkey: *mut XOnlyPubKey,
484 input32: *const u8) -> i32 {
485
486 todo!();
487 /*
488 ge pk;
489 fe x;
490
491 VERIFY_CHECK(ctx != NULL);
492 ARG_CHECK(pubkey != NULL);
493 memset(pubkey, 0, sizeof(*pubkey));
494 ARG_CHECK(input32 != NULL);
495
496 if (!fe_set_b32(&x, input32)) {
497 return 0;
498 }
499 if (!ge_set_xo_var(&pk, &x, 0)) {
500 return 0;
501 }
502 if (!ge_is_in_correct_subgroup(&pk)) {
503 return 0;
504 }
505 xonly_pubkey_save(pubkey, &pk);
506 return 1;
507 */
508}
509
510pub fn xonly_pubkey_serialize(
511 ctx: *const Secp256k1Context,
512 output32: *mut u8,
513 pubkey: *const XOnlyPubKey) -> i32 {
514
515 todo!();
516 /*
517 ge pk;
518
519 VERIFY_CHECK(ctx != NULL);
520 ARG_CHECK(output32 != NULL);
521 memset(output32, 0, 32);
522 ARG_CHECK(pubkey != NULL);
523
524 if (!xonly_pubkey_load(ctx, &pk, pubkey)) {
525 return 0;
526 }
527 fe_get_b32(output32, &pk.x);
528 return 1;
529 */
530}
531
532pub fn xonly_pubkey_cmp(
533 ctx: *const Secp256k1Context,
534 pk0: *const XOnlyPubKey,
535 pk1: *const XOnlyPubKey) -> i32 {
536
537 todo!();
538 /*
539 unsigned char out[2][32];
540 const xonly_pubkey* pk[2];
541 int i;
542
543 VERIFY_CHECK(ctx != NULL);
544 pk[0] = pk0; pk[1] = pk1;
545 for (i = 0; i < 2; i++) {
546 /* If the public key is NULL or invalid, xonly_pubkey_serialize will
547 * call the illegal_callback and return 0. In that case we will
548 * serialize the key as all zeros which is less than any valid public
549 * key. This results in consistent comparisons even if NULL or invalid
550 * pubkeys are involved and prevents edge cases such as sorting
551 * algorithms that use this function and do not terminate as a
552 * result. */
553 if (!xonly_pubkey_serialize(ctx, out[i], pk[i])) {
554 /* Note that xonly_pubkey_serialize should already set the output to
555 * zero in that case, but it's not guaranteed by the API, we can't
556 * test it and writing a VERIFY_CHECK is more complex than
557 * explicitly memsetting (again). */
558 memset(out[i], 0, sizeof(out[i]));
559 }
560 }
561 return memcmp_var(out[0], out[1], sizeof(out[1]));
562 */
563}
564
565/**
566 | Keeps a group element as is if it has an
567 | even Y and otherwise negates it. y_parity
568 | is set to 0 in the former case and to 1 in
569 | the latter case.
570 |
571 | Requires that the coordinates of r are
572 | normalized.
573 |
574 */
575pub fn extrakeys_ge_even_y(r: *mut Ge) -> i32 {
576
577 todo!();
578 /*
579 int y_parity = 0;
580 VERIFY_CHECK(!ge_is_infinity(r));
581
582 if (fe_is_odd(&r->y)) {
583 fe_negate(&r->y, &r->y, 1);
584 y_parity = 1;
585 }
586 return y_parity;
587 */
588}
589
590pub fn xonly_pubkey_from_pubkey(
591 ctx: *const Secp256k1Context,
592 xonly_pubkey: *mut XOnlyPubKey,
593 pk_parity: *mut i32,
594 pubkey: *const PubKey) -> i32 {
595
596 todo!();
597 /*
598 ge pk;
599 int tmp;
600
601 VERIFY_CHECK(ctx != NULL);
602 ARG_CHECK(xonly_pubkey != NULL);
603 ARG_CHECK(pubkey != NULL);
604
605 if (!pubkey_load(ctx, &pk, pubkey)) {
606 return 0;
607 }
608 tmp = extrakeys_ge_even_y(&pk);
609 if (pk_parity != NULL) {
610 *pk_parity = tmp;
611 }
612 xonly_pubkey_save(xonly_pubkey, &pk);
613 return 1;
614 */
615}
616
617pub fn xonly_pubkey_tweak_add(
618 ctx: *const Secp256k1Context,
619 output_pubkey: *mut PubKey,
620 internal_pubkey: *const XOnlyPubKey,
621 tweak32: *const u8) -> i32 {
622
623 todo!();
624 /*
625 ge pk;
626
627 VERIFY_CHECK(ctx != NULL);
628 ARG_CHECK(output_pubkey != NULL);
629 memset(output_pubkey, 0, sizeof(*output_pubkey));
630 ARG_CHECK(ecmult_context_is_built(&ctx->ecmult_ctx));
631 ARG_CHECK(internal_pubkey != NULL);
632 ARG_CHECK(tweak32 != NULL);
633
634 if (!xonly_pubkey_load(ctx, &pk, internal_pubkey)
635 || !ec_pubkey_tweak_add_helper(&ctx->ecmult_ctx, &pk, tweak32)) {
636 return 0;
637 }
638 pubkey_save(output_pubkey, &pk);
639 return 1;
640 */
641}
642
643pub fn xonly_pubkey_tweak_add_check(
644 ctx: *const Secp256k1Context,
645 tweaked_pubkey32: *const u8,
646 tweaked_pk_parity: i32,
647 internal_pubkey: *const XOnlyPubKey,
648 tweak32: *const u8) -> i32 {
649
650 todo!();
651 /*
652 ge pk;
653 unsigned char pk_expected32[32];
654
655 VERIFY_CHECK(ctx != NULL);
656 ARG_CHECK(ecmult_context_is_built(&ctx->ecmult_ctx));
657 ARG_CHECK(internal_pubkey != NULL);
658 ARG_CHECK(tweaked_pubkey32 != NULL);
659 ARG_CHECK(tweak32 != NULL);
660
661 if (!xonly_pubkey_load(ctx, &pk, internal_pubkey)
662 || !ec_pubkey_tweak_add_helper(&ctx->ecmult_ctx, &pk, tweak32)) {
663 return 0;
664 }
665 fe_normalize_var(&pk.x);
666 fe_normalize_var(&pk.y);
667 fe_get_b32(pk_expected32, &pk.x);
668
669 return memcmp_var(&pk_expected32, tweaked_pubkey32, 32) == 0
670 && fe_is_odd(&pk.y) == tweaked_pk_parity;
671 */
672}
673
674pub fn keypair_save(
675 keypair: *mut KeyPair,
676 sk: *const Scalar,
677 pk: *mut Ge) {
678
679 todo!();
680 /*
681 scalar_get_b32(&keypair->data[0], sk);
682 pubkey_save((pubkey *)&keypair->data[32], pk);
683 */
684}
685
686pub fn keypair_seckey_load(
687 ctx: *const Secp256k1Context,
688 sk: *mut Scalar,
689 keypair: *const KeyPair) -> i32 {
690
691 todo!();
692 /*
693 int ret;
694
695 ret = scalar_set_b32_seckey(sk, &keypair->data[0]);
696 /* We can declassify ret here because sk is only zero if a keypair function failed (which zeroes the keypair) and its return value is ignored. */
697 declassify(ctx, &ret, sizeof(ret));
698 ARG_CHECK(ret);
699 return ret;
700 */
701}
702
703/**
704 | Load a keypair into pk and sk (if non-NULL).
705 | This function declassifies pk and ARG_CHECKs
706 | that the keypair is not invalid. It always
707 | initializes sk and pk with dummy values.
708 |
709 */
710pub fn keypair_load(
711 ctx: *const Secp256k1Context,
712 sk: *mut Scalar,
713 pk: *mut Ge,
714 keypair: *const KeyPair) -> i32 {
715
716 todo!();
717 /*
718 int ret;
719 const pubkey *pubkey = (const pubkey *)&keypair->data[32];
720
721 /* Need to declassify the pubkey because pubkey_load ARG_CHECKs if it's
722 * invalid. */
723 declassify(ctx, pubkey, sizeof(*pubkey));
724 ret = pubkey_load(ctx, pk, pubkey);
725 if (sk != NULL) {
726 ret = ret && keypair_seckey_load(ctx, sk, keypair);
727 }
728 if (!ret) {
729 *pk = ge_const_g;
730 if (sk != NULL) {
731 *sk = scalar_one;
732 }
733 }
734 return ret;
735 */
736}
737
738pub fn keypair_create(
739 ctx: *const Secp256k1Context,
740 keypair: *mut KeyPair,
741 seckey32: *const u8) -> i32 {
742
743 todo!();
744 /*
745 scalar sk;
746 ge pk;
747 int ret = 0;
748 VERIFY_CHECK(ctx != NULL);
749 ARG_CHECK(keypair != NULL);
750 memset(keypair, 0, sizeof(*keypair));
751 ARG_CHECK(ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
752 ARG_CHECK(seckey32 != NULL);
753
754 ret = ec_pubkey_create_helper(&ctx->ecmult_gen_ctx, &sk, &pk, seckey32);
755 keypair_save(keypair, &sk, &pk);
756 memczero(keypair, sizeof(*keypair), !ret);
757
758 scalar_clear(&sk);
759 return ret;
760 */
761}
762
763pub fn keypair_sec(
764 ctx: *const Secp256k1Context,
765 seckey: *mut u8,
766 keypair: *const KeyPair) -> i32 {
767
768 todo!();
769 /*
770 VERIFY_CHECK(ctx != NULL);
771 ARG_CHECK(seckey != NULL);
772 memset(seckey, 0, 32);
773 ARG_CHECK(keypair != NULL);
774
775 memcpy(seckey, &keypair->data[0], 32);
776 return 1;
777 */
778}
779
780pub fn keypair_pub(
781 ctx: *const Secp256k1Context,
782 pubkey: *mut PubKey,
783 keypair: *const KeyPair) -> i32 {
784
785 todo!();
786 /*
787 VERIFY_CHECK(ctx != NULL);
788 ARG_CHECK(pubkey != NULL);
789 memset(pubkey, 0, sizeof(*pubkey));
790 ARG_CHECK(keypair != NULL);
791
792 memcpy(pubkey->data, &keypair->data[32], sizeof(*pubkey));
793 return 1;
794 */
795}
796
797pub fn keypair_xonly_pub(
798 ctx: *const Secp256k1Context,
799 pubkey: *mut XOnlyPubKey,
800 pk_parity: *mut i32,
801 keypair: *const KeyPair) -> i32 {
802
803 todo!();
804 /*
805 ge pk;
806 int tmp;
807
808 VERIFY_CHECK(ctx != NULL);
809 ARG_CHECK(pubkey != NULL);
810 memset(pubkey, 0, sizeof(*pubkey));
811 ARG_CHECK(keypair != NULL);
812
813 if (!keypair_load(ctx, NULL, &pk, keypair)) {
814 return 0;
815 }
816 tmp = extrakeys_ge_even_y(&pk);
817 if (pk_parity != NULL) {
818 *pk_parity = tmp;
819 }
820 xonly_pubkey_save(pubkey, &pk);
821
822 return 1;
823 */
824}
825
826pub fn keypair_xonly_tweak_add(
827 ctx: *const Secp256k1Context,
828 keypair: *mut KeyPair,
829 tweak32: *const u8) -> i32 {
830
831 todo!();
832 /*
833 ge pk;
834 scalar sk;
835 int y_parity;
836 int ret;
837
838 VERIFY_CHECK(ctx != NULL);
839 ARG_CHECK(ecmult_context_is_built(&ctx->ecmult_ctx));
840 ARG_CHECK(keypair != NULL);
841 ARG_CHECK(tweak32 != NULL);
842
843 ret = keypair_load(ctx, &sk, &pk, keypair);
844 memset(keypair, 0, sizeof(*keypair));
845
846 y_parity = extrakeys_ge_even_y(&pk);
847 if (y_parity == 1) {
848 scalar_negate(&sk, &sk);
849 }
850
851 ret &= ec_seckey_tweak_add_helper(&sk, tweak32);
852 ret &= ec_pubkey_tweak_add_helper(&ctx->ecmult_ctx, &pk, tweak32);
853
854 declassify(ctx, &ret, sizeof(ret));
855 if (ret) {
856 keypair_save(keypair, &sk, &pk);
857 }
858
859 scalar_clear(&sk);
860 return ret;
861 */
862}
863
864//-------------------------------------------[.cpp/bitcoin/src/secp256k1/src/modules/extrakeys/tests_impl.h]
865
866pub fn api_test_context(
867 flags: i32,
868 ecount: *mut i32) -> *mut Secp256k1Context {
869
870 todo!();
871 /*
872 context *ctx0 = context_create(flags);
873 context_set_error_callback(ctx0, counting_illegal_callback_fn, ecount);
874 context_set_illegal_callback(ctx0, counting_illegal_callback_fn, ecount);
875 return ctx0;
876 */
877}
878
879pub fn test_xonly_pubkey() {
880
881 todo!();
882 /*
883 pubkey pk;
884 xonly_pubkey xonly_pk, xonly_pk_tmp;
885 ge pk1;
886 ge pk2;
887 fe y;
888 unsigned char sk[32];
889 unsigned char xy_sk[32];
890 unsigned char buf32[32];
891 unsigned char ones32[32];
892 unsigned char zeros64[64] = { 0 };
893 int pk_parity;
894 int i;
895
896 int ecount;
897 context *none = api_test_context(CONTEXT_NONE, &ecount);
898 context *sign = api_test_context(CONTEXT_SIGN, &ecount);
899 context *verify = api_test_context(CONTEXT_VERIFY, &ecount);
900
901 testrand256(sk);
902 memset(ones32, 0xFF, 32);
903 testrand256(xy_sk);
904 CHECK(ec_pubkey_create(sign, &pk, sk) == 1);
905 CHECK(xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
906
907 /* Test xonly_pubkey_from_pubkey */
908 ecount = 0;
909 CHECK(xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
910 CHECK(xonly_pubkey_from_pubkey(sign, &xonly_pk, &pk_parity, &pk) == 1);
911 CHECK(xonly_pubkey_from_pubkey(verify, &xonly_pk, &pk_parity, &pk) == 1);
912 CHECK(xonly_pubkey_from_pubkey(none, NULL, &pk_parity, &pk) == 0);
913 CHECK(ecount == 1);
914 CHECK(xonly_pubkey_from_pubkey(none, &xonly_pk, NULL, &pk) == 1);
915 CHECK(xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, NULL) == 0);
916 CHECK(ecount == 2);
917 memset(&pk, 0, sizeof(pk));
918 CHECK(xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 0);
919 CHECK(ecount == 3);
920
921 /* Choose a secret key such that the resulting pubkey and xonly_pubkey match. */
922 memset(sk, 0, sizeof(sk));
923 sk[0] = 1;
924 CHECK(ec_pubkey_create(ctx, &pk, sk) == 1);
925 CHECK(xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk) == 1);
926 CHECK(memcmp_var(&pk, &xonly_pk, sizeof(pk)) == 0);
927 CHECK(pk_parity == 0);
928
929 /* Choose a secret key such that pubkey and xonly_pubkey are each others
930 * negation. */
931 sk[0] = 2;
932 CHECK(ec_pubkey_create(ctx, &pk, sk) == 1);
933 CHECK(xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk) == 1);
934 CHECK(memcmp_var(&xonly_pk, &pk, sizeof(xonly_pk)) != 0);
935 CHECK(pk_parity == 1);
936 pubkey_load(ctx, &pk1, &pk);
937 pubkey_load(ctx, &pk2, (pubkey *) &xonly_pk);
938 CHECK(fe_equal(&pk1.x, &pk2.x) == 1);
939 fe_negate(&y, &pk2.y, 1);
940 CHECK(fe_equal(&pk1.y, &y) == 1);
941
942 /* Test xonly_pubkey_serialize and xonly_pubkey_parse */
943 ecount = 0;
944 CHECK(xonly_pubkey_serialize(none, NULL, &xonly_pk) == 0);
945 CHECK(ecount == 1);
946 CHECK(xonly_pubkey_serialize(none, buf32, NULL) == 0);
947 CHECK(memcmp_var(buf32, zeros64, 32) == 0);
948 CHECK(ecount == 2);
949 {
950 /* A pubkey filled with 0s will fail to serialize due to pubkey_load
951 * special casing. */
952 xonly_pubkey pk_tmp;
953 memset(&pk_tmp, 0, sizeof(pk_tmp));
954 CHECK(xonly_pubkey_serialize(none, buf32, &pk_tmp) == 0);
955 }
956 /* pubkey_load called illegal callback */
957 CHECK(ecount == 3);
958
959 CHECK(xonly_pubkey_serialize(none, buf32, &xonly_pk) == 1);
960 ecount = 0;
961 CHECK(xonly_pubkey_parse(none, NULL, buf32) == 0);
962 CHECK(ecount == 1);
963 CHECK(xonly_pubkey_parse(none, &xonly_pk, NULL) == 0);
964 CHECK(ecount == 2);
965
966 /* Serialization and parse roundtrip */
967 CHECK(xonly_pubkey_from_pubkey(none, &xonly_pk, NULL, &pk) == 1);
968 CHECK(xonly_pubkey_serialize(ctx, buf32, &xonly_pk) == 1);
969 CHECK(xonly_pubkey_parse(ctx, &xonly_pk_tmp, buf32) == 1);
970 CHECK(memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(xonly_pk)) == 0);
971
972 /* Test parsing invalid field elements */
973 memset(&xonly_pk, 1, sizeof(xonly_pk));
974 /* Overflowing field element */
975 CHECK(xonly_pubkey_parse(none, &xonly_pk, ones32) == 0);
976 CHECK(memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
977 memset(&xonly_pk, 1, sizeof(xonly_pk));
978 /* There's no point with x-coordinate 0 on secp256k1 */
979 CHECK(xonly_pubkey_parse(none, &xonly_pk, zeros64) == 0);
980 CHECK(memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
981 /* If a random 32-byte string can not be parsed with ec_pubkey_parse
982 * (because interpreted as X coordinate it does not correspond to a point on
983 * the curve) then xonly_pubkey_parse should fail as well. */
984 for (i = 0; i < count; i++) {
985 unsigned char rand33[33];
986 testrand256(&rand33[1]);
987 rand33[0] = TAG_PUBKEY_EVEN;
988 if (!ec_pubkey_parse(ctx, &pk, rand33, 33)) {
989 memset(&xonly_pk, 1, sizeof(xonly_pk));
990 CHECK(xonly_pubkey_parse(ctx, &xonly_pk, &rand33[1]) == 0);
991 CHECK(memcmp_var(&xonly_pk, zeros64, sizeof(xonly_pk)) == 0);
992 } else {
993 CHECK(xonly_pubkey_parse(ctx, &xonly_pk, &rand33[1]) == 1);
994 }
995 }
996 CHECK(ecount == 2);
997
998 context_destroy(none);
999 context_destroy(sign);
1000 context_destroy(verify);
1001 */
1002}
1003
1004pub fn test_xonly_pubkey_comparison() {
1005
1006 todo!();
1007 /*
1008 unsigned char pk1_ser[32] = {
1009 0x58, 0x84, 0xb3, 0xa2, 0x4b, 0x97, 0x37, 0x88, 0x92, 0x38, 0xa6, 0x26, 0x62, 0x52, 0x35, 0x11,
1010 0xd0, 0x9a, 0xa1, 0x1b, 0x80, 0x0b, 0x5e, 0x93, 0x80, 0x26, 0x11, 0xef, 0x67, 0x4b, 0xd9, 0x23
1011 };
1012 const unsigned char pk2_ser[32] = {
1013 0xde, 0x36, 0x0e, 0x87, 0x59, 0x8f, 0x3c, 0x01, 0x36, 0x2a, 0x2a, 0xb8, 0xc6, 0xf4, 0x5e, 0x4d,
1014 0xb2, 0xc2, 0xd5, 0x03, 0xa7, 0xf9, 0xf1, 0x4f, 0xa8, 0xfa, 0x95, 0xa8, 0xe9, 0x69, 0x76, 0x1c
1015 };
1016 xonly_pubkey pk1;
1017 xonly_pubkey pk2;
1018 int ecount = 0;
1019 context *none = api_test_context(CONTEXT_NONE, &ecount);
1020
1021 CHECK(xonly_pubkey_parse(none, &pk1, pk1_ser) == 1);
1022 CHECK(xonly_pubkey_parse(none, &pk2, pk2_ser) == 1);
1023
1024 CHECK(xonly_pubkey_cmp(none, NULL, &pk2) < 0);
1025 CHECK(ecount == 1);
1026 CHECK(xonly_pubkey_cmp(none, &pk1, NULL) > 0);
1027 CHECK(ecount == 2);
1028 CHECK(xonly_pubkey_cmp(none, &pk1, &pk2) < 0);
1029 CHECK(xonly_pubkey_cmp(none, &pk2, &pk1) > 0);
1030 CHECK(xonly_pubkey_cmp(none, &pk1, &pk1) == 0);
1031 CHECK(xonly_pubkey_cmp(none, &pk2, &pk2) == 0);
1032 CHECK(ecount == 2);
1033 memset(&pk1, 0, sizeof(pk1)); /* illegal pubkey */
1034 CHECK(xonly_pubkey_cmp(none, &pk1, &pk2) < 0);
1035 CHECK(ecount == 3);
1036 CHECK(xonly_pubkey_cmp(none, &pk1, &pk1) == 0);
1037 CHECK(ecount == 5);
1038 CHECK(xonly_pubkey_cmp(none, &pk2, &pk1) > 0);
1039 CHECK(ecount == 6);
1040
1041 context_destroy(none);
1042 */
1043}
1044
1045pub fn test_xonly_pubkey_tweak() {
1046
1047 todo!();
1048 /*
1049 unsigned char zeros64[64] = { 0 };
1050 unsigned char overflows[32];
1051 unsigned char sk[32];
1052 pubkey internal_pk;
1053 xonly_pubkey internal_xonly_pk;
1054 pubkey output_pk;
1055 int pk_parity;
1056 unsigned char tweak[32];
1057 int i;
1058
1059 int ecount;
1060 context *none = api_test_context(CONTEXT_NONE, &ecount);
1061 context *sign = api_test_context(CONTEXT_SIGN, &ecount);
1062 context *verify = api_test_context(CONTEXT_VERIFY, &ecount);
1063
1064 memset(overflows, 0xff, sizeof(overflows));
1065 testrand256(tweak);
1066 testrand256(sk);
1067 CHECK(ec_pubkey_create(ctx, &internal_pk, sk) == 1);
1068 CHECK(xonly_pubkey_from_pubkey(none, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
1069
1070 ecount = 0;
1071 CHECK(xonly_pubkey_tweak_add(none, &output_pk, &internal_xonly_pk, tweak) == 0);
1072 CHECK(ecount == 1);
1073 CHECK(xonly_pubkey_tweak_add(sign, &output_pk, &internal_xonly_pk, tweak) == 0);
1074 CHECK(ecount == 2);
1075 CHECK(xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 1);
1076 CHECK(xonly_pubkey_tweak_add(verify, NULL, &internal_xonly_pk, tweak) == 0);
1077 CHECK(ecount == 3);
1078 CHECK(xonly_pubkey_tweak_add(verify, &output_pk, NULL, tweak) == 0);
1079 CHECK(ecount == 4);
1080 /* NULL internal_xonly_pk zeroes the output_pk */
1081 CHECK(memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
1082 CHECK(xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, NULL) == 0);
1083 CHECK(ecount == 5);
1084 /* NULL tweak zeroes the output_pk */
1085 CHECK(memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
1086
1087 /* Invalid tweak zeroes the output_pk */
1088 CHECK(xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, overflows) == 0);
1089 CHECK(memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
1090
1091 /* A zero tweak is fine */
1092 CHECK(xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, zeros64) == 1);
1093
1094 /* Fails if the resulting key was infinity */
1095 for (i = 0; i < count; i++) {
1096 scalar scalar_tweak;
1097 /* Because sk may be negated before adding, we need to try with tweak =
1098 * sk as well as tweak = -sk. */
1099 scalar_set_b32(&scalar_tweak, sk, NULL);
1100 scalar_negate(&scalar_tweak, &scalar_tweak);
1101 scalar_get_b32(tweak, &scalar_tweak);
1102 CHECK((xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, sk) == 0)
1103 || (xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 0));
1104 CHECK(memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
1105 }
1106
1107 /* Invalid pk with a valid tweak */
1108 memset(&internal_xonly_pk, 0, sizeof(internal_xonly_pk));
1109 testrand256(tweak);
1110 ecount = 0;
1111 CHECK(xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 0);
1112 CHECK(ecount == 1);
1113 CHECK(memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
1114
1115 context_destroy(none);
1116 context_destroy(sign);
1117 context_destroy(verify);
1118 */
1119}
1120
1121pub fn test_xonly_pubkey_tweak_check() {
1122
1123 todo!();
1124 /*
1125 unsigned char zeros64[64] = { 0 };
1126 unsigned char overflows[32];
1127 unsigned char sk[32];
1128 pubkey internal_pk;
1129 xonly_pubkey internal_xonly_pk;
1130 pubkey output_pk;
1131 xonly_pubkey output_xonly_pk;
1132 unsigned char output_pk32[32];
1133 unsigned char buf32[32];
1134 int pk_parity;
1135 unsigned char tweak[32];
1136
1137 int ecount;
1138 context *none = api_test_context(CONTEXT_NONE, &ecount);
1139 context *sign = api_test_context(CONTEXT_SIGN, &ecount);
1140 context *verify = api_test_context(CONTEXT_VERIFY, &ecount);
1141
1142 memset(overflows, 0xff, sizeof(overflows));
1143 testrand256(tweak);
1144 testrand256(sk);
1145 CHECK(ec_pubkey_create(ctx, &internal_pk, sk) == 1);
1146 CHECK(xonly_pubkey_from_pubkey(none, &internal_xonly_pk, &pk_parity, &internal_pk) == 1);
1147
1148 ecount = 0;
1149 CHECK(xonly_pubkey_tweak_add(verify, &output_pk, &internal_xonly_pk, tweak) == 1);
1150 CHECK(xonly_pubkey_from_pubkey(verify, &output_xonly_pk, &pk_parity, &output_pk) == 1);
1151 CHECK(xonly_pubkey_serialize(ctx, buf32, &output_xonly_pk) == 1);
1152 CHECK(xonly_pubkey_tweak_add_check(none, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
1153 CHECK(ecount == 1);
1154 CHECK(xonly_pubkey_tweak_add_check(sign, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
1155 CHECK(ecount == 2);
1156 CHECK(xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, &internal_xonly_pk, tweak) == 1);
1157 CHECK(xonly_pubkey_tweak_add_check(verify, NULL, pk_parity, &internal_xonly_pk, tweak) == 0);
1158 CHECK(ecount == 3);
1159 /* invalid pk_parity value */
1160 CHECK(xonly_pubkey_tweak_add_check(verify, buf32, 2, &internal_xonly_pk, tweak) == 0);
1161 CHECK(ecount == 3);
1162 CHECK(xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, NULL, tweak) == 0);
1163 CHECK(ecount == 4);
1164 CHECK(xonly_pubkey_tweak_add_check(verify, buf32, pk_parity, &internal_xonly_pk, NULL) == 0);
1165 CHECK(ecount == 5);
1166
1167 memset(tweak, 1, sizeof(tweak));
1168 CHECK(xonly_pubkey_from_pubkey(ctx, &internal_xonly_pk, NULL, &internal_pk) == 1);
1169 CHECK(xonly_pubkey_tweak_add(ctx, &output_pk, &internal_xonly_pk, tweak) == 1);
1170 CHECK(xonly_pubkey_from_pubkey(ctx, &output_xonly_pk, &pk_parity, &output_pk) == 1);
1171 CHECK(xonly_pubkey_serialize(ctx, output_pk32, &output_xonly_pk) == 1);
1172 CHECK(xonly_pubkey_tweak_add_check(ctx, output_pk32, pk_parity, &internal_xonly_pk, tweak) == 1);
1173
1174 /* Wrong pk_parity */
1175 CHECK(xonly_pubkey_tweak_add_check(ctx, output_pk32, !pk_parity, &internal_xonly_pk, tweak) == 0);
1176 /* Wrong public key */
1177 CHECK(xonly_pubkey_serialize(ctx, buf32, &internal_xonly_pk) == 1);
1178 CHECK(xonly_pubkey_tweak_add_check(ctx, buf32, pk_parity, &internal_xonly_pk, tweak) == 0);
1179
1180 /* Overflowing tweak not allowed */
1181 CHECK(xonly_pubkey_tweak_add_check(ctx, output_pk32, pk_parity, &internal_xonly_pk, overflows) == 0);
1182 CHECK(xonly_pubkey_tweak_add(ctx, &output_pk, &internal_xonly_pk, overflows) == 0);
1183 CHECK(memcmp_var(&output_pk, zeros64, sizeof(output_pk)) == 0);
1184 CHECK(ecount == 5);
1185
1186 context_destroy(none);
1187 context_destroy(sign);
1188 context_destroy(verify);
1189 */
1190}
1191
1192/**
1193 | Starts with an initial pubkey and recursively
1194 | creates N_PUBKEYS - 1 additional pubkeys
1195 | by calling tweak_add. Then verifies
1196 | every tweak starting from the last pubkey.
1197 |
1198 */
1199pub fn test_xonly_pubkey_tweak_recursive() {
1200
1201 pub const N_PUBKEYS: usize = 32;
1202
1203 todo!();
1204 /*
1205 unsigned char sk[32];
1206 pubkey pk[N_PUBKEYS];
1207 unsigned char pk_serialized[32];
1208 unsigned char tweak[N_PUBKEYS - 1][32];
1209 int i;
1210
1211 testrand256(sk);
1212 CHECK(ec_pubkey_create(ctx, &pk[0], sk) == 1);
1213 /* Add tweaks */
1214 for (i = 0; i < N_PUBKEYS - 1; i++) {
1215 xonly_pubkey xonly_pk;
1216 memset(tweak[i], i + 1, sizeof(tweak[i]));
1217 CHECK(xonly_pubkey_from_pubkey(ctx, &xonly_pk, NULL, &pk[i]) == 1);
1218 CHECK(xonly_pubkey_tweak_add(ctx, &pk[i + 1], &xonly_pk, tweak[i]) == 1);
1219 }
1220
1221 /* Verify tweaks */
1222 for (i = N_PUBKEYS - 1; i > 0; i--) {
1223 xonly_pubkey xonly_pk;
1224 int pk_parity;
1225 CHECK(xonly_pubkey_from_pubkey(ctx, &xonly_pk, &pk_parity, &pk[i]) == 1);
1226 CHECK(xonly_pubkey_serialize(ctx, pk_serialized, &xonly_pk) == 1);
1227 CHECK(xonly_pubkey_from_pubkey(ctx, &xonly_pk, NULL, &pk[i - 1]) == 1);
1228 CHECK(xonly_pubkey_tweak_add_check(ctx, pk_serialized, pk_parity, &xonly_pk, tweak[i - 1]) == 1);
1229 }
1230 */
1231}
1232
1233pub fn test_keypair() {
1234
1235 todo!();
1236 /*
1237 unsigned char sk[32];
1238 unsigned char sk_tmp[32];
1239 unsigned char zeros96[96] = { 0 };
1240 unsigned char overflows[32];
1241 keypair keypair;
1242 pubkey pk, pk_tmp;
1243 xonly_pubkey xonly_pk, xonly_pk_tmp;
1244 int pk_parity, pk_parity_tmp;
1245 int ecount;
1246 context *none = api_test_context(CONTEXT_NONE, &ecount);
1247 context *sign = api_test_context(CONTEXT_SIGN, &ecount);
1248 context *verify = api_test_context(CONTEXT_VERIFY, &ecount);
1249
1250 CHECK(sizeof(zeros96) == sizeof(keypair));
1251 memset(overflows, 0xFF, sizeof(overflows));
1252
1253 /* Test keypair_create */
1254 ecount = 0;
1255 testrand256(sk);
1256 CHECK(keypair_create(none, &keypair, sk) == 0);
1257 CHECK(memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
1258 CHECK(ecount == 1);
1259 CHECK(keypair_create(verify, &keypair, sk) == 0);
1260 CHECK(memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
1261 CHECK(ecount == 2);
1262 CHECK(keypair_create(sign, &keypair, sk) == 1);
1263 CHECK(keypair_create(sign, NULL, sk) == 0);
1264 CHECK(ecount == 3);
1265 CHECK(keypair_create(sign, &keypair, NULL) == 0);
1266 CHECK(memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
1267 CHECK(ecount == 4);
1268
1269 /* Invalid secret key */
1270 CHECK(keypair_create(sign, &keypair, zeros96) == 0);
1271 CHECK(memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
1272 CHECK(keypair_create(sign, &keypair, overflows) == 0);
1273 CHECK(memcmp_var(zeros96, &keypair, sizeof(keypair)) == 0);
1274
1275 /* Test keypair_pub */
1276 ecount = 0;
1277 testrand256(sk);
1278 CHECK(keypair_create(ctx, &keypair, sk) == 1);
1279 CHECK(keypair_pub(none, &pk, &keypair) == 1);
1280 CHECK(keypair_pub(none, NULL, &keypair) == 0);
1281 CHECK(ecount == 1);
1282 CHECK(keypair_pub(none, &pk, NULL) == 0);
1283 CHECK(ecount == 2);
1284 CHECK(memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
1285
1286 /* Using an invalid keypair is fine for keypair_pub */
1287 memset(&keypair, 0, sizeof(keypair));
1288 CHECK(keypair_pub(none, &pk, &keypair) == 1);
1289 CHECK(memcmp_var(zeros96, &pk, sizeof(pk)) == 0);
1290
1291 /* keypair holds the same pubkey as pubkey_create */
1292 CHECK(ec_pubkey_create(sign, &pk, sk) == 1);
1293 CHECK(keypair_create(sign, &keypair, sk) == 1);
1294 CHECK(keypair_pub(none, &pk_tmp, &keypair) == 1);
1295 CHECK(memcmp_var(&pk, &pk_tmp, sizeof(pk)) == 0);
1296
1297 /** Test keypair_xonly_pub **/
1298 ecount = 0;
1299 testrand256(sk);
1300 CHECK(keypair_create(ctx, &keypair, sk) == 1);
1301 CHECK(keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
1302 CHECK(keypair_xonly_pub(none, NULL, &pk_parity, &keypair) == 0);
1303 CHECK(ecount == 1);
1304 CHECK(keypair_xonly_pub(none, &xonly_pk, NULL, &keypair) == 1);
1305 CHECK(keypair_xonly_pub(none, &xonly_pk, &pk_parity, NULL) == 0);
1306 CHECK(ecount == 2);
1307 CHECK(memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
1308 /* Using an invalid keypair will set the xonly_pk to 0 (first reset
1309 * xonly_pk). */
1310 CHECK(keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 1);
1311 memset(&keypair, 0, sizeof(keypair));
1312 CHECK(keypair_xonly_pub(none, &xonly_pk, &pk_parity, &keypair) == 0);
1313 CHECK(memcmp_var(zeros96, &xonly_pk, sizeof(xonly_pk)) == 0);
1314 CHECK(ecount == 3);
1315
1316 /** keypair holds the same xonly pubkey as pubkey_create **/
1317 CHECK(ec_pubkey_create(sign, &pk, sk) == 1);
1318 CHECK(xonly_pubkey_from_pubkey(none, &xonly_pk, &pk_parity, &pk) == 1);
1319 CHECK(keypair_create(sign, &keypair, sk) == 1);
1320 CHECK(keypair_xonly_pub(none, &xonly_pk_tmp, &pk_parity_tmp, &keypair) == 1);
1321 CHECK(memcmp_var(&xonly_pk, &xonly_pk_tmp, sizeof(pk)) == 0);
1322 CHECK(pk_parity == pk_parity_tmp);
1323
1324 /* Test keypair_seckey */
1325 ecount = 0;
1326 testrand256(sk);
1327 CHECK(keypair_create(ctx, &keypair, sk) == 1);
1328 CHECK(keypair_sec(none, sk_tmp, &keypair) == 1);
1329 CHECK(keypair_sec(none, NULL, &keypair) == 0);
1330 CHECK(ecount == 1);
1331 CHECK(keypair_sec(none, sk_tmp, NULL) == 0);
1332 CHECK(ecount == 2);
1333 CHECK(memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
1334
1335 /* keypair returns the same seckey it got */
1336 CHECK(keypair_create(sign, &keypair, sk) == 1);
1337 CHECK(keypair_sec(none, sk_tmp, &keypair) == 1);
1338 CHECK(memcmp_var(sk, sk_tmp, sizeof(sk_tmp)) == 0);
1339
1340 /* Using an invalid keypair is fine for keypair_seckey */
1341 memset(&keypair, 0, sizeof(keypair));
1342 CHECK(keypair_sec(none, sk_tmp, &keypair) == 1);
1343 CHECK(memcmp_var(zeros96, sk_tmp, sizeof(sk_tmp)) == 0);
1344
1345 context_destroy(none);
1346 context_destroy(sign);
1347 context_destroy(verify);
1348 */
1349}
1350
1351pub fn test_keypair_add() {
1352
1353 todo!();
1354 /*
1355 unsigned char sk[32];
1356 keypair keypair;
1357 unsigned char overflows[32];
1358 unsigned char zeros96[96] = { 0 };
1359 unsigned char tweak[32];
1360 int i;
1361 int ecount = 0;
1362 context *none = api_test_context(CONTEXT_NONE, &ecount);
1363 context *sign = api_test_context(CONTEXT_SIGN, &ecount);
1364 context *verify = api_test_context(CONTEXT_VERIFY, &ecount);
1365
1366 CHECK(sizeof(zeros96) == sizeof(keypair));
1367 testrand256(sk);
1368 testrand256(tweak);
1369 memset(overflows, 0xFF, 32);
1370 CHECK(keypair_create(ctx, &keypair, sk) == 1);
1371
1372 CHECK(keypair_xonly_tweak_add(none, &keypair, tweak) == 0);
1373 CHECK(ecount == 1);
1374 CHECK(keypair_xonly_tweak_add(sign, &keypair, tweak) == 0);
1375 CHECK(ecount == 2);
1376 CHECK(keypair_xonly_tweak_add(verify, &keypair, tweak) == 1);
1377 CHECK(keypair_xonly_tweak_add(verify, NULL, tweak) == 0);
1378 CHECK(ecount == 3);
1379 CHECK(keypair_xonly_tweak_add(verify, &keypair, NULL) == 0);
1380 CHECK(ecount == 4);
1381 /* This does not set the keypair to zeroes */
1382 CHECK(memcmp_var(&keypair, zeros96, sizeof(keypair)) != 0);
1383
1384 /* Invalid tweak zeroes the keypair */
1385 CHECK(keypair_create(ctx, &keypair, sk) == 1);
1386 CHECK(keypair_xonly_tweak_add(ctx, &keypair, overflows) == 0);
1387 CHECK(memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
1388
1389 /* A zero tweak is fine */
1390 CHECK(keypair_create(ctx, &keypair, sk) == 1);
1391 CHECK(keypair_xonly_tweak_add(ctx, &keypair, zeros96) == 1);
1392
1393 /* Fails if the resulting keypair was (sk=0, pk=infinity) */
1394 for (i = 0; i < count; i++) {
1395 scalar scalar_tweak;
1396 keypair keypair_tmp;
1397 testrand256(sk);
1398 CHECK(keypair_create(ctx, &keypair, sk) == 1);
1399 memcpy(&keypair_tmp, &keypair, sizeof(keypair));
1400 /* Because sk may be negated before adding, we need to try with tweak =
1401 * sk as well as tweak = -sk. */
1402 scalar_set_b32(&scalar_tweak, sk, NULL);
1403 scalar_negate(&scalar_tweak, &scalar_tweak);
1404 scalar_get_b32(tweak, &scalar_tweak);
1405 CHECK((keypair_xonly_tweak_add(ctx, &keypair, sk) == 0)
1406 || (keypair_xonly_tweak_add(ctx, &keypair_tmp, tweak) == 0));
1407 CHECK(memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0
1408 || memcmp_var(&keypair_tmp, zeros96, sizeof(keypair_tmp)) == 0);
1409 }
1410
1411 /* Invalid keypair with a valid tweak */
1412 memset(&keypair, 0, sizeof(keypair));
1413 testrand256(tweak);
1414 ecount = 0;
1415 CHECK(keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
1416 CHECK(ecount == 1);
1417 CHECK(memcmp_var(&keypair, zeros96, sizeof(keypair)) == 0);
1418 /* Only seckey part of keypair invalid */
1419 CHECK(keypair_create(ctx, &keypair, sk) == 1);
1420 memset(&keypair, 0, 32);
1421 CHECK(keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
1422 CHECK(ecount == 2);
1423 /* Only pubkey part of keypair invalid */
1424 CHECK(keypair_create(ctx, &keypair, sk) == 1);
1425 memset(&keypair.data[32], 0, 64);
1426 CHECK(keypair_xonly_tweak_add(verify, &keypair, tweak) == 0);
1427 CHECK(ecount == 3);
1428
1429 /* Check that the keypair_tweak_add implementation is correct */
1430 CHECK(keypair_create(ctx, &keypair, sk) == 1);
1431 for (i = 0; i < count; i++) {
1432 xonly_pubkey internal_pk;
1433 xonly_pubkey output_pk;
1434 pubkey output_pk_xy;
1435 pubkey output_pk_expected;
1436 unsigned char pk32[32];
1437 unsigned char sk32[32];
1438 int pk_parity;
1439
1440 testrand256(tweak);
1441 CHECK(keypair_xonly_pub(ctx, &internal_pk, NULL, &keypair) == 1);
1442 CHECK(keypair_xonly_tweak_add(ctx, &keypair, tweak) == 1);
1443 CHECK(keypair_xonly_pub(ctx, &output_pk, &pk_parity, &keypair) == 1);
1444
1445 /* Check that it passes xonly_pubkey_tweak_add_check */
1446 CHECK(xonly_pubkey_serialize(ctx, pk32, &output_pk) == 1);
1447 CHECK(xonly_pubkey_tweak_add_check(ctx, pk32, pk_parity, &internal_pk, tweak) == 1);
1448
1449 /* Check that the resulting pubkey matches xonly_pubkey_tweak_add */
1450 CHECK(keypair_pub(ctx, &output_pk_xy, &keypair) == 1);
1451 CHECK(xonly_pubkey_tweak_add(ctx, &output_pk_expected, &internal_pk, tweak) == 1);
1452 CHECK(memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
1453
1454 /* Check that the secret key in the keypair is tweaked correctly */
1455 CHECK(keypair_sec(none, sk32, &keypair) == 1);
1456 CHECK(ec_pubkey_create(ctx, &output_pk_expected, sk32) == 1);
1457 CHECK(memcmp_var(&output_pk_xy, &output_pk_expected, sizeof(output_pk_xy)) == 0);
1458 }
1459 context_destroy(none);
1460 context_destroy(sign);
1461 context_destroy(verify);
1462 */
1463}
1464
1465pub fn run_extrakeys_tests() {
1466
1467 todo!();
1468 /*
1469 /* xonly key test cases */
1470 test_xonly_pubkey();
1471 test_xonly_pubkey_tweak();
1472 test_xonly_pubkey_tweak_check();
1473 test_xonly_pubkey_tweak_recursive();
1474 test_xonly_pubkey_comparison();
1475
1476 /* keypair tests */
1477 test_keypair();
1478 test_keypair_add();
1479 */
1480}
1481
1482//-------------------------------------------[.cpp/bitcoin/src/secp256k1/src/modules/extrakeys/tests_exhaustive_impl.h]
1483
1484pub fn test_exhaustive_extrakeys(
1485 ctx: *const Secp256k1Context,
1486 group: *const Ge) {
1487
1488 todo!();
1489 /*
1490 keypair keypair[EXHAUSTIVE_TEST_ORDER - 1];
1491 pubkey pubkey[EXHAUSTIVE_TEST_ORDER - 1];
1492 xonly_pubkey xonly_pubkey[EXHAUSTIVE_TEST_ORDER - 1];
1493 int parities[EXHAUSTIVE_TEST_ORDER - 1];
1494 unsigned char xonly_pubkey_bytes[EXHAUSTIVE_TEST_ORDER - 1][32];
1495 int i;
1496
1497 for (i = 1; i < EXHAUSTIVE_TEST_ORDER; i++) {
1498 fe fe;
1499 scalar scalar_i;
1500 unsigned char buf[33];
1501 int parity;
1502
1503 scalar_set_int(&scalar_i, i);
1504 scalar_get_b32(buf, &scalar_i);
1505
1506 /* Construct pubkey and keypair. */
1507 CHECK(keypair_create(ctx, &keypair[i - 1], buf));
1508 CHECK(ec_pubkey_create(ctx, &pubkey[i - 1], buf));
1509
1510 /* Construct serialized xonly_pubkey from keypair. */
1511 CHECK(keypair_xonly_pub(ctx, &xonly_pubkey[i - 1], &parities[i - 1], &keypair[i - 1]));
1512 CHECK(xonly_pubkey_serialize(ctx, xonly_pubkey_bytes[i - 1], &xonly_pubkey[i - 1]));
1513
1514 /* Parse the xonly_pubkey back and verify it matches the previously serialized value. */
1515 CHECK(xonly_pubkey_parse(ctx, &xonly_pubkey[i - 1], xonly_pubkey_bytes[i - 1]));
1516 CHECK(xonly_pubkey_serialize(ctx, buf, &xonly_pubkey[i - 1]));
1517 CHECK(memcmp_var(xonly_pubkey_bytes[i - 1], buf, 32) == 0);
1518
1519 /* Construct the xonly_pubkey from the pubkey, and verify it matches the same. */
1520 CHECK(xonly_pubkey_from_pubkey(ctx, &xonly_pubkey[i - 1], &parity, &pubkey[i - 1]));
1521 CHECK(parity == parities[i - 1]);
1522 CHECK(xonly_pubkey_serialize(ctx, buf, &xonly_pubkey[i - 1]));
1523 CHECK(memcmp_var(xonly_pubkey_bytes[i - 1], buf, 32) == 0);
1524
1525 /* Compare the xonly_pubkey bytes against the precomputed group. */
1526 fe_set_b32(&fe, xonly_pubkey_bytes[i - 1]);
1527 CHECK(fe_equal_var(&fe, &group[i].x));
1528
1529 /* Check the parity against the precomputed group. */
1530 fe = group[i].y;
1531 fe_normalize_var(&fe);
1532 CHECK(fe_is_odd(&fe) == parities[i - 1]);
1533
1534 /* Verify that the higher half is identical to the lower half mirrored. */
1535 if (i > EXHAUSTIVE_TEST_ORDER / 2) {
1536 CHECK(memcmp_var(xonly_pubkey_bytes[i - 1], xonly_pubkey_bytes[EXHAUSTIVE_TEST_ORDER - i - 1], 32) == 0);
1537 CHECK(parities[i - 1] == 1 - parities[EXHAUSTIVE_TEST_ORDER - i - 1]);
1538 }
1539 }
1540
1541 /* TODO: keypair/xonly_pubkey tweak tests */
1542 */
1543}