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)]
19#[cfg_attr(feature = "swagger", derive(utoipa::ToSchema))]
20pub struct SecretKey {
21 #[cfg_attr(feature = "swagger", schema(value_type = String))]
22 inner: secp256k1::SecretKey,
23}
24
25impl Deref for SecretKey {
26 type Target = secp256k1::SecretKey;
27
28 fn deref(&self) -> &Self::Target {
29 &self.inner
30 }
31}
32
33impl From<secp256k1::SecretKey> for SecretKey {
34 fn from(inner: secp256k1::SecretKey) -> Self {
35 Self { inner }
36 }
37}
38
39impl fmt::Display for SecretKey {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 write!(f, "{}", self.to_secret_hex())
42 }
43}
44
45impl SecretKey {
46 pub fn from_slice(slice: &[u8]) -> Result<Self, Error> {
48 Ok(Self {
49 inner: secp256k1::SecretKey::from_slice(slice)?,
50 })
51 }
52
53 pub fn from_hex<S>(hex: S) -> Result<Self, Error>
55 where
56 S: AsRef<str>,
57 {
58 Ok(Self {
59 inner: secp256k1::SecretKey::from_str(hex.as_ref())?,
60 })
61 }
62
63 pub fn generate() -> Self {
65 let (secret_key, _) = SECP256K1.generate_keypair(&mut OsRng);
66 Self { inner: secret_key }
67 }
68
69 pub fn to_secret_hex(&self) -> String {
71 self.inner.display_secret().to_string()
72 }
73
74 pub fn as_secret_bytes(&self) -> &[u8] {
76 self.inner.as_ref()
77 }
78
79 pub fn to_secret_bytes(&self) -> [u8; 32] {
81 self.inner.secret_bytes()
82 }
83
84 pub fn sign(&self, msg: &[u8]) -> Result<Signature, Error> {
86 let hash: Sha256Hash = Sha256Hash::hash(msg);
87 let msg = Message::from_digest_slice(hash.as_ref())?;
88 Ok(SECP256K1.sign_schnorr(&msg, &Keypair::from_secret_key(&SECP256K1, &self.inner)))
89 }
90
91 pub fn public_key(&self) -> PublicKey {
93 self.inner.public_key(&SECP256K1).into()
94 }
95
96 #[inline]
98 pub fn to_scalar(self) -> Scalar {
99 Scalar::from(self.inner)
100 }
101
102 #[inline]
104 pub fn as_scalar(&self) -> Scalar {
105 Scalar::from(self.inner)
106 }
107}
108
109impl FromStr for SecretKey {
110 type Err = Error;
111
112 fn from_str(secret_key: &str) -> Result<Self, Self::Err> {
114 Self::from_hex(secret_key)
115 }
116}
117
118impl Serialize for SecretKey {
119 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
120 match serializer.is_human_readable() {
121 true => serializer.serialize_str(&self.to_secret_hex()),
123 false => serializer.serialize_bytes(self.as_secret_bytes()),
125 }
126 }
127}
128
129impl<'de> Deserialize<'de> for SecretKey {
130 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
131 match deserializer.is_human_readable() {
132 true => {
134 let secret_key: String = String::deserialize(deserializer)?;
135 SecretKey::from_hex(secret_key).map_err(serde::de::Error::custom)
136 }
137 false => {
139 struct SecretKeyVisitor;
140
141 impl Visitor<'_> for SecretKeyVisitor {
142 type Value = SecretKey;
143
144 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
145 formatter.write_str("a byte array")
146 }
147
148 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
149 where
150 E: serde::de::Error,
151 {
152 SecretKey::from_slice(value).map_err(serde::de::Error::custom)
153 }
154 }
155
156 deserializer.deserialize_bytes(SecretKeyVisitor)
157 }
158 }
159 }
160}
161
162impl Drop for SecretKey {
163 fn drop(&mut self) {
164 self.inner.non_secure_erase();
165 tracing::trace!("Secret Key dropped.");
166 }
167}