primitives/signing/
mod.rs1pub use ed25519_dalek::{Signature, SigningKey, VerifyingKey};
2use ed25519_dalek::{Signer as DalekSigner, Verifier as DalekVerifier};
3use itertools::chain;
4
5use crate::{
6 errors::{PrimitiveError, VerificationError},
7 types::SessionId,
8};
9
10pub type MessageId = (SessionId, u8, &'static [u8]);
12
13pub trait Signer: UCSigner<Signature> {}
16impl<SR: UCSigner<Signature>> Signer for SR {}
17
18pub trait Verifier: UCVerifier<Signature> + Sync + Send {}
19impl<VR: UCVerifier<Signature>> Verifier for VR {}
20
21pub trait UCSigner<S>: DalekSigner<S> + Sync + Send {
25 fn sign_with(&self, message: &[u8], id: &MessageId) -> Result<S, PrimitiveError> {
28 let round = id.1.to_le_bytes();
29 let message_with_id: Vec<u8> = chain!(message, &id.0, &round, id.2).copied().collect();
30 let signature = self
31 .try_sign(&message_with_id)
32 .map_err(|e| VerificationError::InvalidSignature(e.to_string()))?;
33 Ok(signature)
34 }
35}
36
37pub trait UCVerifier<S>: DalekVerifier<S> + Sync + Send {
40 fn verify_with(
43 &self,
44 message: &[u8],
45 signature: &S,
46 &id: &MessageId,
47 ) -> Result<(), PrimitiveError> {
48 let round = id.1.to_le_bytes();
49 let message_with_id: Vec<u8> = chain!(message, &id.0, &round, id.2).copied().collect();
50 self.verify(&message_with_id, signature)
51 .map_err(|e| VerificationError::InvalidSignature(e.to_string()))?;
52 Ok(())
53 }
54}
55
56impl<S, T: DalekSigner<S> + Sync + Send> UCSigner<S> for T {}
57impl<S, T: DalekVerifier<S> + Sync + Send> UCVerifier<S> for T {}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62 use crate::{
63 random::{self, Random},
64 types::SessionId,
65 };
66
67 #[test]
68 fn test_sign_protocol_message() {
69 let mut rng = random::test_rng();
70 let signing_key = SigningKey::generate(&mut rng);
71 let message = b"Hello, protocol!";
72 let protocol_id: &'static [u8] = &[2, 1];
73 let message_id = (SessionId::random(&mut rng), 1, protocol_id);
74
75 let signature = signing_key.sign_with(message, &message_id).unwrap();
76 assert!(signing_key
77 .verify_with(message, &signature, &message_id)
78 .is_ok());
79 }
80}