From 3c8416bf3113c4a50845dfd5040d45f42e58a263 Mon Sep 17 00:00:00 2001 From: rajarshimaitra Date: Sun, 31 Oct 2021 20:23:25 +0530 Subject: [PATCH 1/4] update dependency dependency updated from tiny-bip39 to rust-bip39 --- Cargo.toml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 32df4862..74619791 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,10 +34,7 @@ cc = { version = ">=1.0.64", optional = true } socks = { version = "0.3", optional = true } lazy_static = { version = "1.4", optional = true } -# the latest 0.8 version of tiny-bip39 depends on zeroize_derive 1.2 which has MSRV 1.51 and our -# MSRV is 1.46, to fix this until we update our MSRV or replace the tiny-bip39 -# dependency https://github.com/bitcoindevkit/bdk/issues/399 we can only use an older version -tiny-bip39 = { version = "< 0.8", optional = true } +bip39 = { version = "1.0.1", optional = true } # backtrace > 0.3.61 includes object v0.27 which doesn't compile on 1.46. this is used by # tiny-bip39 backtrace = { version = "=0.3.61", optional = true } @@ -65,7 +62,7 @@ sqlite = ["rusqlite", "ahash"] compact_filters = ["rocksdb", "socks", "lazy_static", "cc"] key-value-db = ["sled"] all-keys = ["keys-bip39"] -keys-bip39 = ["tiny-bip39", "backtrace"] +keys-bip39 = ["bip39"] rpc = ["core-rpc"] # We currently provide mulitple implementations of `Blockchain`, all are From d2ce2714f2cfb987948f18df7877b0e9356f4761 Mon Sep 17 00:00:00 2001 From: rajarshimaitra Date: Sun, 31 Oct 2021 20:25:00 +0530 Subject: [PATCH 2/4] Replace tiny-bip39 with rust-bip39 Use rust-bip39 for mnemonic derivation everywhere. This requires our own WordCount enum as rust-bip39 doesn't have explicit mnemonic type definition. --- src/keys/bip39.rs | 48 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/keys/bip39.rs b/src/keys/bip39.rs index c12da624..2929c629 100644 --- a/src/keys/bip39.rs +++ b/src/keys/bip39.rs @@ -19,7 +19,23 @@ use bitcoin::Network; use miniscript::ScriptContext; -pub use bip39::{Language, Mnemonic, MnemonicType, Seed}; +pub use bip39::{Language, Mnemonic}; + +type Seed = [u8; 64]; + +/// Type describing entropy length (aka word count) in the mnemonic +pub enum WordsCount { + /// 12 words mnemonic (128 bits entropy) + Words12 = 128, + /// 15 words mnemonic (160 bits entropy) + Words15 = 160, + /// 18 words mnemonic (192 bits entropy) + Words18 = 192, + /// 21 words mnemonic (224 bits entropy) + Words21 = 224, + /// 24 words mnemonic (256 bits entropy) + Words24 = 256, +} use super::{ any_network, DerivableKey, DescriptorKey, ExtendedKey, GeneratableKey, GeneratedKey, KeyError, @@ -40,7 +56,7 @@ pub type MnemonicWithPassphrase = (Mnemonic, Option); #[cfg_attr(docsrs, doc(cfg(feature = "keys-bip39")))] impl DerivableKey for Seed { fn into_extended_key(self) -> Result, KeyError> { - Ok(bip32::ExtendedPrivKey::new_master(Network::Bitcoin, self.as_bytes())?.into()) + Ok(bip32::ExtendedPrivKey::new_master(Network::Bitcoin, &self[..])?.into()) } fn into_descriptor_key( @@ -60,7 +76,7 @@ impl DerivableKey for Seed { impl DerivableKey for MnemonicWithPassphrase { fn into_extended_key(self) -> Result, KeyError> { let (mnemonic, passphrase) = self; - let seed = Seed::new(&mnemonic, passphrase.as_deref().unwrap_or("")); + let seed: Seed = mnemonic.to_seed(passphrase.as_deref().unwrap_or("")); seed.into_extended_key() } @@ -101,15 +117,15 @@ impl DerivableKey for Mnemonic { impl GeneratableKey for Mnemonic { type Entropy = [u8; 32]; - type Options = (MnemonicType, Language); - type Error = Option; + type Options = (WordsCount, Language); + type Error = Option; fn generate_with_entropy( - (mnemonic_type, language): Self::Options, + (word_count, language): Self::Options, entropy: Self::Entropy, ) -> Result, Self::Error> { - let entropy = &entropy.as_ref()[..(mnemonic_type.entropy_bits() / 8)]; - let mnemonic = Mnemonic::from_entropy(entropy, language).map_err(|e| e.downcast().ok())?; + let entropy = &entropy.as_ref()[..(word_count as usize / 8)]; + let mnemonic = Mnemonic::from_entropy_in(language, entropy)?; Ok(GeneratedKey::new(mnemonic, any_network())) } @@ -121,15 +137,17 @@ mod test { use bitcoin::util::bip32; - use bip39::{Language, Mnemonic, MnemonicType}; + use bip39::{Language, Mnemonic}; use crate::keys::{any_network, GeneratableKey, GeneratedKey}; + use super::WordsCount; + #[test] fn test_keys_bip39_mnemonic() { let mnemonic = "aim bunker wash balance finish force paper analyst cabin spoon stable organ"; - let mnemonic = Mnemonic::from_phrase(mnemonic, Language::English).unwrap(); + let mnemonic = Mnemonic::parse_in(Language::English, mnemonic).unwrap(); let path = bip32::DerivationPath::from_str("m/44'/0'/0'/0").unwrap(); let key = (mnemonic, path); @@ -143,7 +161,7 @@ mod test { fn test_keys_bip39_mnemonic_passphrase() { let mnemonic = "aim bunker wash balance finish force paper analyst cabin spoon stable organ"; - let mnemonic = Mnemonic::from_phrase(mnemonic, Language::English).unwrap(); + let mnemonic = Mnemonic::parse_in(Language::English, mnemonic).unwrap(); let path = bip32::DerivationPath::from_str("m/44'/0'/0'/0").unwrap(); let key = ((mnemonic, Some("passphrase".into())), path); @@ -157,7 +175,7 @@ mod test { fn test_keys_generate_bip39() { let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> = Mnemonic::generate_with_entropy( - (MnemonicType::Words12, Language::English), + (WordsCount::Words12, Language::English), crate::keys::test::TEST_ENTROPY, ) .unwrap(); @@ -169,7 +187,7 @@ mod test { let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> = Mnemonic::generate_with_entropy( - (MnemonicType::Words24, Language::English), + (WordsCount::Words24, Language::English), crate::keys::test::TEST_ENTROPY, ) .unwrap(); @@ -180,11 +198,11 @@ mod test { #[test] fn test_keys_generate_bip39_random() { let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> = - Mnemonic::generate((MnemonicType::Words12, Language::English)).unwrap(); + Mnemonic::generate((WordsCount::Words12, Language::English)).unwrap(); assert_eq!(generated_mnemonic.valid_networks, any_network()); let generated_mnemonic: GeneratedKey<_, miniscript::Segwitv0> = - Mnemonic::generate((MnemonicType::Words24, Language::English)).unwrap(); + Mnemonic::generate((WordsCount::Words24, Language::English)).unwrap(); assert_eq!(generated_mnemonic.valid_networks, any_network()); } } From 756858e88280256df8e8a0e49f763ab8fcc005b9 Mon Sep 17 00:00:00 2001 From: rajarshimaitra Date: Tue, 2 Nov 2021 15:41:51 +0530 Subject: [PATCH 3/4] update module doc --- src/keys/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/keys/mod.rs b/src/keys/mod.rs index 15b53e15..d22b03f1 100644 --- a/src/keys/mod.rs +++ b/src/keys/mod.rs @@ -460,9 +460,9 @@ use bdk::keys::bip39::{Mnemonic, Language}; # fn main() -> Result<(), Box> { let xkey: ExtendedKey = - Mnemonic::from_phrase( + Mnemonic::parse_in( + Language::English, "jelly crash boy whisper mouse ecology tuna soccer memory million news short", - Language::English )? .into_extended_key()?; let xprv = xkey.into_xprv(Network::Bitcoin).unwrap(); From 35695d879548f084b5cb655f8c1a17e3875f8053 Mon Sep 17 00:00:00 2001 From: rajarshimaitra Date: Wed, 3 Nov 2021 11:08:21 +0530 Subject: [PATCH 4/4] remove redundant backtrace dependency --- Cargo.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 74619791..502a02f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,10 +35,6 @@ socks = { version = "0.3", optional = true } lazy_static = { version = "1.4", optional = true } bip39 = { version = "1.0.1", optional = true } -# backtrace > 0.3.61 includes object v0.27 which doesn't compile on 1.46. this is used by -# tiny-bip39 -backtrace = { version = "=0.3.61", optional = true } - bitcoinconsensus = { version = "0.19.0-3", optional = true } # Needed by bdk_blockchain_tests macro