What changed, and why it matters
This commit changes how test-only fake data is generated for an extended Bitcoin private key (Xpriv) when the optional 'arbitrary' feature is enabled. Previously, the generator always produced a 'master' key with depth 0. Now it can produce keys at any depth with proper parent fingerprint and child number fields. This is a code-quality/test-coverage improvement; it does not change production key handling or add a security vulnerability.
No security action required. Treat as a normal test-infrastructure improvement. Reviewers may optionally verify that depth 0 still enforces the expected BIP32 master-key invariants in downstream tests.
Security signals we found
No cryptographic operation is changed
No input parsing or deserialization code is modified
Change is gated behind the optional arbitrary feature
No secret-exposure, memory-safety, or validation bypass pattern is present
Evidence from the diff
The patch updates the Arbitrary trait implementation for Xpriv in bitcoin/src/bip32.rs. Instead of always constructing a master key via Xpriv::new_master, it now constructs Xpriv directly, drawing depth, parent_fingerprint, child_number, network, private_key, and chain_code from the arbitrary fuzzer. For depth 0 it supplies default/constant values to match BIP32 invariants. This only affects fuzz/property-test builds that enable the arbitrary feature and has no runtime effect on normal wallet or cryptographic operations.
Changed components
bitcoin/src/bip32.rsArbitrary trait impl for Xpriv (arbitrary feature only)Inspect captured patch +14 / −1
diff --git a/bitcoin/src/bip32.rs b/bitcoin/src/bip32.rs
index 1cb6d461..f71f734d 100644
--- a/bitcoin/src/bip32.rs
+++ b/bitcoin/src/bip32.rs
@@ -1180,7 +1180,20 @@ impl<'a> Arbitrary<'a> for Xpub {
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for Xpriv {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
- Ok(Self::new_master(NetworkKind::arbitrary(u)?, u.arbitrary()?))
+ let depth = u.arbitrary()?;
+ let (parent_fingerprint, child_number) = match depth {
+ 0 => (Fingerprint::default(), ChildNumber::ZERO_NORMAL),
+ _ => (u.arbitrary()?, u.arbitrary()?),
+ };
+
+ Ok(Self {
+ network: u.arbitrary()?,
+ depth,
+ parent_fingerprint,
+ child_number,
+ private_key: u.arbitrary()?,
+ chain_code: u.arbitrary()?,
+ })
}
}
Why this scored 18/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.