bitcoin_key/
pubkey.rs

1crate::ix!();
2
3//-------------------------------------------[.cpp/bitcoin/src/pubkey.h]
4
5pub type ChainCode = u256;
6
7pub fn bip32hash(
8        chain_code: &ChainCode,
9        n_child:    u32,
10        header:     u8,
11        data:       [u8; 32],
12        output:     [u8; 64])  {
13    
14    todo!();
15        /*
16            unsigned char num[4];
17        WriteBE32(num, nChild);
18        CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output);
19        */
20}
21
22pub const BIP32_EXTKEY_SIZE: usize = 74;
23
24/**
25  | A reference to a CKey: the Hash160 of
26  | its serialized public key
27  |
28  */
29#[derive(Clone,PartialEq,Eq,Hash)]
30pub struct KeyID {
31    base: u160,
32}
33
34impl Default for KeyID {
35    
36    fn default() -> Self {
37        todo!();
38        /*
39        : u160(),
40
41        
42        */
43    }
44}
45
46impl From<&u160> for KeyID {
47    
48    fn from(in_: &u160) -> Self {
49    
50        todo!();
51        /*
52        : u160(in),
53        */
54    }
55}
56
57/**
58  | An encapsulated public key.
59  |
60  | Opaque data structure that holds a parsed
61  | and valid public key.
62  | 
63  | The exact representation of data inside
64  | is implementation defined and not guaranteed
65  | to be portable between different platforms
66  | or versions. It is however guaranteed
67  | to be 64 bytes in size, and can be safely
68  | copied/moved.
69  | 
70  | If you need to convert to a format suitable
71  | for storage or transmission, use ec_pubkey_serialize
72  | and ec_pubkey_parse. To compare keys,
73  | use ec_pubkey_cmp.
74  |
75  */
76#[derive(Clone,Hash)]
77pub struct PubKey {
78
79    /**
80      | Just store the serialized data.
81      | 
82      | Its length can very cheaply be computed
83      | from the first byte.
84      |
85      */
86    vch: [u8; PUB_KEY_SIZE],
87}
88
89/**
90  | secp256k1:
91  |
92  */
93pub const PUB_KEY_SIZE:                   usize = 65;
94pub const PUB_KEY_COMPRESSED_SIZE:        usize = 33;
95pub const PUB_KEY_SIGNATURE_SIZE:         usize = 72;
96pub const PUB_KEY_COMPACT_SIGNATURE_SIZE: usize = 65;
97
98/**
99  | see www.keylength.com script supports
100  | up to 75 for single byte push
101  |
102  |
103  */
104const_assert!{
105    PUB_KEY_SIZE >= PUB_KEY_COMPRESSED_SIZE
106} // "COMPRESSED_SIZE is larger than SIZE"
107
108impl Default for PubKey {
109    
110    /**
111      | Construct an invalid public key.
112      |
113      */
114    fn default() -> Self {
115        todo!();
116        /*
117
118
119            Invalidate();
120        */
121    }
122}
123
124impl Index<u32> for PubKey {
125
126    type Output = u8;
127    
128    #[inline] fn index(&self, pos: u32) -> &Self::Output {
129        todo!();
130        /*
131            return vch[pos];
132        */
133    }
134}
135
136impl PartialEq<PubKey> for PubKey {
137    
138    /**
139       Comparator implementation.
140      */
141    #[inline] fn eq(&self, other: &PubKey) -> bool {
142        todo!();
143        /*
144            return a.vch[0] == b.vch[0] &&
145                   memcmp(a.vch, b.vch, a.size()) == 0;
146        */
147    }
148}
149
150impl Eq for PubKey {}
151
152impl Ord for PubKey {
153    
154    #[inline] fn cmp(&self, other: &PubKey) -> Ordering {
155        todo!();
156        /*
157            return a.vch[0] < b.vch[0] ||
158                   (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
159        */
160    }
161}
162
163impl PartialOrd<PubKey> for PubKey {
164    #[inline] fn partial_cmp(&self, other: &PubKey) -> Option<Ordering> {
165        Some(self.cmp(other))
166    }
167}
168
169impl From<&[u8]> for PubKey {
170
171    /**
172      | Construct a public key from a byte vector.
173      |
174      */
175    fn from(vch: &[u8]) -> Self {
176    
177        todo!();
178        /*
179            Set(_vch.begin(), _vch.end());
180        */
181    }
182}
183
184impl PubKey {
185
186    /**
187      | Compute the length of a pubkey with a
188      | given first byte.
189      |
190      */
191    pub fn get_len(ch_header: u8) -> u32 {
192        
193        todo!();
194        /*
195            if (chHeader == 2 || chHeader == 3)
196                return COMPRESSED_SIZE;
197            if (chHeader == 4 || chHeader == 6 || chHeader == 7)
198                return SIZE;
199            return 0;
200        */
201    }
202
203    /**
204      | Set this key data to be invalid
205      |
206      */
207    pub fn invalidate(&mut self)  {
208        
209        todo!();
210        /*
211            vch[0] = 0xFF;
212        */
213    }
214    
215    pub fn valid_size(vch: &Vec<u8>) -> bool {
216        
217        todo!();
218        /*
219            return vch.size() > 0 && GetLen(vch[0]) == vch.size();
220        */
221    }
222
223    /**
224      | Initialize a public key using begin/end
225      | iterators to byte data.
226      |
227      */
228    pub fn set<T>(&mut self, 
229        pbegin: T,
230        pend:   T)  {
231    
232        todo!();
233        /*
234            int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
235            if (len && len == (pend - pbegin))
236                memcpy(vch, (unsigned char*)&pbegin[0], len);
237            else
238                Invalidate();
239        */
240    }
241
242    /**
243      | Construct a public key using begin/end
244      | iterators to byte data.
245      |
246      */
247    pub fn new_with_iter<T>(
248        pbegin: T,
249        pend:   T) -> Self {
250    
251        todo!();
252        /*
253
254
255            Set(pbegin, pend);
256        */
257    }
258
259    /**
260      | Construct a public key using begin/end
261      | iterators to byte data.
262      |
263      */
264    pub fn new(slice: &[u8]) -> Self {
265    
266        todo!();
267        /*
268            Set(pbegin, pend);
269        */
270    }
271
272    /**
273      | Simple read-only vector-like interface
274      | to the pubkey data.
275      |
276      */
277    pub fn size(&self) -> u32 {
278        
279        todo!();
280        /*
281            return GetLen(vch[0]);
282        */
283    }
284    
285    pub fn data(&self) -> *const u8 {
286        
287        todo!();
288        /*
289            return vch;
290        */
291    }
292    
293    pub fn begin(&self) -> *const u8 {
294        
295        todo!();
296        /*
297            return vch;
298        */
299    }
300    
301    pub fn end(&self) -> *const u8 {
302        
303        todo!();
304        /*
305            return vch + size();
306        */
307    }
308
309    /**
310      | Implement serialization, as if this
311      | was a byte vector.
312      |
313      */
314    pub fn serialize<Stream>(&self, s: &mut Stream)  {
315    
316        todo!();
317        /*
318            unsigned int len = size();
319            ::WriteCompactSize(s, len);
320            s.write((char*)vch, len);
321        */
322    }
323    
324    
325    pub fn unserialize<Stream>(&mut self, s: &mut Stream)  {
326    
327        todo!();
328        /*
329            unsigned int len = ::ReadCompactSize(s);
330            if (len <= SIZE) {
331                s.read((char*)vch, len);
332                if (len != size()) {
333                    Invalidate();
334                }
335            } else {
336                // invalid pubkey, skip available data
337                char dummy;
338                while (len--)
339                    s.read(&dummy, 1);
340                Invalidate();
341            }
342        */
343    }
344
345    /**
346      | Get the KeyID of this public key (hash
347      | of its serialization)
348      |
349      */
350    pub fn getid(&self) -> KeyID {
351        
352        todo!();
353        /*
354            return CKeyID(Hash160(MakeSpan(vch).first(size())));
355        */
356    }
357
358    /**
359      | Get the 256-bit hash of this public key.
360      |
361      */
362    pub fn get_hash(&self) -> u256 {
363        
364        todo!();
365        /*
366            return Hash(MakeSpan(vch).first(size()));
367        */
368    }
369
370    /**
371      | Check syntactic correctness.
372      | 
373      | When setting a pubkey (Set()) or deserializing
374      | fails (its header bytes don't match
375      | the length of the data), the size is set
376      | to 0. Thus, by checking size, one can
377      | observe whether Set() or deserialization
378      | has failed.
379      | 
380      | This does not check for more than that.
381      | In particular, it does not verify that
382      | the coordinates correspond to a point
383      | on the curve (see IsFullyValid() for
384      | that instead).
385      | 
386      | -----------
387      | @note
388      | 
389      | this is consensus critical as
390      | 
391      | CheckECDSASignature() calls it!
392      |
393      */
394    pub fn is_valid(&self) -> bool {
395        
396        todo!();
397        /*
398            return size() > 0;
399        */
400    }
401
402    /**
403      | Check whether this is a compressed public
404      | key.
405      |
406      */
407    pub fn is_compressed(&self) -> bool {
408        
409        todo!();
410        /*
411            return size() == COMPRESSED_SIZE;
412        */
413    }
414
415    /**
416      | Check whether a signature is normalized
417      | (lower-S).
418      |
419      */
420    pub fn check_lows(&mut self, vch_sig: &Vec<u8>) -> bool {
421        
422        todo!();
423        /*
424            secp256k1_ecdsa_signature sig;
425        assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
426        if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
427            return false;
428        }
429        return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, nullptr, &sig));
430        */
431    }
432
433    /**
434      | Verify a DER signature (~72 bytes).
435      | 
436      | If this public key is not fully valid,
437      | the return value will be false.
438      |
439      */
440    pub fn verify(&self, 
441        hash:    &u256,
442        vch_sig: &Vec<u8>) -> bool {
443        
444        todo!();
445        /*
446            if (!IsValid())
447            return false;
448        secp256k1_pubkey pubkey;
449        secp256k1_ecdsa_signature sig;
450        assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
451        if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
452            return false;
453        }
454        if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
455            return false;
456        }
457        /* libsecp256k1's ECDSA verification requires lower-S signatures, which have
458         * not historically been enforced in Bitcoin, so normalize them first. */
459        secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig);
460        return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey);
461        */
462    }
463    
464    /**
465      | Recover a public key from a compact signature.
466      |
467      */
468    pub fn recover_compact(&mut self, 
469        hash:    &u256,
470        vch_sig: &Vec<u8>) -> bool {
471        
472        todo!();
473        /*
474            if (vchSig.size() != COMPACT_SIGNATURE_SIZE)
475            return false;
476        int recid = (vchSig[0] - 27) & 3;
477        bool fComp = ((vchSig[0] - 27) & 4) != 0;
478        secp256k1_pubkey pubkey;
479        secp256k1_ecdsa_recoverable_signature sig;
480        assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
481        if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) {
482            return false;
483        }
484        if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) {
485            return false;
486        }
487        unsigned char pub[SIZE];
488        size_t publen = SIZE;
489        secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
490        Set(pub, pub + publen);
491        return true;
492        */
493    }
494    
495    /**
496      | fully validate whether this is a valid
497      | public key (more expensive than IsValid())
498      |
499      */
500    pub fn is_fully_valid(&self) -> bool {
501        
502        todo!();
503        /*
504            if (!IsValid())
505            return false;
506        secp256k1_pubkey pubkey;
507        assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
508        return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size());
509        */
510    }
511    
512    /**
513      | Turn this public key into an uncompressed
514      | public key.
515      |
516      */
517    pub fn decompress(&mut self) -> bool {
518        
519        todo!();
520        /*
521            if (!IsValid())
522            return false;
523        secp256k1_pubkey pubkey;
524        assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
525        if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
526            return false;
527        }
528        unsigned char pub[SIZE];
529        size_t publen = SIZE;
530        secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
531        Set(pub, pub + publen);
532        return true;
533        */
534    }
535    
536    /**
537      | Derive BIP32 child pubkey.
538      |
539      */
540    pub fn derive(&self, 
541        pubkey_child: &mut PubKey,
542        cc_child:     &mut ChainCode,
543        n_child:      u32,
544        cc:           &ChainCode) -> bool {
545        
546        todo!();
547        /*
548            assert(IsValid());
549        assert((nChild >> 31) == 0);
550        assert(size() == COMPRESSED_SIZE);
551        unsigned char out[64];
552        BIP32Hash(cc, nChild, *begin(), begin()+1, out);
553        memcpy(ccChild.begin(), out+32, 32);
554        secp256k1_pubkey pubkey;
555        assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
556        if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
557            return false;
558        }
559        if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) {
560            return false;
561        }
562        unsigned char pub[COMPRESSED_SIZE];
563        size_t publen = COMPRESSED_SIZE;
564        secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
565        pubkeyChild.Set(pub, pub + publen);
566        return true;
567        */
568    }
569}
570
571
572///--------------------------
573#[derive(Default)]
574pub struct XOnlyPubKey {
575    keydata: u256,
576}
577
578impl Index<i32> for XOnlyPubKey {
579    type Output = u8;
580    
581    #[inline] fn index(&self, pos: i32) -> &Self::Output {
582        todo!();
583        /*
584            return *(m_keydata.begin() + pos);
585        */
586    }
587}
588
589impl PartialEq<XOnlyPubKey> for XOnlyPubKey {
590    
591    #[inline] fn eq(&self, other: &XOnlyPubKey) -> bool {
592        todo!();
593        /*
594            return m_keydata == other.m_keydata;
595        */
596    }
597}
598
599impl Eq for XOnlyPubKey {}
600
601impl Ord for XOnlyPubKey {
602    
603    #[inline] fn cmp(&self, other: &XOnlyPubKey) -> Ordering {
604        todo!();
605        /*
606            return m_keydata < other.m_keydata;
607        */
608    }
609}
610
611impl PartialOrd<XOnlyPubKey> for XOnlyPubKey {
612    #[inline] fn partial_cmp(&self, other: &XOnlyPubKey) -> Option<Ordering> {
613        Some(self.cmp(other))
614    }
615}
616
617impl From<&PubKey> for XOnlyPubKey {
618
619    /**
620      | Construct an x-only pubkey from a normal
621      | pubkey.
622      |
623      */
624    fn from(pubkey: &PubKey) -> Self {
625    
626        todo!();
627        /*
628            : XOnlyPubKey(Span<const unsigned char>(pubkey.begin() + 1, pubkey.begin() + 33))
629        */
630    }
631}
632
633impl From<&[u8]> for XOnlyPubKey {
634
635    /**
636      | Construct an x-only pubkey from exactly
637      | 32 bytes.
638      |
639      */
640    fn from(bytes: &[u8]) -> Self {
641    
642        todo!();
643        /*
644
645
646            assert(bytes.size() == 32);
647        std::copy(bytes.begin(), bytes.end(), m_keydata.begin());
648        */
649    }
650}
651
652impl XOnlyPubKey {
653
654    /**
655      | Test whether this is the 0 key (the result
656      | of default construction). This implies
657      | !IsFullyValid().
658      |
659      */
660    pub fn is_null(&self) -> bool {
661        
662        todo!();
663        /*
664            return m_keydata.IsNull();
665        */
666    }
667
668    pub fn data(&self) -> *const u8 {
669        
670        todo!();
671        /*
672            return m_keydata.begin();
673        */
674    }
675    
676    pub fn size() -> usize {
677        
678        todo!();
679        /*
680            return decltype(m_keydata)::size();
681        */
682    }
683    
684    pub fn begin(&self) -> *const u8 {
685        
686        todo!();
687        /*
688            return m_keydata.begin();
689        */
690    }
691    
692    pub fn end(&self) -> *const u8 {
693        
694        todo!();
695        /*
696            return m_keydata.end();
697        */
698    }
699    
700    pub fn begin_mut(&mut self) -> *mut u8 {
701        
702        todo!();
703        /*
704            return m_keydata.begin();
705        */
706    }
707    
708    pub fn end_mut(&mut self) -> *mut u8 {
709        
710        todo!();
711        /*
712            return m_keydata.end();
713        */
714    }
715
716    /**
717      | Returns a list of CKeyIDs for the CPubKeys
718      | that could have been used to create this
719      | 
720      | XOnlyPubKey.
721      | 
722      | This is needed for key lookups since
723      | keys are indexed by CKeyID.
724      |
725      */
726    pub fn get_key_ids(&self) -> Vec<KeyID> {
727        
728        todo!();
729        /*
730            std::vector<CKeyID> out;
731        // For now, use the old full pubkey-based key derivation logic. As it is indexed by
732        // Hash160(full pubkey), we need to return both a version prefixed with 0x02, and one
733        // with 0x03.
734        unsigned char b[33] = {0x02};
735        std::copy(m_keydata.begin(), m_keydata.end(), b + 1);
736        CPubKey fullpubkey;
737        fullpubkey.Set(b, b + 33);
738        out.push_back(fullpubkey.GetID());
739        b[0] = 0x03;
740        fullpubkey.Set(b, b + 33);
741        out.push_back(fullpubkey.GetID());
742        return out;
743        */
744    }
745    
746    /**
747      | Determine if this pubkey is fully valid.
748      | This is true for approximately 50% of
749      | all possible 32-byte arrays. If false,
750      | 
751      | VerifySchnorr and CreatePayToContract
752      | will always fail.
753      |
754      */
755    pub fn is_fully_valid(&self) -> bool {
756        
757        todo!();
758        /*
759            secp256k1_xonly_pubkey pubkey;
760        return secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &pubkey, m_keydata.data());
761        */
762    }
763    
764    /**
765      | Verify a Schnorr signature against
766      | this public key. sigbytes must be exactly
767      | 64 bytes.
768      |
769      */
770    pub fn verify_schnorr(&self, 
771        msg:      &u256,
772        sigbytes: &[u8]) -> bool {
773        
774        todo!();
775        /*
776            assert(sigbytes.size() == 64);
777        secp256k1_xonly_pubkey pubkey;
778        if (!secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &pubkey, m_keydata.data())) return false;
779        return secp256k1_schnorrsig_verify(secp256k1_context_verify, sigbytes.data(), msg.begin(), 32, &pubkey);
780        */
781    }
782    
783    /**
784      | Compute the Taproot tweak as specified
785      | in BIP341, with *this as internal key:
786      | 
787      | - if merkle_root == nullptr: H_TapTweak(xonly_pubkey)
788      | 
789      | - otherwise: H_TapTweak(xonly_pubkey || *merkle_root)
790      | 
791      | -----------
792      | @note
793      | 
794      | the behavior of this function with merkle_root
795      | != nullptr is consensus critical.
796      |
797      */
798    pub fn compute_tap_tweak_hash(&self, merkle_root: *const u256) -> u256 {
799        
800        todo!();
801        /*
802            if (merkle_root == nullptr) {
803            // We have no scripts. The actual tweak does not matter, but follow BIP341 here to
804            // allow for reproducible tweaking.
805            return (CHashWriter(HASHER_TAPTWEAK) << m_keydata).GetSHA256();
806        } else {
807            return (CHashWriter(HASHER_TAPTWEAK) << m_keydata << *merkle_root).GetSHA256();
808        }
809        */
810    }
811    
812    /**
813      | Verify that this is a Taproot tweaked
814      | output point, against a specified internal
815      | key,
816      | 
817      | Merkle root, and parity.
818      |
819      */
820    pub fn check_tap_tweak(&self, 
821        internal:    &XOnlyPubKey,
822        merkle_root: &u256,
823        parity:      bool) -> bool {
824        
825        todo!();
826        /*
827            secp256k1_xonly_pubkey internal_key;
828        if (!secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &internal_key, internal.data())) return false;
829        uint256 tweak = internal.ComputeTapTweakHash(&merkle_root);
830        return secp256k1_xonly_pubkey_tweak_add_check(secp256k1_context_verify, m_keydata.begin(), parity, &internal_key, tweak.begin());
831        */
832    }
833    
834    /**
835      | Construct a Taproot tweaked output
836      | point with this point as internal key.
837      |
838      */
839    pub fn create_tap_tweak(&self, merkle_root: *const u256) -> Option<(XOnlyPubKey,bool)> {
840        
841        todo!();
842        /*
843            secp256k1_xonly_pubkey base_point;
844        if (!secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &base_point, data())) return std::nullopt;
845        secp256k1_pubkey out;
846        uint256 tweak = ComputeTapTweakHash(merkle_root);
847        if (!secp256k1_xonly_pubkey_tweak_add(secp256k1_context_verify, &out, &base_point, tweak.data())) return std::nullopt;
848        int parity = -1;
849        std::pair<XOnlyPubKey, bool> ret;
850        secp256k1_xonly_pubkey out_xonly;
851        if (!secp256k1_xonly_pubkey_from_pubkey(secp256k1_context_verify, &out_xonly, &parity, &out)) return std::nullopt;
852        secp256k1_xonly_pubkey_serialize(secp256k1_context_verify, ret.first.begin(), &out_xonly);
853        assert(parity == 0 || parity == 1);
854        ret.second = parity;
855        return ret;
856        */
857    }
858}
859
860///------------------------
861pub struct ExtPubKey {
862    n_depth:         u8,
863    vch_fingerprint: [u8; 4],
864    n_child:         u32,
865    chaincode:       ChainCode,
866    pubkey:          PubKey,
867}
868
869impl PartialEq<ExtPubKey> for ExtPubKey {
870    
871    #[inline] fn eq(&self, other: &ExtPubKey) -> bool {
872        todo!();
873        /*
874            return a.nDepth == b.nDepth &&
875                memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
876                a.nChild == b.nChild &&
877                a.chaincode == b.chaincode &&
878                a.pubkey == b.pubkey;
879        */
880    }
881}
882
883impl Eq for ExtPubKey {}
884
885impl ExtPubKey {
886
887    pub fn encode(&self, code: [u8; BIP32_EXTKEY_SIZE])  {
888        
889        todo!();
890        /*
891            code[0] = nDepth;
892        memcpy(code+1, vchFingerprint, 4);
893        WriteBE32(code+5, nChild);
894        memcpy(code+9, chaincode.begin(), 32);
895        assert(pubkey.size() == CPubKey::COMPRESSED_SIZE);
896        memcpy(code+41, pubkey.begin(), CPubKey::COMPRESSED_SIZE);
897        */
898    }
899    
900    pub fn decode(&mut self, code: [u8; BIP32_EXTKEY_SIZE])  {
901        
902        todo!();
903        /*
904            nDepth = code[0];
905        memcpy(vchFingerprint, code+1, 4);
906        nChild = ReadBE32(code+5);
907        memcpy(chaincode.begin(), code+9, 32);
908        pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE);
909        if ((nDepth == 0 && (nChild != 0 || ReadLE32(vchFingerprint) != 0)) || !pubkey.IsFullyValid()) pubkey = CPubKey();
910        */
911    }
912    
913    pub fn derive(&self, 
914        out:     &mut ExtPubKey,
915        n_child: u32) -> bool {
916        
917        todo!();
918        /*
919            out.nDepth = nDepth + 1;
920        CKeyID id = pubkey.GetID();
921        memcpy(out.vchFingerprint, &id, 4);
922        out.nChild = _nChild;
923        return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode);
924        */
925    }
926}
927
928/**
929  | Users of this module must hold an
930  | 
931  | ECCVerifyHandle. The constructor
932  | and destructor of these are not allowed
933  | to run in parallel, though.
934  |
935  */
936pub struct ECCVerifyHandle {}
937
938pub mod ecc_verify_handle {
939
940    use super::*;
941
942    lazy_static!{
943        /*
944        static int refcount;
945        int ECCVerifyHandle::refcount = 0;
946        */
947    }
948}
949
950//-------------------------------------------[.cpp/bitcoin/src/pubkey.cpp]
951
952/**
953  | Global secp256k1_context object used
954  | for verification.
955  |
956  */
957lazy_static!{
958    /*
959    secp256k1_context* secp256k1_context_verify = nullptr;
960    */
961}
962
963///-------------------------
964impl Default for ECCVerifyHandle {
965    
966    fn default() -> Self {
967    
968        todo!();
969        /*
970        if (refcount == 0) {
971            assert(secp256k1_context_verify == nullptr);
972            secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
973            assert(secp256k1_context_verify != nullptr);
974        }
975        refcount++;
976        */
977    }
978}
979
980impl Drop for ECCVerifyHandle {
981
982    fn drop(&mut self) {
983        todo!();
984        /*
985            refcount--;
986        if (refcount == 0) {
987            assert(secp256k1_context_verify != nullptr);
988            secp256k1_context_destroy(secp256k1_context_verify);
989            secp256k1_context_verify = nullptr;
990        }
991        */
992    }
993}