diff --git a/crypto/src/vrf/mod.rs b/crypto/src/vrf/mod.rs index 4de87f2fcc..dec529b652 100644 --- a/crypto/src/vrf/mod.rs +++ b/crypto/src/vrf/mod.rs @@ -55,17 +55,31 @@ pub enum VRFKeyKind { } #[must_use] -#[derive(Debug, PartialEq, Eq, Clone, Decode, Encode)] +#[derive(PartialEq, Eq, Clone, Decode, Encode)] pub struct VRFPrivateKey { key: VRFPrivateKeyHolder, } -#[derive(Debug, PartialEq, Eq, Clone, Decode, Encode)] +impl std::fmt::Debug for VRFPrivateKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Keep the key material out of the formatted output; this type can end up in + // log lines through derived Debug impls of larger structures. + f.write_str("VRFPrivateKey()") + } +} + +#[derive(PartialEq, Eq, Clone, Decode, Encode)] pub(crate) enum VRFPrivateKeyHolder { #[codec(index = 0)] Schnorrkel(SchnorrkelPrivateKey), } +impl std::fmt::Debug for VRFPrivateKeyHolder { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("VRFPrivateKeyHolder()") + } +} + #[must_use] #[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Decode, Encode)] pub struct VRFPublicKey { @@ -348,6 +362,14 @@ mod tests { use super::*; + #[test] + fn private_key_debug_hides_key_material() { + let mut rng = make_seedable_rng(Seed::from_entropy()); + let (sk, _pk) = VRFPrivateKey::new_from_rng(&mut rng, VRFKeyKind::Schnorrkel); + + assert_eq!(format!("{sk:?}"), "VRFPrivateKey()"); + } + #[rstest] #[trace] #[case(Seed::from_entropy())] diff --git a/crypto/src/vrf/schnorrkel/mod.rs b/crypto/src/vrf/schnorrkel/mod.rs index c7f13ba6ed..8ae635c62b 100644 --- a/crypto/src/vrf/schnorrkel/mod.rs +++ b/crypto/src/vrf/schnorrkel/mod.rs @@ -115,12 +115,20 @@ impl Decode for SchnorrkelPublicKey { } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq)] #[must_use] pub struct SchnorrkelPrivateKey { key: schnorrkel::SecretKey, } +impl std::fmt::Debug for SchnorrkelPrivateKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // Keep the key material out of the formatted output; this type can end up in + // log lines through derived Debug impls of larger structures. + f.write_str("SchnorrkelPrivateKey()") + } +} + impl SchnorrkelPrivateKey { pub fn new(rng: &mut R) -> (SchnorrkelPrivateKey, SchnorrkelPublicKey) { let sk = schnorrkel::SecretKey::generate_with(&mut Rng08Adapter(rng)); @@ -221,6 +229,14 @@ mod tests { use serialization::{DecodeAll, Encode}; use test_utils::random::{Seed, make_seedable_rng}; + #[test] + fn private_key_debug_hides_key_material() { + let mut rng = make_true_rng(); + let (sk, _pk) = SchnorrkelPrivateKey::new(&mut rng); + + assert_eq!(format!("{sk:?}"), "SchnorrkelPrivateKey()"); + } + #[test] fn key_serialization() { let mut rng = make_true_rng();