1use ed25519_dalek::{SigningKey, VerifyingKey};
2use rand::rngs::OsRng;
3
4use crate::CryptoError;
5
6pub struct KeyPair {
8 signing_key: SigningKey,
9}
10
11impl KeyPair {
12 pub fn generate() -> Self {
14 let signing_key = SigningKey::generate(&mut OsRng);
15 Self { signing_key }
16 }
17
18 pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self, CryptoError> {
20 let signing_key = SigningKey::from_bytes(bytes);
21 Ok(Self { signing_key })
22 }
23
24 pub fn signing_key(&self) -> &SigningKey {
26 &self.signing_key
27 }
28
29 pub fn verifying_key(&self) -> VerifyingKey {
31 self.signing_key.verifying_key()
32 }
33
34 pub fn to_bytes(&self) -> [u8; 32] {
36 self.signing_key.to_bytes()
37 }
38
39 pub fn public_key_bytes(&self) -> [u8; 32] {
41 self.verifying_key().to_bytes()
42 }
43
44 pub fn save_to_file(&self, path: &std::path::Path) -> Result<(), CryptoError> {
46 std::fs::write(path, self.to_bytes())?;
47 Ok(())
48 }
49
50 pub fn load_from_file(path: &std::path::Path) -> Result<Self, CryptoError> {
52 let bytes = std::fs::read(path)?;
53 let arr: [u8; 32] = bytes
54 .try_into()
55 .map_err(|_| CryptoError::InvalidKey("expected 32 bytes".into()))?;
56 Self::from_bytes(&arr)
57 }
58}