cliquenet/
x25519.rs

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(());