diff --git a/crates/derive/keyfork-derive-util/src/extended_key/private_key.rs b/crates/derive/keyfork-derive-util/src/extended_key/private_key.rs index 5921159..f63846e 100644 --- a/crates/derive/keyfork-derive-util/src/extended_key/private_key.rs +++ b/crates/derive/keyfork-derive-util/src/extended_key/private_key.rs @@ -10,18 +10,10 @@ const KEY_SIZE: usize = 256; /// Errors associated with creating or deriving Extended Private Keys. #[derive(Error, Clone, Debug)] pub enum Error { - /// The seed has an unsuitable length; supported lengths are 16 bytes, 32 bytes, or 64 bytes. - #[error("Seed had an unsuitable length: {0}")] - BadSeedLength(usize), - /// The maximum depth for key derivation has been reached. The supported maximum depth is 255. #[error("Reached maximum depth for key derivation")] Depth, - /// This should never happen. HMAC keys should be able to take any size input. - #[error("Invalid length for HMAC key while generating master key (report me!)")] - HmacInvalidLength(#[from] hmac::digest::InvalidLength), - /// An unknown error occurred while deriving a child key. #[error("Unknown error while deriving child key")] Derivation, @@ -98,7 +90,7 @@ where /// # Errors /// An error may be returned if: /// * The given seed had an incorrect length. - /// * A `HmacSha512` can't be constructed - this should be impossible. + /// * A `HmacSha512` can't be constructed. /// /// # Examples /// ```rust @@ -107,37 +99,30 @@ where /// # public_key::TestPublicKey as PublicKey, /// # private_key::TestPrivateKey as PrivateKey, /// # }; - /// # fn main() -> Result<(), Box> { /// let seed: &[u8; 64] = // /// # b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - /// let xprv = ExtendedPrivateKey::::new(seed)?; - /// # Ok(()) - /// # } + /// let xprv = ExtendedPrivateKey::::new(seed); /// ``` - pub fn new(seed: impl AsRef<[u8]>) -> Result { + pub fn new(seed: impl AsRef<[u8]>) -> Self { Self::new_internal(seed.as_ref()) } - fn new_internal(seed: &[u8]) -> Result { - let len = seed.len(); - if ![16, 32, 64].contains(&len) { - return Err(Error::BadSeedLength(len)); - } - - let hash = HmacSha512::new_from_slice(&K::key().bytes().collect::>())? + fn new_internal(seed: &[u8]) -> Self { + let hash = HmacSha512::new_from_slice(&K::key().bytes().collect::>()) + .expect("HmacSha512 InvalidLength should be infallible") .chain_update(seed) .finalize() .into_bytes(); let (private_key, chain_code) = hash.split_at(KEY_SIZE / 8); - Ok(Self::new_from_parts( + Self::new_from_parts( private_key .try_into() .expect("KEY_SIZE / 8 did not give a 32 byte slice"), 0, // Checked: chain_code is always the same length, hash is static size chain_code.try_into().expect("Invalid chain code length"), - )) + ) } /// Create an [`ExtendedPrivateKey`] from a given `seed`, `depth`, and `chain_code`. @@ -160,7 +145,7 @@ where /// ``` pub fn new_from_parts(key: &[u8; 32], depth: u8, chain_code: [u8; 32]) -> Self { Self { - private_key: K::from_bytes(&key), + private_key: K::from_bytes(key), depth, chain_code, } @@ -206,7 +191,7 @@ where /// # 102, 201, 210, 159, 219, 222, 42, 201, 44, 196, 27, /// # 90, 221, 80, 85, 135, 79, 39, 253, 223, 35, 251 /// # ]; - /// let xprv = ExtendedPrivateKey::::new(seed)?; + /// let xprv = ExtendedPrivateKey::::new(seed); /// let xpub = xprv.extended_public_key(); /// assert_eq!(known_key, xpub.public_key().to_bytes()); /// # Ok(()) @@ -230,7 +215,7 @@ where /// # fn main() -> Result<(), Box> { /// let seed: &[u8; 64] = // /// # b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - /// let xprv = ExtendedPrivateKey::::new(seed)?; + /// let xprv = ExtendedPrivateKey::::new(seed); /// let pubkey = xprv.public_key(); /// # Ok(()) /// # } @@ -248,15 +233,12 @@ where /// # public_key::TestPublicKey as PublicKey, /// # private_key::TestPrivateKey as PrivateKey, /// # }; - /// # fn main() -> Result<(), Box> { /// let key: &[u8; 32] = // /// # b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; /// let chain_code: &[u8; 32] = // /// # b"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"; - /// let xprv = ExtendedPrivateKey::::new_from_parts(key, 4, *chain_code)?; + /// let xprv = ExtendedPrivateKey::::new_from_parts(key, 4, *chain_code); /// assert_eq!(xprv.depth(), 4); - /// # Ok(()) - /// # } /// ``` pub fn depth(&self) -> u8 { self.depth @@ -271,15 +253,12 @@ where /// # public_key::TestPublicKey as PublicKey, /// # private_key::TestPrivateKey as PrivateKey, /// # }; - /// # fn main() -> Result<(), Box> { /// let key: &[u8; 32] = // /// # b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; /// let chain_code: &[u8; 32] = // /// # b"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"; - /// let xprv = ExtendedPrivateKey::::new_from_parts(key, 4, *chain_code)?; + /// let xprv = ExtendedPrivateKey::::new_from_parts(key, 4, *chain_code); /// assert_eq!(chain_code, &xprv.chain_code()); - /// # Ok(()) - /// # } /// ``` pub fn chain_code(&self) -> [u8; 32] { self.chain_code @@ -301,7 +280,7 @@ where /// # fn main() -> Result<(), Box> { /// let seed: &[u8; 64] = // /// # b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - /// let root_xprv = ExtendedPrivateKey::::new(seed)?; + /// let root_xprv = ExtendedPrivateKey::::new(seed); /// let path = DerivationPath::default() /// .chain_push(DerivationIndex::new(44, true)?) /// .chain_push(DerivationIndex::new(0, true)?) @@ -347,7 +326,7 @@ where /// # fn main() -> Result<(), Box> { /// let seed: &[u8; 64] = // /// # b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; - /// let root_xprv = ExtendedPrivateKey::::new(seed)?; + /// let root_xprv = ExtendedPrivateKey::::new(seed); /// let bip44_wallet = DerivationPath::default() /// .chain_push(DerivationIndex::new(44, true)?) /// .chain_push(DerivationIndex::new(0, true)?) @@ -363,8 +342,8 @@ where pub fn derive_child(&self, index: &DerivationIndex) -> Result { let depth = self.depth.checked_add(1).ok_or(Error::Depth)?; - let mut hmac = - HmacSha512::new_from_slice(&self.chain_code).map_err(Error::HmacInvalidLength)?; + let mut hmac = HmacSha512::new_from_slice(&self.chain_code) + .expect("HmacSha512 InvalidLength should be infallible"); if index.is_hardened() { hmac.update(&[0]); hmac.update(&self.private_key.to_bytes()); diff --git a/crates/derive/keyfork-derive-util/src/request.rs b/crates/derive/keyfork-derive-util/src/request.rs index c609adc..cb5c63b 100644 --- a/crates/derive/keyfork-derive-util/src/request.rs +++ b/crates/derive/keyfork-derive-util/src/request.rs @@ -68,7 +68,7 @@ impl DerivationAlgorithm { match self { #[cfg(feature = "ed25519")] Self::Ed25519 => { - let key = ExtendedPrivateKey::::new(seed)?; + let key = ExtendedPrivateKey::::new(seed); let derived_key = key.derive_path(path)?; Ok(DerivationResponse::with_algo_and_xprv( self.clone(), @@ -77,7 +77,7 @@ impl DerivationAlgorithm { } #[cfg(feature = "secp256k1")] Self::Secp256k1 => { - let key = ExtendedPrivateKey::::new(seed)?; + let key = ExtendedPrivateKey::::new(seed); let derived_key = key.derive_path(path)?; Ok(DerivationResponse::with_algo_and_xprv( self.clone(), @@ -85,7 +85,7 @@ impl DerivationAlgorithm { )) } Self::Internal => { - let key = ExtendedPrivateKey::::new(seed)?; + let key = ExtendedPrivateKey::::new(seed); let derived_key = key.derive_path(path)?; Ok(DerivationResponse::with_algo_and_xprv( self.clone(), diff --git a/crates/derive/keyfork-derive-util/src/tests.rs b/crates/derive/keyfork-derive-util/src/tests.rs index f4238e3..eb9d6f4 100644 --- a/crates/derive/keyfork-derive-util/src/tests.rs +++ b/crates/derive/keyfork-derive-util/src/tests.rs @@ -30,7 +30,7 @@ fn secp256k1() { } = test; // Tests for ExtendedPrivateKey - let xkey = ExtendedPrivateKey::::new(seed).unwrap(); + let xkey = ExtendedPrivateKey::::new(seed); let derived_key = xkey.derive_path(&chain).unwrap(); assert_eq!( derived_key.chain_code().as_slice(), @@ -51,7 +51,7 @@ fn secp256k1() { // Tests for DerivationRequest let request = DerivationRequest::new(DerivationAlgorithm::Secp256k1, &chain); let response = request.derive_with_master_seed(seed.clone()).unwrap(); - assert_eq!(&response.data, private_key, "test: {chain}"); + assert_eq!(&response.data, private_key.as_slice(), "test: {chain}"); } } } @@ -75,7 +75,7 @@ fn ed25519() { } = test; // Tests for ExtendedPrivateKey - let xkey = ExtendedPrivateKey::::new(seed).unwrap(); + let xkey = ExtendedPrivateKey::::new(seed); let derived_key = xkey.derive_path(&chain).unwrap(); assert_eq!( derived_key.chain_code().as_slice(), @@ -96,7 +96,7 @@ fn ed25519() { // Tests for DerivationRequest let request = DerivationRequest::new(DerivationAlgorithm::Ed25519, &chain); let response = request.derive_with_master_seed(seed.to_vec()).unwrap(); - assert_eq!(&response.data, private_key, "test: {chain}"); + assert_eq!(&response.data, private_key.as_slice(), "test: {chain}"); } } } @@ -108,7 +108,7 @@ fn panics_with_unhardened_derivation() { use ed25519_dalek::SigningKey; let seed = hex!("000102030405060708090a0b0c0d0e0f"); - let xkey = ExtendedPrivateKey::::new(seed).unwrap(); + let xkey = ExtendedPrivateKey::::new(seed); xkey.derive_path(&DerivationPath::from_str("m/0").unwrap()) .unwrap(); } @@ -120,7 +120,7 @@ fn panics_at_depth() { use ed25519_dalek::SigningKey; let seed = hex!("000102030405060708090a0b0c0d0e0f"); - let mut xkey = ExtendedPrivateKey::::new(seed).unwrap(); + let mut xkey = ExtendedPrivateKey::::new(seed); for i in 0..=u32::from(u8::MAX) { xkey = xkey .derive_child(&DerivationIndex::new(i, true).unwrap()) diff --git a/crates/keyfork-shard/src/openpgp.rs b/crates/keyfork-shard/src/openpgp.rs index a081b51..c3c1aad 100644 --- a/crates/keyfork-shard/src/openpgp.rs +++ b/crates/keyfork-shard/src/openpgp.rs @@ -648,7 +648,7 @@ pub fn combine( // TODO: extract as function let userid = UserID::from("keyfork-sss"); let path = DerivationPath::from_str("m/7366512'/0'")?; - let xprv = XPrv::new(&secret)?.derive_path(&path)?; + let xprv = XPrv::new(&secret).derive_path(&path)?; let derived_cert = keyfork_derive_openpgp::derive( xprv, &[KeyFlags::empty().set_certification().set_signing()], @@ -682,7 +682,7 @@ pub fn split(threshold: u8, certs: Vec, secret: &[u8], output: impl Write) // build cert to sign encrypted shares let userid = UserID::from("keyfork-sss"); let path = DerivationPath::from_str("m/7366512'/0'")?; - let xprv = XPrv::new(&secret)?.derive_path(&path)?; + let xprv = XPrv::new(&secret).derive_path(&path)?; let derived_cert = keyfork_derive_openpgp::derive( xprv, &[KeyFlags::empty().set_certification().set_signing()], diff --git a/crates/keyfork/src/cli/wizard.rs b/crates/keyfork/src/cli/wizard.rs index f3f9992..fb52abe 100644 --- a/crates/keyfork/src/cli/wizard.rs +++ b/crates/keyfork/src/cli/wizard.rs @@ -42,7 +42,7 @@ fn derive_key(seed: &[u8], index: u8) -> Result { .chain_push(chain) .chain_push(account) .chain_push(subkey); - let xprv = XPrv::new(seed)?.derive_path(&path)?; + let xprv = XPrv::new(seed).derive_path(&path)?; let userid = UserID::from(format!("Keyfork Shard {index}")); let cert = keyfork_derive_openpgp::derive(xprv, &subkeys, &userid)?; Ok(cert)