quorum_crypto_core/
verifier.rs1use crate::CryptoError;
10use std::collections::HashMap;
11use std::fmt::Debug;
12use std::sync::Arc;
13
14pub trait AuditVerifier: Send + Sync + Debug {
19 fn algorithm(&self) -> &str;
21
22 fn verify(
24 &self,
25 message: &[u8],
26 signature: &[u8],
27 public_key: &[u8],
28 ) -> Result<bool, CryptoError>;
29}
30
31#[derive(Debug, Default)]
36pub struct VerifierRegistry {
37 verifiers: HashMap<String, Arc<dyn AuditVerifier>>,
38}
39
40impl VerifierRegistry {
41 pub fn new() -> Self {
43 Self::default()
44 }
45
46 pub fn with_defaults() -> Self {
48 let mut registry = Self::new();
49 registry.register(Arc::new(Ed25519Verifier));
50 registry.register(Arc::new(Secp256k1Verifier));
51 registry
52 }
53
54 pub fn register(&mut self, verifier: Arc<dyn AuditVerifier>) {
56 self.verifiers
57 .insert(verifier.algorithm().to_string(), verifier);
58 }
59
60 pub fn verify(
62 &self,
63 algorithm: &str,
64 message: &[u8],
65 signature: &[u8],
66 public_key: &[u8],
67 ) -> Result<bool, CryptoError> {
68 let verifier = self
69 .verifiers
70 .get(algorithm)
71 .ok_or_else(|| CryptoError::UnknownAlgorithm(algorithm.to_string()))?;
72 verifier.verify(message, signature, public_key)
73 }
74
75 pub fn algorithms(&self) -> Vec<&str> {
77 self.verifiers.keys().map(|s| s.as_str()).collect()
78 }
79}
80
81#[derive(Debug)]
87pub struct Ed25519Verifier;
88
89impl AuditVerifier for Ed25519Verifier {
90 fn algorithm(&self) -> &str {
91 "ed25519"
92 }
93
94 fn verify(
95 &self,
96 message: &[u8],
97 signature: &[u8],
98 public_key: &[u8],
99 ) -> Result<bool, CryptoError> {
100 use ed25519_dalek::Verifier;
101
102 let pubkey_bytes: [u8; 32] = public_key
103 .try_into()
104 .map_err(|_| CryptoError::InvalidKey("Ed25519 public key must be 32 bytes".into()))?;
105 let sig_bytes: [u8; 64] = signature.try_into().map_err(|_| {
106 CryptoError::VerificationFailed("Ed25519 signature must be 64 bytes".into())
107 })?;
108
109 let pubkey = ed25519_dalek::VerifyingKey::from_bytes(&pubkey_bytes)
110 .map_err(|e| CryptoError::InvalidKey(format!("Invalid Ed25519 public key: {e}")))?;
111 let sig = ed25519_dalek::Signature::from_bytes(&sig_bytes);
112
113 match pubkey.verify(message, &sig) {
114 Ok(()) => Ok(true),
115 Err(_) => Ok(false),
116 }
117 }
118}
119
120#[derive(Debug)]
122pub struct Secp256k1Verifier;
123
124impl AuditVerifier for Secp256k1Verifier {
125 fn algorithm(&self) -> &str {
126 "secp256k1"
127 }
128
129 fn verify(
135 &self,
136 message: &[u8],
137 signature: &[u8],
138 public_key: &[u8],
139 ) -> Result<bool, CryptoError> {
140 use k256::ecdsa::signature::Verifier;
141 use k256::ecdsa::VerifyingKey;
142
143 let pubkey = VerifyingKey::from_sec1_bytes(public_key)
144 .map_err(|e| CryptoError::InvalidKey(format!("Invalid secp256k1 public key: {e}")))?;
145
146 let sig_bytes = if signature.len() == 65 {
148 &signature[..64] } else {
150 signature
151 };
152 let sig = k256::ecdsa::Signature::from_slice(sig_bytes).map_err(|e| {
153 CryptoError::VerificationFailed(format!("Invalid secp256k1 signature: {e}"))
154 })?;
155
156 match pubkey.verify(message, &sig) {
157 Ok(()) => Ok(true),
158 Err(_) => Ok(false),
159 }
160 }
161}
162
163#[cfg(test)]
164mod tests {
165 use super::*;
166 use crate::signer::{AuditSigner, Ed25519Signer, Secp256k1Signer};
167
168 #[tokio::test]
169 async fn ed25519_verifier_roundtrip() {
170 let signer = Ed25519Signer::generate();
171 let message = b"test message";
172 let sig = signer.sign(message).await.unwrap();
173
174 let verifier = Ed25519Verifier;
175 assert!(verifier
176 .verify(message, &sig, &signer.public_key_bytes())
177 .unwrap());
178 }
179
180 #[tokio::test]
181 async fn ed25519_verifier_rejects_wrong_message() {
182 let signer = Ed25519Signer::generate();
183 let sig = signer.sign(b"correct").await.unwrap();
184
185 let verifier = Ed25519Verifier;
186 assert!(!verifier
187 .verify(b"wrong", &sig, &signer.public_key_bytes())
188 .unwrap());
189 }
190
191 #[tokio::test]
192 async fn secp256k1_verifier_roundtrip() {
193 let signer = Secp256k1Signer::generate();
194 let message = b"test message";
195 let sig = signer.sign(message).await.unwrap();
196
197 let verifier = Secp256k1Verifier;
198 assert!(verifier
199 .verify(message, &sig, &signer.public_key_bytes())
200 .unwrap());
201 }
202
203 #[tokio::test]
204 async fn secp256k1_verifier_rejects_wrong_key() {
205 let signer = Secp256k1Signer::generate();
206 let other = Secp256k1Signer::generate();
207 let sig = signer.sign(b"test").await.unwrap();
208
209 let verifier = Secp256k1Verifier;
210 assert!(!verifier
211 .verify(b"test", &sig, &other.public_key_bytes())
212 .unwrap());
213 }
214
215 #[tokio::test]
216 async fn registry_with_defaults_verifies_both() {
217 let registry = VerifierRegistry::with_defaults();
218
219 let ed = Ed25519Signer::generate();
220 let ed_sig = ed.sign(b"hello").await.unwrap();
221 assert!(registry
222 .verify("ed25519", b"hello", &ed_sig, &ed.public_key_bytes())
223 .unwrap());
224
225 let secp = Secp256k1Signer::generate();
226 let secp_sig = secp.sign(b"hello").await.unwrap();
227 assert!(registry
228 .verify("secp256k1", b"hello", &secp_sig, &secp.public_key_bytes())
229 .unwrap());
230 }
231
232 #[test]
233 fn registry_unknown_algorithm_errors() {
234 let registry = VerifierRegistry::new();
235 let result = registry.verify("unknown", b"msg", b"sig", b"key");
236 assert!(result.is_err());
237 }
238
239 #[test]
240 fn ed25519_verifier_rejects_invalid_key_size() {
241 let verifier = Ed25519Verifier;
242 let result = verifier.verify(b"msg", &[0u8; 64], &[0u8; 16]); assert!(result.is_err());
244 assert!(matches!(result.unwrap_err(), CryptoError::InvalidKey(_)));
245 }
246
247 #[test]
248 fn ed25519_verifier_rejects_invalid_sig_size() {
249 let verifier = Ed25519Verifier;
250 let result = verifier.verify(b"msg", &[0u8; 32], &[0u8; 32]); assert!(result.is_err());
252 }
253
254 #[test]
255 fn secp256k1_verifier_rejects_invalid_key() {
256 let verifier = Secp256k1Verifier;
257 let result = verifier.verify(b"msg", &[0u8; 64], &[0u8; 5]); assert!(result.is_err());
259 }
260
261 #[test]
262 fn registry_algorithms_lists_registered() {
263 let registry = VerifierRegistry::with_defaults();
264 let algos = registry.algorithms();
265 assert!(algos.contains(&"ed25519"));
266 assert!(algos.contains(&"secp256k1"));
267 }
268
269 #[test]
270 fn empty_registry_has_no_algorithms() {
271 let registry = VerifierRegistry::new();
272 assert!(registry.algorithms().is_empty());
273 }
274}