mithril_common/crypto_helper/
ed25519.rs1use anyhow::anyhow;
4use ed25519_dalek::{Signer, SigningKey};
5use rand_chacha::ChaCha20Rng;
6use rand_chacha::rand_core::{CryptoRng, RngCore, SeedableRng};
7use serde::{Deserialize, Serialize};
8use thiserror::Error;
9
10use crate::{StdError, StdResult};
11
12use super::ProtocolKey;
13
14pub type Ed25519VerificationKey = ProtocolKey<ed25519_dalek::VerifyingKey>;
16
17pub type Ed25519SecretKey = ProtocolKey<ed25519_dalek::SigningKey>;
19
20pub type Ed25519Signature = ProtocolKey<ed25519_dalek::Signature>;
22
23#[derive(Error, Debug)]
24#[error("Ed25519 signature verification error")]
26pub struct Ed25519VerifierError(#[source] StdError);
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct Ed25519Signer {
31 pub(crate) secret_key: Ed25519SecretKey,
32}
33
34impl Ed25519Signer {
35 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 pub fn create_deterministic_signer() -> Self {
46 let rng = ChaCha20Rng::from_seed([0u8; 32]);
47 Self::create_test_signer(rng)
48 }
49
50 pub fn create_non_deterministic_signer() -> Self {
52 let rng = rand_core::OsRng;
53 Self::create_test_signer(rng)
54 }
55
56 pub fn secret_key(&self) -> Ed25519SecretKey {
58 self.secret_key.clone()
59 }
60
61 pub fn verification_key(&self) -> Ed25519VerificationKey {
63 self.secret_key.verifying_key().into()
64 }
65
66 pub fn from_secret_key(secret_key: Ed25519SecretKey) -> Self {
68 Self { secret_key }
69 }
70
71 pub fn create_verifier(&self) -> Ed25519Verifier {
73 Ed25519Verifier::from_verification_key(self.secret_key.verifying_key().into())
74 }
75
76 pub fn sign(&self, message: &[u8]) -> Ed25519Signature {
78 self.secret_key.sign(message).into()
79 }
80}
81
82#[derive(Debug, Serialize, Deserialize, Clone)]
84pub struct Ed25519Verifier {
85 pub(crate) verification_key: Ed25519VerificationKey,
86}
87
88impl Ed25519Verifier {
89 pub fn from_verification_key(verification_key: Ed25519VerificationKey) -> Self {
91 Self { verification_key }
92 }
93
94 pub fn to_verification_key(&self) -> Ed25519VerificationKey {
96 self.verification_key
97 }
98
99 pub fn verify(&self, message: &[u8], signature: &Ed25519Signature) -> StdResult<()> {
101 self.verification_key.verify(message, signature)
102 }
103}
104
105impl Ed25519VerificationKey {
106 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 = "5b32332c32372c3131322c362c35372c38342c3138302c342c3135302c3233322c3233372c3132362c3131392c\
119 3231342c33352c35342c38312c3230382c3231372c39392c3137302c3233312c3133392c362c3132322c39342c3\
120 9322c3137322c32332c3130322c3135372c3136375d";
121 const GOLDEN_ED25519_SECRET_KEY: &str = "5b34332c3133322c3232312c3138382c3235332c3132372c3235352c38362c3136322c3133312c3233332c3131\
122 362c3134322c3233352c3131312c3133332c3134312c3138332c302c33392c3132302c3139372c39322c3133302\
123 c3233342c34362c3135372c32352c3133322c31352c3234312c3235345d";
124
125 #[test]
126 fn golden_master() {
127 Ed25519VerificationKey::from_json_hex(GOLDEN_ED25519_VERIFICATION_KEY)
128 .expect("Decoding golden verification key should not fail");
129
130 Ed25519SecretKey::from_json_hex(GOLDEN_ED25519_SECRET_KEY)
131 .expect("Decoding golden secret key should not fail");
132 }
133
134 #[test]
135 fn test_generate_test_deterministic_keypair() {
136 let signer = Ed25519Signer::create_deterministic_signer();
137 let verifier = signer.create_verifier();
138 let signer_2 = Ed25519Signer::create_deterministic_signer();
139 let verifier_2 = signer.create_verifier();
140 assert_eq!(signer.secret_key.to_bytes(), signer_2.secret_key.to_bytes());
141 assert_eq!(
142 verifier.verification_key.as_bytes(),
143 verifier_2.verification_key.as_bytes()
144 );
145
146 println!(
147 "Deterministic Verification Key={}",
148 verifier.verification_key.to_json_hex().unwrap()
149 );
150 println!(
151 "Deterministic Secret Key=={}",
152 signer.secret_key.to_json_hex().unwrap()
153 );
154 }
155
156 #[test]
157 fn test_generate_test_non_deterministic_keypair() {
158 let signer = Ed25519Signer::create_non_deterministic_signer();
159 let verifier = signer.create_verifier();
160
161 println!(
162 "Non Deterministic Verification Key={}",
163 verifier.verification_key.to_json_hex().unwrap()
164 );
165 println!(
166 "Non Deterministic Secret Key=={}",
167 signer.secret_key.to_json_hex().unwrap()
168 );
169 }
170
171 #[test]
172 fn test_codec_keypair() {
173 let signer = Ed25519Signer::create_deterministic_signer();
174 let verifier = signer.create_verifier();
175 let secret_key_encoded = signer.secret_key.to_json_hex().unwrap();
176 let verification_key_encoded = verifier.verification_key.to_json_hex().unwrap();
177 let secret_key_decoded: Ed25519SecretKey = secret_key_encoded.try_into().unwrap();
178 let verification_key_decoded: Ed25519VerificationKey =
179 verification_key_encoded.try_into().unwrap();
180 let signer_decoded = Ed25519Signer::from_secret_key(secret_key_decoded);
181 let verifier_decoded = Ed25519Verifier::from_verification_key(verification_key_decoded);
182
183 let message: &[u8] = b"some message.";
184 let signature = signer_decoded.sign(message);
185 let verify_signature = verifier_decoded.verify(message, &signature);
186 assert!(
187 verify_signature.is_ok(),
188 "signature verification should not fail"
189 );
190 }
191}