1use crate::tn_public_address;
2use crate::txn_lib::TnPubkey;
3use crate::{tn_public_address::tn_pubkey_to_address_string, tn_signature_encoding};
4use anyhow::Result;
5use ed25519_dalek::SigningKey;
6use hex;
7use rand::TryRngCore;
8use rand::rngs::OsRng;
9use serde::{Deserialize, Serialize};
10use std::fmt;
11
12use thiserror::Error;
13
14pub fn gen_key() -> Result<[u8; 32]> {
15 let mut private_key = [0u8; 32];
16 let mut rng = OsRng;
17 rng.try_fill_bytes(&mut private_key).unwrap();
18 Ok(private_key)
19}
20
21#[derive(Debug, Clone)]
22pub struct KeyPair {
23 pub name: String,
24 pub private_key: [u8; 32],
25 pub public_key: TnPubkey,
26 pub address_string: Pubkey,
27}
28
29impl KeyPair {
30 pub fn generate(name: &str) -> Result<Self> {
31 let mut private_key = [0u8; 32];
33 let mut rng = OsRng;
34 rng.try_fill_bytes(&mut private_key)?;
35 let signing_key = SigningKey::from_bytes(&private_key);
37 let verifying_key = signing_key.verifying_key();
38 let public_key = verifying_key.to_bytes();
39
40 let address_string = Pubkey::from_bytes(&public_key);
42
43 Ok(Self {
44 name: name.to_string(),
45 private_key,
46 public_key,
47 address_string,
48 })
49 }
50
51 pub fn from_hex_private_key<P: AsRef<[u8]>>(name: &str, hex_private_key: P) -> Result<Self> {
52 let private_key_bytes = hex::decode(hex_private_key)
54 .map_err(|e| anyhow::anyhow!("Failed to decode hex private key: {}", e))?;
55
56 if private_key_bytes.len() != 32 {
57 return Err(anyhow::anyhow!(
58 "Private key must be 32 bytes, got {}",
59 private_key_bytes.len()
60 ));
61 }
62
63 let mut private_key = [0u8; 32];
64 private_key.copy_from_slice(&private_key_bytes);
65
66 let signing_key = SigningKey::from_bytes(&private_key);
68 let verifying_key = signing_key.verifying_key();
69 let public_key = verifying_key.to_bytes();
70
71 let address_string = Pubkey::from_bytes(&public_key);
73
74 Ok(Self {
75 name: name.to_string(),
76 private_key,
77 public_key,
78 address_string,
79 })
80 }
81
82 pub fn public_key_hex(&self) -> String {
83 hex::encode(self.public_key)
84 }
85 pub fn public_key_str(&self) -> String {
86 tn_pubkey_to_address_string(&self.public_key)
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
95pub struct Pubkey(String);
96
97impl Pubkey {
98 pub fn new(key: String) -> Result<Self> {
102 if key.is_empty() {
104 return Err(ValidationError::InvalidPubkey("empty pubkey".to_string()).into());
105 }
106
107 if key.len() != 46 {
109 return Err(ValidationError::InvalidPubkey(format!(
110 "invalid pubkey length: expected 46, got {}",
111 key.len()
112 ))
113 .into());
114 }
115
116 if !key.starts_with("ta") {
117 return Err(
118 ValidationError::InvalidPubkey("pubkey must start with 'ta'".to_string()).into(),
119 );
120 }
121
122 let mut decoded = [0u8; 32];
124 match tn_public_address::tn_public_address_decode(&mut decoded, key.as_bytes()) {
125 Ok(()) => Ok(Self(key)),
126 Err(code) => Err(ValidationError::InvalidPubkey(format!(
127 "invalid pubkey format: decode error {}",
128 code
129 ))
130 .into()),
131 }
132 }
133
134 pub fn as_str(&self) -> &str {
136 &self.0
137 }
138
139 pub fn to_bytes(&self) -> Result<[u8; 32]> {
141 let mut bytes = [0u8; 32];
142 match tn_public_address::tn_public_address_decode(&mut bytes, self.0.as_bytes()) {
143 Ok(()) => Ok(bytes),
144 Err(code) => Err(ValidationError::InvalidPubkey(format!(
145 "failed to decode pubkey: error {}",
146 code
147 ))
148 .into()),
149 }
150 }
151
152 pub fn from_bytes(bytes: &[u8; 32]) -> Self {
154 let address = tn_public_address::tn_pubkey_to_address_string(bytes);
155 Self(address)
157 }
158
159 pub fn from_hex(hex_str: &str) -> Result<Self> {
163 let hex_str = hex_str.strip_prefix("0x").unwrap_or(hex_str);
165
166 if hex_str.len() != 64 {
168 return Err(ValidationError::InvalidPubkey(format!(
169 "invalid hex pubkey length: expected 64 characters, got {}",
170 hex_str.len()
171 ))
172 .into());
173 }
174
175 let bytes = hex::decode(hex_str).map_err(|e| {
177 ValidationError::InvalidPubkey(format!("invalid hex pubkey format: {}", e))
178 })?;
179
180 if bytes.len() != 32 {
182 return Err(ValidationError::InvalidPubkey(format!(
183 "invalid hex pubkey: expected 32 bytes, got {}",
184 bytes.len()
185 ))
186 .into());
187 }
188
189 let mut bytes_array = [0u8; 32];
190 bytes_array.copy_from_slice(&bytes);
191
192 Ok(Self::from_bytes(&bytes_array))
194 }
195}
196
197impl fmt::Display for Pubkey {
198 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199 write!(f, "{}", self.0)
200 }
201}
202
203#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
208pub struct Signature(String);
209
210impl Signature {
211 pub fn new(sig: String) -> Result<Self> {
215 if sig.is_empty() {
217 return Err(ValidationError::InvalidSignature("empty signature".to_string()).into());
218 }
219
220 if sig.len() != 90 {
222 return Err(ValidationError::InvalidSignature(format!(
223 "invalid signature length: expected 90, got {}",
224 sig.len()
225 ))
226 .into());
227 }
228
229 if !sig.starts_with("ts") {
230 return Err(ValidationError::InvalidSignature(
231 "signature must start with 'ts'".to_string(),
232 )
233 .into());
234 }
235
236 let mut decoded = [0u8; 64];
238 match tn_signature_encoding::tn_signature_decode(&mut decoded, sig.as_bytes()) {
239 Ok(()) => Ok(Self(sig)),
240 Err(code) => Err(ValidationError::InvalidSignature(format!(
241 "invalid signature format: decode error {}",
242 code
243 ))
244 .into()),
245 }
246 }
247
248 pub fn as_str(&self) -> &str {
250 &self.0
251 }
252
253 pub fn to_bytes(&self) -> Result<[u8; 64]> {
255 let mut bytes = [0u8; 64];
256 match tn_signature_encoding::tn_signature_decode(&mut bytes, self.0.as_bytes()) {
257 Ok(()) => Ok(bytes),
258 Err(code) => Err(ValidationError::InvalidSignature(format!(
259 "failed to decode signature: error {}",
260 code
261 ))
262 .into()),
263 }
264 }
265
266 pub fn from_bytes(bytes: &[u8; 64]) -> Self {
268 let signature = tn_signature_encoding::tn_signature_to_string(bytes);
269 Self(signature)
271 }
272}
273
274impl fmt::Display for Signature {
275 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
276 write!(f, "{}", self.0)
277 }
278}
279
280#[derive(Error, Debug)]
282pub enum ValidationError {
283 #[error("Invalid public key: {0}")]
285 InvalidPubkey(String),
286
287 #[error("Invalid signature: {0}")]
289 InvalidSignature(String),
290}
291
292#[cfg(test)]
293mod tests {
294
295 use super::*;
296
297 #[test]
298 fn test_pubkey_validation() {
299 let bytes = [1u8; 32];
301 let valid_pubkey = tn_public_address::tn_pubkey_to_address_string(&bytes);
302 assert!(Pubkey::new(valid_pubkey.to_string()).is_ok());
303
304 assert!(Pubkey::new("".to_string()).is_err());
306
307 assert!(Pubkey::new("ta111".to_string()).is_err());
309
310 assert!(Pubkey::new("tb1111111111111111111111111111111111111111111".to_string()).is_err());
312
313 assert!(Pubkey::new("ta!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!".to_string()).is_err());
315 }
316
317 #[test]
318 fn test_signature_validation() {
319 let bytes = [1u8; 64];
321 let valid_signature = tn_signature_encoding::tn_signature_to_string(&bytes);
322 assert!(Signature::new(valid_signature.to_string()).is_ok());
323
324 assert!(Signature::new("".to_string()).is_err());
326
327 assert!(Signature::new("ts111".to_string()).is_err());
329
330 assert!(Signature::new("ta111111111111111111111111111111111111111111111111111111111111111111111111111111111111".to_string()).is_err());
332
333 assert!(Signature::new("ts!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!".to_string()).is_err());
335 }
336
337 #[test]
338 fn test_pubkey_roundtrip() {
339 let bytes = [1u8; 32];
341 let pubkey = Pubkey::from_bytes(&bytes);
342 let decoded_bytes = pubkey.to_bytes().unwrap();
343 assert_eq!(bytes, decoded_bytes);
344 }
345
346 #[test]
347 fn test_signature_roundtrip() {
348 let bytes = [1u8; 64];
350 let signature = Signature::from_bytes(&bytes);
351 let decoded_bytes = signature.to_bytes().unwrap();
352 assert_eq!(bytes, decoded_bytes);
353 }
354}