1use crate::peer_record::PeerDHTRecord;
35use crate::{P2PError, Result};
36use blake3::Hash;
37use ed25519_dalek::{Signature, Verifier, VerifyingKey};
38use std::collections::HashMap;
39use std::time::{Duration, Instant};
40
41const MAX_BATCH_SIZE: usize = 64;
43
44const VERIFICATION_CACHE_SIZE: usize = 1024;
46
47const SIGNATURE_FRESHNESS_WINDOW: Duration = Duration::from_secs(300);
49
50pub struct EnhancedSignatureVerifier {
52 key_cache: HashMap<[u8; 32], CachedVerificationKey>,
54 stats: VerificationStats,
56}
57
58#[derive(Clone)]
60struct CachedVerificationKey {
61 key: VerifyingKey,
63 _precomputed_point: Option<Vec<u8>>, last_used: Instant,
67 usage_count: u64,
69}
70
71#[derive(Debug, Clone, Default)]
73pub struct VerificationStats {
74 pub total_verified: u64,
76 pub batch_verifications: u64,
78 pub cache_hits: u64,
80 pub cache_misses: u64,
82 pub avg_verification_time_us: u64,
84 pub verification_errors: u64,
86}
87
88pub struct BatchVerificationRequest {
90 pub message: Vec<u8>,
92 pub signature: Signature,
94 pub public_key: VerifyingKey,
96 pub context: Option<String>,
98}
99
100pub struct BatchVerificationResult {
102 pub index: usize,
104 pub success: bool,
106 pub error: Option<String>,
108}
109
110impl EnhancedSignatureVerifier {
111 pub fn new() -> Self {
113 Self {
114 key_cache: HashMap::with_capacity(VERIFICATION_CACHE_SIZE),
115 stats: VerificationStats::default(),
116 }
117 }
118
119 pub fn verify_signature(&mut self, record: &PeerDHTRecord) -> Result<()> {
121 let start_time = Instant::now();
122
123 self.validate_timestamp_freshness(record)?;
125
126 let cached_key = self.get_or_create_cached_key(&record.public_key)?;
128
129 let verification_result = self.verify_signature_constant_time(
131 &cached_key.key,
132 &record.create_signable_message()?,
133 &record.signature,
134 );
135
136 self.update_stats(start_time, verification_result.is_ok());
138
139 verification_result
140 }
141
142 pub fn verify_batch(
144 &mut self,
145 requests: Vec<BatchVerificationRequest>,
146 ) -> Vec<BatchVerificationResult> {
147 let _start_time = Instant::now();
148 let mut results = Vec::with_capacity(requests.len());
149
150 if requests.len() > MAX_BATCH_SIZE {
152 return requests
154 .into_iter()
155 .enumerate()
156 .map(|(index, _req)| BatchVerificationResult {
157 index,
158 success: false,
159 error: Some("Batch size exceeds maximum".to_string()),
160 })
161 .collect();
162 }
163
164 for (index, request) in requests.into_iter().enumerate() {
166 let result = self.verify_single_batch_request(request);
167 results.push(BatchVerificationResult {
168 index,
169 success: result.is_ok(),
170 error: result.err().map(|e| format!("Verification failed: {e}")),
171 });
172 }
173
174 self.stats.batch_verifications += 1;
176 self.stats.total_verified += results.len() as u64;
177
178 results
179 }
180
181 fn verify_single_batch_request(&mut self, request: BatchVerificationRequest) -> Result<()> {
183 let cached_key = self.get_or_create_cached_key(&request.public_key)?;
185
186 self.verify_signature_constant_time(&cached_key.key, &request.message, &request.signature)
188 }
189
190 fn validate_timestamp_freshness(&self, record: &PeerDHTRecord) -> Result<()> {
192 let now = std::time::SystemTime::now()
193 .duration_since(std::time::UNIX_EPOCH)
194 .map_err(|e| {
195 P2PError::Identity(crate::error::IdentityError::SystemTime(
196 format!("Time error: {e}").into(),
197 ))
198 })?
199 .as_secs();
200
201 let age = now.saturating_sub(record.timestamp);
202
203 if age > SIGNATURE_FRESHNESS_WINDOW.as_secs() {
204 return Err(P2PError::Security(
205 crate::error::SecurityError::SignatureVerificationFailed(
206 "Signature verification failed".to_string().into(),
207 ),
208 ));
209 }
210
211 if record.timestamp > now + 60 {
213 return Err(P2PError::Security(
214 crate::error::SecurityError::SignatureVerificationFailed(
215 "Signature verification failed".to_string().into(),
216 ),
217 ));
218 }
219
220 Ok(())
221 }
222
223 fn get_or_create_cached_key(
225 &mut self,
226 public_key: &VerifyingKey,
227 ) -> Result<CachedVerificationKey> {
228 let key_bytes = public_key.as_bytes();
229
230 if let Some(cached_key) = self.key_cache.get_mut(key_bytes) {
232 cached_key.last_used = Instant::now();
233 cached_key.usage_count += 1;
234 self.stats.cache_hits += 1;
235 return Ok(cached_key.clone());
236 }
237
238 let verifying_key = self.create_verifying_key(public_key)?;
240 let cached_key = CachedVerificationKey {
241 key: verifying_key,
242 _precomputed_point: None, last_used: Instant::now(),
244 usage_count: 1,
245 };
246
247 if self.key_cache.len() >= VERIFICATION_CACHE_SIZE {
249 self.evict_least_used_key();
250 }
251
252 self.key_cache.insert(*key_bytes, cached_key.clone());
253 self.stats.cache_misses += 1;
254
255 Ok(cached_key)
256 }
257
258 fn create_verifying_key(&self, public_key: &VerifyingKey) -> Result<VerifyingKey> {
260 let key_bytes = public_key.as_bytes();
262
263 if self.is_low_order_point(key_bytes) {
265 return Err(P2PError::Security(crate::error::SecurityError::InvalidKey(
266 "Invalid curve point".to_string().into(),
267 )));
268 }
269
270 Ok(*public_key)
273 }
274
275 fn is_low_order_point(&self, key_bytes: &[u8; 32]) -> bool {
277 const LOW_ORDER_POINTS: &[[u8; 32]] = &[
279 [
281 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
283 0x00, 0x00, 0x00, 0x00,
284 ],
285 ];
287
288 LOW_ORDER_POINTS.contains(key_bytes)
289 }
290
291 fn verify_signature_constant_time(
293 &self,
294 verifying_key: &VerifyingKey,
295 message: &[u8],
296 signature: &Signature,
297 ) -> Result<()> {
298 verifying_key.verify(message, signature).map_err(|_| {
300 P2PError::Security(crate::error::SecurityError::SignatureVerificationFailed(
301 "Signature verification failed".to_string().into(),
302 ))
303 })
304 }
305
306 fn evict_least_used_key(&mut self) {
308 let oldest_key = self
309 .key_cache
310 .iter()
311 .min_by_key(|(_, cached_key)| cached_key.last_used)
312 .map(|(key, _)| *key);
313
314 if let Some(key) = oldest_key {
315 self.key_cache.remove(&key);
316 }
317 }
318
319 fn update_stats(&mut self, start_time: Instant, success: bool) {
321 let elapsed = start_time.elapsed().as_micros() as u64;
322
323 let total_verifications = self.stats.total_verified + 1;
325 self.stats.avg_verification_time_us =
326 (self.stats.avg_verification_time_us * self.stats.total_verified + elapsed)
327 / total_verifications;
328
329 self.stats.total_verified = total_verifications;
330
331 if !success {
332 self.stats.verification_errors += 1;
333 }
334 }
335
336 pub fn get_stats(&self) -> VerificationStats {
338 self.stats.clone()
339 }
340
341 pub fn clear_cache(&mut self) {
343 self.key_cache.clear();
344 }
345
346 pub fn cache_utilization(&self) -> f64 {
348 (self.key_cache.len() as f64 / VERIFICATION_CACHE_SIZE as f64) * 100.0
349 }
350}
351
352impl Default for EnhancedSignatureVerifier {
353 fn default() -> Self {
354 Self::new()
355 }
356}
357
358pub trait EnhancedSignatureVerification {
360 fn verify_enhanced(&self, verifier: &mut EnhancedSignatureVerifier) -> Result<()>;
362
363 fn verification_hash(&self) -> Hash;
365}
366
367impl EnhancedSignatureVerification for PeerDHTRecord {
368 fn verify_enhanced(&self, verifier: &mut EnhancedSignatureVerifier) -> Result<()> {
369 verifier.verify_signature(self)
370 }
371
372 fn verification_hash(&self) -> Hash {
373 let mut hasher = blake3::Hasher::new();
374 hasher.update(b"verification_hash");
375 hasher.update(&self.user_id.hash);
376 hasher.update(&self.sequence_number.to_be_bytes());
377 hasher.update(&self.timestamp.to_be_bytes());
378 hasher.update(self.public_key.as_bytes());
379 hasher.finalize()
380 }
381}
382
383#[cfg(test)]
384mod tests {
385 use super::*;
386 use crate::NetworkAddress;
387 use crate::peer_record::{EndpointId, NatType, PeerDHTRecord, PeerEndpoint, UserId};
388 use ed25519_dalek::{Signer, SigningKey, VerifyingKey};
389 use rand::rngs::OsRng;
390 fn create_test_keypair() -> (SigningKey, VerifyingKey) {
393 let mut csprng = OsRng {};
394 let signing_key = SigningKey::generate(&mut csprng);
395 let verifying_key = signing_key.verifying_key().clone();
396 (signing_key, verifying_key)
397 }
398
399 fn create_test_record(signing_key: &SigningKey, verifying_key: &VerifyingKey) -> PeerDHTRecord {
400 let user_id = UserId::from_public_key(verifying_key);
401 let endpoint = PeerEndpoint::new(
402 EndpointId::new(),
403 "192.168.1.1:8080"
404 .parse::<NetworkAddress>()
405 .expect("valid crypto operation"),
406 NatType::FullCone,
407 vec!["coordinator1".to_string()],
408 Some("test-device".to_string()),
409 );
410
411 let mut record = PeerDHTRecord::new(
412 user_id,
413 *verifying_key,
414 1,
415 Some("test-user".to_string()),
416 vec![endpoint],
417 300,
418 )
419 .expect("valid crypto operation");
420
421 record.sign(signing_key).expect("valid crypto operation");
422 record
423 }
424
425 #[test]
426 fn test_enhanced_signature_verification() {
427 let (secret_key, public_key) = create_test_keypair();
428 let record = create_test_record(&secret_key, &public_key);
429
430 let mut verifier = EnhancedSignatureVerifier::new();
431
432 assert!(verifier.verify_signature(&record).is_ok());
434
435 assert!(verifier.verify_signature(&record).is_ok());
437
438 let stats = verifier.get_stats();
440 assert_eq!(stats.total_verified, 2);
441 assert_eq!(stats.cache_hits, 1);
442 assert_eq!(stats.cache_misses, 1);
443 }
444
445 #[test]
446 fn test_batch_verification() {
447 let mut verifier = EnhancedSignatureVerifier::new();
448 let mut requests = Vec::new();
449
450 for i in 0..5 {
452 let (secret_key, public_key) = create_test_keypair();
453 let message = format!("test message {}", i).into_bytes();
454 let signature = secret_key.sign(&message);
455
456 requests.push(BatchVerificationRequest {
457 message,
458 signature,
459 public_key,
460 context: Some(format!("test_{}", i).into()),
461 });
462 }
463
464 let results = verifier.verify_batch(requests);
466
467 assert_eq!(results.len(), 5);
469 assert!(results.iter().all(|r| r.success));
470
471 let stats = verifier.get_stats();
473 assert_eq!(stats.batch_verifications, 1);
474 assert_eq!(stats.total_verified, 5);
475 }
476
477 #[test]
478 fn test_timestamp_freshness_validation() {
479 let (secret_key, public_key) = create_test_keypair();
480 let mut record = create_test_record(&secret_key, &public_key);
481
482 record.timestamp = std::time::SystemTime::now()
484 .duration_since(std::time::UNIX_EPOCH)
485 .expect("valid crypto operation")
486 .as_secs()
487 - 400; record.sign(&secret_key).expect("valid crypto operation");
491
492 let mut verifier = EnhancedSignatureVerifier::new();
493
494 assert!(verifier.verify_signature(&record).is_err());
496 }
497
498 #[test]
499 fn test_cache_eviction() {
500 let mut verifier = EnhancedSignatureVerifier::new();
501
502 for _i in 0..VERIFICATION_CACHE_SIZE + 10 {
504 let (secret_key, public_key) = create_test_keypair();
505 let record = create_test_record(&secret_key, &public_key);
506
507 let _ = verifier.verify_signature(&record);
509 }
510
511 assert!(verifier.cache_utilization() <= 100.0);
513
514 let stats = verifier.get_stats();
515 assert_eq!(stats.total_verified, (VERIFICATION_CACHE_SIZE + 10) as u64);
516 }
517
518 #[test]
519 fn test_enhanced_verification_trait() {
520 let (secret_key, public_key) = create_test_keypair();
521 let record = create_test_record(&secret_key, &public_key);
522
523 let mut verifier = EnhancedSignatureVerifier::new();
524
525 assert!(record.verify_enhanced(&mut verifier).is_ok());
527
528 let hash1 = record.verification_hash();
530 let hash2 = record.verification_hash();
531 assert_eq!(hash1, hash2); }
533}