Fix lint warnings after upgrade to secp 0.31
What changed, and why it matters
This commit is a routine maintenance patch that updates example code and tests to match a newer version of the underlying secp256k1 cryptography library. It replaces deprecated random-number calls with their modern equivalents and switches to a renamed key-construction function. There is no indication of a security vulnerability being fixed.
No security action required. Treat as a normal dependency/API compatibility update.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff updates rust-bitcoin to be compatible with secp256k1 0.31 and the rand crate API changes. Changes include: replacing rand::thread_rng() with rand::rng(), gen() with random(), gen_range() with random_range(), and Keypair::from_seckey_slice() with Keypair::from_seckey_byte_array(). These are mechanical API migrations in examples, documentation, and test code. No production cryptographic logic is altered.
Changed components
bitcoin/examples/create-p2wpkh-address.rsbitcoin/examples/sign-tx-segwit-v0.rsbitcoin/examples/sign-tx-taproot.rsbitcoin/examples/taproot-psbt.rsbitcoin/src/address/mod.rs (docs)bitcoin/src/bip32.rsbitcoin/src/consensus/encode.rs (tests)bitcoin/src/crypto/key.rsbitcoin/src/merkle_tree/block.rs (tests)bitcoin/src/psbt/mod.rs (tests)bitcoin/src/sign_message.rs (tests)Inspect captured patch +20 / −22
diff --git a/bitcoin/examples/create-p2wpkh-address.rs b/bitcoin/examples/create-p2wpkh-address.rs
index e92ffe53..7899c303 100644
--- a/bitcoin/examples/create-p2wpkh-address.rs
+++ b/bitcoin/examples/create-p2wpkh-address.rs
@@ -8,7 +8,7 @@ fn main() {
let secp = Secp256k1::new();
// Generate secp256k1 public and private key pair.
- let (secret_key, public_key) = secp.generate_keypair(&mut rand::thread_rng());
+ let (secret_key, public_key) = secp.generate_keypair(&mut rand::rng());
// Create a Bitcoin private key to be used on the Bitcoin mainnet.
let private_key = PrivateKey::new(secret_key, Network::Bitcoin);
diff --git a/bitcoin/examples/sign-tx-segwit-v0.rs b/bitcoin/examples/sign-tx-segwit-v0.rs
index a8c43042..e0379aa2 100644
--- a/bitcoin/examples/sign-tx-segwit-v0.rs
+++ b/bitcoin/examples/sign-tx-segwit-v0.rs
@@ -88,7 +88,7 @@ fn main() {
///
/// In a real application these would be actual secrets.
fn senders_keys<C: Signing>(secp: &Secp256k1<C>) -> (SecretKey, WPubkeyHash) {
- let sk = SecretKey::new(&mut rand::thread_rng());
+ let sk = SecretKey::new(&mut rand::rng());
let pk = bitcoin::PublicKey::new(sk.public_key(secp));
let wpkh = pk.wpubkey_hash().expect("key is compressed");
diff --git a/bitcoin/examples/sign-tx-taproot.rs b/bitcoin/examples/sign-tx-taproot.rs
index 69339fdd..53f4b80a 100644
--- a/bitcoin/examples/sign-tx-taproot.rs
+++ b/bitcoin/examples/sign-tx-taproot.rs
@@ -86,7 +86,7 @@ fn main() {
///
/// In a real application these would be actual secrets.
fn senders_keys<C: Signing>(secp: &Secp256k1<C>) -> Keypair {
- let sk = SecretKey::new(&mut rand::thread_rng());
+ let sk = SecretKey::new(&mut rand::rng());
Keypair::from_secret_key(secp, &sk)
}
diff --git a/bitcoin/examples/taproot-psbt.rs b/bitcoin/examples/taproot-psbt.rs
index d47d75ec..32f6a17b 100644
--- a/bitcoin/examples/taproot-psbt.rs
+++ b/bitcoin/examples/taproot-psbt.rs
@@ -748,7 +748,7 @@ fn sign_psbt_taproot(
sighash_type: TapSighashType,
secp: &Secp256k1<secp256k1::All>,
) {
- let keypair = secp256k1::Keypair::from_seckey_slice(secp, secret_key.as_ref()).unwrap();
+ let keypair = secp256k1::Keypair::from_seckey_byte_array(secp, secret_key.secret_bytes()).unwrap();
let keypair = match leaf_hash {
None => keypair.tap_tweak(secp, psbt_input.tap_merkle_root).to_keypair(),
Some(_) => keypair, // no tweak for script spend
diff --git a/bitcoin/src/address/mod.rs b/bitcoin/src/address/mod.rs
index 3f7b6640..a24de091 100644
--- a/bitcoin/src/address/mod.rs
+++ b/bitcoin/src/address/mod.rs
@@ -15,7 +15,7 @@
//!
//! // Generate random key pair.
//! let secp = Secp256k1::new();
-//! let (_sk, pk) = secp.generate_keypair(&mut rand::thread_rng());
+//! let (_sk, pk) = secp.generate_keypair(&mut rand::rng());
//! let public_key = PublicKey::new(pk); // Or `PublicKey::from(pk)`.
//!
//! // Generate a mainnet pay-to-pubkey-hash address.
diff --git a/bitcoin/src/bip32.rs b/bitcoin/src/bip32.rs
index d8a470f6..4f0797d4 100644
--- a/bitcoin/src/bip32.rs
+++ b/bitcoin/src/bip32.rs
@@ -745,7 +745,7 @@ impl Xpriv {
/// Constructs a new BIP-0340 keypair for Schnorr signatures and Taproot use matching the internal
/// secret key representation.
pub fn to_keypair<C: secp256k1::Signing>(self, secp: &Secp256k1<C>) -> Keypair {
- Keypair::from_seckey_slice(secp, &self.private_key[..])
+ Keypair::from_seckey_byte_array(secp, self.private_key.secret_bytes())
.expect("BIP-0032 internal private key representation is broken")
}
diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs
index 90e44d0c..1d309491 100644
--- a/bitcoin/src/consensus/encode.rs
+++ b/bitcoin/src/consensus/encode.rs
@@ -988,12 +988,12 @@ mod tests {
#[test]
#[cfg(feature = "rand-std")]
fn serialization_round_trips() {
- use secp256k1::rand::{thread_rng, Rng};
+ use secp256k1::rand::{self, Rng};
macro_rules! round_trip {
($($val_type:ty),*) => {
$(
- let r: $val_type = thread_rng().gen();
+ let r: $val_type = rand::rng().random();
assert_eq!(deserialize::<$val_type>(&serialize(&r)).unwrap(), r);
)*
};
@@ -1001,7 +1001,7 @@ mod tests {
macro_rules! round_trip_bytes {
($(($val_type:ty, $data:expr)),*) => {
$(
- thread_rng().fill(&mut $data[..]);
+ rand::rng().fill(&mut $data[..]);
assert_eq!(deserialize::<$val_type>(&serialize(&$data)).unwrap()[..], $data[..]);
)*
};
@@ -1016,7 +1016,7 @@ mod tests {
data.clear();
data64.clear();
- let len = thread_rng().gen_range(1..256);
+ let len = rand::rng().random_range(1..256);
data.resize(len, 0u8);
data64.resize(len, 0u64);
let mut arr33 = [0u8; 33];
diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs
index 60fefe7b..eafe5637 100644
--- a/bitcoin/src/crypto/key.rs
+++ b/bitcoin/src/crypto/key.rs
@@ -543,7 +543,7 @@ impl PrivateKey {
/// a secure random number generator.
#[cfg(feature = "rand-std")]
pub fn generate(network: impl Into<NetworkKind>) -> Self {
- let secret_key = secp256k1::SecretKey::new(&mut rand::thread_rng());
+ let secret_key = secp256k1::SecretKey::new(&mut rand::rng());
Self::new(secret_key, network.into())
}
/// Constructs a new compressed ECDSA private key from the provided generic secp256k1 private key
@@ -873,7 +873,7 @@ pub type UntweakedKeypair = Keypair;
/// # use bitcoin::key::{Keypair, TweakedKeypair, TweakedPublicKey};
/// # use bitcoin::secp256k1::{rand, Secp256k1};
/// # let secp = Secp256k1::new();
-/// # let keypair = TweakedKeypair::dangerous_assume_tweaked(Keypair::new(&secp, &mut rand::thread_rng()));
+/// # let keypair = TweakedKeypair::dangerous_assume_tweaked(Keypair::new(&secp, &mut rand::rng()));
/// // There are various conversion methods available to get a tweaked pubkey from a tweaked keypair.
/// let (_pk, _parity) = keypair.public_parts();
/// let _pk = TweakedPublicKey::from_keypair(keypair);
@@ -1745,7 +1745,7 @@ mod tests {
use secp256k1::rand;
let secp = Secp256k1::new();
- let kp = Keypair::new(&secp, &mut rand::thread_rng());
+ let kp = Keypair::new(&secp, &mut rand::rng());
let _ = PublicKey::new(kp);
let _ = PublicKey::new_uncompressed(kp);
diff --git a/bitcoin/src/merkle_tree/block.rs b/bitcoin/src/merkle_tree/block.rs
index f06a3809..4b6edc1c 100644
--- a/bitcoin/src/merkle_tree/block.rs
+++ b/bitcoin/src/merkle_tree/block.rs
@@ -576,7 +576,7 @@ mod tests {
#[cfg(feature = "rand-std")]
fn pmt_test(tx_count: usize) {
- let mut rng = secp256k1::rand::thread_rng();
+ let mut rng = secp256k1::rand::rng();
// Create some fake tx ids
let tx_ids = (1..=tx_count)
.map(|i| format!("{:064x}", i).parse::<Txid>().unwrap())
@@ -600,7 +600,7 @@ mod tests {
// Generate `att / 2` random bits
let rand_bits = match att / 2 {
0 => 0,
- bits => rng.gen::<u64>() >> (64 - bits),
+ bits => rng.random::<u64>() >> (64 - bits),
};
let include = rand_bits == 0;
matches[j] = include;
@@ -748,8 +748,8 @@ 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 bit = rng.gen::<u8>();
+ let n = rng.random_range(0..self.hashes.len());
+ let bit = rng.random::<u8>();
let hashes = &mut self.hashes;
let mut hash = hashes[n].to_byte_array();
hash[(bit >> 3) as usize] ^= 1 << (bit & 7);
diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs
index 95aaf3b8..ccfcbbf5 100644
--- a/bitcoin/src/psbt/mod.rs
+++ b/bitcoin/src/psbt/mod.rs
@@ -2369,11 +2369,11 @@ mod tests {
#[cfg(feature = "rand-std")]
fn gen_keys() -> (PrivateKey, PublicKey, Secp256k1<All>) {
- use secp256k1::rand::thread_rng;
+ use secp256k1::rand;
let secp = Secp256k1::new();
- let sk = SecretKey::new(&mut thread_rng());
+ let sk = SecretKey::new(&mut rand::rng());
let priv_key = PrivateKey::new(sk, NetworkKind::Test);
let pk = PublicKey::from_private_key(&secp, priv_key);
diff --git a/bitcoin/src/sign_message.rs b/bitcoin/src/sign_message.rs
index d905cddb..d3903485 100644
--- a/bitcoin/src/sign_message.rs
+++ b/bitcoin/src/sign_message.rs
@@ -244,15 +244,13 @@ mod tests {
#[test]
#[cfg(all(feature = "secp-recovery", feature = "base64", feature = "rand-std"))]
fn message_signature() {
- use secp256k1;
-
use crate::{Address, AddressType, Network, NetworkKind};
let secp = secp256k1::Secp256k1::new();
let message = "rust-bitcoin MessageSignature test";
let msg_hash = super::signed_msg_hash(message);
let msg = secp256k1::Message::from_digest(msg_hash.to_byte_array());
- let privkey = secp256k1::SecretKey::new(&mut secp256k1::rand::thread_rng());
+ let privkey = secp256k1::SecretKey::new(&mut secp256k1::rand::rng());
let secp_sig = secp.sign_ecdsa_recoverable(msg, &privkey);
let signature = super::MessageSignature { signature: secp_sig, compressed: true };
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.