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 hybrid;
22// Legacy modules deprecated - use ant-quic PQC functions directly
23// pub mod ml_dsa;
24// pub mod ml_kem;
25pub mod types;
26pub mod ant_quic_integration;
27
28// NOTE: Not using wildcard import to avoid conflicts with ant-quic types
29// Selectively re-export only non-conflicting types from our types module
30pub use self::types::{
31    GroupId, ParticipantId, PeerId, SessionId, QuantumPeerIdentity, 
32    SecureSession, SessionState, HandshakeParameters, HybridSignature,
33    Ed25519PublicKey, Ed25519PrivateKey, Ed25519Signature,
34    FrostPublicKey, FrostGroupPublicKey, FrostKeyShare, FrostCommitment, FrostSignature,
35};
36
37
38use serde::{Deserialize, Serialize};
39use thiserror::Error;
40
41/// Quantum cryptography errors
42#[derive(Debug, Error)]
43pub enum QuantumCryptoError {
44    #[error("ML-KEM error: {0}")]
45    MlKemError(String),
46
47    #[error("ML-DSA error: {0}")]
48    MlDsaError(String),
49
50    #[error("Key generation failed: {0}")]
51    KeyGenerationError(String),
52
53    #[error("Invalid key material: {0}")]
54    InvalidKeyError(String),
55
56    #[error("Signature verification failed")]
57    SignatureVerificationFailed,
58
59    #[error("Encapsulation failed: {0}")]
60    EncapsulationError(String),
61
62    #[error("Decapsulation failed: {0}")]
63    DecapsulationError(String),
64
65    #[error("Unsupported algorithm: {0}")]
66    UnsupportedAlgorithm(String),
67}
68
69/// Result type for quantum crypto operations
70pub type Result<T> = std::result::Result<T, QuantumCryptoError>;
71
72/// Cryptographic algorithm capabilities
73#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
74pub struct CryptoCapabilities {
75    pub supports_ml_kem: bool,
76    pub supports_ml_dsa: bool,
77    pub supports_frost: bool,
78    pub supports_hybrid: bool,
79    pub threshold_capable: bool,
80    pub supported_versions: Vec<ProtocolVersion>,
81}
82
83impl Default for CryptoCapabilities {
84    fn default() -> Self {
85        Self {
86            supports_ml_kem: true,
87            supports_ml_dsa: true,
88            supports_frost: true,
89            supports_hybrid: true,
90            threshold_capable: true,
91            supported_versions: vec![ProtocolVersion::V1, ProtocolVersion::V2],
92        }
93    }
94}
95
96/// Protocol version for algorithm negotiation
97#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
98pub enum ProtocolVersion {
99    /// Initial version with ML-KEM-768 and ML-DSA-65
100    V1,
101    /// Enhanced version with additional algorithms
102    V2,
103}
104
105/// Signature scheme selection
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub enum SignatureScheme {
108    /// Classical Ed25519 signatures (for backward compatibility)
109    Classical(Vec<u8>),
110
111    /// Post-quantum ML-DSA signatures
112    PostQuantum(Vec<u8>),
113
114    /// Dual signatures for hybrid mode
115    Dual {
116        classical: Vec<u8>,
117        post_quantum: Vec<u8>,
118    },
119}
120
121// NOTE: SignatureScheme::verify method removed - use ant-quic PQC verify functions directly:
122// - ml_dsa_verify(public_key: &MlDsaPublicKey, message: &[u8], signature: &MlDsaSignature)
123// - For Ed25519: use ed25519_verify from this module
124// These are re-exported from ant_quic_integration module
125
126impl SignatureScheme {
127    // verify method removed - see note above
128}
129
130// NOTE: PublicKeySet and PrivateKeySet removed - use ant-quic PQC types directly
131
132// NOTE: KeyPair struct and generate_keypair function removed to avoid conflicts
133// Use ant-quic PQC functions directly:
134// - generate_ml_dsa_keypair() -> (MlDsaPublicKey, MlDsaSecretKey)
135// - generate_ml_kem_keypair() -> (MlKemPublicKey, MlKemSecretKey) 
136// - For Ed25519: generate_ed25519_keypair() below
137//
138// These functions are re-exported from ant_quic_integration module
139
140/// Generate Ed25519 keypair (placeholder for actual implementation)
141fn generate_ed25519_keypair() -> Result<(Vec<u8>, Vec<u8>)> {
142    use ed25519_dalek::SigningKey;
143    use rand::rngs::OsRng;
144
145    let signing_key = SigningKey::generate(&mut OsRng);
146    let public_key = signing_key.verifying_key().to_bytes().to_vec();
147
148    // Create 64-byte private key (signing key + public key)
149    let mut private_key = vec![0u8; 64];
150    private_key[..32].copy_from_slice(&signing_key.to_bytes());
151    private_key[32..].copy_from_slice(&public_key);
152
153    Ok((public_key, private_key))
154}
155
156/// Algorithm negotiation for establishing connections
157pub fn negotiate_algorithms(
158    local_caps: &CryptoCapabilities,
159    remote_caps: &CryptoCapabilities,
160) -> Result<NegotiatedAlgorithms> {
161    // Find common supported algorithms
162    let use_ml_kem = local_caps.supports_ml_kem && remote_caps.supports_ml_kem;
163    let use_ml_dsa = local_caps.supports_ml_dsa && remote_caps.supports_ml_dsa;
164    let use_hybrid = local_caps.supports_hybrid && remote_caps.supports_hybrid;
165
166    // Find common protocol version
167    let version = local_caps
168        .supported_versions
169        .iter()
170        .find(|v| remote_caps.supported_versions.contains(v))
171        .copied()
172        .ok_or_else(|| {
173            QuantumCryptoError::UnsupportedAlgorithm("No common protocol version".to_string())
174        })?;
175
176    Ok(NegotiatedAlgorithms {
177        kem_algorithm: if use_ml_kem {
178            KemAlgorithm::MlKem768
179        } else {
180            KemAlgorithm::ClassicalEcdh
181        },
182        signature_algorithm: if use_ml_dsa {
183            SignatureAlgorithm::MlDsa65
184        } else {
185            SignatureAlgorithm::Ed25519
186        },
187        hybrid_mode: use_hybrid,
188        protocol_version: version,
189    })
190}
191
192/// Negotiated algorithm set
193#[derive(Debug, Clone, Serialize, Deserialize)]
194pub struct NegotiatedAlgorithms {
195    pub kem_algorithm: KemAlgorithm,
196    pub signature_algorithm: SignatureAlgorithm,
197    pub hybrid_mode: bool,
198    pub protocol_version: ProtocolVersion,
199}
200
201/// Key encapsulation mechanism algorithm
202#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
203pub enum KemAlgorithm {
204    MlKem768,
205    ClassicalEcdh,
206}
207
208/// Signature algorithm
209#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
210pub enum SignatureAlgorithm {
211    MlDsa65,
212    Ed25519,
213}
214
215#[cfg(test)]
216mod tests {
217    use super::*;
218
219    #[tokio::test]
220    async fn test_keypair_generation() {
221        // NOTE: Legacy test deprecated - use ant-quic PQC functions directly:
222        // - generate_ml_dsa_keypair() -> (MlDsaPublicKey, MlDsaSecretKey)
223        // - generate_ml_kem_keypair() -> (MlKemPublicKey, MlKemSecretKey)
224        let _caps = CryptoCapabilities::default();
225        // Test deprecated - would need significant rewrite for ant-quic types
226    }
227
228    #[test]
229    fn test_algorithm_negotiation() {
230        let local_caps = CryptoCapabilities::default();
231        let remote_caps = CryptoCapabilities {
232            supports_ml_kem: true,
233            supports_ml_dsa: false,
234            supports_frost: false,
235            supports_hybrid: true,
236            threshold_capable: false,
237            supported_versions: vec![ProtocolVersion::V1],
238        };
239
240        let negotiated = negotiate_algorithms(&local_caps, &remote_caps).unwrap();
241        assert_eq!(negotiated.kem_algorithm, KemAlgorithm::MlKem768);
242        assert_eq!(negotiated.signature_algorithm, SignatureAlgorithm::Ed25519);
243        assert!(negotiated.hybrid_mode);
244    }
245}