contracthash: expose key tweak in new function

Needed for applications where the tweak and the secret key material are on different
devices (and the one with the secret material does not want to know how to compute
the tweak itself).
This commit is contained in:
Andrew Poelstra 2016-06-10 18:36:15 +00:00
parent 6ccd157775
commit 46681bbcac
2 changed files with 12 additions and 7 deletions

View File

@ -1,7 +1,7 @@
[package] [package]
name = "bitcoin" name = "bitcoin"
version = "0.5.10" version = "0.5.11"
authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"] authors = ["Andrew Poelstra <apoelstra@wpsoftware.net>"]
license = "CC0-1.0" license = "CC0-1.0"
homepage = "https://github.com/apoelstra/rust-bitcoin/" homepage = "https://github.com/apoelstra/rust-bitcoin/"

View File

@ -181,16 +181,21 @@ pub fn tweak_keys(secp: &Secp256k1, keys: &[PublicKey], contract: &[u8]) -> Resu
Ok(ret) Ok(ret)
} }
/// Tweak a secret key using some arbitrary data /// Compute a tweak from some given data for the given public key
pub fn tweak_secret_key(secp: &Secp256k1, key: &SecretKey, contract: &[u8]) -> Result<SecretKey, Error> { pub fn compute_tweak(secp: &Secp256k1, pk: &PublicKey, contract: &[u8]) -> Result<SecretKey, Error> {
// Compute public key
let pk = try!(PublicKey::from_secret_key(secp, &key).map_err(Error::Secp));
// Compute HMAC tweak
let mut hmac_raw = [0; 32]; let mut hmac_raw = [0; 32];
let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &pk.serialize_vec(&secp, true)); let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &pk.serialize_vec(&secp, true));
hmac.input(contract); hmac.input(contract);
hmac.raw_result(&mut hmac_raw); hmac.raw_result(&mut hmac_raw);
let hmac_sk = try!(SecretKey::from_slice(&secp, &hmac_raw).map_err(Error::BadTweak)); SecretKey::from_slice(&secp, &hmac_raw).map_err(Error::BadTweak)
}
/// Tweak a secret key using some arbitrary data (calls `compute_tweak` internally)
pub fn tweak_secret_key(secp: &Secp256k1, key: &SecretKey, contract: &[u8]) -> Result<SecretKey, Error> {
// Compute public key
let pk = try!(PublicKey::from_secret_key(secp, &key).map_err(Error::Secp));
// Compute tweak
let hmac_sk = try!(compute_tweak(secp, &pk, contract));
// Execute the tweak // Execute the tweak
let mut key = *key; let mut key = *key;
try!(key.add_assign(&secp, &hmac_sk).map_err(Error::Secp)); try!(key.add_assign(&secp, &hmac_sk).map_err(Error::Secp));