Improvements to extended keys encoding logic end errors

This commit is contained in:
Dr Maxim Orlovsky 2020-11-06 20:53:03 +01:00
parent 259259eabf
commit d802872310
No known key found for this signature in database
GPG Key ID: FFC0250947E5C6F7
1 changed files with 25 additions and 24 deletions

View File

@ -27,7 +27,7 @@ use secp256k1::{self, Secp256k1};
use network::constants::Network; use network::constants::Network;
use util::{base58, endian}; use util::{base58, endian};
use util::key::{PublicKey, PrivateKey}; use util::key::{self, PublicKey, PrivateKey};
/// A chain code /// A chain code
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -422,6 +422,15 @@ impl error::Error for Error {
} }
} }
impl From<key::Error> for Error {
fn from(err: key::Error) -> Self {
match err {
key::Error::Base58(e) => Error::Base58(e),
key::Error::Secp256k1(e) => Error::Ecdsa(e),
}
}
}
impl From<secp256k1::Error> for Error { impl From<secp256k1::Error> for Error {
fn from(e: secp256k1::Error) -> Error { Error::Ecdsa(e) } fn from(e: secp256k1::Error) -> Error { Error::Ecdsa(e) }
} }
@ -432,12 +441,6 @@ impl From<base58::Error> for Error {
} }
} }
impl From<Error> for base58::Error {
fn from(err: Error) -> Self {
base58::Error::Other(err.to_string())
}
}
impl ExtendedPrivKey { impl ExtendedPrivKey {
/// Construct a new master key from a seed value /// Construct a new master key from a seed value
pub fn new_master(network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> { pub fn new_master(network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> {
@ -516,31 +519,28 @@ impl ExtendedPrivKey {
return Err(Error::WrongExtendedKeyLength(data.len())) return Err(Error::WrongExtendedKeyLength(data.len()))
} }
let cn_int: u32 = endian::slice_to_u32_be(&data[9..13]);
let child_number: ChildNumber = ChildNumber::from(cn_int);
let network = if data[0..4] == [0x04u8, 0x88, 0xAD, 0xE4] { let network = if data[0..4] == [0x04u8, 0x88, 0xAD, 0xE4] {
Network::Bitcoin Network::Bitcoin
} else if data[0..4] == [0x04u8, 0x35, 0x83, 0x94] { } else if data[0..4] == [0x04u8, 0x35, 0x83, 0x94] {
Network::Testnet Network::Testnet
} else { } else {
return Err(base58::Error::InvalidVersion((&data[0..4]).to_vec()).into()); let mut ver = [0u8; 4];
ver.copy_from_slice(&data[0..4]);
return Err(Error::UnknownVersion(ver));
}; };
Ok(ExtendedPrivKey { Ok(ExtendedPrivKey {
network: network, network: network,
depth: data[4], depth: data[4],
parent_fingerprint: Fingerprint::from(&data[5..9]), parent_fingerprint: Fingerprint::from(&data[5..9]),
child_number: child_number, child_number: endian::slice_to_u32_be(&data[9..13]).into(),
chain_code: ChainCode::from(&data[13..45]), chain_code: ChainCode::from(&data[13..45]),
private_key: PrivateKey { private_key: PrivateKey {
compressed: true, compressed: true,
network: network, network: network,
key: secp256k1::SecretKey::from_slice( key: secp256k1::SecretKey::from_slice(
&data[46..78] &data[46..78]
).map_err(|e| ).map_err(Error::Ecdsa)?,
base58::Error::Other(e.to_string())
)?,
}, },
}) })
} }
@ -659,15 +659,16 @@ impl ExtendedPubKey {
} else if data[0..4] == [0x04u8, 0x35, 0x87, 0xCF] { } else if data[0..4] == [0x04u8, 0x35, 0x87, 0xCF] {
Network::Testnet Network::Testnet
} else { } else {
return Err(base58::Error::InvalidVersion((&data[0..4]).to_vec()).into()); let mut ver = [0u8; 4];
ver.copy_from_slice(&data[0..4]);
return Err(Error::UnknownVersion(ver));
}, },
depth: data[4], depth: data[4],
parent_fingerprint: Fingerprint::from(&data[5..9]), parent_fingerprint: Fingerprint::from(&data[5..9]),
child_number: child_number, child_number: child_number,
chain_code: ChainCode::from(&data[13..45]), chain_code: ChainCode::from(&data[13..45]),
public_key: PublicKey::from_slice( public_key: PublicKey::from_slice(
&data[45..78]).map_err(|e| &data[45..78])?,
base58::Error::Other(e.to_string()))?,
}) })
} }
@ -706,13 +707,13 @@ impl fmt::Display for ExtendedPrivKey {
} }
impl FromStr for ExtendedPrivKey { impl FromStr for ExtendedPrivKey {
type Err = base58::Error; type Err = Error;
fn from_str(inp: &str) -> Result<ExtendedPrivKey, base58::Error> { fn from_str(inp: &str) -> Result<ExtendedPrivKey, Error> {
let data = base58::from_check(inp)?; let data = base58::from_check(inp)?;
if data.len() != 78 { if data.len() != 78 {
return Err(base58::Error::InvalidLength(data.len())); return Err(base58::Error::InvalidLength(data.len()).into());
} }
Ok(ExtendedPrivKey::decode(&data[..])?) Ok(ExtendedPrivKey::decode(&data[..])?)
@ -726,13 +727,13 @@ impl fmt::Display for ExtendedPubKey {
} }
impl FromStr for ExtendedPubKey { impl FromStr for ExtendedPubKey {
type Err = base58::Error; type Err = Error;
fn from_str(inp: &str) -> Result<ExtendedPubKey, base58::Error> { fn from_str(inp: &str) -> Result<ExtendedPubKey, Error> {
let data = base58::from_check(inp)?; let data = base58::from_check(inp)?;
if data.len() != 78 { if data.len() != 78 {
return Err(base58::Error::InvalidLength(data.len())); return Err(base58::Error::InvalidLength(data.len()).into());
} }
Ok(ExtendedPubKey::decode(&data[..])?) Ok(ExtendedPubKey::decode(&data[..])?)