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}