1use core::fmt;
2
3use crate::encoding::{self, SiaDecodable, SiaDecode, SiaEncodable, SiaEncode};
4use crate::encoding_async::AsyncSiaDecode;
5use crate::types::{Hash256, HexParseError};
6use ed25519_dalek::{Signature as ED25519Signature, Signer, SigningKey, Verifier, VerifyingKey};
7use serde::de::Error;
8use serde::{Deserialize, Serialize};
9use zeroize::ZeroizeOnDrop;
10
11#[derive(Debug, Eq, Hash, PartialEq, Clone, Copy, SiaEncode, SiaDecode, AsyncSiaDecode)]
13pub struct PublicKey([u8; 32]);
14
15impl PublicKey {
16 const PREFIX: &'static str = "ed25519:";
17}
18
19impl Serialize for PublicKey {
20 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
21 String::serialize(&self.to_string(), serializer)
22 }
23}
24
25impl<'de> Deserialize<'de> for PublicKey {
26 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
27 where
28 D: serde::Deserializer<'de>,
29 {
30 let s = String::deserialize(deserializer)?;
31 let result = s.parse().map_err(|e| Error::custom(format!("{e:?}")))?;
32 Ok(result)
33 }
34}
35
36impl std::str::FromStr for PublicKey {
37 type Err = crate::types::HexParseError;
38
39 fn from_str(s: &str) -> Result<Self, Self::Err> {
40 let s = s
41 .strip_prefix(Self::PREFIX)
42 .ok_or(HexParseError::MissingPrefix)?;
43 let mut pk = [0; 32];
44 hex::decode_to_slice(s, &mut pk)?;
45 Ok(Self::new(pk))
46 }
47}
48
49impl fmt::Display for PublicKey {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 write!(f, "{}{}", Self::PREFIX, hex::encode(self.0))
52 }
53}
54
55impl PublicKey {
56 pub const fn new(buf: [u8; 32]) -> Self {
57 PublicKey(buf)
58 }
59
60 pub fn verify(&self, msg: &[u8], signature: &Signature) -> bool {
62 let pk = VerifyingKey::from_bytes(&self.0).unwrap();
63 pk.verify(msg, &ED25519Signature::from_bytes(signature.as_ref()))
64 .is_ok()
65 }
66}
67
68impl From<PublicKey> for [u8; 32] {
69 fn from(val: PublicKey) -> Self {
70 val.0
71 }
72}
73
74impl AsRef<[u8]> for PublicKey {
75 fn as_ref(&self) -> &[u8] {
76 &self.0
77 }
78}
79
80#[derive(Debug, PartialEq, Clone, ZeroizeOnDrop)]
82pub struct PrivateKey([u8; 64]);
83
84impl PrivateKey {
85 pub fn from_seed(seed: &[u8; 32]) -> Self {
86 let sk = SigningKey::from_bytes(seed);
87 PrivateKey(sk.to_keypair_bytes())
88 }
89
90 pub fn public_key(&self) -> PublicKey {
91 let mut buf = [0u8; 32];
92 buf.copy_from_slice(&self.0[32..]);
93 PublicKey::new(buf)
94 }
95
96 pub fn sign(&self, h: &[u8]) -> Signature {
97 let sk = SigningKey::from_bytes(&self.0[..32].try_into().unwrap());
98 Signature::new(sk.sign(h).to_bytes())
99 }
100}
101
102impl AsRef<[u8]> for PrivateKey {
103 fn as_ref(&self) -> &[u8] {
104 &self.0
105 }
106}
107
108impl From<[u8; 64]> for PrivateKey {
109 fn from(key: [u8; 64]) -> Self {
110 PrivateKey(key)
111 }
112}
113
114impl From<Hash256> for PrivateKey {
115 fn from(hash: Hash256) -> Self {
116 PrivateKey::from_seed(hash.as_ref())
117 }
118}
119
120#[derive(Debug, Clone, PartialEq, Eq, SiaEncode, SiaDecode, AsyncSiaDecode)]
121pub struct Signature([u8; 64]);
122
123impl Serialize for Signature {
124 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
125 String::serialize(&hex::encode(self.0), serializer)
126 }
127}
128
129impl<'de> Deserialize<'de> for Signature {
130 fn deserialize<D>(deserializer: D) -> Result<Signature, D::Error>
131 where
132 D: serde::Deserializer<'de>,
133 {
134 let buf = hex::decode(String::deserialize(deserializer)?)
135 .map_err(|e| D::Error::custom(format!("{e:?}")))?;
136 if buf.len() != 64 {
137 return Err(D::Error::custom("Invalid signature length"));
138 }
139 Ok(Signature(buf.try_into().unwrap()))
140 }
141}
142
143impl Signature {
144 pub const fn new(sig: [u8; 64]) -> Self {
145 Signature(sig)
146 }
147
148 pub fn data(&self) -> &[u8] {
149 &self.0
150 }
151}
152
153impl Default for Signature {
154 fn default() -> Self {
155 Signature([0; 64])
156 }
157}
158
159impl AsRef<[u8; 64]> for Signature {
160 fn as_ref(&self) -> &[u8; 64] {
161 &self.0
162 }
163}
164
165impl From<[u8; 64]> for Signature {
166 fn from(buf: [u8; 64]) -> Self {
167 Signature(buf)
168 }
169}
170
171impl std::str::FromStr for Signature {
172 type Err = crate::types::HexParseError;
173
174 fn from_str(s: &str) -> Result<Self, Self::Err> {
175 let data = hex::decode(s).map_err(HexParseError::HexError)?;
176 if data.len() != 64 {
177 return Err(HexParseError::InvalidLength(data.len()));
178 }
179
180 let mut sig = [0u8; 64];
181 sig.copy_from_slice(&data);
182 Ok(Signature(sig))
183 }
184}
185
186impl TryFrom<&[u8]> for Signature {
190 type Error = encoding::Error;
191 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
192 if value.len() != 64 {
193 return Err(encoding::Error::InvalidLength(value.len()));
194 }
195 let mut sig = [0u8; 64];
196 sig.copy_from_slice(value);
197 Ok(Signature(sig))
198 }
199}
200
201impl fmt::Display for Signature {
202 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
203 write!(f, "{}", hex::encode(self.0))
204 }
205}
206
207#[cfg(test)]
208mod tests {
209 use super::*;
210
211 #[test]
212 fn test_serialize_publickey() {
213 let public_key_str = "9aac1ffb1cfd1079a8c6c87b47da1d567e35b97234993c288c1ad0db1d1ce1b6";
214 let public_key = PublicKey::new(hex::decode(public_key_str).unwrap().try_into().unwrap());
215
216 let mut public_key_serialized = Vec::new();
218 public_key.encode(&mut public_key_serialized).unwrap();
219 assert_eq!(public_key_serialized, hex::decode(public_key_str).unwrap());
220 let public_key_deserialized =
221 PublicKey::decode(&mut public_key_serialized.as_slice()).unwrap();
222 assert_eq!(public_key_deserialized, public_key);
223
224 let public_key_serialized = serde_json::to_string(&public_key).unwrap();
226 let public_key_deserialized: PublicKey =
227 serde_json::from_str(&public_key_serialized).unwrap();
228 assert_eq!(
229 public_key_serialized,
230 format!("\"ed25519:{public_key_str}\"")
231 );
232 assert_eq!(public_key_deserialized, public_key);
233 }
234}