From d42c2bd25fef054e96b58a18ba6069e54ddb865d Mon Sep 17 00:00:00 2001 From: Mairon Date: Fri, 14 Aug 2026 14:40:57 +0200 Subject: [PATCH] Zeroize transient seed material in Mnemonic::new --- crates/bitcoin/Cargo.toml | 1 + crates/bitcoin/src/mnemonic.rs | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/bitcoin/Cargo.toml b/crates/bitcoin/Cargo.toml index 79b3e4d..84d6821 100644 --- a/crates/bitcoin/Cargo.toml +++ b/crates/bitcoin/Cargo.toml @@ -30,6 +30,7 @@ async-trait = { workspace = true } serde = { workspace = true } hex = "0.4.3" +zeroize = "1.9" [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-bindgen = { version = "0.2", features = [ diff --git a/crates/bitcoin/src/mnemonic.rs b/crates/bitcoin/src/mnemonic.rs index 4d9195e..a95128f 100644 --- a/crates/bitcoin/src/mnemonic.rs +++ b/crates/bitcoin/src/mnemonic.rs @@ -8,6 +8,7 @@ use bdk_wallet::{ }, miniscript::BareCtx, }; +use zeroize::{Zeroize, Zeroizing}; use crate::error::Error; @@ -90,8 +91,14 @@ impl Mnemonic { let generated_key: GeneratedKey<_, BareCtx> = BdkMnemonic::generate_with_entropy((word_count, Language::English), entropy).expect("should not fail"); - - let mnemonic = BdkMnemonic::parse_in(Language::English, generated_key.to_string())?; + // The entropy has been consumed to derive the mnemonic; wipe our copy so + // the raw seed material does not linger in memory. + entropy.zeroize(); + + // `generated_key.to_string()` materialises the mnemonic phrase as a plaintext + // String; keep it in a Zeroizing wrapper so it is wiped once parsed. + let phrase = Zeroizing::new(generated_key.to_string()); + let mnemonic = BdkMnemonic::parse_in(Language::English, phrase.as_str())?; Ok(Mnemonic { inner: mnemonic }) }