1use std::{cmp::Ordering, fmt};
2
3use ed25519_compact::x25519;
4
5#[derive(Clone, PartialEq, Eq, Hash)]
6pub struct Keypair {
7 pair: x25519::KeyPair,
8}
9
10#[derive(Copy, Clone, PartialEq, Eq, Hash)]
11pub struct PublicKey {
12 key: x25519::PublicKey,
13}
14
15#[derive(Clone, PartialEq, Eq, Hash)]
16pub struct SecretKey {
17 key: x25519::SecretKey,
18}
19
20impl Keypair {
21 pub fn generate() -> Result<Self, InvalidKeypair> {
22 let pair = x25519::KeyPair::generate();
23 if pair.validate().is_err() {
24 return Err(InvalidKeypair(()));
25 }
26 Ok(Self { pair })
27 }
28
29 pub fn public_key(&self) -> PublicKey {
30 PublicKey { key: self.pair.pk }
31 }
32
33 pub fn secret_key(&self) -> SecretKey {
34 SecretKey {
35 key: self.pair.sk.clone(),
36 }
37 }
38}
39
40impl PublicKey {
41 pub fn as_bytes(&self) -> [u8; 32] {
42 *self.key
43 }
44
45 pub fn as_slice(&self) -> &[u8] {
46 &self.key[..]
47 }
48}
49
50impl SecretKey {
51 pub fn public_key(&self) -> PublicKey {
52 let key = self.key.recover_public_key().expect("valid public key");
53 PublicKey { key }
54 }
55
56 pub fn as_bytes(&self) -> [u8; 32] {
57 *self.key
58 }
59
60 pub fn as_slice(&self) -> &[u8] {
61 &self.key[..]
62 }
63}
64
65impl From<SecretKey> for Keypair {
66 fn from(k: SecretKey) -> Self {
67 let p = k.public_key();
68 Self {
69 pair: x25519::KeyPair {
70 sk: k.key,
71 pk: p.key,
72 },
73 }
74 }
75}
76
77impl From<SecretKey> for PublicKey {
78 fn from(k: SecretKey) -> Self {
79 k.public_key()
80 }
81}
82
83impl Ord for PublicKey {
84 fn cmp(&self, other: &Self) -> Ordering {
85 self.key[..].cmp(&other.key[..])
86 }
87}
88
89impl PartialOrd for PublicKey {
90 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
91 Some(self.cmp(other))
92 }
93}
94
95impl fmt::Debug for SecretKey {
96 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97 f.write_str("SecretKey")
98 }
99}
100
101impl fmt::Debug for Keypair {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 f.debug_struct("Keypair")
104 .field("public_key", &self.public_key())
105 .field("secret_key", &"SecretKey")
106 .finish()
107 }
108}
109
110impl fmt::Debug for PublicKey {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 write!(f, "{}", bs58::encode(&self.as_bytes()).into_string())
113 }
114}
115
116impl fmt::Display for PublicKey {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 <Self as fmt::Debug>::fmt(self, f)
119 }
120}
121
122impl TryFrom<&[u8]> for PublicKey {
123 type Error = InvalidPublicKey;
124
125 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
126 let key = x25519::PublicKey::from_slice(value).map_err(|_| InvalidPublicKey(()))?;
127 Ok(Self { key })
128 }
129}
130
131impl TryFrom<&[u8]> for SecretKey {
132 type Error = InvalidSecretKey;
133
134 fn try_from(s: &[u8]) -> Result<Self, Self::Error> {
135 let k = x25519::SecretKey::from_slice(s).map_err(|_| InvalidSecretKey(()))?;
136 if k.recover_public_key().is_err() {
137 return Err(InvalidSecretKey(()));
138 }
139 Ok(Self { key: k })
140 }
141}
142
143impl TryFrom<&str> for PublicKey {
144 type Error = InvalidPublicKey;
145
146 fn try_from(s: &str) -> Result<Self, Self::Error> {
147 bs58::decode(s)
148 .into_vec()
149 .map_err(|_| InvalidPublicKey(()))
150 .and_then(|v| PublicKey::try_from(v.as_slice()))
151 }
152}
153
154impl TryFrom<&str> for SecretKey {
155 type Error = InvalidSecretKey;
156
157 fn try_from(s: &str) -> Result<Self, Self::Error> {
158 bs58::decode(s)
159 .into_vec()
160 .map_err(|_| InvalidSecretKey(()))
161 .and_then(|v| SecretKey::try_from(v.as_slice()))
162 }
163}
164
165impl From<[u8; 32]> for SecretKey {
166 fn from(bytes: [u8; 32]) -> Self {
167 SecretKey {
168 key: x25519::SecretKey::new(bytes),
169 }
170 }
171}
172
173#[derive(Debug, thiserror::Error)]
174#[error("invalid keypair")]
175pub struct InvalidKeypair(());
176
177#[derive(Debug, thiserror::Error)]
178#[error("invalid secret key")]
179pub struct InvalidSecretKey(());
180
181#[derive(Debug, thiserror::Error)]
182#[error("invalid public key")]
183pub struct InvalidPublicKey(());