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)]
30pub struct SecretKey {
31 inner: secp256k1::SecretKey,
32}
33
34impl Deref for SecretKey {
35 type Target = secp256k1::SecretKey;
36
37 fn deref(&self) -> &Self::Target {
38 &self.inner
39 }
40}
41
42impl From<secp256k1::SecretKey> for SecretKey {
43 fn from(inner: secp256k1::SecretKey) -> Self {
44 Self { inner }
45 }
46}
47
48impl SecretKey {
49 pub fn from_slice(slice: &[u8]) -> Result<Self, Error> {
51 Ok(Self {
52 inner: secp256k1::SecretKey::from_slice(slice)?,
53 })
54 }
55
56 pub fn from_hex<S>(hex: S) -> Result<Self, Error>
58 where
59 S: AsRef<str>,
60 {
61 Ok(Self {
62 inner: secp256k1::SecretKey::from_str(hex.as_ref())?,
63 })
64 }
65
66 pub fn generate() -> Self {
68 let (secret_key, _) = SECP256K1.generate_keypair(&mut OsRng);
69 Self { inner: secret_key }
70 }
71
72 pub fn to_secret_hex(&self) -> String {
74 self.inner.display_secret().to_string()
75 }
76
77 pub fn as_secret_bytes(&self) -> &[u8] {
79 self.inner.as_ref()
80 }
81
82 pub fn to_secret_bytes(&self) -> [u8; 32] {
84 self.inner.secret_bytes()
85 }
86
87 pub fn sign(&self, msg: &[u8]) -> Result<Signature, Error> {
89 let hash: Sha256Hash = Sha256Hash::hash(msg);
90 let msg = Message::from_digest_slice(hash.as_ref())?;
91 Ok(SECP256K1.sign_schnorr(&msg, &Keypair::from_secret_key(&SECP256K1, &self.inner)))
92 }
93
94 pub fn public_key(&self) -> PublicKey {
96 self.inner.public_key(&SECP256K1).into()
97 }
98
99 #[inline]
101 pub fn to_scalar(self) -> Scalar {
102 Scalar::from(self.inner)
103 }
104
105 #[inline]
107 pub fn as_scalar(&self) -> Scalar {
108 Scalar::from(self.inner)
109 }
110}
111
112impl FromStr for SecretKey {
113 type Err = Error;
114
115 fn from_str(secret_key: &str) -> Result<Self, Self::Err> {
117 Self::from_hex(secret_key)
118 }
119}
120
121impl Serialize for SecretKey {
122 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
123 match serializer.is_human_readable() {
124 true => serializer.serialize_str(&self.to_secret_hex()),
126 false => serializer.serialize_bytes(self.as_secret_bytes()),
128 }
129 }
130}
131
132impl<'de> Deserialize<'de> for SecretKey {
133 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
134 match deserializer.is_human_readable() {
135 true => {
137 let secret_key: String = String::deserialize(deserializer)?;
138 SecretKey::from_hex(secret_key).map_err(serde::de::Error::custom)
139 }
140 false => {
142 struct SecretKeyVisitor;
143
144 impl Visitor<'_> for SecretKeyVisitor {
145 type Value = SecretKey;
146
147 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
148 formatter.write_str("a byte array")
149 }
150
151 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
152 where
153 E: serde::de::Error,
154 {
155 SecretKey::from_slice(value).map_err(serde::de::Error::custom)
156 }
157 }
158
159 deserializer.deserialize_bytes(SecretKeyVisitor)
160 }
161 }
162 }
163}
164
165impl Drop for SecretKey {
166 fn drop(&mut self) {
167 self.inner.non_secure_erase();
168 tracing::trace!("Secret Key dropped.");
169 }
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175
176 #[test]
177 fn secret_hex_export_is_explicit() {
178 let hex = "50d7fd7aa2b2fe4607f41f4ce6f8794fc184dd47b8cdfbe4b3d1249aa02d35aa";
179 let secret_key = SecretKey::from_hex(hex).unwrap();
180
181 assert_eq!(secret_key.to_secret_hex(), hex);
182 }
183}