diff --git a/Cargo.lock b/Cargo.lock index b2a4ab3..de2a22f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -437,6 +437,7 @@ dependencies = [ name = "slip10" version = "0.1.0" dependencies = [ + "generic-array", "generic-ec", "hex-literal", "hmac", diff --git a/Cargo.toml b/Cargo.toml index 29f5ab4..f5690a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ generic-ec = { version = "0.1", default-features = false } hmac = { version = "0.12", default-features = false } sha2 = { version = "0.10", default-features = false } subtle = { version = "2", default-features = false } +generic-array = "0.14" [dev-dependencies] hex-literal = "0.4" diff --git a/src/lib.rs b/src/lib.rs index 9e3a75d..00751e5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,6 +52,10 @@ use core::ops; +use generic_array::{ + typenum::{U32, U64}, + GenericArray, +}; use generic_ec::{Curve, Point, Scalar, SecretScalar}; use hmac::Mac as _; @@ -278,16 +282,13 @@ pub fn derive_master_key( let mut i = hmac.clone().chain_update(seed).finalize().into_bytes(); loop { - let i_left = &i[..32]; - let i_right: [u8; 32] = i[32..] - .try_into() - .expect("this should never fail as size of output is fixed"); + let (i_left, i_right) = split_into_two_halfes(&i); if let Ok(mut sk) = Scalar::::from_be_bytes(i_left) { if !bool::from(subtle::ConstantTimeEq::ct_eq(&sk, &Scalar::zero())) { return Ok(ExtendedSecretKey { secret_key: SecretScalar::new(&mut sk), - chain_code: i_right, + chain_code: i_right.clone().into(), }); } } @@ -403,10 +404,7 @@ fn calculate_shift( mut i: hmac::digest::Output, ) -> DerivedShift { loop { - let i_left = &i[..32]; - let i_right: [u8; 32] = i[32..] - .try_into() - .expect("this should never fail as size of output is fixed"); + let (i_left, i_right) = split_into_two_halfes(&i); if let Ok(shift) = Scalar::::from_be_bytes(i_left) { let child_pk = parent_public_key.public_key + Point::generator() * shift; @@ -415,7 +413,7 @@ fn calculate_shift( shift, child_public_key: ExtendedPublicKey { public_key: child_pk, - chain_code: i_right, + chain_code: i_right.clone().into(), }, }; } @@ -430,3 +428,10 @@ fn calculate_shift( .into_bytes() } } + +/// Splits array `I` of 64 bytes into two arrays `I_L = I[..32]` and `I_R = I[32..]` +fn split_into_two_halfes( + i: &GenericArray, +) -> (&GenericArray, &GenericArray) { + generic_array::sequence::Split::split(i) +}