Skip to main content

ruvector_dag/qudag/crypto/
security_notice.rs

1//! # Security Notice for QuDAG Cryptography
2//!
3//! ## Security Status
4//!
5//! | Component | With `production-crypto` | Without Feature |
6//! |-----------|-------------------------|-----------------|
7//! | ML-DSA-65 | ✓ Dilithium3 (NIST PQC) | ✗ HMAC-SHA256 placeholder |
8//! | ML-KEM-768 | ✓ Kyber768 (NIST PQC) | ✗ HKDF-SHA256 placeholder |
9//! | Differential Privacy | ✓ Production-ready | ✓ Production-ready |
10//! | Keystore | ✓ Uses zeroize | ✓ Uses zeroize |
11//!
12//! ## Enabling Production Cryptography
13//!
14//! Add to your Cargo.toml:
15//! ```toml
16//! ruvector-dag = { version = "0.1", features = ["production-crypto"] }
17//! ```
18//!
19//! ## NIST Post-Quantum Cryptography Standards
20//!
21//! - **FIPS 203**: ML-KEM (Module-Lattice Key Encapsulation Mechanism)
22//! - **FIPS 204**: ML-DSA (Module-Lattice Digital Signature Algorithm)
23//!
24//! The `production-crypto` feature uses:
25//! - `pqcrypto-dilithium` (Dilithium3 ≈ ML-DSA-65 security level)
26//! - `pqcrypto-kyber` (Kyber768 ≈ ML-KEM-768 security level)
27//!
28//! ## Security Contact
29//!
30//! Report security issues to: security@ruvector.io
31
32use super::{ml_dsa, ml_kem};
33
34/// Check cryptographic security at startup
35///
36/// Call this function during application initialization to log
37/// warnings about placeholder crypto usage.
38///
39/// # Example
40///
41/// ```rust,ignore
42/// fn main() {
43///     ruvector_dag::qudag::crypto::check_crypto_security();
44///     // ... rest of application
45/// }
46/// ```
47#[cold]
48pub fn check_crypto_security() {
49    let status = security_status();
50
51    if status.production_ready {
52        tracing::info!("✓ QuDAG cryptography: Production mode enabled (Dilithium3 + Kyber768)");
53    } else {
54        tracing::warn!(
55            "⚠️ SECURITY WARNING: Using placeholder cryptography. \
56             NOT suitable for production. Enable 'production-crypto' feature."
57        );
58        tracing::warn!(
59            "   ML-DSA: {} | ML-KEM: {}",
60            if status.ml_dsa_ready {
61                "Ready"
62            } else {
63                "PLACEHOLDER"
64            },
65            if status.ml_kem_ready {
66                "Ready"
67            } else {
68                "PLACEHOLDER"
69            }
70        );
71    }
72}
73
74/// Runtime check for production readiness
75pub fn is_production_ready() -> bool {
76    ml_dsa::is_production() && ml_kem::is_production()
77}
78
79/// Get detailed security status report
80pub fn security_status() -> SecurityStatus {
81    let ml_dsa_ready = ml_dsa::is_production();
82    let ml_kem_ready = ml_kem::is_production();
83
84    SecurityStatus {
85        ml_dsa_ready,
86        ml_kem_ready,
87        dp_ready: true,
88        keystore_ready: true,
89        production_ready: ml_dsa_ready && ml_kem_ready,
90    }
91}
92
93/// Security status of cryptographic components
94#[derive(Debug, Clone)]
95pub struct SecurityStatus {
96    /// ML-DSA-65 uses real implementation (Dilithium3)
97    pub ml_dsa_ready: bool,
98    /// ML-KEM-768 uses real implementation (Kyber768)
99    pub ml_kem_ready: bool,
100    /// Differential privacy is properly implemented
101    pub dp_ready: bool,
102    /// Keystore uses proper zeroization
103    pub keystore_ready: bool,
104    /// Overall production readiness
105    pub production_ready: bool,
106}
107
108impl std::fmt::Display for SecurityStatus {
109    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
110        writeln!(f, "QuDAG Cryptography Security Status:")?;
111        writeln!(
112            f,
113            "  ML-DSA-65:  {} ({})",
114            if self.ml_dsa_ready { "✓" } else { "✗" },
115            if self.ml_dsa_ready {
116                "Dilithium3"
117            } else {
118                "PLACEHOLDER"
119            }
120        )?;
121        writeln!(
122            f,
123            "  ML-KEM-768: {} ({})",
124            if self.ml_kem_ready { "✓" } else { "✗" },
125            if self.ml_kem_ready {
126                "Kyber768"
127            } else {
128                "PLACEHOLDER"
129            }
130        )?;
131        writeln!(
132            f,
133            "  DP:         {} ({})",
134            if self.dp_ready { "✓" } else { "✗" },
135            if self.dp_ready { "Ready" } else { "Not Ready" }
136        )?;
137        writeln!(
138            f,
139            "  Keystore:   {} ({})",
140            if self.keystore_ready { "✓" } else { "✗" },
141            if self.keystore_ready {
142                "Ready"
143            } else {
144                "Not Ready"
145            }
146        )?;
147        writeln!(f)?;
148        writeln!(
149            f,
150            "  OVERALL:    {}",
151            if self.production_ready {
152                "✓ PRODUCTION READY (Post-Quantum Secure)"
153            } else {
154                "✗ NOT PRODUCTION READY - Enable 'production-crypto' feature"
155            }
156        )
157    }
158}
159
160#[cfg(test)]
161mod tests {
162    use super::*;
163
164    #[test]
165    fn test_security_status() {
166        let status = security_status();
167        // These should always be ready
168        assert!(status.dp_ready);
169        assert!(status.keystore_ready);
170
171        // ML-DSA and ML-KEM depend on feature flag
172        #[cfg(feature = "production-crypto")]
173        {
174            assert!(status.ml_dsa_ready);
175            assert!(status.ml_kem_ready);
176            assert!(status.production_ready);
177        }
178
179        #[cfg(not(feature = "production-crypto"))]
180        {
181            assert!(!status.ml_dsa_ready);
182            assert!(!status.ml_kem_ready);
183            assert!(!status.production_ready);
184        }
185    }
186
187    #[test]
188    fn test_is_production_ready() {
189        #[cfg(feature = "production-crypto")]
190        assert!(is_production_ready());
191
192        #[cfg(not(feature = "production-crypto"))]
193        assert!(!is_production_ready());
194    }
195
196    #[test]
197    fn test_display() {
198        let status = security_status();
199        let display = format!("{}", status);
200        assert!(display.contains("QuDAG Cryptography Security Status"));
201        assert!(display.contains("ML-DSA-65"));
202        assert!(display.contains("ML-KEM-768"));
203    }
204}