saorsa_core/quantum_crypto/
mod.rs

1// Copyright 2024 Saorsa Labs Limited
2//
3// This software is dual-licensed under:
4// - GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later)
5// - Commercial License
6//
7// For AGPL-3.0 license, see LICENSE-AGPL-3.0
8// For commercial licensing, contact: saorsalabs@gmail.com
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under these licenses is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
14//! Quantum-resistant cryptography module
15//!
16//! This module provides post-quantum cryptographic primitives including:
17//! - ML-KEM (Module-Lattice Key Encapsulation Mechanism) for key exchange
18//! - ML-DSA (Module-Lattice Digital Signature Algorithm) for signatures
19//! - Hybrid modes for gradual migration from classical algorithms
20
21pub mod ant_quic_integration;
22pub mod hybrid;
23pub mod types;
24
25// NOTE: Not using wildcard import to avoid conflicts with ant-quic types
26// Selectively re-export only non-conflicting types from our types module
27pub use self::types::{
28    Ed25519PrivateKey, Ed25519PublicKey, Ed25519Signature, FrostCommitment, FrostGroupPublicKey,
29    FrostKeyShare, FrostPublicKey, FrostSignature, GroupId, HandshakeParameters, ParticipantId,
30    PeerId, QuantumPeerIdentity, SecureSession, SessionId, SessionState,
31};
32
33// Re-export all ant-quic PQC functions for convenience
34pub use self::ant_quic_integration::{
35    // Configuration functions
36    create_default_pqc_config,
37    // Performance optimization
38    create_pqc_memory_pool,
39    create_pqc_only_config,
40    // Hybrid functions
41    generate_hybrid_kem_keypair,
42    generate_hybrid_signature_keypair,
43    // ML-DSA functions
44    generate_ml_dsa_keypair,
45    // ML-KEM functions
46    generate_ml_kem_keypair,
47    hybrid_kem_decapsulate,
48    hybrid_kem_encapsulate,
49    hybrid_sign,
50    hybrid_verify,
51    ml_dsa_sign,
52    ml_dsa_verify,
53    ml_kem_decapsulate,
54    ml_kem_encapsulate,
55};
56
57use serde::{Deserialize, Serialize};
58use thiserror::Error;
59
60// Primary post-quantum cryptography types from saorsa-pqc 0.3.0
61pub use saorsa_pqc::{
62    // Symmetric encryption (quantum-resistant)
63    ChaCha20Poly1305Cipher,
64    // Encrypted message types
65    EncryptedMessage,
66    // Hybrid modes (classical + post-quantum)
67    HybridKem,
68    HybridPublicKeyEncryption,
69
70    HybridSignature,
71    MlDsa65,
72
73    MlDsaOperations,
74
75    // Algorithm implementations
76    MlKem768,
77    // Core traits for operations
78    MlKemOperations,
79    SymmetricEncryptedMessage,
80
81    // Errors
82    SymmetricError,
83
84    SymmetricKey,
85
86    // Library initialization
87    init as saorsa_pqc_init,
88    // Types and results
89    pqc::types::{
90        HybridKemCiphertext, HybridKemPublicKey, HybridKemSecretKey, HybridSignaturePublicKey,
91        HybridSignatureSecretKey, HybridSignatureValue, MlDsaPublicKey, MlDsaSecretKey,
92        MlDsaSignature, MlKemCiphertext, MlKemPublicKey, MlKemSecretKey, PqcError,
93        PqcResult as SaorsaPqcResult, SharedSecret,
94    },
95};
96
97/// Quantum cryptography errors
98#[derive(Debug, Error)]
99pub enum QuantumCryptoError {
100    #[error("ML-KEM error: {0}")]
101    MlKemError(String),
102
103    #[error("ML-DSA error: {0}")]
104    MlDsaError(String),
105
106    #[error("Key generation failed: {0}")]
107    KeyGenerationError(String),
108
109    #[error("Invalid key material: {0}")]
110    InvalidKeyError(String),
111
112    #[error("Signature verification failed")]
113    SignatureVerificationFailed,
114
115    #[error("Encapsulation failed: {0}")]
116    EncapsulationError(String),
117
118    #[error("Decapsulation failed: {0}")]
119    DecapsulationError(String),
120
121    #[error("Unsupported algorithm: {0}")]
122    UnsupportedAlgorithm(String),
123}
124
125/// Result type for quantum crypto operations
126pub type Result<T> = std::result::Result<T, QuantumCryptoError>;
127
128/// Cryptographic algorithm capabilities
129#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
130pub struct CryptoCapabilities {
131    pub supports_ml_kem: bool,
132    pub supports_ml_dsa: bool,
133    pub supports_frost: bool,
134    pub supports_hybrid: bool,
135    pub threshold_capable: bool,
136    pub supported_versions: Vec<ProtocolVersion>,
137}
138
139impl Default for CryptoCapabilities {
140    fn default() -> Self {
141        Self {
142            supports_ml_kem: true,
143            supports_ml_dsa: true,
144            supports_frost: true,
145            supports_hybrid: true,
146            threshold_capable: true,
147            supported_versions: vec![ProtocolVersion::V1, ProtocolVersion::V2],
148        }
149    }
150}
151
152/// Protocol version for algorithm negotiation
153#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
154pub enum ProtocolVersion {
155    /// Initial version with ML-KEM-768 and ML-DSA-65
156    V1,
157    /// Enhanced version with additional algorithms
158    V2,
159}
160
161/// Signature scheme selection
162#[derive(Debug, Clone, Serialize, Deserialize)]
163pub enum SignatureScheme {
164    /// Classical Ed25519 signatures (for backward compatibility)
165    Classical(Vec<u8>),
166
167    /// Post-quantum ML-DSA signatures
168    PostQuantum(Vec<u8>),
169
170    /// Dual signatures for hybrid mode
171    Dual {
172        classical: Vec<u8>,
173        post_quantum: Vec<u8>,
174    },
175}
176
177// NOTE: SignatureScheme::verify method removed - use ant-quic PQC verify functions directly:
178// - ml_dsa_verify(public_key: &MlDsaPublicKey, message: &[u8], signature: &MlDsaSignature)
179// - For Ed25519: use ed25519_verify from this module
180// These are re-exported from ant_quic_integration module
181
182impl SignatureScheme {
183    // verify method removed - see note above
184}
185
186// NOTE: PublicKeySet and PrivateKeySet removed - use ant-quic PQC types directly
187
188// NOTE: KeyPair struct and generate_keypair function removed to avoid conflicts
189// Use ant-quic PQC functions directly:
190// - generate_ml_dsa_keypair() -> (MlDsaPublicKey, MlDsaSecretKey)
191// - generate_ml_kem_keypair() -> (MlKemPublicKey, MlKemSecretKey)
192// - For Ed25519: generate_ed25519_keypair() below
193//
194// These functions are re-exported from ant_quic_integration module
195
196/// Generate Ed25519 keypair (placeholder for actual implementation)
197#[allow(dead_code)]
198fn generate_ed25519_keypair() -> Result<(Vec<u8>, Vec<u8>)> {
199    use ed25519_dalek::SigningKey;
200    use rand::rngs::OsRng;
201
202    let signing_key = SigningKey::generate(&mut OsRng);
203    let public_key = signing_key.verifying_key().to_bytes().to_vec();
204
205    // Create 64-byte private key (signing key + public key)
206    let mut private_key = vec![0u8; 64];
207    private_key[..32].copy_from_slice(&signing_key.to_bytes());
208    private_key[32..].copy_from_slice(&public_key);
209
210    Ok((public_key, private_key))
211}
212
213/// Algorithm negotiation for establishing connections
214pub fn negotiate_algorithms(
215    local_caps: &CryptoCapabilities,
216    remote_caps: &CryptoCapabilities,
217) -> Result<NegotiatedAlgorithms> {
218    // Find common supported algorithms
219    let use_ml_kem = local_caps.supports_ml_kem && remote_caps.supports_ml_kem;
220    let use_ml_dsa = local_caps.supports_ml_dsa && remote_caps.supports_ml_dsa;
221    let use_hybrid = local_caps.supports_hybrid && remote_caps.supports_hybrid;
222
223    // Find common protocol version
224    let version = local_caps
225        .supported_versions
226        .iter()
227        .find(|v| remote_caps.supported_versions.contains(v))
228        .copied()
229        .ok_or_else(|| {
230            QuantumCryptoError::UnsupportedAlgorithm("No common protocol version".to_string())
231        })?;
232
233    Ok(NegotiatedAlgorithms {
234        kem_algorithm: if use_ml_kem {
235            KemAlgorithm::MlKem768
236        } else {
237            KemAlgorithm::ClassicalEcdh
238        },
239        signature_algorithm: if use_ml_dsa {
240            SignatureAlgorithm::MlDsa65
241        } else {
242            SignatureAlgorithm::Ed25519
243        },
244        hybrid_mode: use_hybrid,
245        protocol_version: version,
246    })
247}
248
249/// Negotiated algorithm set
250#[derive(Debug, Clone, Serialize, Deserialize)]
251pub struct NegotiatedAlgorithms {
252    pub kem_algorithm: KemAlgorithm,
253    pub signature_algorithm: SignatureAlgorithm,
254    pub hybrid_mode: bool,
255    pub protocol_version: ProtocolVersion,
256}
257
258/// Key encapsulation mechanism algorithm
259#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
260pub enum KemAlgorithm {
261    MlKem768,
262    ClassicalEcdh,
263}
264
265/// Signature algorithm
266#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
267pub enum SignatureAlgorithm {
268    MlDsa65,
269    Ed25519,
270}
271
272#[cfg(test)]
273mod tests {
274    use super::*;
275
276    #[test]
277    fn test_saorsa_pqc_availability() {
278        // Test that saorsa-pqc types are available and can be instantiated
279        let _ml_kem = MlKem768::default();
280        let _ml_dsa = MlDsa65::default();
281        let _hybrid_kem = HybridKem::default();
282        let _hybrid_sig = HybridSignature::default();
283        let _hybrid_pke = HybridPublicKeyEncryption::default();
284
285        println!("✅ saorsa-pqc 0.3.0 types are available");
286        println!("✅ Confirmed we are using saorsa-pqc effectively");
287        println!("✅ ChaCha20Poly1305 integration ready for use");
288    }
289
290    #[test]
291    fn test_algorithm_negotiation() {
292        let local_caps = CryptoCapabilities::default();
293        let remote_caps = CryptoCapabilities {
294            supports_ml_kem: true,
295            supports_ml_dsa: false,
296            supports_frost: false,
297            supports_hybrid: true,
298            threshold_capable: false,
299            supported_versions: vec![ProtocolVersion::V1],
300        };
301
302        let negotiated = negotiate_algorithms(&local_caps, &remote_caps).unwrap();
303        assert_eq!(negotiated.kem_algorithm, KemAlgorithm::MlKem768);
304        assert_eq!(negotiated.signature_algorithm, SignatureAlgorithm::Ed25519);
305        assert!(negotiated.hybrid_mode);
306    }
307}