diff --git a/Cargo.toml b/Cargo.toml index b085fb7..160e543 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ all-languages = [ bitcoin = "0.32.4" bip39 = { version = "2.1.0", optional = true } sha3 = "0.10.8" +base64 = "0.22.1" [[example]] name = "mnemonic" diff --git a/README.md b/README.md index 278a0ca..4616b2f 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This work is sponsored by [Bull Bitcoin](https://bullbitcoin.com) [( + secp: &Secp256k1, + root: &Xpriv, + length: u32, + index: u32, +) -> Result { + const BIP85_PWD_B64_APPLICATION_NUMBER: ChildNumber = ChildNumber::Hardened { index: 707764 }; + if length < 20 || length > 86 { + return Err(Error::InvalidLength(length)); + } + if index >= 0x80000000 { + return Err(Error::InvalidIndex(index)); + } + let path = DerivationPath::from(vec![ + BIP85_PWD_B64_APPLICATION_NUMBER, + ChildNumber::from_hardened_idx(length).unwrap(), + ChildNumber::from_hardened_idx(index).unwrap(), + ]); + let data = crate::derive(secp, root, &path)?; + let mut pwd = BASE64_STANDARD.encode(data); + pwd.truncate(length.try_into().unwrap()); + Ok(pwd) +} diff --git a/tests/pwd_base64_test.rs b/tests/pwd_base64_test.rs new file mode 100644 index 0000000..0d2392f --- /dev/null +++ b/tests/pwd_base64_test.rs @@ -0,0 +1,15 @@ +use std::str::FromStr; + +use bitcoin::{bip32::Xpriv, key::Secp256k1}; + +#[test] +fn test_pwd_base64() { + let root = Xpriv::from_str( + "xprv9s21ZrQH143K2LBWUUQRFXhucrQqBpKdRRxNVq2zBqsx8HVqFk2uYo8kmbaLLHRdqtQpUm98uKfu3vca1LqdGhUtyoFnCNkfmXRyPXLjbKb", + ) + .unwrap(); + + let pwd_base64 = bip85_fork::to_pwd_base64(&Secp256k1::new(), &root, 21, 0).unwrap(); + let expected = "dKLoepugzdVJvdL56ogNV"; + assert_eq!(expected, pwd_base64); +}