Skip to content

Commit 989f6c8

Browse files
committed
Merge commit 'c9e6b53536093eea36a77d10603b00447bcd425a' into update_2022_10
c9e6b53 Merge rust-bitcoin/rust-miniscript#475: Fix unreachable code from calling derive_public_key
2 parents f1349b1 + c9e6b53 commit 989f6c8

File tree

1 file changed

+27
-40
lines changed

1 file changed

+27
-40
lines changed

src/descriptor/key.rs

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -481,39 +481,6 @@ impl DescriptorPublicKey {
481481
DefiniteDescriptorKey::new(definite)
482482
.expect("The key should not contain any wildcards at this point")
483483
}
484-
485-
/// Computes the public key corresponding to this descriptor key.
486-
/// When deriving from an XOnlyPublicKey, it adds the default 0x02 y-coordinate
487-
/// and returns the obtained full [`bitcoin::PublicKey`]. All BIP32 derivations
488-
/// always return a compressed key
489-
///
490-
/// Will return an error if the descriptor key has any hardened derivation steps in its path. To
491-
/// avoid this error you should replace any such public keys first with [`translate_pk`].
492-
///
493-
/// [`translate_pk`]: crate::TranslatePk::translate_pk
494-
pub fn derive_public_key<C: Verification>(
495-
&self,
496-
secp: &Secp256k1<C>,
497-
) -> Result<bitcoin::PublicKey, ConversionError> {
498-
match *self {
499-
DescriptorPublicKey::Single(ref pk) => match pk.key {
500-
SinglePubKey::FullKey(pk) => Ok(pk),
501-
SinglePubKey::XOnly(xpk) => Ok(xpk.to_public_key()),
502-
},
503-
DescriptorPublicKey::XPub(ref xpk) => match xpk.wildcard {
504-
Wildcard::Unhardened | Wildcard::Hardened => {
505-
unreachable!("we've excluded this error case")
506-
}
507-
Wildcard::None => match xpk.xkey.derive_pub(secp, &xpk.derivation_path.as_ref()) {
508-
Ok(xpub) => Ok(bitcoin::PublicKey::new(xpub.public_key)),
509-
Err(bip32::Error::CannotDeriveFromHardenedKey) => {
510-
Err(ConversionError::HardenedChild)
511-
}
512-
Err(e) => unreachable!("cryptographically unreachable: {}", e),
513-
},
514-
},
515-
}
516-
}
517484
}
518485

519486
impl FromStr for DescriptorSecretKey {
@@ -737,17 +704,37 @@ impl MiniscriptKey for DescriptorPublicKey {
737704
}
738705

739706
impl DefiniteDescriptorKey {
740-
/// Computes the raw [`bitcoin::PublicKey`] for this descriptor key.
707+
/// Computes the public key corresponding to this descriptor key.
708+
/// When deriving from an XOnlyPublicKey, it adds the default 0x02 y-coordinate
709+
/// and returns the obtained full [`bitcoin::PublicKey`]. All BIP32 derivations
710+
/// always return a compressed key
741711
///
742-
/// Will return an error if the key has any hardened derivation steps
743-
/// in its path, but unlike [`DescriptorPublicKey::derive_public_key`]
744-
/// this won't error in case of wildcards, because derived keys are
745-
/// guaranteed to never contain one.
712+
/// Will return an error if the descriptor key has any hardened derivation steps in its path. To
713+
/// avoid this error you should replace any such public keys first with [`translate_pk`].
714+
///
715+
/// [`translate_pk`]: crate::TranslatePk::translate_pk
746716
pub fn derive_public_key<C: Verification>(
747717
&self,
748718
secp: &Secp256k1<C>,
749719
) -> Result<bitcoin::PublicKey, ConversionError> {
750-
self.0.derive_public_key(secp)
720+
match self.0 {
721+
DescriptorPublicKey::Single(ref pk) => match pk.key {
722+
SinglePubKey::FullKey(pk) => Ok(pk),
723+
SinglePubKey::XOnly(xpk) => Ok(xpk.to_public_key()),
724+
},
725+
DescriptorPublicKey::XPub(ref xpk) => match xpk.wildcard {
726+
Wildcard::Unhardened | Wildcard::Hardened => {
727+
unreachable!("we've excluded this error case")
728+
}
729+
Wildcard::None => match xpk.xkey.derive_pub(secp, &xpk.derivation_path.as_ref()) {
730+
Ok(xpub) => Ok(bitcoin::PublicKey::new(xpub.public_key)),
731+
Err(bip32::Error::CannotDeriveFromHardenedKey) => {
732+
Err(ConversionError::HardenedChild)
733+
}
734+
Err(e) => unreachable!("cryptographically unreachable: {}", e),
735+
},
736+
},
737+
}
751738
}
752739

753740
/// Construct an instance from a descriptor key and a derivation index
@@ -809,7 +796,7 @@ impl MiniscriptKey for DefiniteDescriptorKey {
809796
impl ToPublicKey for DefiniteDescriptorKey {
810797
fn to_public_key(&self) -> bitcoin::PublicKey {
811798
let secp = Secp256k1::verification_only();
812-
self.0.derive_public_key(&secp).unwrap()
799+
self.derive_public_key(&secp).unwrap()
813800
}
814801

815802
fn to_sha256(hash: &sha256::Hash) -> sha256::Hash {

0 commit comments

Comments
 (0)