Merge pull request #213 from dongcarl/2019-01-secp-0.12-bump

Bump secp to 0.12
This commit is contained in:
Andrew Poelstra 2019-01-15 19:03:03 +00:00 committed by GitHub
commit 282daaab69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 51 deletions

View File

@ -39,5 +39,5 @@ default-features = false
version = "=0.3.2" version = "=0.3.2"
[dependencies.secp256k1] [dependencies.secp256k1]
version = "0.11" version = "0.12"
features = [ "rand" ] features = [ "rand" ]

View File

@ -403,7 +403,6 @@ mod tests {
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use secp256k1::Secp256k1;
use secp256k1::key::PublicKey; use secp256k1::key::PublicKey;
use hex::decode as hex_decode; use hex::decode as hex_decode;
@ -413,7 +412,7 @@ mod tests {
use super::*; use super::*;
macro_rules! hex (($hex:expr) => (hex_decode($hex).unwrap())); macro_rules! hex (($hex:expr) => (hex_decode($hex).unwrap()));
macro_rules! hex_key (($secp:expr, $hex:expr) => (PublicKey::from_slice($secp, &hex!($hex)).unwrap())); macro_rules! hex_key (($hex:expr) => (PublicKey::from_slice(&hex!($hex)).unwrap()));
macro_rules! hex_script (($hex:expr) => (Script::from(hex!($hex)))); macro_rules! hex_script (($hex:expr) => (Script::from(hex!($hex))));
#[test] #[test]
@ -432,13 +431,11 @@ mod tests {
#[test] #[test]
fn test_p2pkh_from_key() { fn test_p2pkh_from_key() {
let secp = Secp256k1::without_caps(); let key = hex_key!("048d5141948c1702e8c95f438815794b87f706a8d4cd2bffad1dc1570971032c9b6042a0431ded2478b5c9cf2d81c124a5e57347a3c63ef0e7716cf54d613ba183");
let key = hex_key!(&secp, "048d5141948c1702e8c95f438815794b87f706a8d4cd2bffad1dc1570971032c9b6042a0431ded2478b5c9cf2d81c124a5e57347a3c63ef0e7716cf54d613ba183");
let addr = Address::p2upkh(&key, Bitcoin); let addr = Address::p2upkh(&key, Bitcoin);
assert_eq!(&addr.to_string(), "1QJVDzdqb1VpbDK7uDeyVXy9mR27CJiyhY"); assert_eq!(&addr.to_string(), "1QJVDzdqb1VpbDK7uDeyVXy9mR27CJiyhY");
let key = hex_key!(&secp, &"03df154ebfcf29d29cc10d5c2565018bce2d9edbab267c31d2caf44a63056cf99f"); let key = hex_key!(&"03df154ebfcf29d29cc10d5c2565018bce2d9edbab267c31d2caf44a63056cf99f");
let addr = Address::p2pkh(&key, Testnet); let addr = Address::p2pkh(&key, Testnet);
assert_eq!(&addr.to_string(), "mqkhEMH6NCeYjFybv7pvFC22MFeaNT9AQC"); assert_eq!(&addr.to_string(), "mqkhEMH6NCeYjFybv7pvFC22MFeaNT9AQC");
} }
@ -446,8 +443,7 @@ mod tests {
#[test] #[test]
fn test_p2pk () { fn test_p2pk () {
// one of Satoshi's coins, from Bitcoin transaction 9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5 // one of Satoshi's coins, from Bitcoin transaction 9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5
let secp = Secp256k1::without_caps(); let key = hex_key!("047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77");
let key = hex_key!(&secp, "047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77");
let addr = Address::p2pk(&key, Bitcoin); let addr = Address::p2pk(&key, Bitcoin);
assert_eq!(&addr.to_string(), "1HLoD9E4SDFFPDiYfNYnkBLQ85Y51J3Zb1"); assert_eq!(&addr.to_string(), "1HLoD9E4SDFFPDiYfNYnkBLQ85Y51J3Zb1");
} }
@ -478,8 +474,7 @@ mod tests {
#[test] #[test]
fn test_p2wpkh () { fn test_p2wpkh () {
// stolen from Bitcoin transaction: b3c8c2b6cfc335abbcb2c7823a8453f55d64b2b5125a9a61e8737230cdb8ce20 // stolen from Bitcoin transaction: b3c8c2b6cfc335abbcb2c7823a8453f55d64b2b5125a9a61e8737230cdb8ce20
let secp = Secp256k1::without_caps(); let key = hex_key!("033bc8c83c52df5712229a2f72206d90192366c36428cb0c12b6af98324d97bfbc");
let key = hex_key!(&secp, "033bc8c83c52df5712229a2f72206d90192366c36428cb0c12b6af98324d97bfbc");
let addr = Address::p2wpkh(&key, Bitcoin); let addr = Address::p2wpkh(&key, Bitcoin);
assert_eq!(&addr.to_string(), "bc1qvzvkjn4q3nszqxrv3nraga2r822xjty3ykvkuw"); assert_eq!(&addr.to_string(), "bc1qvzvkjn4q3nszqxrv3nraga2r822xjty3ykvkuw");
} }

View File

@ -107,14 +107,13 @@ mod tests {
use util::misc::hex_bytes; use util::misc::hex_bytes;
use util::address::Address; use util::address::Address;
use hex; use hex;
use secp256k1::{Secp256k1, PublicKey}; use secp256k1::PublicKey;
use super::*; use super::*;
fn p2pkh_hex(pk: &str) -> Script { fn p2pkh_hex(pk: &str) -> Script {
let ctx = Secp256k1::new();
let pk = hex::decode(pk).unwrap(); let pk = hex::decode(pk).unwrap();
let pk = PublicKey::from_slice(&ctx, pk.as_slice()).unwrap(); let pk = PublicKey::from_slice(pk.as_slice()).unwrap();
let witness_script = Address::p2pkh(&pk, Network::Bitcoin).script_pubkey(); let witness_script = Address::p2pkh(&pk, Network::Bitcoin).script_pubkey();
witness_script witness_script
} }

View File

@ -236,7 +236,7 @@ impl From<secp256k1::Error> for Error {
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<C>(secp: &Secp256k1<C>, network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> { pub fn new_master(network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> {
let mut result = [0; 64]; let mut result = [0; 64];
let mut hmac = Hmac::new(Sha512::new(), b"Bitcoin seed"); let mut hmac = Hmac::new(Sha512::new(), b"Bitcoin seed");
hmac.input(seed); hmac.input(seed);
@ -247,7 +247,7 @@ impl ExtendedPrivKey {
depth: 0, depth: 0,
parent_fingerprint: Default::default(), parent_fingerprint: Default::default(),
child_number: ChildNumber::from_normal_idx(0), child_number: ChildNumber::from_normal_idx(0),
secret_key: SecretKey::from_slice(secp, &result[..32]).map_err(Error::Ecdsa)?, secret_key: SecretKey::from_slice(&result[..32]).map_err(Error::Ecdsa)?,
chain_code: ChainCode::from(&result[32..]) chain_code: ChainCode::from(&result[32..])
}) })
} }
@ -285,8 +285,8 @@ impl ExtendedPrivKey {
hmac.input(&be_n); hmac.input(&be_n);
hmac.raw_result(&mut result); hmac.raw_result(&mut result);
let mut sk = SecretKey::from_slice(secp, &result[..32]).map_err(Error::Ecdsa)?; let mut sk = SecretKey::from_slice(&result[..32]).map_err(Error::Ecdsa)?;
sk.add_assign(secp, &self.secret_key).map_err(Error::Ecdsa)?; sk.add_assign(&self.secret_key[..]).map_err(Error::Ecdsa)?;
Ok(ExtendedPrivKey { Ok(ExtendedPrivKey {
network: self.network, network: self.network,
@ -349,7 +349,7 @@ impl ExtendedPubKey {
} }
/// Compute the scalar tweak added to this key to get a child key /// Compute the scalar tweak added to this key to get a child key
pub fn ckd_pub_tweak<C>(&self, secp: &Secp256k1<C>, i: ChildNumber) -> Result<(SecretKey, ChainCode), Error> { pub fn ckd_pub_tweak(&self, i: ChildNumber) -> Result<(SecretKey, ChainCode), Error> {
match i { match i {
ChildNumber::Hardened {..} => { ChildNumber::Hardened {..} => {
Err(Error::CannotDeriveFromHardenedKey) Err(Error::CannotDeriveFromHardenedKey)
@ -364,7 +364,7 @@ impl ExtendedPubKey {
let mut result = [0; 64]; let mut result = [0; 64];
hmac.raw_result(&mut result); hmac.raw_result(&mut result);
let secret_key = SecretKey::from_slice(secp, &result[..32])?; let secret_key = SecretKey::from_slice(&result[..32])?;
let chain_code = ChainCode::from(&result[32..]); let chain_code = ChainCode::from(&result[32..]);
Ok((secret_key, chain_code)) Ok((secret_key, chain_code))
} }
@ -377,9 +377,9 @@ impl ExtendedPubKey {
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
i: ChildNumber, i: ChildNumber,
) -> Result<ExtendedPubKey, Error> { ) -> Result<ExtendedPubKey, Error> {
let (sk, chain_code) = self.ckd_pub_tweak(secp, i)?; let (sk, chain_code) = self.ckd_pub_tweak(i)?;
let mut pk = self.public_key.clone(); let mut pk = self.public_key.clone();
pk.add_exp_assign(secp, &sk).map_err(Error::Ecdsa)?; pk.add_exp_assign(secp, &sk[..]).map_err(Error::Ecdsa)?;
Ok(ExtendedPubKey { Ok(ExtendedPubKey {
network: self.network, network: self.network,
@ -436,7 +436,6 @@ impl FromStr for ExtendedPrivKey {
type Err = base58::Error; type Err = base58::Error;
fn from_str(inp: &str) -> Result<ExtendedPrivKey, base58::Error> { fn from_str(inp: &str) -> Result<ExtendedPrivKey, base58::Error> {
let s = Secp256k1::without_caps();
let data = base58::from_check(inp)?; let data = base58::from_check(inp)?;
if data.len() != 78 { if data.len() != 78 {
@ -458,7 +457,7 @@ impl FromStr for ExtendedPrivKey {
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]),
secret_key: SecretKey::from_slice(&s, secret_key: SecretKey::from_slice(
&data[46..78]).map_err(|e| &data[46..78]).map_err(|e|
base58::Error::Other(e.to_string()))? base58::Error::Other(e.to_string()))?
}) })
@ -487,7 +486,6 @@ impl FromStr for ExtendedPubKey {
type Err = base58::Error; type Err = base58::Error;
fn from_str(inp: &str) -> Result<ExtendedPubKey, base58::Error> { fn from_str(inp: &str) -> Result<ExtendedPubKey, base58::Error> {
let s = Secp256k1::without_caps();
let data = base58::from_check(inp)?; let data = base58::from_check(inp)?;
if data.len() != 78 { if data.len() != 78 {
@ -509,7 +507,7 @@ impl FromStr for ExtendedPubKey {
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(&s, public_key: PublicKey::from_slice(
&data[45..78]).map_err(|e| &data[45..78]).map_err(|e|
base58::Error::Other(e.to_string()))? base58::Error::Other(e.to_string()))?
}) })
@ -537,7 +535,7 @@ mod tests {
expected_sk: &str, expected_sk: &str,
expected_pk: &str) { expected_pk: &str) {
let mut sk = ExtendedPrivKey::new_master(secp, network, seed).unwrap(); let mut sk = ExtendedPrivKey::new_master(network, seed).unwrap();
let mut pk = ExtendedPubKey::from_private(secp, &sk); let mut pk = ExtendedPubKey::from_private(secp, &sk);
// Check derivation convenience method for ExtendedPrivKey // Check derivation convenience method for ExtendedPrivKey

View File

@ -177,20 +177,20 @@ pub fn tweak_keys<C: secp256k1::Verification>(secp: &Secp256k1<C>, keys: &[Publi
let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &key.serialize()); let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &key.serialize());
hmac.input(contract); hmac.input(contract);
hmac.raw_result(&mut hmac_raw); hmac.raw_result(&mut hmac_raw);
let hmac_sk = SecretKey::from_slice(secp, &hmac_raw).map_err(Error::BadTweak)?; let hmac_sk = SecretKey::from_slice(&hmac_raw).map_err(Error::BadTweak)?;
key.add_exp_assign(secp, &hmac_sk).map_err(Error::Secp)?; key.add_exp_assign(secp, &hmac_sk[..]).map_err(Error::Secp)?;
ret.push(key); ret.push(key);
} }
Ok(ret) Ok(ret)
} }
/// Compute a tweak from some given data for the given public key /// Compute a tweak from some given data for the given public key
pub fn compute_tweak<C>(secp: &Secp256k1<C>, pk: &PublicKey, contract: &[u8]) -> Result<SecretKey, Error> { pub fn compute_tweak(pk: &PublicKey, contract: &[u8]) -> Result<SecretKey, Error> {
let mut hmac_raw = [0; 32]; let mut hmac_raw = [0; 32];
let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &pk.serialize()); let mut hmac = hmac::Hmac::new(sha2::Sha256::new(), &pk.serialize());
hmac.input(contract); hmac.input(contract);
hmac.raw_result(&mut hmac_raw); hmac.raw_result(&mut hmac_raw);
SecretKey::from_slice(secp, &hmac_raw).map_err(Error::BadTweak) SecretKey::from_slice(&hmac_raw).map_err(Error::BadTweak)
} }
/// Tweak a secret key using some arbitrary data (calls `compute_tweak` internally) /// Tweak a secret key using some arbitrary data (calls `compute_tweak` internally)
@ -198,10 +198,10 @@ pub fn tweak_secret_key<C: secp256k1::Signing>(secp: &Secp256k1<C>, key: &Secret
// Compute public key // Compute public key
let pk = PublicKey::from_secret_key(secp, &key); let pk = PublicKey::from_secret_key(secp, &key);
// Compute tweak // Compute tweak
let hmac_sk = compute_tweak(secp, &pk, contract)?; let hmac_sk = compute_tweak(&pk, contract)?;
// Execute the tweak // Execute the tweak
let mut key = *key; let mut key = *key;
key.add_assign(&secp, &hmac_sk).map_err(Error::Secp)?; key.add_assign(&hmac_sk[..]).map_err(Error::Secp)?;
// Return // Return
Ok(key) Ok(key)
} }
@ -227,7 +227,6 @@ pub fn create_address<C: secp256k1::Verification>(secp: &Secp256k1<C>,
pub fn untemplate(script: &script::Script) -> Result<(Template, Vec<PublicKey>), Error> { pub fn untemplate(script: &script::Script) -> Result<(Template, Vec<PublicKey>), Error> {
let mut ret = script::Builder::new(); let mut ret = script::Builder::new();
let mut retkeys = vec![]; let mut retkeys = vec![];
let secp = Secp256k1::without_caps();
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
enum Mode { enum Mode {
@ -241,7 +240,7 @@ pub fn untemplate(script: &script::Script) -> Result<(Template, Vec<PublicKey>),
match instruction { match instruction {
script::Instruction::PushBytes(data) => { script::Instruction::PushBytes(data) => {
let n = data.len(); let n = data.len();
ret = match PublicKey::from_slice(&secp, data) { ret = match PublicKey::from_slice(data) {
Ok(key) => { Ok(key) => {
if n == 65 { return Err(Error::UncompressedKey); } if n == 65 { return Err(Error::UncompressedKey); }
if mode == Mode::SeekingCheckMulti { return Err(Error::ExpectedChecksig); } if mode == Mode::SeekingCheckMulti { return Err(Error::ExpectedChecksig); }
@ -304,22 +303,22 @@ mod tests {
use super::*; use super::*;
macro_rules! hex (($hex:expr) => (hex_decode($hex).unwrap())); macro_rules! hex (($hex:expr) => (hex_decode($hex).unwrap()));
macro_rules! hex_key (($secp:expr, $hex:expr) => (PublicKey::from_slice($secp, &hex!($hex)).unwrap())); macro_rules! hex_key (($hex:expr) => (PublicKey::from_slice(&hex!($hex)).unwrap()));
macro_rules! alpha_template(() => (Template::from(&hex!("55fefefefefefefe57AE")[..]))); macro_rules! alpha_template(() => (Template::from(&hex!("55fefefefefefefe57AE")[..])));
macro_rules! alpha_keys(($secp:expr) => ( macro_rules! alpha_keys(() => (
&[hex_key!($secp, "0269992fb441ae56968e5b77d46a3e53b69f136444ae65a94041fc937bdb28d933"), &[hex_key!("0269992fb441ae56968e5b77d46a3e53b69f136444ae65a94041fc937bdb28d933"),
hex_key!($secp, "021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a"), hex_key!("021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a"),
hex_key!($secp, "02174c82021492c2c6dfcbfa4187d10d38bed06afb7fdcd72c880179fddd641ea1"), hex_key!("02174c82021492c2c6dfcbfa4187d10d38bed06afb7fdcd72c880179fddd641ea1"),
hex_key!($secp, "033f96e43d72c33327b6a4631ccaa6ea07f0b106c88b9dc71c9000bb6044d5e88a"), hex_key!("033f96e43d72c33327b6a4631ccaa6ea07f0b106c88b9dc71c9000bb6044d5e88a"),
hex_key!($secp, "0313d8748790f2a86fb524579b46ce3c68fedd58d2a738716249a9f7d5458a15c2"), hex_key!("0313d8748790f2a86fb524579b46ce3c68fedd58d2a738716249a9f7d5458a15c2"),
hex_key!($secp, "030b632eeb079eb83648886122a04c7bf6d98ab5dfb94cf353ee3e9382a4c2fab0"), hex_key!("030b632eeb079eb83648886122a04c7bf6d98ab5dfb94cf353ee3e9382a4c2fab0"),
hex_key!($secp, "02fb54a7fcaa73c307cfd70f3fa66a2e4247a71858ca731396343ad30c7c4009ce")] hex_key!("02fb54a7fcaa73c307cfd70f3fa66a2e4247a71858ca731396343ad30c7c4009ce")]
)); ));
#[test] #[test]
fn sanity() { fn sanity() {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let keys = alpha_keys!(&secp); let keys = alpha_keys!();
// This is the first withdraw ever, in alpha a94f95cc47b444c10449c0eed51d895e4970560c4a1a9d15d46124858abc3afe // This is the first withdraw ever, in alpha a94f95cc47b444c10449c0eed51d895e4970560c4a1a9d15d46124858abc3afe
let contract = hex!("5032534894ffbf32c1f1c0d3089b27c98fd991d5d7329ebd7d711223e2cde5a9417a1fa3e852c576"); let contract = hex!("5032534894ffbf32c1f1c0d3089b27c98fd991d5d7329ebd7d711223e2cde5a9417a1fa3e852c576");
@ -329,8 +328,7 @@ mod tests {
#[test] #[test]
fn script() { fn script() {
let secp = Secp256k1::new(); let alpha_keys = alpha_keys!();
let alpha_keys = alpha_keys!(&secp);
let alpha_template = alpha_template!(); let alpha_template = alpha_template!();
let alpha_redeem = Script::from(hex!("55210269992fb441ae56968e5b77d46a3e53b69f136444ae65a94041fc937bdb28d93321021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a2102174c82021492c2c6dfcbfa4187d10d38bed06afb7fdcd72c880179fddd641ea121033f96e43d72c33327b6a4631ccaa6ea07f0b106c88b9dc71c9000bb6044d5e88a210313d8748790f2a86fb524579b46ce3c68fedd58d2a738716249a9f7d5458a15c221030b632eeb079eb83648886122a04c7bf6d98ab5dfb94cf353ee3e9382a4c2fab02102fb54a7fcaa73c307cfd70f3fa66a2e4247a71858ca731396343ad30c7c4009ce57ae")); let alpha_redeem = Script::from(hex!("55210269992fb441ae56968e5b77d46a3e53b69f136444ae65a94041fc937bdb28d93321021df31471281d4478df85bfce08a10aab82601dca949a79950f8ddf7002bd915a2102174c82021492c2c6dfcbfa4187d10d38bed06afb7fdcd72c880179fddd641ea121033f96e43d72c33327b6a4631ccaa6ea07f0b106c88b9dc71c9000bb6044d5e88a210313d8748790f2a86fb524579b46ce3c68fedd58d2a738716249a9f7d5458a15c221030b632eeb079eb83648886122a04c7bf6d98ab5dfb94cf353ee3e9382a4c2fab02102fb54a7fcaa73c307cfd70f3fa66a2e4247a71858ca731396343ad30c7c4009ce57ae"));
@ -364,8 +362,7 @@ mod tests {
#[test] #[test]
fn bad_key_number() { fn bad_key_number() {
let secp = Secp256k1::new(); let alpha_keys = alpha_keys!();
let alpha_keys = alpha_keys!(&secp);
let template_short = Template::from(&hex!("55fefefefefefe57AE")[..]); let template_short = Template::from(&hex!("55fefefefefefe57AE")[..]);
let template_long = Template::from(&hex!("55fefefefefefefefe57AE")[..]); let template_long = Template::from(&hex!("55fefefefefefefefe57AE")[..]);
let template = Template::from(&hex!("55fefefefefefefe57AE")[..]); let template = Template::from(&hex!("55fefefefefefefe57AE")[..]);

View File

@ -135,8 +135,7 @@ impl Privkey {
x => { return Err(encode::Error::Base58(base58::Error::InvalidVersion(vec![x]))); } x => { return Err(encode::Error::Base58(base58::Error::InvalidVersion(vec![x]))); }
}; };
let secp = Secp256k1::without_caps(); let key = SecretKey::from_slice(&data[1..33])
let key = SecretKey::from_slice(&secp, &data[1..33])
.map_err(|_| base58::Error::Other("Secret key out of range".to_owned()))?; .map_err(|_| base58::Error::Other("Secret key out of range".to_owned()))?;
Ok(Privkey { Ok(Privkey {