update to secp256k1 0.10.0

This commit is contained in:
Andrew Poelstra 2018-07-27 20:15:48 +00:00
parent 85ddb66be0
commit 94f3d4b0f9
4 changed files with 43 additions and 39 deletions

View File

@ -32,5 +32,5 @@ git = "https://github.com/KokaKiwi/rust-hex"
rev = "19fd37137686c30058bd9d11d21590e726ffdf31"
[dependencies.secp256k1]
version = "0.9"
version = "0.10"
features = [ "rand" ]

View File

@ -230,7 +230,7 @@ impl From<secp256k1::Error> for Error {
impl ExtendedPrivKey {
/// 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<C>(secp: &Secp256k1<C>, network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> {
let mut result = [0; 64];
let mut hmac = Hmac::new(Sha512::new(), b"Bitcoin seed");
hmac.input(seed);
@ -247,9 +247,9 @@ impl ExtendedPrivKey {
}
/// Attempts to derive an extended private key from a path.
pub fn derive_priv(
pub fn derive_priv<C: secp256k1::Signing>(
&self,
secp: &Secp256k1,
secp: &Secp256k1<C>,
cnums: &[ChildNumber],
) -> Result<ExtendedPrivKey, Error> {
let mut sk: ExtendedPrivKey = *self;
@ -260,14 +260,14 @@ impl ExtendedPrivKey {
}
/// Private->Private child key derivation
pub fn ckd_priv(&self, secp: &Secp256k1, i: ChildNumber) -> Result<ExtendedPrivKey, Error> {
pub fn ckd_priv<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>, i: ChildNumber) -> Result<ExtendedPrivKey, Error> {
let mut result = [0; 64];
let mut hmac = Hmac::new(Sha512::new(), &self.chain_code[..]);
let mut be_n = [0; 4];
match i {
ChildNumber::Normal {..} => {
// Non-hardened key: compute public data and use that
hmac.input(&PublicKey::from_secret_key(secp, &self.secret_key).unwrap().serialize()[..]);
hmac.input(&PublicKey::from_secret_key(secp, &self.secret_key).serialize()[..]);
}
ChildNumber::Hardened {..} => {
// Hardened key: use only secret data to prevent public derivation
@ -293,7 +293,7 @@ impl ExtendedPrivKey {
}
/// Returns the HASH160 of the chaincode
pub fn identifier(&self, secp: &Secp256k1) -> [u8; 20] {
pub fn identifier<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> [u8; 20] {
let mut sha2_res = [0; 32];
let mut ripemd_res = [0; 20];
// Compute extended public key
@ -311,28 +311,28 @@ impl ExtendedPrivKey {
}
/// Returns the first four bytes of the identifier
pub fn fingerprint(&self, secp: &Secp256k1) -> Fingerprint {
pub fn fingerprint<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> Fingerprint {
Fingerprint::from(&self.identifier(secp)[0..4])
}
}
impl ExtendedPubKey {
/// Derives a public key from a private key
pub fn from_private(secp: &Secp256k1, sk: &ExtendedPrivKey) -> ExtendedPubKey {
pub fn from_private<C: secp256k1::Signing>(secp: &Secp256k1<C>, sk: &ExtendedPrivKey) -> ExtendedPubKey {
ExtendedPubKey {
network: sk.network,
depth: sk.depth,
parent_fingerprint: sk.parent_fingerprint,
child_number: sk.child_number,
public_key: PublicKey::from_secret_key(secp, &sk.secret_key).unwrap(),
public_key: PublicKey::from_secret_key(secp, &sk.secret_key),
chain_code: sk.chain_code
}
}
/// Attempts to derive an extended public key from a path.
pub fn derive_pub(
pub fn derive_pub<C: secp256k1::Verification>(
&self,
secp: &Secp256k1,
secp: &Secp256k1<C>,
cnums: &[ChildNumber],
) -> Result<ExtendedPubKey, Error> {
let mut pk: ExtendedPubKey = *self;
@ -343,7 +343,7 @@ impl ExtendedPubKey {
}
/// Compute the scalar tweak added to this key to get a child key
pub fn ckd_pub_tweak(&self, secp: &Secp256k1, i: ChildNumber) -> Result<(SecretKey, ChainCode), Error> {
pub fn ckd_pub_tweak<C>(&self, secp: &Secp256k1<C>, i: ChildNumber) -> Result<(SecretKey, ChainCode), Error> {
match i {
ChildNumber::Hardened {..} => {
Err(Error::CannotDeriveFromHardenedKey)
@ -366,7 +366,11 @@ impl ExtendedPubKey {
}
/// Public->Public child key derivation
pub fn ckd_pub(&self, secp: &Secp256k1, i: ChildNumber) -> Result<ExtendedPubKey, Error> {
pub fn ckd_pub<C: secp256k1::Verification>(
&self,
secp: &Secp256k1<C>,
i: ChildNumber,
) -> Result<ExtendedPubKey, Error> {
let (sk, chain_code) = self.ckd_pub_tweak(secp, i)?;
let mut pk = self.public_key.clone();
pk.add_exp_assign(secp, &sk).map_err(Error::Ecdsa)?;
@ -426,7 +430,7 @@ impl FromStr for ExtendedPrivKey {
type Err = base58::Error;
fn from_str(inp: &str) -> Result<ExtendedPrivKey, base58::Error> {
let s = Secp256k1::with_caps(secp256k1::ContextFlag::None);
let s = Secp256k1::without_caps();
let data = base58::from_check(inp)?;
if data.len() != 78 {
@ -477,7 +481,7 @@ impl FromStr for ExtendedPubKey {
type Err = base58::Error;
fn from_str(inp: &str) -> Result<ExtendedPubKey, base58::Error> {
let s = Secp256k1::with_caps(secp256k1::ContextFlag::None);
let s = Secp256k1::without_caps();
let data = base58::from_check(inp)?;
if data.len() != 78 {
@ -511,7 +515,7 @@ mod tests {
use std::str::FromStr;
use std::string::ToString;
use secp256k1::Secp256k1;
use secp256k1::{self, Secp256k1};
use hex::decode as hex_decode;
use network::constants::Network::{self, Bitcoin};
@ -520,7 +524,7 @@ mod tests {
use super::ChildNumber::{Hardened, Normal};
use super::Error;
fn test_path(secp: &Secp256k1,
fn test_path<C: secp256k1::Signing + secp256k1::Verification>(secp: &Secp256k1<C>,
network: Network,
seed: &[u8],
path: &[ChildNumber],

View File

@ -170,7 +170,7 @@ impl<'a> From<&'a [u8]> for Template {
}
/// Tweak keys using some arbitrary data
pub fn tweak_keys(secp: &Secp256k1, keys: &[PublicKey], contract: &[u8]) -> Result<Vec<PublicKey>, Error> {
pub fn tweak_keys<C: secp256k1::Verification>(secp: &Secp256k1<C>, keys: &[PublicKey], contract: &[u8]) -> Result<Vec<PublicKey>, Error> {
let mut ret = Vec::with_capacity(keys.len());
for mut key in keys.iter().cloned() {
let mut hmac_raw = [0; 32];
@ -185,7 +185,7 @@ pub fn tweak_keys(secp: &Secp256k1, keys: &[PublicKey], contract: &[u8]) -> Resu
}
/// Compute a tweak from some given data for the given public key
pub fn compute_tweak(secp: &Secp256k1, pk: &PublicKey, contract: &[u8]) -> Result<SecretKey, Error> {
pub fn compute_tweak<C>(secp: &Secp256k1<C>, pk: &PublicKey, contract: &[u8]) -> Result<SecretKey, Error> {
let mut hmac_raw = [0; 32];
let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &pk.serialize());
hmac.input(contract);
@ -194,9 +194,9 @@ pub fn compute_tweak(secp: &Secp256k1, pk: &PublicKey, contract: &[u8]) -> Resul
}
/// 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> {
pub fn tweak_secret_key<C: secp256k1::Signing>(secp: &Secp256k1<C>, key: &SecretKey, contract: &[u8]) -> Result<SecretKey, Error> {
// Compute public key
let pk = PublicKey::from_secret_key(secp, &key).map_err(Error::Secp)?;
let pk = PublicKey::from_secret_key(secp, &key);
// Compute tweak
let hmac_sk = compute_tweak(secp, &pk, contract)?;
// Execute the tweak
@ -207,7 +207,7 @@ pub fn tweak_secret_key(secp: &Secp256k1, key: &SecretKey, contract: &[u8]) -> R
}
/// Takes a contract, template and key set and runs through all the steps
pub fn create_address(secp: &Secp256k1,
pub fn create_address<C: secp256k1::Verification>(secp: &Secp256k1<C>,
network: Network,
contract: &[u8],
keys: &[PublicKey],
@ -343,9 +343,9 @@ mod tests {
#[test]
fn tweak_secret() {
let secp = Secp256k1::new();
let (sk1, pk1) = secp.generate_keypair(&mut thread_rng()).unwrap();
let (sk2, pk2) = secp.generate_keypair(&mut thread_rng()).unwrap();
let (sk3, pk3) = secp.generate_keypair(&mut thread_rng()).unwrap();
let (sk1, pk1) = secp.generate_keypair(&mut thread_rng());
let (sk2, pk2) = secp.generate_keypair(&mut thread_rng());
let (sk3, pk3) = secp.generate_keypair(&mut thread_rng());
let pks = [pk1, pk2, pk3];
let contract = b"if bottle mt dont remembr drink wont pay";
@ -353,9 +353,9 @@ mod tests {
// Directly compute tweaks on pubkeys
let tweaked_pks = tweak_keys(&secp, &pks, &contract[..]).unwrap();
// Compute tweaks on secret keys
let tweaked_pk1 = PublicKey::from_secret_key(&secp, &tweak_secret_key(&secp, &sk1, &contract[..]).unwrap()).unwrap();
let tweaked_pk2 = PublicKey::from_secret_key(&secp, &tweak_secret_key(&secp, &sk2, &contract[..]).unwrap()).unwrap();
let tweaked_pk3 = PublicKey::from_secret_key(&secp, &tweak_secret_key(&secp, &sk3, &contract[..]).unwrap()).unwrap();
let tweaked_pk1 = PublicKey::from_secret_key(&secp, &tweak_secret_key(&secp, &sk1, &contract[..]).unwrap());
let tweaked_pk2 = PublicKey::from_secret_key(&secp, &tweak_secret_key(&secp, &sk2, &contract[..]).unwrap());
let tweaked_pk3 = PublicKey::from_secret_key(&secp, &tweak_secret_key(&secp, &sk3, &contract[..]).unwrap());
// Check equality
assert_eq!(tweaked_pks[0], tweaked_pk1);
assert_eq!(tweaked_pks[1], tweaked_pk2);

View File

@ -17,7 +17,7 @@
//!
use std::str::FromStr;
use util::Error;
use secp256k1::Secp256k1;
use secp256k1::{self, Secp256k1};
use secp256k1::key::{PublicKey, SecretKey};
use util::address::Address;
use network::constants::Network;
@ -46,24 +46,24 @@ impl Privkey {
}
/// Computes the public key as supposed to be used with this secret
pub fn public_key(&self, secp: &Secp256k1) -> Result<PublicKey, Error> {
Ok(PublicKey::from_secret_key(secp, &self.key)?)
pub fn public_key<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> PublicKey {
PublicKey::from_secret_key(secp, &self.key)
}
/// Converts a private key to a segwit address
#[inline]
pub fn to_address(&self, secp: &Secp256k1) -> Result<Address, Error> {
Ok(Address::p2wpkh(&self.public_key(secp)?, self.network))
pub fn to_address<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> Address {
Address::p2wpkh(&self.public_key(secp), self.network)
}
/// Converts a private key to a legacy (non-segwit) address
#[inline]
pub fn to_legacy_address(&self, secp: &Secp256k1) -> Result<Address, Error> {
pub fn to_legacy_address<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> Address {
if self.compressed {
Ok(Address::p2pkh(&self.public_key(secp)?, self.network))
Address::p2pkh(&self.public_key(secp), self.network)
}
else {
Ok(Address::p2upkh(&self.public_key(secp)?, self.network))
Address::p2upkh(&self.public_key(secp), self.network)
}
}
@ -156,7 +156,7 @@ mod tests {
assert_eq!(&sk.to_string(), "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy");
let secp = Secp256k1::new();
let pk = sk.to_legacy_address(&secp).unwrap();
let pk = sk.to_legacy_address(&secp);
assert_eq!(&pk.to_string(), "mqwpxxvfv3QbM8PU8uBx2jaNt9btQqvQNx");
// mainnet uncompressed
@ -166,7 +166,7 @@ mod tests {
assert_eq!(&sk.to_string(), "5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3");
let secp = Secp256k1::new();
let pk = sk.to_legacy_address(&secp).unwrap();
let pk = sk.to_legacy_address(&secp);
assert_eq!(&pk.to_string(), "1GhQvF6dL8xa6wBxLnWmHcQsurx9RxiMc8");
}
}