use core::fmt;
use crate::constants::SECRET_KEY_SIZE;
use crate::ecdh::SharedSecret;
use crate::key::{Keypair, SecretKey};
use crate::to_hex;
macro_rules! impl_display_secret {
($thing:ident) => {
#[cfg(feature = "hashes")]
impl ::core::fmt::Debug for $thing {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
use hashes::{sha256, Hash, HashEngine};
let tag = "rust-secp256k1DEBUG";
let mut engine = sha256::Hash::engine();
let tag_hash = sha256::Hash::hash(tag.as_bytes());
engine.input(&tag_hash.as_ref());
engine.input(&tag_hash.as_ref());
engine.input(&self.secret_bytes());
let hash = sha256::Hash::from_engine(engine);
f.debug_tuple(stringify!($thing)).field(&format_args!("#{:.16}", hash)).finish()
}
}
#[cfg(not(feature = "hashes"))]
impl ::core::fmt::Debug for $thing {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(
f,
"<secret key; enable `hashes` feature of `secp256k1` to display fingerprint>"
)
}
}
};
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct DisplaySecret {
secret: [u8; SECRET_KEY_SIZE],
}
impl_non_secure_erase!(DisplaySecret, secret, [0u8; SECRET_KEY_SIZE]);
impl fmt::Debug for DisplaySecret {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut slice = [0u8; SECRET_KEY_SIZE * 2];
let hex = to_hex(&self.secret, &mut slice).expect("fixed-size hex serializer failed");
f.debug_tuple("DisplaySecret").field(&hex).finish()
}
}
impl fmt::Display for DisplaySecret {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in &self.secret {
write!(f, "{:02x}", byte)?;
}
Ok(())
}
}
impl SecretKey {
#[inline]
pub fn display_secret(&self) -> DisplaySecret { DisplaySecret { secret: self.secret_bytes() } }
}
impl Keypair {
#[inline]
pub fn display_secret(&self) -> DisplaySecret { DisplaySecret { secret: self.secret_bytes() } }
}
impl SharedSecret {
#[inline]
pub fn display_secret(&self) -> DisplaySecret { DisplaySecret { secret: self.secret_bytes() } }
}