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}