1use crate::algorithms::{HybridCrypto, MlDsa44, MlKem768};
21use crate::bridge::{CryptographyBridge, KeyEncapsulationBridge};
22use crate::errors::{CryptoError, Result};
23use crate::types::{
24 Algorithm, ClassicalAlgorithm, HybridKeyPair, HybridPolicy, HybridPublicBundle,
25 PostQuantumAlgorithm, PublicKey, SecurityLevel, TransitionMode,
26};
27use zeroize::Zeroizing;
28
29pub struct QuantumSigner {
31 bridge: MlDsa44,
32 public_key: <MlDsa44 as CryptographyBridge>::PublicKey,
33 secret_key: <MlDsa44 as CryptographyBridge>::SecretKey,
34}
35
36impl QuantumSigner {
37 pub fn new() -> Result<Self> {
39 let bridge = MlDsa44;
40 let (public_key, secret_key) = bridge.key_generator()?;
41 Ok(Self {
42 bridge,
43 public_key,
44 secret_key,
45 })
46 }
47
48 pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>> {
50 let signature = self.bridge.sign(&self.secret_key, message)?;
51 Ok(self.bridge.signature_to_bytes(&signature))
52 }
53
54 pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<bool> {
56 let sig_vec = signature.to_vec();
58 self.bridge.verify(&self.public_key, message, &sig_vec)
59 }
60
61 pub fn public_key_bytes(&self) -> Vec<u8> {
63 self.bridge.public_key_to_bytes(&self.public_key)
64 }
65}
66
67pub struct HybridSigner {
69 hybrid_crypto: HybridCrypto,
70 hybrid_keypair: HybridKeyPair,
71}
72
73impl HybridSigner {
74 pub fn new() -> Result<Self> {
76 let hybrid_crypto = HybridCrypto::new_default();
77 let hybrid_keypair = hybrid_crypto.generate_hybrid_keypair()?;
78 Ok(Self {
79 hybrid_crypto,
80 hybrid_keypair,
81 })
82 }
83
84 pub fn with_policy(policy: HybridPolicy) -> Result<Self> {
86 let hybrid_crypto = HybridCrypto::new(policy);
87 let hybrid_keypair = hybrid_crypto.generate_hybrid_keypair()?;
88 Ok(Self {
89 hybrid_crypto,
90 hybrid_keypair,
91 })
92 }
93
94 pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>> {
95 let signature = self
96 .hybrid_crypto
97 .sign_hybrid(&self.hybrid_keypair, message)?;
98 serde_json::to_vec(&signature).map_err(|_| {
99 CryptoError::SerializationError("Failed to serialize signature".to_string())
100 })
101 }
102
103 pub fn sign_compact(&self, message: &[u8]) -> Result<Vec<u8>> {
106 let compressed_sig = self
107 .hybrid_crypto
108 .sign_hybrid_compressed(&self.hybrid_keypair, message)?;
109 serde_json::to_vec(&compressed_sig).map_err(|_| {
110 CryptoError::SerializationError("Failed to serialize compressed signature".to_string())
111 })
112 }
113
114 pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<bool> {
115 let sig = serde_json::from_slice(signature).map_err(|_| {
116 CryptoError::SerializationError("Failed to deserialize signature".to_string())
117 })?;
118 self.hybrid_crypto
119 .verify_hybrid(&self.hybrid_keypair, message, &sig)
120 }
121
122 pub fn verify_compact(&self, message: &[u8], compressed_signature: &[u8]) -> Result<bool> {
123 let compressed_sig = serde_json::from_slice(compressed_signature).map_err(|_| {
124 CryptoError::SerializationError(
125 "Failed to deserialize compressed signature".to_string(),
126 )
127 })?;
128 self.hybrid_crypto
129 .verify_hybrid_compressed(&self.hybrid_keypair, message, &compressed_sig)
130 }
131
132 pub fn classical_signature(&self, message: &[u8]) -> Result<Vec<u8>> {
134 use crate::algorithms::EcdsaCrypto;
135 let sig = EcdsaCrypto::sign(&self.hybrid_keypair.classical_keypair.private_key, message)?;
136 Ok(sig.bytes)
137 }
138
139 pub fn classical_public_key(&self) -> Vec<u8> {
142 self.hybrid_keypair
143 .classical_keypair
144 .public_key
145 .bytes
146 .clone()
147 }
148
149 pub fn public_keys(&self) -> (&[u8], &[u8]) {
152 (
153 &self.hybrid_keypair.classical_keypair.public_key.bytes,
154 &self.hybrid_keypair.post_quantum_keypair.public_key.bytes,
155 )
156 }
157
158 pub fn public_key_bundle(&self) -> HybridPublicBundle {
161 HybridPublicBundle {
162 classical_public_key: self.hybrid_keypair.classical_keypair.public_key.clone(),
163 post_quantum_public_key: self
164 .hybrid_keypair
165 .post_quantum_keypair
166 .public_key
167 .clone(),
168 security_level: self.hybrid_keypair.security_level,
169 transition_mode: self.hybrid_crypto.get_policy().transition_mode,
170 }
171 }
172
173 pub fn verifier(&self) -> HybridVerifier {
175 HybridVerifier::from_bundle(self.public_key_bundle())
176 }
177}
178
179pub struct QuantumEncryptor {
182 bridge: MlKem768,
183 public_key: <MlKem768 as KeyEncapsulationBridge>::PublicKey,
184 secret_key: <MlKem768 as KeyEncapsulationBridge>::SecretKey,
185}
186
187impl QuantumEncryptor {
188 pub fn new() -> Result<Self> {
189 let bridge = MlKem768;
190 let (public_key, secret_key) = bridge.kem_keygen()?;
191 Ok(Self {
192 bridge,
193 public_key,
194 secret_key,
195 })
196 }
197
198 pub fn encapsulate(&self) -> Result<(Vec<u8>, Vec<u8>)> {
201 let (ciphertext, shared_secret) = self.bridge.encapsulate(&self.public_key)?;
202 use fips203::traits::SerDes;
203 Ok((ciphertext.into_bytes().to_vec(), shared_secret))
204 }
205
206 pub fn decapsulate(&self, ciphertext_bytes: &[u8]) -> Result<Zeroizing<Vec<u8>>> {
207 use fips203::ml_kem_768::{CipherText, CT_LEN};
208 use fips203::traits::SerDes;
209
210 let ct_array: [u8; CT_LEN] = ciphertext_bytes
211 .try_into()
212 .map_err(|_| CryptoError::Generic("Invalid ciphertext size".to_string()))?;
213 let ciphertext = CipherText::try_from_bytes(ct_array)
214 .map_err(|_| CryptoError::Generic("Invalid ciphertext".to_string()))?;
215
216 let shared_secret = self.bridge.decapsulate(&self.secret_key, &ciphertext)?;
217 Ok(Zeroizing::new(shared_secret))
218 }
219
220 pub fn public_key_bytes(&self) -> Vec<u8> {
221 self.bridge.kem_public_key_to_bytes(&self.public_key)
222 }
223}
224
225pub struct QuantumVerifier {
228 public_key: PublicKey,
229}
230
231impl QuantumVerifier {
232 pub fn from_bytes(public_key_bytes: &[u8]) -> Result<Self> {
234 Ok(Self {
235 public_key: PublicKey {
236 bytes: public_key_bytes.to_vec(),
237 algorithm: Algorithm::MlDsa44,
238 },
239 })
240 }
241
242 pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<bool> {
244 use crate::algorithms::MlDsaCrypto;
245 use crate::types::Signature;
246 let sig = Signature { bytes: signature.to_vec(), algorithm: Algorithm::MlDsa44 };
247 MlDsaCrypto::verify(&self.public_key, message, &sig)
248 }
249}
250
251pub struct HybridVerifier {
255 bundle: HybridPublicBundle,
256 hybrid_crypto: HybridCrypto,
257}
258
259impl HybridVerifier {
260 pub fn from_bundle(bundle: HybridPublicBundle) -> Self {
262 let classical_algorithm = match bundle.classical_public_key.algorithm {
263 Algorithm::EcdsaK256 => ClassicalAlgorithm::EcdsaK256,
264 Algorithm::EcdsaP256 => ClassicalAlgorithm::EcdsaP256,
265 Algorithm::Schnorr => ClassicalAlgorithm::Schnorr,
266 _ => ClassicalAlgorithm::EcdsaK256,
267 };
268 let post_quantum_algorithm = match bundle.post_quantum_public_key.algorithm {
269 Algorithm::MlDsa44 => PostQuantumAlgorithm::MlDsa44,
270 Algorithm::SlhDsaSha2128f => PostQuantumAlgorithm::SlhDsaSha2128f,
271 _ => PostQuantumAlgorithm::MlDsa44,
272 };
273 let policy = HybridPolicy {
274 security_level: bundle.security_level,
275 transition_mode: bundle.transition_mode,
276 classical_algorithm,
277 post_quantum_algorithm,
278 compression_enabled: false,
279 compression_config: None,
280 };
281 Self {
282 bundle,
283 hybrid_crypto: HybridCrypto::new(policy),
284 }
285 }
286
287 pub fn verify(&self, message: &[u8], signature: &[u8]) -> crate::errors::Result<bool> {
289 let sig = serde_json::from_slice(signature).map_err(|_| {
290 crate::errors::CryptoError::SerializationError(
291 "Failed to deserialize signature".to_string(),
292 )
293 })?;
294 self.hybrid_crypto.verify_hybrid_bundle(&self.bundle, message, &sig)
295 }
296
297 pub fn verify_compact(
299 &self,
300 message: &[u8],
301 compressed_signature: &[u8],
302 ) -> crate::errors::Result<bool> {
303 let compressed_sig = serde_json::from_slice(compressed_signature).map_err(|_| {
304 crate::errors::CryptoError::SerializationError(
305 "Failed to deserialize compressed signature".to_string(),
306 )
307 })?;
308 self.hybrid_crypto
309 .verify_hybrid_bundle_compressed(&self.bundle, message, &compressed_sig)
310 }
311}
312
313pub mod qurox {
314 use super::*;
315
316 pub fn quantum_signer() -> Result<QuantumSigner> {
317 QuantumSigner::new()
318 }
319
320 pub fn hybrid_signer() -> Result<HybridSigner> {
321 HybridSigner::new()
322 }
323
324 pub fn quantum_encryptor() -> Result<QuantumEncryptor> {
325 QuantumEncryptor::new()
326 }
327
328 pub fn secure_signer() -> Result<HybridSigner> {
330 let policy = HybridPolicy {
331 security_level: SecurityLevel::Hybrid,
332 transition_mode: TransitionMode::HybridRequired,
333 classical_algorithm: ClassicalAlgorithm::EcdsaK256,
334 post_quantum_algorithm: PostQuantumAlgorithm::MlDsa44,
335 compression_enabled: true,
336 compression_config: None,
337 };
338 HybridSigner::with_policy(policy)
339 }
340
341 pub fn compact_signer() -> Result<HybridSigner> {
343 let policy = HybridPolicy {
344 security_level: SecurityLevel::Hybrid,
345 transition_mode: TransitionMode::HybridOptional,
346 classical_algorithm: ClassicalAlgorithm::EcdsaK256,
347 post_quantum_algorithm: PostQuantumAlgorithm::MlDsa44,
348 compression_enabled: true,
349 compression_config: None,
350 };
351 HybridSigner::with_policy(policy)
352 }
353}
354
355#[cfg(test)]
356mod tests {
357 use super::*;
358
359 #[test]
360 fn test_quantum_signer() {
361 let signer = QuantumSigner::new().unwrap();
362 let message = b"quantum test message";
363
364 let signature = signer.sign(message).unwrap();
365 let is_valid = signer.verify(message, &signature).unwrap();
366
367 assert!(is_valid);
368 assert!(!signature.is_empty());
369 assert!(!signer.public_key_bytes().is_empty());
370 }
371
372 #[test]
373 fn test_hybrid_signer() {
374 let signer = HybridSigner::new().unwrap();
375 let message = b"hybrid test message";
376
377 let signature = signer.sign(message).unwrap();
378 let is_valid = signer.verify(message, &signature).unwrap();
379
380 assert!(is_valid);
381 assert!(!signature.is_empty());
382 }
383
384 #[test]
385 fn test_compact_signing() {
386 let signer = HybridSigner::new().unwrap();
387 let message = b"compact test message";
388
389 let compact_sig = signer.sign_compact(message).unwrap();
390 let is_valid = signer.verify_compact(message, &compact_sig).unwrap();
391
392 assert!(is_valid);
393 assert!(!compact_sig.is_empty());
394 }
395
396 #[test]
397 fn test_quantum_encryptor() {
398 let encryptor = QuantumEncryptor::new().unwrap();
399
400 let (ciphertext, shared_secret1) = encryptor.encapsulate().unwrap();
401 let shared_secret2 = encryptor.decapsulate(&ciphertext).unwrap();
402
403 assert_eq!(shared_secret1.as_slice(), shared_secret2.as_slice());
404 assert!(!ciphertext.is_empty());
405 assert!(!shared_secret1.is_empty());
406 }
407
408 #[test]
409 fn test_quantum_verifier_cross_party() {
410 let alice = QuantumSigner::new().unwrap();
411 let message = b"signed by alice";
412
413 let sig = alice.sign(message).unwrap();
414
415 let bob = QuantumVerifier::from_bytes(&alice.public_key_bytes()).unwrap();
417 assert!(bob.verify(message, &sig).unwrap());
418
419 assert!(!bob.verify(b"not alice's message", &sig).unwrap());
421 }
422
423 #[test]
424 fn test_hybrid_verifier_cross_party() {
425 let alice = HybridSigner::new().unwrap();
426 let message = b"hybrid signed by alice";
427
428 let sig = alice.sign(message).unwrap();
429
430 let bob = alice.verifier();
432 assert!(bob.verify(message, &sig).unwrap());
433
434 assert!(!bob.verify(b"tampered", &sig).unwrap());
436 }
437
438 #[test]
439 fn test_hybrid_verifier_compact_cross_party() {
440 let alice = HybridSigner::new().unwrap();
441 let message = b"compact hybrid signed by alice";
442
443 let compact_sig = alice.sign_compact(message).unwrap();
444
445 let bob = alice.verifier();
446 assert!(bob.verify_compact(message, &compact_sig).unwrap());
447 }
448
449 #[test]
450 fn test_hybrid_verifier_rejects_wrong_signer() {
451 let alice = HybridSigner::new().unwrap();
452 let eve = HybridSigner::new().unwrap();
453 let message = b"signed by alice";
454
455 let sig = alice.sign(message).unwrap();
456
457 let eve_verifier = eve.verifier();
459 assert!(!eve_verifier.verify(message, &sig).unwrap());
460 }
461
462 #[test]
463 fn test_qurox_api() {
464 let quantum = qurox::quantum_signer().unwrap();
466 let hybrid = qurox::hybrid_signer().unwrap();
467 let encryptor = qurox::quantum_encryptor().unwrap();
468 let secure = qurox::secure_signer().unwrap();
469 let compact = qurox::compact_signer().unwrap();
470
471 let message = b"qurox api test";
472
473 let q_sig = quantum.sign(message).unwrap();
475 assert!(quantum.verify(message, &q_sig).unwrap());
476
477 let h_sig = hybrid.sign(message).unwrap();
479 assert!(hybrid.verify(message, &h_sig).unwrap());
480
481 let s_sig = secure.sign(message).unwrap();
483 assert!(secure.verify(message, &s_sig).unwrap());
484
485 let c_sig = compact.sign_compact(message).unwrap();
487 assert!(compact.verify_compact(message, &c_sig).unwrap());
488
489 let (ct, ss1) = encryptor.encapsulate().unwrap();
491 let ss2 = encryptor.decapsulate(&ct).unwrap();
492 assert_eq!(ss1.as_slice(), ss2.as_slice());
493 }
494}