From d161766ce4c96b66f6849b0d95aca442ccb0f48b Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 28 Jun 2022 12:47:29 +1000 Subject: [PATCH] Upgrade to secp256k1 v0.23.0 We recently released a new version of `rust-secp256k1`, upgrade to use it. --- Cargo.toml | 4 ++-- src/consensus/encode.rs | 2 +- src/util/bip32.rs | 11 +++++------ src/util/merkleblock.rs | 2 +- src/util/schnorr.rs | 18 ++++++++---------- src/util/sighash.rs | 7 +++---- src/util/taproot.rs | 12 +++++++++--- 7 files changed, 29 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b751315..5233841 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ rustdoc-args = ["--cfg", "docsrs"] [dependencies] bech32 = { version = "0.8.1", default-features = false } bitcoin_hashes = { version = "0.10.0", default-features = false } -secp256k1 = { version = "0.22.0", default-features = false } +secp256k1 = { version = "0.23.0", default-features = false } core2 = { version = "0.3.0", optional = true, default-features = false } base64 = { version = "0.13.0", optional = true } @@ -48,7 +48,7 @@ hashbrown = { version = "0.8", optional = true } [dev-dependencies] serde_json = "<1.0.45" serde_test = "1" -secp256k1 = { version = "0.22.0", features = [ "recovery", "rand-std" ] } +secp256k1 = { version = "0.23.0", features = [ "recovery", "rand-std" ] } bincode = "1.3.1" [[example]] diff --git a/src/consensus/encode.rs b/src/consensus/encode.rs index b2316a9..cdc85d4 100644 --- a/src/consensus/encode.rs +++ b/src/consensus/encode.rs @@ -1126,7 +1126,7 @@ mod tests { data.clear(); data64.clear(); - let len = thread_rng().gen_range(1, 256); + let len = thread_rng().gen_range(1..256); data.resize(len, 0u8); data64.resize(len, 0u64); let mut arr33 = [0u8; 33]; diff --git a/src/util/bip32.rs b/src/util/bip32.rs index cd5421a..a07ba5a 100644 --- a/src/util/bip32.rs +++ b/src/util/bip32.rs @@ -600,15 +600,15 @@ impl ExtendedPrivKey { hmac_engine.input(&endian::u32_to_array_be(u32::from(i))); let hmac_result: Hmac = Hmac::from_engine(hmac_engine); - let mut sk = secp256k1::SecretKey::from_slice(&hmac_result[..32])?; - sk.add_assign(&self.private_key[..])?; + let sk = secp256k1::SecretKey::from_slice(&hmac_result[..32]).expect("statistically impossible to hit"); + let tweaked = sk.add_tweak(&self.private_key.into()).expect("statistically impossible to hit"); Ok(ExtendedPrivKey { network: self.network, depth: self.depth + 1, parent_fingerprint: self.fingerprint(secp), child_number: i, - private_key: sk, + private_key: tweaked, chain_code: ChainCode::from(&hmac_result[32..]) }) } @@ -741,15 +741,14 @@ impl ExtendedPubKey { i: ChildNumber, ) -> Result { let (sk, chain_code) = self.ckd_pub_tweak(i)?; - let mut pk = self.public_key; - pk.add_exp_assign(secp, &sk[..])?; + let tweaked = self.public_key.add_exp_tweak(secp, &sk.into())?; Ok(ExtendedPubKey { network: self.network, depth: self.depth + 1, parent_fingerprint: self.fingerprint(), child_number: i, - public_key: pk, + public_key: tweaked, chain_code, }) } diff --git a/src/util/merkleblock.rs b/src/util/merkleblock.rs index 54107e2..a26cb0d 100644 --- a/src/util/merkleblock.rs +++ b/src/util/merkleblock.rs @@ -727,7 +727,7 @@ mod tests { impl PartialMerkleTree { /// Flip one bit in one of the hashes - this should break the authentication fn damage(&mut self, rng: &mut ThreadRng) { - let n = rng.gen_range(0, self.hashes.len()); + let n = rng.gen_range(0..self.hashes.len()); let bit = rng.gen::(); let hashes = &mut self.hashes; let mut hash = hashes[n].into_inner(); diff --git a/src/util/schnorr.rs b/src/util/schnorr.rs index 8a63c7e..7d52870 100644 --- a/src/util/schnorr.rs +++ b/src/util/schnorr.rs @@ -22,7 +22,6 @@ use core::fmt; use crate::prelude::*; use secp256k1::{self, Secp256k1, Verification, constants}; -use crate::hashes::Hash; use crate::util::taproot::{TapBranchHash, TapTweakHash}; use crate::SchnorrSighashType; @@ -111,11 +110,10 @@ impl TapTweak for UntweakedPublicKey { /// # Returns /// The tweaked key and its parity. fn tap_tweak(self, secp: &Secp256k1, merkle_root: Option) -> (TweakedPublicKey, secp256k1::Parity) { - let tweak_value = TapTweakHash::from_key_and_tweak(self, merkle_root).into_inner(); - let mut output_key = self; - let parity = output_key.tweak_add_assign(secp, &tweak_value).expect("Tap tweak failed"); + let tweak = TapTweakHash::from_key_and_tweak(self, merkle_root).to_scalar(); + let (output_key, parity) = self.add_tweak(secp, &tweak).expect("Tap tweak failed"); - debug_assert!(self.tweak_add_check(secp, &output_key, parity, tweak_value)); + debug_assert!(self.tweak_add_check(secp, &output_key, parity, tweak)); (TweakedPublicKey(output_key), parity) } @@ -140,11 +138,11 @@ impl TapTweak for UntweakedKeyPair { /// /// # Returns /// The tweaked key and its parity. - fn tap_tweak(mut self, secp: &Secp256k1, merkle_root: Option) -> TweakedKeyPair { - let pubkey = crate::XOnlyPublicKey::from_keypair(&self); - let tweak_value = TapTweakHash::from_key_and_tweak(pubkey, merkle_root).into_inner(); - self.tweak_add_assign(secp, &tweak_value).expect("Tap tweak failed"); - TweakedKeyPair(self) + fn tap_tweak(self, secp: &Secp256k1, merkle_root: Option) -> TweakedKeyPair { + let (pubkey, _parity) = crate::XOnlyPublicKey::from_keypair(&self); + let tweak = TapTweakHash::from_key_and_tweak(pubkey, merkle_root).to_scalar(); + let tweaked = self.add_xonly_tweak(secp, &tweak).expect("Tap tweak failed"); + TweakedKeyPair(tweaked) } fn dangerous_assume_tweaked(self) -> TweakedKeyPair { diff --git a/src/util/sighash.rs b/src/util/sighash.rs index a8686e2..98c9801 100644 --- a/src/util/sighash.rs +++ b/src/util/sighash.rs @@ -1137,11 +1137,10 @@ mod tests { }; // tests - let keypair = secp256k1::KeyPair::from_secret_key(secp, internal_priv_key); - let internal_key = XOnlyPublicKey::from_keypair(&keypair); + let keypair = secp256k1::KeyPair::from_secret_key(secp, &internal_priv_key); + let (internal_key, _parity) = XOnlyPublicKey::from_keypair(&keypair); let tweak = TapTweakHash::from_key_and_tweak(internal_key, merkle_root); - let mut tweaked_keypair = keypair; - tweaked_keypair.tweak_add_assign(secp, &tweak).unwrap(); + let tweaked_keypair = keypair.add_xonly_tweak(secp, &tweak.to_scalar()).unwrap(); let mut sig_msg = Vec::new(); cache.taproot_encode_signing_data_to( &mut sig_msg, diff --git a/src/util/taproot.rs b/src/util/taproot.rs index afdba36..e1e3a2b 100644 --- a/src/util/taproot.rs +++ b/src/util/taproot.rs @@ -18,7 +18,7 @@ use crate::prelude::*; use crate::io; -use secp256k1::{self, Secp256k1}; +use secp256k1::{self, Secp256k1, Scalar}; use core::convert::TryFrom; use core::fmt; @@ -90,6 +90,12 @@ impl TapTweakHash { } TapTweakHash::from_engine(eng) } + + /// Converts a `TapTweakHash` into a `Scalar` ready for use with key tweaking API. + pub fn to_scalar(&self) -> Scalar { + // This is statistically extremely unlikely to panic. + Scalar::from_be_bytes(self.into_inner()).expect("hash value greater than curve order") + } } impl TapLeafHash { @@ -847,12 +853,12 @@ impl ControlBlock { ); } // compute the taptweak - let tweak = TapTweakHash::from_key_and_tweak(self.internal_key, Some(curr_hash)); + let tweak = TapTweakHash::from_key_and_tweak(self.internal_key, Some(curr_hash)).to_scalar(); self.internal_key.tweak_add_check( secp, &output_key, self.output_key_parity, - tweak.into_inner(), + tweak, ) } }