bip32: add accessor for the tweak used in public key derivation

This commit is contained in:
Andrew Poelstra 2016-06-24 19:25:47 +00:00
parent 14af175a11
commit f7d4ae8265
1 changed files with 25 additions and 14 deletions

View File

@ -128,6 +128,10 @@ pub enum Error {
RngError(String) RngError(String)
} }
impl From<secp256k1::Error> for Error {
fn from(e: secp256k1::Error) -> Error { Error::Ecdsa(e) }
}
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(secp: &Secp256k1, network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> { pub fn new_master(secp: &Secp256k1, network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> {
@ -228,8 +232,8 @@ impl ExtendedPubKey {
} }
} }
/// Public->Public child key derivation /// Compute the scalar tweak added to this key to get a child key
pub fn ckd_pub(&self, secp: &Secp256k1, i: ChildNumber) -> Result<ExtendedPubKey, Error> { pub fn ckd_pub_tweak(&self, secp: &Secp256k1, i: ChildNumber) -> Result<(SecretKey, ChainCode), Error> {
match i { match i {
ChildNumber::Hardened(n) => { ChildNumber::Hardened(n) => {
if n >= (1 << 31) { if n >= (1 << 31) {
@ -248,7 +252,16 @@ impl ExtendedPubKey {
let mut result = [0; 64]; let mut result = [0; 64];
hmac.raw_result(&mut result); hmac.raw_result(&mut result);
let sk = try!(SecretKey::from_slice(secp, &result[..32]).map_err(Error::Ecdsa)); let secret_key = try!(SecretKey::from_slice(secp, &result[..32]));
let chain_code = ChainCode::from(&result[32..]);
Ok((secret_key, chain_code))
}
}
}
/// Public->Public child key derivation
pub fn ckd_pub(&self, secp: &Secp256k1, i: ChildNumber) -> Result<ExtendedPubKey, Error> {
let (sk, chain_code) = try!(self.ckd_pub_tweak(secp, i));
let mut pk = self.public_key.clone(); let mut pk = self.public_key.clone();
try!(pk.add_exp_assign(secp, &sk).map_err(Error::Ecdsa)); try!(pk.add_exp_assign(secp, &sk).map_err(Error::Ecdsa));
@ -258,11 +271,9 @@ impl ExtendedPubKey {
parent_fingerprint: self.fingerprint(), parent_fingerprint: self.fingerprint(),
child_number: i, child_number: i,
public_key: pk, public_key: pk,
chain_code: ChainCode::from(&result[32..]) chain_code: chain_code
}) })
} }
}
}
/// Returns the HASH160 of the chaincode /// Returns the HASH160 of the chaincode
pub fn identifier(&self) -> [u8; 20] { pub fn identifier(&self) -> [u8; 20] {