#![allow(clippy::implicit_clone)] use crate::{request::*, *}; use hex_literal::hex; use std::str::FromStr; // Pulled from: https://github.com/satoshilabs/slips/blob/master/slip-0010.md use keyfork_slip10_test_data::{test_data, Test}; #[cfg(feature = "secp256k1")] #[test] fn secp256k1() { use k256::SecretKey; let tests = test_data() .unwrap() .remove(&"secp256k1".to_string()) .unwrap(); for per_seed in tests { let seed = &per_seed.seed; for test in &per_seed.tests { let chain = DerivationPath::from_str(test.chain).unwrap(); let Test { chain_code, private_key, public_key, .. } = test; // Tests for ExtendedPrivateKey let xkey = ExtendedPrivateKey::::new(seed); let derived_key = xkey.derive_path(&chain).unwrap(); assert_eq!( derived_key.chain_code().as_slice(), chain_code, "test: {chain}", ); assert_eq!( PrivateKey::to_bytes(derived_key.private_key()).as_slice(), private_key, "test: {chain}", ); assert_eq!( PublicKey::to_bytes(&derived_key.public_key()).as_slice(), public_key, "test: {chain}", ); // 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.as_slice(), "test: {chain}"); } } } #[cfg(feature = "ed25519")] #[test] fn ed25519() { use ed25519_dalek::SigningKey; let tests = test_data().unwrap().remove(&"ed25519".to_string()).unwrap(); for per_seed in tests { let seed = &per_seed.seed; for test in &per_seed.tests { let chain = DerivationPath::from_str(test.chain).unwrap(); let Test { chain_code, private_key, public_key, .. } = test; // Tests for ExtendedPrivateKey let xkey = ExtendedPrivateKey::::new(seed); let derived_key = xkey.derive_path(&chain).unwrap(); assert_eq!( derived_key.chain_code().as_slice(), chain_code, "test: {chain}", ); assert_eq!( PrivateKey::to_bytes(derived_key.private_key()).as_slice(), private_key, "test: {chain}", ); assert_eq!( PublicKey::to_bytes(&derived_key.public_key()).as_slice(), public_key, "test: {chain}", ); // 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.as_slice(), "test: {chain}"); } } } #[cfg(feature = "ed25519")] #[test] #[should_panic] fn panics_with_unhardened_derivation() { use ed25519_dalek::SigningKey; let seed = hex!("000102030405060708090a0b0c0d0e0f"); let xkey = ExtendedPrivateKey::::new(seed); xkey.derive_path(&DerivationPath::from_str("m/0").unwrap()) .unwrap(); } #[cfg(feature = "ed25519")] #[test] #[should_panic] fn panics_at_depth() { use ed25519_dalek::SigningKey; let seed = hex!("000102030405060708090a0b0c0d0e0f"); let mut xkey = ExtendedPrivateKey::::new(seed); for i in 0..=u32::from(u8::MAX) { xkey = xkey .derive_child(&DerivationIndex::new(i, true).unwrap()) .unwrap(); } }