keys: Remove rng argument from Keypair::generate
What changed, and why it matters
This is a routine API cleanup, not a security fix. The change removes the requirement for callers to supply their own random number generator when creating a new keypair. Instead, the function now creates the generator internally, matching how the related PrivateKey API already works. There is no vulnerability here; it is a convenience and consistency change.
No security action required. Treat as a normal API-breaking change and update downstream code that previously passed an rng argument.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors Keypair::generate to hide the rand::rng argument, switching from an externally supplied Rng to an internally constructed one. It also narrows the cfg gate from feature = “rand” to all(feature = “rand”, feature = “std”), matching the doc-test guard and the behavior of PrivateKey::generate. The implementation changes from Self::from(secp256k1::Keypair::new(rng)) to Self::from_secp(secp256k1::Keypair::new(&mut rand::rng())). Call sites and doc tests are updated accordingly. No cryptographic weakness, entropy reduction, or bug fix is present in the diff.
Changed components
bitcoin/src/crypto/key.rsKeypair::generate APIInspect captured patch +9 / −11
diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs
index 93ed7bb9..90d29232 100644
--- a/bitcoin/src/crypto/key.rs
+++ b/bitcoin/src/crypto/key.rs
@@ -220,8 +220,7 @@ mod encapsulate {
/// ```
/// # #[cfg(all(feature = "rand", feature = "std"))] {
/// # use bitcoin::key::{Keypair, TweakedKeypair, TweakedPublicKey};
- /// # use bitcoin::secp256k1::rand;
- /// # let keypair = TweakedKeypair::dangerous_assume_tweaked(Keypair::generate(&mut rand::rng()));
+ /// # let keypair = TweakedKeypair::dangerous_assume_tweaked(Keypair::generate());
/// // 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);
@@ -406,15 +405,16 @@ impl Keypair {
///
/// ```
/// # #[cfg(all(feature = "rand", feature = "std"))] {
- /// use bitcoin::{secp256k1::rand, Keypair};
+ /// use bitcoin::Keypair;
///
- /// let keypair = Keypair::generate(&mut rand::rng());
+ /// let keypair = Keypair::generate();
/// # }
/// ```
#[inline]
- #[cfg(feature = "rand")]
- pub fn generate<R: secp256k1::rand::Rng + ?Sized>(rng: &mut R) -> Self {
- Self::from(secp256k1::Keypair::new(rng))
+ #[cfg(all(feature = "rand", feature = "std"))]
+ pub fn generate() -> Self {
+ let kp = secp256k1::Keypair::new(&mut rand::rng());
+ Self::from_secp(kp)
}
/// Creates a [`Keypair`] directly from a secp256k1 secret key.
@@ -2037,9 +2037,7 @@ mod tests {
#[test]
#[cfg(all(feature = "rand", feature = "std"))]
fn public_key_constructors() {
- use secp256k1::rand;
-
- let kp = Keypair::generate(&mut rand::rng());
+ let kp = Keypair::generate();
let _ = PublicKey::from_secp(kp);
let _ = PublicKey::from_secp_uncompressed(kp);
@@ -2157,7 +2155,7 @@ mod tests {
#[test]
fn keypair_from_str_roundtrip() {
#[cfg(all(feature = "rand", feature = "std"))]
- let keypair = Keypair::generate(&mut rand::rng());
+ let keypair = Keypair::generate();
#[cfg(not(all(feature = "rand", feature = "std")))]
let keypair = {
let bytes = <[u8; 32]>::from_hex(
Why this scored 19/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.