1use super::*;
4
5pub struct SignatureEngine {
7 signing_algorithms: HashMap<KeyAlgorithm, SigningAlgorithm>,
8 verification_algorithms: HashMap<KeyAlgorithm, VerificationAlgorithm>,
9 pub(super) signature_storage: SignatureStorage,
10 pub(super) performance_optimizer: SignaturePerformanceOptimizer,
11}
12
13#[derive(Debug, Clone)]
15pub struct SigningAlgorithm {
16 pub algorithm_id: String,
17 pub key_algorithm: KeyAlgorithm,
18 pub hash_function: String,
19 pub parameters: SigningParameters,
20}
21
22#[derive(Debug, Clone)]
24pub struct SigningParameters {
25 pub padding: Option<String>,
26 pub salt_length: Option<usize>,
27 pub deterministic: bool,
28 pub custom_params: HashMap<String, Vec<u8>>,
29}
30
31#[derive(Debug, Clone)]
33pub struct VerificationAlgorithmConfig {
34 pub algorithm_id: String,
35 pub key_algorithm: KeyAlgorithm,
36 pub hash_function: String,
37 pub parameters: VerificationParameters,
38}
39
40#[derive(Debug, Clone)]
42pub struct VerificationParameters {
43 pub strict_verification: bool,
44 pub allow_weak_hashes: bool,
45 pub custom_params: HashMap<String, Vec<u8>>,
46}
47
48pub struct SignatureStorage {
50 signatures: HashMap<String, Signature>,
51 verification_records: HashMap<String, VerificationRecord>,
52 pub(super) audit_log: SignatureAuditLog,
53}
54
55#[derive(Debug, Clone)]
57pub struct SignatureRecord {
58 pub signature_id: String,
59 pub key_id: String,
60 pub algorithm: KeyAlgorithm,
61 pub data_hash: Vec<u8>,
62 pub signature: Vec<u8>,
63 pub timestamp: u64,
64 pub metadata: SignatureMetadata,
65}
66
67#[derive(Debug, Clone)]
69pub struct SignatureMetadata {
70 pub signer_id: String,
71 pub purpose: String,
72 pub context: Vec<String>,
73 pub validity_period: Option<(u64, u64)>,
74}
75
76#[derive(Debug, Clone)]
78pub struct VerificationRecord {
79 pub verification_id: String,
80 pub signature_id: String,
81 pub verifier_id: String,
82 pub result: VerificationResult,
83 pub timestamp: u64,
84}
85
86#[derive(Debug, Clone)]
88pub struct VerificationResult {
89 pub valid: bool,
90 pub error_message: Option<String>,
91 pub verification_time: u64,
92 pub confidence: f64,
93}
94
95pub struct SignatureAuditLog {
97 entries: Vec<SignatureAuditEntry>,
98 retention_policy: RetentionPolicy,
99}
100
101#[derive(Debug, Clone)]
103pub struct SignatureAuditEntry {
104 pub entry_id: String,
105 pub timestamp: u64,
106 pub signature_id: String,
107 pub operation: SignatureOperation,
108 pub user_id: String,
109 pub ip_address: String,
110 pub success: bool,
111}
112
113#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
115pub enum SignatureOperation {
116 Sign,
117 Verify,
118 Revoke,
119 Renew,
120}
121
122pub struct SignaturePerformanceOptimizer {
124 optimization_strategies: Vec<SignatureOptimizationStrategy>,
125 performance_metrics: SignaturePerformanceMetrics,
126}
127
128#[derive(Debug, Clone, PartialEq)]
130pub enum SignatureOptimizationStrategy {
131 BatchSigning,
132 Precomputation,
133 ParallelVerification,
134 Caching,
135 HardwareAcceleration,
136}
137
138#[derive(Debug, Clone)]
140pub struct SignaturePerformanceMetrics {
141 pub average_signing_time: f64,
142 pub average_verification_time: f64,
143 pub throughput: f64,
144 pub error_rate: f64,
145 pub cache_hit_rate: f64,
146}
147impl SignatureEngine {
148 pub fn new() -> Self {
149 Self {
150 signing_algorithms: HashMap::new(),
151 verification_algorithms: HashMap::new(),
152 signature_storage: SignatureStorage::new(),
153 performance_optimizer: SignaturePerformanceOptimizer::new(),
154 }
155 }
156
157 pub fn initialize(&mut self) -> Result<(), CryptographicError> {
158 self.signature_storage.initialize()?;
159 self.performance_optimizer.initialize()?;
160 Ok(())
161 }
162
163 pub fn add_signing_algorithm(&mut self, algorithm: SigningAlgorithm) {
165 self.signing_algorithms
166 .insert(algorithm.key_algorithm, algorithm);
167 }
168
169 pub fn get_signing_algorithm(&self, algorithm: &KeyAlgorithm) -> Option<&SigningAlgorithm> {
171 self.signing_algorithms.get(algorithm)
172 }
173
174 pub fn list_signing_algorithms(&self) -> impl Iterator<Item = &SigningAlgorithm> {
176 self.signing_algorithms.values()
177 }
178
179 pub fn add_verification_algorithm(
181 &mut self,
182 key_algorithm: KeyAlgorithm,
183 algorithm: VerificationAlgorithm,
184 ) {
185 self.verification_algorithms
186 .insert(key_algorithm, algorithm);
187 }
188
189 pub fn get_verification_algorithm(
191 &self,
192 algorithm: &KeyAlgorithm,
193 ) -> Option<&VerificationAlgorithm> {
194 self.verification_algorithms.get(algorithm)
195 }
196
197 pub fn list_verification_algorithms(&self) -> impl Iterator<Item = &VerificationAlgorithm> {
199 self.verification_algorithms.values()
200 }
201
202 fn fiduciary_context() -> CryptoContext {
205 CryptoContext {
206 domain: "qualia.fiduciary".to_string(),
207 purpose: "sign".to_string(),
208 timestamp: 0,
209 nonce: [0u8; 32],
210 }
211 }
212
213 pub fn sign_data(
214 &mut self,
215 private_key: &Key,
216 data: &[u8],
217 ) -> Result<Signature, CryptographicError> {
218 let start_time = std::time::Instant::now();
219
220 let signature_data = match private_key.key_algorithm {
221 KeyAlgorithm::MLDSA => {
222 let ctx = Self::fiduciary_context();
225 let sig = MlDsaSigner::sign_with_secret(&private_key.key_data, data, &ctx)
226 .map_err(|e| {
227 CryptographicError::SignatureError(format!("ML-DSA sign failed: {e}"))
228 })?;
229 sig.sig_bytes
230 }
231 KeyAlgorithm::SPHINCS => {
232 use fips205::slh_dsa_sha2_256s;
233 use fips205::traits::{SerDes, Signer};
234 let sk_arr: [u8; slh_dsa_sha2_256s::SK_LEN] =
235 private_key.key_data.as_slice().try_into().map_err(|_| {
236 CryptographicError::InvalidKey(format!(
237 "SPHINCS secret key must be {} bytes",
238 slh_dsa_sha2_256s::SK_LEN
239 ))
240 })?;
241 let sk = slh_dsa_sha2_256s::PrivateKey::try_from_bytes(&sk_arr)
242 .map_err(|e| CryptographicError::SignatureError(e.to_string()))?;
243 let sig = sk
244 .try_sign(data, b"", true)
245 .map_err(|e| CryptographicError::SignatureError(e.to_string()))?;
246 sig.to_vec()
247 }
248 KeyAlgorithm::ECDSA => {
249 #[cfg(feature = "interop-crypto")]
250 {
251 use crate::fiduciary_crypto::InteropEcdsaSigner;
252 let signer = InteropEcdsaSigner::from_secret_key(&private_key.key_data)
253 .map_err(|e| CryptographicError::SignatureError(e.to_string()))?;
254 let sig = signer
255 .sign(data)
256 .map_err(|e| CryptographicError::SignatureError(e.to_string()))?;
257 sig.sig_bytes
258 }
259 #[cfg(not(feature = "interop-crypto"))]
260 {
261 return Err(CryptographicError::UnsupportedAlgorithm(
262 "ECDSA requires interop-crypto feature".to_string(),
263 ));
264 }
265 }
266 KeyAlgorithm::RSA => {
267 #[cfg(feature = "interop-crypto")]
268 {
269 use rsa::pkcs1v15::SigningKey;
270 use rsa::sha2::Sha256;
271 use rsa::signature::{SignatureEncoding, Signer};
272 use rsa::{pkcs8::DecodePrivateKey, RsaPrivateKey};
273 let priv_key = RsaPrivateKey::from_pkcs8_der(&private_key.key_data)
274 .map_err(|e| CryptographicError::SignatureError(e.to_string()))?;
275 let signing_key = SigningKey::<Sha256>::new(priv_key);
276 signing_key.sign(data).to_bytes().to_vec()
277 }
278 #[cfg(not(feature = "interop-crypto"))]
279 {
280 return Err(CryptographicError::UnsupportedAlgorithm(
281 "RSA requires interop-crypto feature".to_string(),
282 ));
283 }
284 }
285 _ => {
286 let hash = self.compute_data_hash(data)?;
288 self.sign_hash(&private_key, &hash)?
289 }
290 };
291
292 let signature = Signature {
293 signature_id: format!(
294 "sig_{}",
295 std::time::SystemTime::now()
296 .duration_since(std::time::UNIX_EPOCH)
297 .unwrap()
298 .as_secs()
299 ),
300 key_id: private_key.key_id.clone(),
301 algorithm: private_key.key_algorithm.clone(),
302 data: data.to_vec(),
303 signature: signature_data,
304 timestamp: start_time.elapsed().as_millis() as u64,
305 };
306
307 self.signature_storage.store_signature(signature.clone())?;
309
310 self.signature_storage.audit_log.log_entry(
312 &signature.signature_id,
313 SignatureOperation::Sign,
314 "system",
315 true,
316 );
317
318 self.performance_optimizer
320 .record_signing_time(start_time.elapsed().as_millis() as f64);
321
322 Ok(signature)
323 }
324
325 pub fn verify_signature(
326 &mut self,
327 public_key: &Key,
328 signature: &Signature,
329 data: &[u8],
330 ) -> Result<bool, CryptographicError> {
331 let start_time = std::time::Instant::now();
332
333 let is_valid = match public_key.key_algorithm {
334 KeyAlgorithm::MLDSA => {
335 let ctx = Self::fiduciary_context();
336 let sig = MlDsaSignature {
337 sig_bytes: signature.signature.clone(),
338 };
339 MlDsaSigner::verify_with_public(&public_key.key_data, data, &sig, &ctx).map_err(
340 |e| CryptographicError::SignatureError(format!("ML-DSA verify failed: {e}")),
341 )?
342 }
343 KeyAlgorithm::SPHINCS => {
344 use fips205::slh_dsa_sha2_256s;
345 use fips205::traits::{SerDes, Verifier};
346 let pk_arr: [u8; slh_dsa_sha2_256s::PK_LEN] =
347 public_key.key_data.as_slice().try_into().map_err(|_| {
348 CryptographicError::InvalidKey(format!(
349 "SPHINCS public key must be {} bytes",
350 slh_dsa_sha2_256s::PK_LEN
351 ))
352 })?;
353 let pk = slh_dsa_sha2_256s::PublicKey::try_from_bytes(&pk_arr)
354 .map_err(|e| CryptographicError::SignatureError(e.to_string()))?;
355 if signature.signature.len() != slh_dsa_sha2_256s::SIG_LEN {
356 return Ok(false);
357 }
358 let mut sig_arr = [0u8; slh_dsa_sha2_256s::SIG_LEN];
359 sig_arr.copy_from_slice(&signature.signature);
360 pk.verify(data, &sig_arr, b"")
361 }
362 KeyAlgorithm::ECDSA => {
363 #[cfg(feature = "interop-crypto")]
364 {
365 use crate::fiduciary_crypto::{InteropEcdsaSignature, InteropEcdsaSigner};
366 let signer = InteropEcdsaSigner::from_public_key(&public_key.key_data)
367 .map_err(|e| CryptographicError::SignatureError(e.to_string()))?;
368 let sig = InteropEcdsaSignature {
369 sig_bytes: signature.signature.clone(),
370 };
371 signer
372 .verify(data, &sig)
373 .map_err(|e| CryptographicError::SignatureError(e.to_string()))?
374 }
375 #[cfg(not(feature = "interop-crypto"))]
376 {
377 return Err(CryptographicError::UnsupportedAlgorithm(
378 "ECDSA requires interop-crypto feature".to_string(),
379 ));
380 }
381 }
382 KeyAlgorithm::RSA => {
383 #[cfg(feature = "interop-crypto")]
384 {
385 use rsa::pkcs1v15::{Signature as RsaSignature, VerifyingKey};
386 use rsa::sha2::Sha256;
387 use rsa::signature::Verifier;
388 use rsa::{pkcs8::DecodePublicKey, RsaPublicKey};
389 let pub_key = RsaPublicKey::from_public_key_der(&public_key.key_data)
390 .map_err(|e| CryptographicError::SignatureError(e.to_string()))?;
391 let verifying_key = VerifyingKey::<Sha256>::new(pub_key);
392 let sig = RsaSignature::try_from(signature.signature.as_slice())
393 .map_err(|e| CryptographicError::SignatureError(e.to_string()))?;
394 verifying_key.verify(data, &sig).is_ok()
395 }
396 #[cfg(not(feature = "interop-crypto"))]
397 {
398 return Err(CryptographicError::UnsupportedAlgorithm(
399 "RSA requires interop-crypto feature".to_string(),
400 ));
401 }
402 }
403 _ => {
404 let hash = self.compute_data_hash(data)?;
405 self.verify_hash_signature(&public_key, &signature.signature, &hash)?
406 }
407 };
408
409 let verification_record = VerificationRecord {
411 verification_id: format!(
412 "verif_{}",
413 std::time::SystemTime::now()
414 .duration_since(std::time::UNIX_EPOCH)
415 .unwrap()
416 .as_secs()
417 ),
418 signature_id: signature.signature_id.clone(),
419 verifier_id: "system".to_string(),
420 result: VerificationResult {
421 valid: is_valid,
422 error_message: None,
423 verification_time: start_time.elapsed().as_millis() as u64,
424 confidence: 1.0,
425 },
426 timestamp: start_time.elapsed().as_millis() as u64,
427 };
428
429 self.signature_storage
430 .store_verification_record(verification_record)?;
431
432 self.signature_storage.audit_log.log_entry(
434 &signature.signature_id,
435 SignatureOperation::Verify,
436 "system",
437 is_valid,
438 );
439
440 self.performance_optimizer
442 .record_verification_time(start_time.elapsed().as_millis() as f64);
443 if !is_valid {
444 self.performance_optimizer.record_error();
445 }
446
447 Ok(is_valid)
448 }
449
450 fn compute_data_hash(&self, data: &[u8]) -> Result<Vec<u8>, CryptographicError> {
451 use sha2::{Digest, Sha256};
453 let mut hasher = Sha256::new();
454 hasher.update(data);
455 Ok(hasher.finalize().to_vec())
456 }
457
458 fn sign_hash(&self, private_key: &Key, hash: &[u8]) -> Result<Vec<u8>, CryptographicError> {
459 use ed25519_dalek::{Signer, SigningKey};
460 if private_key.key_data.len() < 32 {
461 return Err(CryptographicError::InvalidKey(
462 "Private key too short for signing".to_string(),
463 ));
464 }
465 let mut seed = [0u8; 32];
466 seed.copy_from_slice(&private_key.key_data[..32]);
467 let signing_key = SigningKey::from_bytes(&seed);
468 let sig = signing_key.sign(hash);
469 Ok(sig.to_bytes().to_vec())
470 }
471
472 fn verify_hash_signature(
473 &self,
474 public_key: &Key,
475 signature: &[u8],
476 hash: &[u8],
477 ) -> Result<bool, CryptographicError> {
478 use ed25519_dalek::{Signature, Verifier, VerifyingKey};
479 if public_key.key_data.len() < 32 {
480 return Err(CryptographicError::InvalidKey(
481 "Public key too short for verification".to_string(),
482 ));
483 }
484 let mut key_bytes = [0u8; 32];
485 key_bytes.copy_from_slice(&public_key.key_data[..32]);
486 let verifying_key = VerifyingKey::from_bytes(&key_bytes)
487 .map_err(|e| CryptographicError::InvalidKey(e.to_string()))?;
488 if signature.len() != 64 {
489 return Ok(false);
490 }
491 let mut sig_bytes = [0u8; 64];
492 sig_bytes.copy_from_slice(signature);
493 let sig = Signature::from_bytes(&sig_bytes);
494 Ok(verifying_key.verify(hash, &sig).is_ok())
495 }
496}
497
498impl SignatureStorage {
499 pub fn new() -> Self {
500 Self {
501 signatures: HashMap::new(),
502 verification_records: HashMap::new(),
503 audit_log: SignatureAuditLog::new(),
504 }
505 }
506
507 pub fn initialize(&mut self) -> Result<(), CryptographicError> {
508 Ok(())
509 }
510
511 pub fn store_signature(&mut self, signature: Signature) -> Result<(), CryptographicError> {
512 self.signatures
513 .insert(signature.signature_id.clone(), signature);
514 Ok(())
515 }
516
517 pub fn store_verification_record(
518 &mut self,
519 record: VerificationRecord,
520 ) -> Result<(), CryptographicError> {
521 self.verification_records
522 .insert(record.verification_id.clone(), record);
523 Ok(())
524 }
525}
526
527impl SignatureAuditLog {
528 pub fn new() -> Self {
529 Self {
530 entries: Vec::new(),
531 retention_policy: RetentionPolicy {
532 retention_days: 365,
533 auto_delete: true,
534 archive_before_delete: true,
535 },
536 }
537 }
538
539 pub fn log_entry(
541 &mut self,
542 signature_id: &str,
543 operation: SignatureOperation,
544 user_id: &str,
545 success: bool,
546 ) {
547 let timestamp = std::time::SystemTime::now()
548 .duration_since(std::time::UNIX_EPOCH)
549 .unwrap_or_default()
550 .as_secs();
551 let entry = SignatureAuditEntry {
552 entry_id: format!("sig_{}_{}", timestamp, self.entries.len()),
553 timestamp,
554 signature_id: signature_id.to_string(),
555 operation,
556 user_id: user_id.to_string(),
557 ip_address: String::new(),
558 success,
559 };
560 self.entries.push(entry);
561 let cutoff =
562 timestamp.saturating_sub((self.retention_policy.retention_days as u64) * 86400);
563 self.entries.retain(|e| e.timestamp >= cutoff);
564 }
565
566 pub fn entry_count(&self) -> usize {
568 self.entries.len()
569 }
570
571 pub fn entries(&self) -> &[SignatureAuditEntry] {
573 &self.entries
574 }
575}
576
577impl SignaturePerformanceOptimizer {
578 pub fn new() -> Self {
579 Self {
580 optimization_strategies: vec![
581 SignatureOptimizationStrategy::BatchSigning,
582 SignatureOptimizationStrategy::Caching,
583 ],
584 performance_metrics: SignaturePerformanceMetrics {
585 average_signing_time: 0.0,
586 average_verification_time: 0.0,
587 throughput: 0.0,
588 error_rate: 0.0,
589 cache_hit_rate: 0.0,
590 },
591 }
592 }
593
594 pub fn initialize(&mut self) -> Result<(), CryptographicError> {
595 Ok(())
596 }
597
598 pub fn optimization_strategies(&self) -> &[SignatureOptimizationStrategy] {
600 &self.optimization_strategies
601 }
602
603 pub fn add_optimization_strategy(&mut self, strategy: SignatureOptimizationStrategy) {
605 if !self.optimization_strategies.contains(&strategy) {
606 self.optimization_strategies.push(strategy);
607 }
608 }
609
610 pub fn record_signing_time(&mut self, duration_ms: f64) {
612 let m = &mut self.performance_metrics;
613 if m.average_signing_time == 0.0 {
614 m.average_signing_time = duration_ms;
615 } else {
616 m.average_signing_time = 0.9 * m.average_signing_time + 0.1 * duration_ms;
618 }
619 if duration_ms > 0.0 {
620 m.throughput = 1000.0 / m.average_signing_time;
621 }
622 }
623
624 pub fn record_verification_time(&mut self, duration_ms: f64) {
626 let m = &mut self.performance_metrics;
627 if m.average_verification_time == 0.0 {
628 m.average_verification_time = duration_ms;
629 } else {
630 m.average_verification_time = 0.9 * m.average_verification_time + 0.1 * duration_ms;
631 }
632 }
633
634 pub fn record_error(&mut self) {
636 let m = &mut self.performance_metrics;
637 m.error_rate = 0.95 * m.error_rate + 0.05;
639 }
640
641 pub fn metrics(&self) -> &SignaturePerformanceMetrics {
643 &self.performance_metrics
644 }
645}
646
647impl SignaturePerformanceMetrics {
648 pub fn new() -> Self {
649 Self {
650 average_signing_time: 0.0,
651 average_verification_time: 0.0,
652 throughput: 0.0,
653 error_rate: 0.0,
654 cache_hit_rate: 0.0,
655 }
656 }
657}