mithril_common/crypto_helper/
ed25519.rs

1//! Ed25519 cryptographic helpers
2
3use anyhow::anyhow;
4use ed25519_dalek::{Signer, SigningKey};
5use rand_chacha::rand_core::{CryptoRng, RngCore, SeedableRng};
6use rand_chacha::ChaCha20Rng;
7use serde::{Deserialize, Serialize};
8use thiserror::Error;
9
10use crate::{StdError, StdResult};
11
12use super::ProtocolKey;
13
14/// Wrapper of [Ed25519:PublicKey](https://docs.rs/ed25519-dalek/latest/ed25519_dalek/struct.VerifyingKey.html).
15pub type Ed25519VerificationKey = ProtocolKey<ed25519_dalek::VerifyingKey>;
16
17/// Wrapper of [Ed25519:SigningKey](https://docs.rs/ed25519-dalek/latest/ed25519_dalek/struct.SigningKey.html).
18pub type Ed25519SecretKey = ProtocolKey<ed25519_dalek::SigningKey>;
19
20/// Wrapper of [Ed25519:Signature](https://docs.rs/ed25519-dalek/latest/ed25519_dalek/struct.Signature.html).
21pub type Ed25519Signature = ProtocolKey<ed25519_dalek::Signature>;
22
23#[derive(Error, Debug)]
24/// [Ed25519Signer] and [Ed25519Verifier] related errors.
25#[error("Ed25519 signature verification error")]
26pub struct Ed25519VerifierError(#[source] StdError);
27
28/// A cryptographic signer that is responsible for signing messages using Ed25519 signature scheme
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct Ed25519Signer {
31    pub(crate) secret_key: Ed25519SecretKey,
32}
33
34impl Ed25519Signer {
35    /// [Ed25519Signer] factory
36    pub fn create_test_signer<R>(mut rng: R) -> Self
37    where
38        R: CryptoRng + RngCore,
39    {
40        let secret_key = SigningKey::generate(&mut rng);
41        Self::from_secret_key(secret_key.into())
42    }
43
44    /// [Ed25519Signer] deterministic
45    pub fn create_deterministic_signer() -> Self {
46        let rng = ChaCha20Rng::from_seed([0u8; 32]);
47        Self::create_test_signer(rng)
48    }
49
50    /// [Ed25519Signer] non deterministic
51    pub fn create_non_deterministic_signer() -> Self {
52        let rng = rand_core::OsRng;
53        Self::create_test_signer(rng)
54    }
55
56    /// Get the [Ed25519SecretKey]
57    pub fn secret_key(&self) -> Ed25519SecretKey {
58        self.secret_key.clone()
59    }
60
61    /// Get the [Ed25519VerificationKey]
62    pub fn verification_key(&self) -> Ed25519VerificationKey {
63        self.secret_key.verifying_key().into()
64    }
65
66    /// [Ed25519Signer] from [Ed25519SecretKey]
67    pub fn from_secret_key(secret_key: Ed25519SecretKey) -> Self {
68        Self { secret_key }
69    }
70
71    /// Create a [Ed25519Verifier]
72    pub fn create_verifier(&self) -> Ed25519Verifier {
73        Ed25519Verifier::from_verification_key(self.secret_key.verifying_key().into())
74    }
75
76    /// Signs a message and returns a [Ed25519Signature]
77    pub fn sign(&self, message: &[u8]) -> Ed25519Signature {
78        self.secret_key.sign(message).into()
79    }
80}
81
82/// Ed25519 verifier that checks the authenticity of Ed25519 signatures
83#[derive(Debug, Serialize, Deserialize, Clone)]
84pub struct Ed25519Verifier {
85    pub(crate) verification_key: Ed25519VerificationKey,
86}
87
88impl Ed25519Verifier {
89    /// [Ed25519Verifier] from [Ed25519VerificationKey]
90    pub fn from_verification_key(verification_key: Ed25519VerificationKey) -> Self {
91        Self { verification_key }
92    }
93
94    /// [Ed25519Verifier] to [Ed25519VerificationKey]
95    pub fn to_verification_key(&self) -> Ed25519VerificationKey {
96        self.verification_key
97    }
98
99    /// Verifies the signature of a message
100    pub fn verify(&self, message: &[u8], signature: &Ed25519Signature) -> StdResult<()> {
101        self.verification_key.verify(message, signature)
102    }
103}
104
105impl Ed25519VerificationKey {
106    /// Verifies the signature of a message
107    pub fn verify(&self, message: &[u8], signature: &Ed25519Signature) -> StdResult<()> {
108        Ok(self
109            .verify_strict(message, signature)
110            .map_err(|e| Ed25519VerifierError(anyhow!(e)))?)
111    }
112}
113
114#[cfg(test)]
115mod tests {
116    use super::*;
117
118    const GOLDEN_ED25519_VERIFICATION_KEY: &str =
119        "5b32332c32372c3131322c362c35372c38342c3138302c342c3135302c3233322c3233372c3132362c3131392c\
120        3231342c33352c35342c38312c3230382c3231372c39392c3137302c3233312c3133392c362c3132322c39342c3\
121        9322c3137322c32332c3130322c3135372c3136375d";
122    const GOLDEN_ED25519_SECRET_KEY: &str =
123        "5b34332c3133322c3232312c3138382c3235332c3132372c3235352c38362c3136322c3133312c3233332c3131\
124        362c3134322c3233352c3131312c3133332c3134312c3138332c302c33392c3132302c3139372c39322c3133302\
125        c3233342c34362c3135372c32352c3133322c31352c3234312c3235345d";
126
127    #[test]
128    fn golden_master() {
129        Ed25519VerificationKey::from_json_hex(GOLDEN_ED25519_VERIFICATION_KEY)
130            .expect("Decoding golden verification key should not fail");
131
132        Ed25519SecretKey::from_json_hex(GOLDEN_ED25519_SECRET_KEY)
133            .expect("Decoding golden secret key should not fail");
134    }
135
136    #[test]
137    fn test_generate_test_deterministic_keypair() {
138        let signer = Ed25519Signer::create_deterministic_signer();
139        let verifier = signer.create_verifier();
140        let signer_2 = Ed25519Signer::create_deterministic_signer();
141        let verifier_2 = signer.create_verifier();
142        assert_eq!(signer.secret_key.to_bytes(), signer_2.secret_key.to_bytes());
143        assert_eq!(
144            verifier.verification_key.as_bytes(),
145            verifier_2.verification_key.as_bytes()
146        );
147
148        println!(
149            "Deterministic Verification Key={}",
150            verifier.verification_key.to_json_hex().unwrap()
151        );
152        println!(
153            "Deterministic Secret Key=={}",
154            signer.secret_key.to_json_hex().unwrap()
155        );
156    }
157
158    #[test]
159    fn test_generate_test_non_deterministic_keypair() {
160        let signer = Ed25519Signer::create_non_deterministic_signer();
161        let verifier = signer.create_verifier();
162
163        println!(
164            "Non Deterministic Verification Key={}",
165            verifier.verification_key.to_json_hex().unwrap()
166        );
167        println!(
168            "Non Deterministic Secret Key=={}",
169            signer.secret_key.to_json_hex().unwrap()
170        );
171    }
172
173    #[test]
174    fn test_codec_keypair() {
175        let signer = Ed25519Signer::create_deterministic_signer();
176        let verifier = signer.create_verifier();
177        let secret_key_encoded = signer.secret_key.to_json_hex().unwrap();
178        let verification_key_encoded = verifier.verification_key.to_json_hex().unwrap();
179        let secret_key_decoded: Ed25519SecretKey = secret_key_encoded.try_into().unwrap();
180        let verification_key_decoded: Ed25519VerificationKey =
181            verification_key_encoded.try_into().unwrap();
182        let signer_decoded = Ed25519Signer::from_secret_key(secret_key_decoded);
183        let verifier_decoded = Ed25519Verifier::from_verification_key(verification_key_decoded);
184
185        let message: &[u8] = b"some message.";
186        let signature = signer_decoded.sign(message);
187        let verify_signature = verifier_decoded.verify(message, &signature);
188        assert!(
189            verify_signature.is_ok(),
190            "signature verification should not fail"
191        );
192    }
193}