Rust · 10784 bytes Raw Blame History
1 //! Verification module for ZephyrFS
2 //!
3 //! Provides comprehensive content verification and integrity checking
4 //! without compromising zero-knowledge architecture.
5
6 pub mod integrity_checks;
7
8 pub use integrity_checks::{
9 IntegrityVerifier, IntegrityConfig, IntegrityProof, VerificationResult, VerificationReport
10 };
11
12 use anyhow::Result;
13 use serde::{Deserialize, Serialize};
14 use std::collections::HashMap;
15 use uuid::Uuid;
16
17 /// Unified verification configuration
18 #[derive(Debug, Clone, Serialize, Deserialize)]
19 pub struct VerificationConfig {
20 /// Integrity verification configuration
21 pub integrity_config: integrity_checks::IntegrityConfig,
22 /// Global verification policies
23 pub global_policies: GlobalVerificationPolicies,
24 }
25
26 /// Global verification policies
27 #[derive(Debug, Clone, Serialize, Deserialize)]
28 pub struct GlobalVerificationPolicies {
29 /// Require verification for all chunks
30 pub mandatory_verification: bool,
31 /// Maximum age for cached verification results (seconds)
32 pub verification_cache_ttl: u64,
33 /// Minimum confidence threshold for acceptance
34 pub acceptance_threshold: f64,
35 /// Enable periodic re-verification
36 pub periodic_reverification: bool,
37 /// Re-verification interval (seconds)
38 pub reverification_interval: u64,
39 }
40
41 impl Default for VerificationConfig {
42 fn default() -> Self {
43 Self {
44 integrity_config: integrity_checks::IntegrityConfig::default(),
45 global_policies: GlobalVerificationPolicies {
46 mandatory_verification: true,
47 verification_cache_ttl: 3600, // 1 hour
48 acceptance_threshold: 0.95,
49 periodic_reverification: true,
50 reverification_interval: 86400, // 24 hours
51 },
52 }
53 }
54 }
55
56 /// Unified verification manager
57 pub struct UnifiedVerificationManager {
58 integrity_verifier: IntegrityVerifier,
59 config: VerificationConfig,
60 verification_cache: HashMap<Uuid, CachedVerificationResult>,
61 }
62
63 impl UnifiedVerificationManager {
64 /// Create new unified verification manager
65 pub fn new(config: VerificationConfig) -> Self {
66 let integrity_verifier = IntegrityVerifier::new(config.integrity_config.clone());
67
68 Self {
69 integrity_verifier,
70 config,
71 verification_cache: HashMap::new(),
72 }
73 }
74
75 /// Verify chunk with comprehensive checks
76 pub async fn verify_chunk(
77 &mut self,
78 chunk_id: Uuid,
79 encrypted_content: &[u8],
80 stored_proof: Option<&IntegrityProof>,
81 ) -> Result<ComprehensiveVerificationResult> {
82 // Check cache first
83 if let Some(cached_result) = self.get_cached_verification(chunk_id) {
84 if !self.is_cache_expired(&cached_result) {
85 return Ok(ComprehensiveVerificationResult {
86 chunk_id,
87 verification_result: cached_result.result.clone(),
88 from_cache: true,
89 recommendations: self.generate_recommendations(&cached_result.result),
90 });
91 }
92 }
93
94 // Perform fresh verification
95 let verification_result = if let Some(proof) = stored_proof {
96 // Verify against existing proof
97 self.integrity_verifier.verify_integrity(encrypted_content, proof)?
98 } else {
99 // Generate new proof and verify
100 let new_proof = self.integrity_verifier.generate_proof(encrypted_content)?;
101 self.integrity_verifier.verify_integrity(encrypted_content, &new_proof)?
102 };
103
104 // Cache the result
105 let cached_result = CachedVerificationResult {
106 result: verification_result.clone(),
107 timestamp: std::time::SystemTime::now()
108 .duration_since(std::time::UNIX_EPOCH)?
109 .as_secs(),
110 };
111 self.verification_cache.insert(chunk_id, cached_result);
112
113 let recommendations = self.generate_recommendations(&verification_result);
114
115 Ok(ComprehensiveVerificationResult {
116 chunk_id,
117 verification_result,
118 from_cache: false,
119 recommendations,
120 })
121 }
122
123 /// Generate integrity proof for chunk
124 pub fn generate_integrity_proof(&self, encrypted_content: &[u8]) -> Result<IntegrityProof> {
125 self.integrity_verifier.generate_proof(encrypted_content)
126 }
127
128 /// Verify integrity proof
129 pub fn verify_integrity_proof(
130 &self,
131 encrypted_content: &[u8],
132 proof: &IntegrityProof,
133 ) -> Result<VerificationResult> {
134 self.integrity_verifier.verify_integrity(encrypted_content, proof)
135 }
136
137 /// Check if chunk needs re-verification
138 pub fn needs_reverification(&self, chunk_id: Uuid, last_verification: u64) -> bool {
139 if !self.config.global_policies.periodic_reverification {
140 return false;
141 }
142
143 let current_time = std::time::SystemTime::now()
144 .duration_since(std::time::UNIX_EPOCH)
145 .unwrap_or_default()
146 .as_secs();
147
148 current_time - last_verification >= self.config.global_policies.reverification_interval
149 }
150
151 /// Get verification statistics
152 pub fn get_verification_stats(&self) -> VerificationStats {
153 let total_cached = self.verification_cache.len();
154 let valid_results = self.verification_cache.values()
155 .filter(|result| result.result.is_valid)
156 .count();
157
158 VerificationStats {
159 total_verifications: total_cached,
160 successful_verifications: valid_results,
161 failed_verifications: total_cached - valid_results,
162 cache_hit_rate: 0.0, // Would need to track cache hits/misses
163 average_confidence: self.calculate_average_confidence(),
164 }
165 }
166
167 /// Update verification configuration
168 pub fn update_config(&mut self, new_config: VerificationConfig) {
169 self.config = new_config;
170 // Clear cache to ensure new policies take effect
171 self.verification_cache.clear();
172 }
173
174 /// Get cached verification result if valid
175 fn get_cached_verification(&self, chunk_id: Uuid) -> Option<&CachedVerificationResult> {
176 self.verification_cache.get(&chunk_id)
177 }
178
179 /// Check if cached result is expired
180 fn is_cache_expired(&self, cached_result: &CachedVerificationResult) -> bool {
181 let current_time = std::time::SystemTime::now()
182 .duration_since(std::time::UNIX_EPOCH)
183 .unwrap_or_default()
184 .as_secs();
185
186 current_time - cached_result.timestamp >= self.config.global_policies.verification_cache_ttl
187 }
188
189 /// Generate recommendations based on verification results
190 fn generate_recommendations(&self, result: &VerificationResult) -> Vec<VerificationRecommendation> {
191 let mut recommendations = Vec::new();
192
193 if !result.is_valid {
194 recommendations.push(VerificationRecommendation::RequireReUpload);
195 recommendations.push(VerificationRecommendation::InvestigateCorruption);
196 } else if result.confidence < self.config.global_policies.acceptance_threshold {
197 recommendations.push(VerificationRecommendation::RequireAdditionalVerification);
198
199 if result.confidence < 0.8 {
200 recommendations.push(VerificationRecommendation::MarkForReview);
201 }
202 }
203
204 if result.confidence >= self.config.global_policies.acceptance_threshold {
205 recommendations.push(VerificationRecommendation::AcceptAsValid);
206 }
207
208 recommendations
209 }
210
211 /// Calculate average confidence across all cached results
212 fn calculate_average_confidence(&self) -> f64 {
213 if self.verification_cache.is_empty() {
214 return 0.0;
215 }
216
217 let total_confidence: f64 = self.verification_cache.values()
218 .map(|result| result.result.confidence)
219 .sum();
220
221 total_confidence / self.verification_cache.len() as f64
222 }
223 }
224
225 /// Cached verification result
226 #[derive(Debug, Clone)]
227 struct CachedVerificationResult {
228 result: VerificationResult,
229 timestamp: u64,
230 }
231
232 /// Comprehensive verification result
233 #[derive(Debug, Clone)]
234 pub struct ComprehensiveVerificationResult {
235 pub chunk_id: Uuid,
236 pub verification_result: VerificationResult,
237 pub from_cache: bool,
238 pub recommendations: Vec<VerificationRecommendation>,
239 }
240
241 /// Verification recommendations
242 #[derive(Debug, Clone)]
243 pub enum VerificationRecommendation {
244 AcceptAsValid,
245 RequireAdditionalVerification,
246 RequireReUpload,
247 MarkForReview,
248 InvestigateCorruption,
249 ScheduleReverification,
250 }
251
252 /// Verification statistics
253 #[derive(Debug, Clone)]
254 pub struct VerificationStats {
255 pub total_verifications: usize,
256 pub successful_verifications: usize,
257 pub failed_verifications: usize,
258 pub cache_hit_rate: f64,
259 pub average_confidence: f64,
260 }
261
262 #[cfg(test)]
263 mod tests {
264 use super::*;
265
266 #[tokio::test]
267 async fn test_unified_verification_manager() -> Result<()> {
268 let config = VerificationConfig::default();
269 let mut verification_manager = UnifiedVerificationManager::new(config);
270
271 let chunk_id = Uuid::new_v4();
272 let test_data = b"Test encrypted chunk data for verification";
273
274 let result = verification_manager
275 .verify_chunk(chunk_id, test_data, None)
276 .await?;
277
278 assert_eq!(result.chunk_id, chunk_id);
279 assert!(!result.from_cache); // First verification shouldn't be from cache
280 assert!(!result.recommendations.is_empty());
281
282 Ok(())
283 }
284
285 #[tokio::test]
286 async fn test_verification_caching() -> Result<()> {
287 let config = VerificationConfig::default();
288 let mut verification_manager = UnifiedVerificationManager::new(config);
289
290 let chunk_id = Uuid::new_v4();
291 let test_data = b"Test data for caching verification";
292
293 // First verification
294 let result1 = verification_manager
295 .verify_chunk(chunk_id, test_data, None)
296 .await?;
297 assert!(!result1.from_cache);
298
299 // Second verification should use cache
300 let result2 = verification_manager
301 .verify_chunk(chunk_id, test_data, None)
302 .await?;
303 assert!(result2.from_cache);
304
305 Ok(())
306 }
307
308 #[test]
309 fn test_verification_stats() {
310 let config = VerificationConfig::default();
311 let verification_manager = UnifiedVerificationManager::new(config);
312
313 let stats = verification_manager.get_verification_stats();
314 assert_eq!(stats.total_verifications, 0);
315 assert_eq!(stats.successful_verifications, 0);
316 assert_eq!(stats.failed_verifications, 0);
317 }
318 }