1use ed25519_dalek::{
7 SigningKey as Ed25519SigningKey,
8 VerifyingKey as Ed25519VerifyingKey,
9 Signature as Ed25519Signature,
10 Signer, Verifier,
11};
12use x25519_dalek::{
13 StaticSecret as X25519StaticSecret,
14 PublicKey as X25519PublicKey,
15 SharedSecret as X25519SharedSecret,
16};
17use zeroize::ZeroizeOnDrop;
18use serde::{Serialize, Deserialize};
19
20use crate::{CryptoError, Result};
21
22#[derive(ZeroizeOnDrop)]
27pub struct StaticSecret {
28 inner: X25519StaticSecret,
29}
30
31impl StaticSecret {
32 pub fn generate() -> Self {
34 Self {
35 inner: X25519StaticSecret::random_from_rng(rand::rngs::OsRng),
36 }
37 }
38
39 pub fn from_bytes(bytes: [u8; 32]) -> Self {
41 Self {
42 inner: X25519StaticSecret::from(bytes),
43 }
44 }
45
46 pub fn public_key(&self) -> PublicKey {
48 PublicKey {
49 inner: X25519PublicKey::from(&self.inner),
50 }
51 }
52
53 pub fn diffie_hellman(&self, their_public: &PublicKey) -> SharedSecret {
55 SharedSecret {
56 inner: self.inner.diffie_hellman(&their_public.inner),
57 }
58 }
59
60 pub fn to_bytes(&self) -> [u8; 32] {
62 self.inner.to_bytes()
63 }
64}
65
66#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
68pub struct PublicKey {
69 #[serde(with = "serde_bytes_array")]
70 inner: X25519PublicKey,
71}
72
73mod serde_bytes_array {
74 use serde::{Deserialize, Deserializer, Serialize, Serializer};
75 use x25519_dalek::PublicKey;
76
77 pub fn serialize<S>(key: &PublicKey, serializer: S) -> Result<S::Ok, S::Error>
78 where
79 S: Serializer,
80 {
81 key.as_bytes().serialize(serializer)
82 }
83
84 pub fn deserialize<'de, D>(deserializer: D) -> Result<PublicKey, D::Error>
85 where
86 D: Deserializer<'de>,
87 {
88 let bytes: [u8; 32] = Deserialize::deserialize(deserializer)?;
89 Ok(PublicKey::from(bytes))
90 }
91}
92
93impl PublicKey {
94 pub fn from_bytes(bytes: [u8; 32]) -> Self {
96 Self {
97 inner: X25519PublicKey::from(bytes),
98 }
99 }
100
101 pub fn as_bytes(&self) -> &[u8; 32] {
103 self.inner.as_bytes()
104 }
105
106 pub fn to_bytes(&self) -> [u8; 32] {
108 *self.inner.as_bytes()
109 }
110}
111
112#[derive(ZeroizeOnDrop)]
114pub struct SharedSecret {
115 inner: X25519SharedSecret,
116}
117
118impl SharedSecret {
119 pub fn as_bytes(&self) -> &[u8; 32] {
124 self.inner.as_bytes()
125 }
126}
127
128#[derive(ZeroizeOnDrop)]
130pub struct SigningKey {
131 inner: Ed25519SigningKey,
132}
133
134impl SigningKey {
135 pub fn generate() -> Self {
137 Self {
138 inner: Ed25519SigningKey::generate(&mut rand::rngs::OsRng),
139 }
140 }
141
142 pub fn from_bytes(bytes: &[u8; 32]) -> Self {
144 Self {
145 inner: Ed25519SigningKey::from_bytes(bytes),
146 }
147 }
148
149 pub fn verifying_key(&self) -> VerifyingKey {
151 VerifyingKey {
152 inner: self.inner.verifying_key(),
153 }
154 }
155
156 pub fn sign(&self, message: &[u8]) -> Signature {
158 Signature {
159 inner: self.inner.sign(message),
160 }
161 }
162
163 pub fn to_bytes(&self) -> [u8; 32] {
165 self.inner.to_bytes()
166 }
167
168 #[allow(dead_code)]
170 pub(crate) fn inner(&self) -> &Ed25519SigningKey {
171 &self.inner
172 }
173}
174
175#[derive(Clone, Debug, PartialEq, Eq)]
177pub struct VerifyingKey {
178 inner: Ed25519VerifyingKey,
179}
180
181impl VerifyingKey {
182 pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self> {
184 let inner = Ed25519VerifyingKey::from_bytes(bytes)
185 .map_err(|_| CryptoError::InvalidKeyLength { expected: 32, got: bytes.len() })?;
186 Ok(Self { inner })
187 }
188
189 pub fn verify(&self, message: &[u8], signature: &Signature) -> Result<()> {
191 self.inner
192 .verify(message, &signature.inner)
193 .map_err(|_| CryptoError::InvalidSignature)
194 }
195
196 pub fn as_bytes(&self) -> &[u8; 32] {
198 self.inner.as_bytes()
199 }
200
201 pub fn to_bytes(&self) -> [u8; 32] {
203 self.inner.to_bytes()
204 }
205}
206
207#[derive(Clone, Debug)]
209pub struct Signature {
210 inner: Ed25519Signature,
211}
212
213impl Signature {
214 pub fn from_bytes(bytes: &[u8; 64]) -> Self {
216 Self {
217 inner: Ed25519Signature::from_bytes(bytes),
218 }
219 }
220
221 pub fn to_bytes(&self) -> [u8; 64] {
223 self.inner.to_bytes()
224 }
225}
226
227pub struct KeyPair {
229 pub exchange: StaticSecret,
231 pub signing: SigningKey,
233}
234
235impl KeyPair {
236 pub fn generate() -> Self {
238 Self {
239 exchange: StaticSecret::generate(),
240 signing: SigningKey::generate(),
241 }
242 }
243}
244
245pub struct EphemeralKeyPair {
249 secret: StaticSecret,
250 public: PublicKey,
251}
252
253impl EphemeralKeyPair {
254 pub fn generate() -> Self {
256 let secret = StaticSecret::generate();
257 let public = secret.public_key();
258 Self { secret, public }
259 }
260
261 pub fn public_key(&self) -> &PublicKey {
263 &self.public
264 }
265
266 pub fn diffie_hellman(self, their_public: &PublicKey) -> SharedSecret {
268 self.secret.diffie_hellman(their_public)
269 }
270}
271
272#[cfg(test)]
273mod tests {
274 use super::*;
275
276 #[test]
277 fn test_key_exchange() {
278 let alice = StaticSecret::generate();
279 let bob = StaticSecret::generate();
280
281 let alice_public = alice.public_key();
282 let bob_public = bob.public_key();
283
284 let alice_shared = alice.diffie_hellman(&bob_public);
285 let bob_shared = bob.diffie_hellman(&alice_public);
286
287 assert_eq!(alice_shared.as_bytes(), bob_shared.as_bytes());
288 }
289
290 #[test]
291 fn test_signing() {
292 let signing_key = SigningKey::generate();
293 let verifying_key = signing_key.verifying_key();
294
295 let message = b"test message";
296 let signature = signing_key.sign(message);
297
298 assert!(verifying_key.verify(message, &signature).is_ok());
299 assert!(verifying_key.verify(b"wrong message", &signature).is_err());
300 }
301
302 #[test]
303 fn test_ephemeral_pfs() {
304 let server_static = StaticSecret::generate();
305 let client_ephemeral = EphemeralKeyPair::generate();
306
307 let client_public = client_ephemeral.public_key().clone();
308 let shared1 = client_ephemeral.diffie_hellman(&server_static.public_key());
309 let shared2 = server_static.diffie_hellman(&client_public);
310
311 assert_eq!(shared1.as_bytes(), shared2.as_bytes());
312 }
313}