1use core::iter;
8
9use curve25519_dalek::edwards::CompressedEdwardsY;
10use curve25519_dalek::traits::IsIdentity;
11use curve25519_dalek::{EdwardsPoint, Scalar};
12use digest::Digest;
13pub use ed25519_dalek;
14use ed25519_dalek::hazmat::ExpandedSecretKey;
15use ed25519_dalek::{SecretKey, Sha512};
16use generic_array::GenericArray;
17use generic_array::typenum::{U32, U64};
18use rand::{CryptoRng, Rng};
19use zeroize::{Zeroize, ZeroizeOnDrop};
20
21use super::Group;
22use crate::ciphersuite::CipherSuite;
23use crate::errors::{InternalError, ProtocolError};
24use crate::key_exchange::sigma_i::hash_eddsa::implementation::HashEddsaImpl;
25use crate::key_exchange::sigma_i::pure_eddsa::implementation::PureEddsaImpl;
26pub use crate::key_exchange::sigma_i::shared::PreHash;
27use crate::key_exchange::sigma_i::{CachedMessage, Message, MessageBuilder};
28use crate::serialization::{ConcatExt, SliceExt, UpdateExt};
29
30pub struct Ed25519;
32
33impl Group for Ed25519 {
34 type Pk = VerifyingKey;
35 type PkLen = U32;
36 type Sk = SigningKey;
37 type SkLen = U32;
38
39 fn serialize_pk(pk: &Self::Pk) -> GenericArray<u8, Self::PkLen> {
40 pk.compressed.0.into()
41 }
42
43 fn deserialize_take_pk(bytes: &mut &[u8]) -> Result<Self::Pk, ProtocolError> {
44 let bytes = bytes.take_array::<U32>("public key")?;
45
46 VerifyingKey::from_bytes(bytes.into())
47 }
48
49 fn random_sk<R: Rng + CryptoRng>(rng: &mut R) -> Self::Sk {
50 let mut sk = <[u8; 32]>::default();
51 rng.fill_bytes(&mut sk);
52
53 SigningKey::from_bytes(sk)
54 }
55
56 fn derive_scalar(seed: GenericArray<u8, Self::SkLen>) -> Result<Self::Sk, InternalError> {
57 Ok(SigningKey::from_bytes(seed.into()))
58 }
59
60 fn public_key(sk: &Self::Sk) -> Self::Pk {
61 sk.verifying_key
62 }
63
64 fn serialize_sk(sk: &Self::Sk) -> GenericArray<u8, Self::SkLen> {
65 sk.sk.into()
66 }
67
68 fn deserialize_take_sk(bytes: &mut &[u8]) -> Result<Self::Sk, ProtocolError> {
69 Ok(SigningKey::from_bytes(
70 bytes.take_array::<U32>("secret key")?.into(),
71 ))
72 }
73}
74
75impl PureEddsaImpl for Ed25519 {
76 type Signature = Signature;
77 type SignatureLen = U64;
78
79 fn sign<CS: CipherSuite, KE: Group>(
80 sk: &Self::Sk,
81 message: &Message<CS, KE>,
82 ) -> (Self::Signature, CachedMessage<CS, KE>) {
83 (sign(sk, false, message.sign_message()), message.to_cached())
84 }
85
86 fn verify<CS: CipherSuite, KE: Group>(
89 pk: &Self::Pk,
90 message_builder: MessageBuilder<'_, CS>,
91 state: CachedMessage<CS, KE>,
92 signature: &Self::Signature,
93 ) -> Result<(), ProtocolError> {
94 verify(
95 pk,
96 false,
97 message_builder.build::<KE>(state).verify_message(),
98 signature,
99 )
100 }
101
102 fn deserialize_take_signature(bytes: &mut &[u8]) -> Result<Self::Signature, ProtocolError> {
103 Signature::deserialize_take(bytes)
104 }
105
106 fn serialize_signature(signature: &Self::Signature) -> GenericArray<u8, Self::SignatureLen> {
107 signature.serialize()
108 }
109}
110
111impl HashEddsaImpl for Ed25519 {
112 type Signature = Signature;
113 type SignatureLen = U64;
114 type VerifyState<CS: CipherSuite, KE: Group> = PreHash<Sha512>;
115
116 fn sign<CS: CipherSuite, KE: Group>(
117 sk: &Self::Sk,
118 message: &Message<CS, KE>,
119 ) -> (Self::Signature, Self::VerifyState<CS, KE>) {
120 let hash = message.hash::<Sha512>();
121
122 (
123 sign(sk, true, iter::once(hash.sign.finalize().as_slice())),
124 PreHash(hash.verify.finalize()),
125 )
126 }
127
128 fn verify<CS: CipherSuite, KE: Group>(
131 pk: &Self::Pk,
132 state: Self::VerifyState<CS, KE>,
133 signature: &Self::Signature,
134 ) -> Result<(), ProtocolError> {
135 verify(pk, true, iter::once(state.0.as_slice()), signature)
136 }
137
138 fn deserialize_take_signature(bytes: &mut &[u8]) -> Result<Self::Signature, ProtocolError> {
139 Signature::deserialize_take(bytes)
140 }
141
142 fn serialize_signature(signature: &Self::Signature) -> GenericArray<u8, Self::SignatureLen> {
143 signature.serialize()
144 }
145}
146
147fn sign<'a>(
151 sk: &SigningKey,
152 pre_hash: bool,
153 message: impl Clone + Iterator<Item = &'a [u8]>,
154) -> Signature {
155 let mut h = Sha512::new();
156
157 if pre_hash {
158 h.update(b"SigEd25519 no Ed25519 collisions");
159 h.update([1]); h.update([0]);
161 }
162
163 h.update(sk.hash_prefix);
164 h.update_iter(message.clone());
165
166 let r = Scalar::from_hash(h);
167 #[allow(non_snake_case)]
168 let R = EdwardsPoint::mul_base(&r).compress();
169
170 h = Sha512::new();
171
172 if pre_hash {
173 h.update(b"SigEd25519 no Ed25519 collisions");
174 h.update([1]); h.update([0]);
176 }
177
178 h.update(R.as_bytes());
179 h.update(sk.verifying_key.compressed.0);
180 h.update_iter(message);
181
182 let k = Scalar::from_hash(h);
183 let s: Scalar = (k * sk.scalar) + r;
184
185 Signature { R, s }
186}
187
188fn verify<'a>(
189 pk: &VerifyingKey,
190 pre_hash: bool,
191 message: impl Iterator<Item = &'a [u8]>,
192 signature: &Signature,
193) -> Result<(), ProtocolError> {
194 let mut h = Sha512::new();
195
196 if pre_hash {
197 h.update(b"SigEd25519 no Ed25519 collisions");
198 h.update([1]); h.update([0]);
200 }
201
202 h.update(signature.R.as_bytes());
203 h.update(pk.compressed.as_bytes());
204 h.update_iter(message);
205 let k = Scalar::from_hash(h);
206
207 #[allow(non_snake_case)]
208 let minus_A: EdwardsPoint = -pk.point;
209 #[allow(non_snake_case)]
210 let expected_R =
211 EdwardsPoint::vartime_double_scalar_mul_basepoint(&k, &(minus_A), &signature.s).compress();
212
213 if expected_R == signature.R {
214 Ok(())
215 } else {
216 Err(ProtocolError::InvalidLoginError)
217 }
218}
219
220#[derive(Clone, Copy, Debug, Eq, PartialEq, Zeroize)]
226pub struct VerifyingKey {
227 point: EdwardsPoint,
228 compressed: CompressedEdwardsY,
229}
230
231impl VerifyingKey {
232 fn from_bytes(bytes: [u8; 32]) -> Result<Self, ProtocolError> {
233 let compressed = CompressedEdwardsY(bytes);
234
235 if let Some(point) = compressed.decompress().filter(|point| !point.is_identity()) {
236 Ok(Self { point, compressed })
237 } else {
238 Err(ProtocolError::SerializationError)
239 }
240 }
241}
242
243#[cfg(feature = "serde")]
244impl<'de> serde::Deserialize<'de> for VerifyingKey {
245 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
246 where
247 D: serde::Deserializer<'de>,
248 {
249 use core::fmt::{self, Formatter};
250
251 use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor};
252
253 struct VerifyingKeyVisitor;
254
255 impl<'de> Visitor<'de> for VerifyingKeyVisitor {
256 type Value = VerifyingKey;
257
258 fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
259 Formatter::write_str(formatter, "tuple struct VerifyingKey")
260 }
261
262 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
263 where
264 D: Deserializer<'de>,
265 {
266 let compressed = CompressedEdwardsY::deserialize(deserializer)?;
267 VerifyingKey::from_bytes(compressed.0).map_err(Error::custom)
268 }
269
270 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
271 where
272 A: SeqAccess<'de>,
273 {
274 let compressed: CompressedEdwardsY = seq.next_element()?.ok_or_else(|| {
275 Error::invalid_length(0, &"tuple struct VerifyingKey with 1 element")
276 })?;
277 VerifyingKey::from_bytes(compressed.0).map_err(Error::custom)
278 }
279 }
280
281 deserializer.deserialize_newtype_struct("VerifyingKey", VerifyingKeyVisitor)
282 }
283}
284
285#[cfg(feature = "serde")]
286impl serde::Serialize for VerifyingKey {
287 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
288 where
289 S: serde::Serializer,
290 {
291 serializer.serialize_newtype_struct("VerifyingKey", &self.compressed)
292 }
293}
294
295#[derive(Clone, Debug, Eq, PartialEq, ZeroizeOnDrop)]
299pub struct SigningKey {
300 sk: SecretKey,
305 verifying_key: VerifyingKey,
306 scalar: Scalar,
310 hash_prefix: [u8; 32],
311}
312
313impl SigningKey {
314 fn from_bytes(sk: [u8; 32]) -> Self {
315 let ExpandedSecretKey {
316 scalar,
317 hash_prefix,
318 } = ExpandedSecretKey::from(&sk);
319 let point = EdwardsPoint::mul_base(&scalar);
320 let verifying_key = VerifyingKey {
321 point,
322 compressed: point.compress(),
323 };
324
325 SigningKey {
326 sk,
327 verifying_key,
328 scalar,
329 hash_prefix,
330 }
331 }
332}
333
334#[cfg(feature = "serde")]
335impl<'de> serde::Deserialize<'de> for SigningKey {
336 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
337 where
338 D: serde::Deserializer<'de>,
339 {
340 use core::fmt::{self, Formatter};
341
342 use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor};
343
344 struct SigningKeyVisitor;
345
346 impl<'de> Visitor<'de> for SigningKeyVisitor {
347 type Value = SigningKey;
348
349 fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
350 Formatter::write_str(formatter, "tuple struct SigningKey")
351 }
352
353 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
354 where
355 D: Deserializer<'de>,
356 {
357 let sk = Scalar::deserialize(deserializer)?;
358 Ok(SigningKey::from_bytes(sk.to_bytes()))
359 }
360
361 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
362 where
363 A: SeqAccess<'de>,
364 {
365 let sk: Scalar = seq.next_element()?.ok_or_else(|| {
366 Error::invalid_length(0, &"tuple struct SigningKey with 1 element")
367 })?;
368 Ok(SigningKey::from_bytes(sk.to_bytes()))
369 }
370 }
371
372 deserializer.deserialize_newtype_struct("SigningKey", SigningKeyVisitor)
373 }
374}
375
376#[cfg(feature = "serde")]
377impl serde::Serialize for SigningKey {
378 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
379 where
380 S: serde::Serializer,
381 {
382 serializer.serialize_newtype_struct("SigningKey", &self.sk)
383 }
384}
385
386#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
389#[derive(Clone, Copy, Debug, Eq, PartialEq)]
390#[allow(non_snake_case)]
391pub struct Signature {
392 R: CompressedEdwardsY,
393 s: Scalar,
394}
395
396impl Signature {
397 pub fn from_slice(mut bytes: &[u8]) -> Result<Self, ProtocolError> {
400 Self::deserialize_take(&mut bytes)
401 }
402
403 fn deserialize_take(bytes: &mut &[u8]) -> Result<Self, ProtocolError> {
404 #[allow(non_snake_case)]
405 let R = CompressedEdwardsY(bytes.take_array::<U32>("signature R")?.into());
406
407 let s = Scalar::from_canonical_bytes(bytes.take_array::<U32>("signature s")?.into())
408 .into_option()
409 .ok_or(ProtocolError::SerializationError)?;
410
411 Ok(Self { R, s })
412 }
413
414 fn serialize(&self) -> GenericArray<u8, U64> {
415 GenericArray::<u8, U32>::from(self.R.0)
416 .cat(GenericArray::<u8, U32>::from(self.s.to_bytes()))
417 }
418}
419
420impl Zeroize for Signature {
421 fn zeroize(&mut self) {
422 self.R.0 = [0; 32];
423 self.s = Scalar::default();
424 }
425}
426
427#[cfg(test)]
428mod test {
429 use std::iter;
430
431 use ed25519_dalek::{Signer, SigningKey, Verifier, VerifyingKey};
432 use rand::rand_core::UnwrapErr;
433 use rand::rngs::SysRng;
434
435 use super::*;
436
437 #[test]
438 fn pure_eddsa() {
439 let mut message = [0; 1024];
440 UnwrapErr(SysRng).fill_bytes(&mut message);
441
442 let mut sk = SecretKey::default();
443 UnwrapErr(SysRng).fill_bytes(&mut sk);
444 let signing_key = SigningKey::from_bytes(&sk);
445
446 let signature = signing_key.sign(&message);
447
448 let custom_sk = Ed25519::deserialize_take_sk(&mut sk.as_slice()).unwrap();
449 let custom_signature = sign(&custom_sk, false, iter::once(message.as_slice()));
450
451 assert_eq!(
452 signature.to_bytes(),
453 custom_signature.serialize().as_slice()
454 );
455
456 let verifying_key = VerifyingKey::from(&signing_key);
457 verifying_key.verify(&message, &signature).unwrap();
458
459 let custom_pk = Ed25519::public_key(&custom_sk);
460 verify(
461 &custom_pk,
462 false,
463 iter::once(message.as_slice()),
464 &custom_signature,
465 )
466 .unwrap();
467 }
468
469 #[test]
470 fn hash_eddsa() {
471 let mut message = [0; 1024];
472 UnwrapErr(SysRng).fill_bytes(&mut message);
473 let message = Sha512::new_with_prefix(message);
474 let pre_hash = message.clone().finalize();
475
476 let mut sk = SecretKey::default();
477 UnwrapErr(SysRng).fill_bytes(&mut sk);
478 let signing_key = SigningKey::from_bytes(&sk);
479
480 let signature = signing_key.sign_prehashed(message.clone(), None).unwrap();
481
482 let custom_sk = Ed25519::deserialize_take_sk(&mut sk.as_slice()).unwrap();
483 let custom_signature = sign(&custom_sk, true, iter::once(pre_hash.as_slice()));
484
485 assert_eq!(
486 signature.to_bytes(),
487 custom_signature.serialize().as_slice()
488 );
489
490 let verifying_key = VerifyingKey::from(&signing_key);
491 verifying_key
492 .verify_prehashed(message, None, &signature)
493 .unwrap();
494
495 let custom_pk = Ed25519::public_key(&custom_sk);
496 verify(
497 &custom_pk,
498 true,
499 iter::once(pre_hash.as_slice()),
500 &custom_signature,
501 )
502 .unwrap();
503 }
504}