cashu/nuts/nut01/
secret_key.rs1use core::fmt;
2use core::ops::Deref;
3use core::str::FromStr;
4
5use bitcoin::hashes::sha256::Hash as Sha256Hash;
6use bitcoin::hashes::Hash;
7use bitcoin::secp256k1;
8use bitcoin::secp256k1::rand::rngs::OsRng;
9use bitcoin::secp256k1::schnorr::Signature;
10use bitcoin::secp256k1::{Keypair, Message, Scalar};
11use serde::de::Visitor;
12use serde::{Deserialize, Deserializer, Serialize};
13
14use super::{Error, PublicKey};
15use crate::SECP256K1;
16
17#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct SecretKey {
20 inner: secp256k1::SecretKey,
21}
22
23impl Deref for SecretKey {
24 type Target = secp256k1::SecretKey;
25
26 fn deref(&self) -> &Self::Target {
27 &self.inner
28 }
29}
30
31impl From<secp256k1::SecretKey> for SecretKey {
32 fn from(inner: secp256k1::SecretKey) -> Self {
33 Self { inner }
34 }
35}
36
37impl fmt::Display for SecretKey {
38 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39 write!(f, "{}", self.to_secret_hex())
40 }
41}
42
43impl SecretKey {
44 pub fn from_slice(slice: &[u8]) -> Result<Self, Error> {
46 Ok(Self {
47 inner: secp256k1::SecretKey::from_slice(slice)?,
48 })
49 }
50
51 pub fn from_hex<S>(hex: S) -> Result<Self, Error>
53 where
54 S: AsRef<str>,
55 {
56 Ok(Self {
57 inner: secp256k1::SecretKey::from_str(hex.as_ref())?,
58 })
59 }
60
61 pub fn generate() -> Self {
63 let (secret_key, _) = SECP256K1.generate_keypair(&mut OsRng);
64 Self { inner: secret_key }
65 }
66
67 pub fn to_secret_hex(&self) -> String {
69 self.inner.display_secret().to_string()
70 }
71
72 pub fn as_secret_bytes(&self) -> &[u8] {
74 self.inner.as_ref()
75 }
76
77 pub fn to_secret_bytes(&self) -> [u8; 32] {
79 self.inner.secret_bytes()
80 }
81
82 pub fn sign(&self, msg: &[u8]) -> Result<Signature, Error> {
84 let hash: Sha256Hash = Sha256Hash::hash(msg);
85 let msg = Message::from_digest_slice(hash.as_ref())?;
86 Ok(SECP256K1.sign_schnorr(&msg, &Keypair::from_secret_key(&SECP256K1, &self.inner)))
87 }
88
89 pub fn public_key(&self) -> PublicKey {
91 self.inner.public_key(&SECP256K1).into()
92 }
93
94 #[inline]
96 pub fn to_scalar(self) -> Scalar {
97 Scalar::from(self.inner)
98 }
99
100 #[inline]
102 pub fn as_scalar(&self) -> Scalar {
103 Scalar::from(self.inner)
104 }
105}
106
107impl FromStr for SecretKey {
108 type Err = Error;
109
110 fn from_str(secret_key: &str) -> Result<Self, Self::Err> {
112 Self::from_hex(secret_key)
113 }
114}
115
116impl Serialize for SecretKey {
117 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
118 match serializer.is_human_readable() {
119 true => serializer.serialize_str(&self.to_secret_hex()),
121 false => serializer.serialize_bytes(self.as_secret_bytes()),
123 }
124 }
125}
126
127impl<'de> Deserialize<'de> for SecretKey {
128 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
129 match deserializer.is_human_readable() {
130 true => {
132 let secret_key: String = String::deserialize(deserializer)?;
133 SecretKey::from_hex(secret_key).map_err(serde::de::Error::custom)
134 }
135 false => {
137 struct SecretKeyVisitor;
138
139 impl Visitor<'_> for SecretKeyVisitor {
140 type Value = SecretKey;
141
142 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
143 formatter.write_str("a byte array")
144 }
145
146 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
147 where
148 E: serde::de::Error,
149 {
150 SecretKey::from_slice(value).map_err(serde::de::Error::custom)
151 }
152 }
153
154 deserializer.deserialize_bytes(SecretKeyVisitor)
155 }
156 }
157 }
158}
159
160impl Drop for SecretKey {
161 fn drop(&mut self) {
162 self.inner.non_secure_erase();
163 tracing::trace!("Secret Key dropped.");
164 }
165}