#[cfg(any(feature = "post-quantum", feature = "ml-kem"))]
use rand::rngs::OsRng;
#[cfg(feature = "ml-kem")]
use rust_bottle::{
hybrid_decrypt_mlkem768_x25519, hybrid_encrypt_mlkem768_x25519, mlkem1024_decrypt,
mlkem1024_encrypt, mlkem768_decrypt, mlkem768_encrypt, MlKem1024Key, MlKem768Key,
};
#[cfg(feature = "post-quantum")]
use rust_bottle::{
MlDsa44Key, MlDsa65Key, MlDsa87Key,
SlhDsa128sKey, SlhDsa128fKey, SlhDsa192sKey, SlhDsa192fKey, SlhDsa256sKey, SlhDsa256fKey,
SlhDsaSha2_128sKey, SlhDsaSha2_128fKey, SlhDsaSha2_192sKey, SlhDsaSha2_192fKey, SlhDsaSha2_256sKey, SlhDsaSha2_256fKey,
};
use rust_bottle::{
ecdh_decrypt, ecdh_encrypt, Bottle, Ed25519Key, IDCard, Keychain, Opener, Sign, Verify,
X25519Key,
};
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem768_encryption() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
let plaintext = b"ML-KEM-768 encrypted message";
let ciphertext = mlkem768_encrypt(rng, plaintext, &key.public_key_bytes()).unwrap();
let decrypted = mlkem768_decrypt(&ciphertext, &key.private_key_bytes()).unwrap();
assert_eq!(decrypted, plaintext);
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem768_key_sizes() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
assert_eq!(key.public_key_bytes().len(), 1184);
assert_eq!(key.private_key_bytes().len(), 3584); }
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem768_different_keys() {
let rng = &mut OsRng;
let alice_key = MlKem768Key::generate(rng);
let bob_key = MlKem768Key::generate(rng);
let plaintext = b"Message for Bob";
let ciphertext = mlkem768_encrypt(rng, plaintext, &bob_key.public_key_bytes()).unwrap();
let decrypted = mlkem768_decrypt(&ciphertext, &bob_key.private_key_bytes()).unwrap();
assert_eq!(decrypted, plaintext);
assert!(mlkem768_decrypt(&ciphertext, &alice_key.private_key_bytes()).is_err());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem1024_encryption() {
let rng = &mut OsRng;
let key = MlKem1024Key::generate(rng);
let plaintext = b"ML-KEM-1024 encrypted message";
let ciphertext = mlkem1024_encrypt(rng, plaintext, &key.public_key_bytes()).unwrap();
let decrypted = mlkem1024_decrypt(&ciphertext, &key.private_key_bytes()).unwrap();
assert_eq!(decrypted, plaintext);
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem1024_key_sizes() {
let rng = &mut OsRng;
let key = MlKem1024Key::generate(rng);
assert_eq!(key.public_key_bytes().len(), 1568);
assert_eq!(key.private_key_bytes().len(), 4736); }
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem_automatic_detection() {
let rng = &mut OsRng;
let mlkem768_key = MlKem768Key::generate(rng);
let plaintext = b"Auto-detected ML-KEM-768";
let ciphertext = ecdh_encrypt(rng, plaintext, &mlkem768_key.public_key_bytes()).unwrap();
let decrypted = ecdh_decrypt(&ciphertext, &mlkem768_key.private_key_bytes()).unwrap();
assert_eq!(decrypted, plaintext);
let mlkem1024_key = MlKem1024Key::generate(rng);
let plaintext2 = b"Auto-detected ML-KEM-1024";
let ciphertext2 = ecdh_encrypt(rng, plaintext2, &mlkem1024_key.public_key_bytes()).unwrap();
let decrypted2 = ecdh_decrypt(&ciphertext2, &mlkem1024_key.private_key_bytes()).unwrap();
assert_eq!(decrypted2, plaintext2);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_mldsa44_signing() {
let rng = &mut OsRng;
let key = MlDsa44Key::generate(rng);
let message = b"ML-DSA-44 signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
assert!(key.verify(b"Different message", &signature).is_err());
let wrong_sig = vec![0u8; signature.len()];
assert!(key.verify(message, &wrong_sig).is_err());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_mldsa44_key_sizes() {
let rng = &mut OsRng;
let key = MlDsa44Key::generate(rng);
let pub_key = key.public_key_bytes();
let priv_key = key.private_key_bytes();
assert_eq!(pub_key.len(), 1312);
assert_eq!(priv_key.len(), 2560);
let signature = key.sign(rng, b"test").unwrap();
assert!(signature.len() >= 2000); }
#[cfg(feature = "post-quantum")]
#[test]
fn test_mldsa65_signing() {
let rng = &mut OsRng;
let key = MlDsa65Key::generate(rng);
let message = b"ML-DSA-65 signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_mldsa65_key_sizes() {
let rng = &mut OsRng;
let key = MlDsa65Key::generate(rng);
assert!(key.public_key_bytes().len() > 1000);
assert!(key.private_key_bytes().len() > 2000);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_mldsa87_signing() {
let rng = &mut OsRng;
let key = MlDsa87Key::generate(rng);
let message = b"ML-DSA-87 signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_mldsa87_key_sizes() {
let rng = &mut OsRng;
let key = MlDsa87Key::generate(rng);
assert!(key.public_key_bytes().len() > 2000);
assert!(key.private_key_bytes().len() > 4000);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa128s_signing() {
let rng = &mut OsRng;
let key = SlhDsa128sKey::generate(rng);
let message = b"SLH-DSA-128s signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
assert!(key.verify(b"Different message", &signature).is_err());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa128s_key_sizes() {
let rng = &mut OsRng;
let key = SlhDsa128sKey::generate(rng);
assert_eq!(key.public_key_bytes().len(), 32);
assert_eq!(key.private_key_bytes().len(), 64);
let signature = key.sign(rng, b"test").unwrap();
assert!(signature.len() >= 7000); }
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa192s_signing() {
let rng = &mut OsRng;
let key = SlhDsa192sKey::generate(rng);
let message = b"SLH-DSA-192s signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa192s_key_sizes() {
let rng = &mut OsRng;
let key = SlhDsa192sKey::generate(rng);
assert_eq!(key.public_key_bytes().len(), 48);
assert_eq!(key.private_key_bytes().len(), 96);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa256s_signing() {
let rng = &mut OsRng;
let key = SlhDsa256sKey::generate(rng);
let message = b"SLH-DSA-256s signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa256s_key_sizes() {
let rng = &mut OsRng;
let key = SlhDsa256sKey::generate(rng);
assert_eq!(key.public_key_bytes().len(), 64);
assert_eq!(key.private_key_bytes().len(), 128);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa128f_signing() {
let rng = &mut OsRng;
let key = SlhDsa128fKey::generate(rng);
let message = b"SLH-DSA-128f signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa192f_signing() {
let rng = &mut OsRng;
let key = SlhDsa192fKey::generate(rng);
let message = b"SLH-DSA-192f signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa256f_signing() {
let rng = &mut OsRng;
let key = SlhDsa256fKey::generate(rng);
let message = b"SLH-DSA-256f signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa_sha2_128s_signing() {
let rng = &mut OsRng;
let key = SlhDsaSha2_128sKey::generate(rng);
let message = b"SLH-DSA-SHA2-128s signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa_sha2_128f_signing() {
let rng = &mut OsRng;
let key = SlhDsaSha2_128fKey::generate(rng);
let message = b"SLH-DSA-SHA2-128f signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa_sha2_192s_signing() {
let rng = &mut OsRng;
let key = SlhDsaSha2_192sKey::generate(rng);
let message = b"SLH-DSA-SHA2-192s signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa_sha2_192f_signing() {
let rng = &mut OsRng;
let key = SlhDsaSha2_192fKey::generate(rng);
let message = b"SLH-DSA-SHA2-192f signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa_sha2_256s_signing() {
let rng = &mut OsRng;
let key = SlhDsaSha2_256sKey::generate(rng);
let message = b"SLH-DSA-SHA2-256s signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa_sha2_256f_signing() {
let rng = &mut OsRng;
let key = SlhDsaSha2_256fKey::generate(rng);
let message = b"SLH-DSA-SHA2-256f signed message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_hybrid_encryption() {
let rng = &mut OsRng;
let mlkem_key = MlKem768Key::generate(rng);
let x25519_key = X25519Key::generate(rng);
let plaintext = b"Hybrid encrypted message";
let ciphertext = hybrid_encrypt_mlkem768_x25519(
rng,
plaintext,
&mlkem_key.public_key_bytes(),
&x25519_key.public_key_bytes(),
)
.unwrap();
let mlkem_sec = mlkem_key.private_key_bytes();
let x25519_sec: [u8; 32] = x25519_key.private_key_bytes().try_into().unwrap();
let decrypted = hybrid_decrypt_mlkem768_x25519(&ciphertext, &mlkem_sec, &x25519_sec).unwrap();
assert_eq!(decrypted, plaintext);
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_hybrid_encryption_fallback() {
let rng = &mut OsRng;
let mlkem_key = MlKem768Key::generate(rng);
let x25519_key = X25519Key::generate(rng);
let plaintext = b"Hybrid encrypted with fallback";
let ciphertext = hybrid_encrypt_mlkem768_x25519(
rng,
plaintext,
&mlkem_key.public_key_bytes(),
&x25519_key.public_key_bytes(),
)
.unwrap();
let x25519_sec: [u8; 32] = x25519_key.private_key_bytes().try_into().unwrap();
let dummy_mlkem_sec = vec![0u8; 2400];
let decrypted = hybrid_decrypt_mlkem768_x25519(&ciphertext, &dummy_mlkem_sec, &x25519_sec);
if decrypted.is_ok() {
assert_eq!(decrypted.unwrap(), plaintext);
}
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_pqc_bottle_encryption() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"Post-quantum encrypted".to_vec());
let mlkem_key = MlKem768Key::generate(rng);
bottle.encrypt(rng, &mlkem_key.public_key_bytes()).unwrap();
assert!(bottle.is_encrypted());
let opener = Opener::new();
let decrypted = opener
.open(&bottle, Some(&mlkem_key.private_key_bytes()))
.unwrap();
assert_eq!(decrypted, b"Post-quantum encrypted");
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_pqc_bottle_signing() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"Post-quantum signed".to_vec());
let mldsa_key = MlDsa44Key::generate(rng);
let pub_key = mldsa_key.public_key_bytes();
bottle.sign(rng, &mldsa_key, &pub_key).unwrap();
assert!(bottle.is_signed());
let opener = Opener::new();
let info = opener.open_info(&bottle).unwrap();
assert!(info.is_signed_by(&pub_key));
}
#[cfg(all(feature = "post-quantum", feature = "ml-kem"))]
#[test]
fn test_pqc_bottle_encrypted_and_signed() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"Post-quantum encrypted and signed".to_vec());
let mlkem_key = MlKem768Key::generate(rng);
let mldsa_key = MlDsa44Key::generate(rng);
let mldsa_pub = mldsa_key.public_key_bytes();
bottle.encrypt(rng, &mlkem_key.public_key_bytes()).unwrap();
bottle.sign(rng, &mldsa_key, &mldsa_pub).unwrap();
assert!(bottle.is_encrypted());
assert!(bottle.is_signed());
let opener = Opener::new();
let decrypted = opener
.open(&bottle, Some(&mlkem_key.private_key_bytes()))
.unwrap();
assert_eq!(decrypted, b"Post-quantum encrypted and signed");
let info = opener.open_info(&bottle).unwrap();
assert!(info.is_signed_by(&mldsa_pub));
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_pqc_bottle_layered_encryption() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"Multi-layer PQC encrypted".to_vec());
let key1 = MlKem768Key::generate(rng);
let key2 = MlKem1024Key::generate(rng);
bottle.encrypt(rng, &key1.public_key_bytes()).unwrap();
bottle.encrypt(rng, &key2.public_key_bytes()).unwrap();
assert_eq!(bottle.encryption_count(), 2);
let opener = Opener::new();
let info = opener.open_info(&bottle).unwrap();
assert!(info.is_encrypted);
assert_eq!(info.recipients.len(), 2);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_pqc_bottle_multiple_signatures() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"Multi-signed PQC message".to_vec());
let mldsa_key1 = MlDsa44Key::generate(rng);
let mldsa_key2 = MlDsa65Key::generate(rng);
let slhdsa_key = SlhDsa128sKey::generate(rng);
let pub1 = mldsa_key1.public_key_bytes();
let pub2 = mldsa_key2.public_key_bytes();
let pub3 = slhdsa_key.public_key_bytes();
bottle.sign(rng, &mldsa_key1, &pub1).unwrap();
bottle.sign(rng, &mldsa_key2, &pub2).unwrap();
bottle.sign(rng, &slhdsa_key, &pub3).unwrap();
assert!(bottle.is_signed());
let opener = Opener::new();
let info = opener.open_info(&bottle).unwrap();
assert!(info.is_signed_by(&pub1));
assert!(info.is_signed_by(&pub2));
assert!(info.is_signed_by(&pub3));
assert_eq!(info.signers.len(), 3);
}
#[cfg(all(feature = "post-quantum", feature = "ml-kem"))]
#[test]
fn test_pqc_bottle_serialization() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"Serializable PQC bottle".to_vec());
let mlkem_key = MlKem768Key::generate(rng);
let mldsa_key = MlDsa44Key::generate(rng);
let pub_key = mldsa_key.public_key_bytes();
bottle.encrypt(rng, &mlkem_key.public_key_bytes()).unwrap();
bottle.sign(rng, &mldsa_key, &pub_key).unwrap();
bottle.set_metadata("pqc", "true");
let serialized = bottle.to_bytes().unwrap();
let deserialized = Bottle::from_bytes(&serialized).unwrap();
assert_eq!(deserialized.encryption_count(), bottle.encryption_count());
assert_eq!(deserialized.metadata("pqc"), Some("true"));
let opener = Opener::new();
let info = opener.open_info(&deserialized).unwrap();
assert!(info.is_signed_by(&pub_key));
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_pqc_keychain() {
let rng = &mut OsRng;
let mut keychain = Keychain::new();
let mldsa_key = MlDsa44Key::generate(rng);
let slhdsa_key = SlhDsa128sKey::generate(rng);
keychain.add_key(mldsa_key);
keychain.add_key(slhdsa_key);
assert_eq!(keychain.signers().count(), 2);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_pqc_keychain_signing() {
let rng = &mut OsRng;
let mut keychain = Keychain::new();
let mldsa_key = MlDsa44Key::generate(rng);
let pub_key = mldsa_key.public_key_bytes();
keychain.add_key(mldsa_key);
let message = b"Message signed with keychain";
let signature = keychain.sign(rng, &pub_key, message).unwrap();
let _key = keychain.get_key(&pub_key).unwrap();
assert!(!signature.is_empty());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_pqc_keychain_mixed_keys() {
let rng = &mut OsRng;
let mut keychain = Keychain::new();
let ed25519_key = Ed25519Key::generate(rng);
let mldsa_key = MlDsa44Key::generate(rng);
let slhdsa_key = SlhDsa128sKey::generate(rng);
keychain.add_key(ed25519_key);
keychain.add_key(mldsa_key);
keychain.add_key(slhdsa_key);
assert_eq!(keychain.signers().count(), 3);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_pqc_idcard() {
let rng = &mut OsRng;
let mldsa_key = MlDsa44Key::generate(rng);
let mut idcard = IDCard::new(&mldsa_key.public_key_bytes());
idcard.set_metadata("name", "Post-Quantum Entity");
idcard.set_key_purposes(&mldsa_key.public_key_bytes(), &["sign"]);
assert!(idcard
.test_key_purpose(&mldsa_key.public_key_bytes(), "sign")
.is_ok());
}
#[cfg(all(feature = "post-quantum", feature = "ml-kem"))]
#[test]
fn test_pqc_idcard_multiple_keys() {
let rng = &mut OsRng;
let mldsa_key = MlDsa44Key::generate(rng);
let mlkem_key = MlKem768Key::generate(rng);
let mut idcard = IDCard::new(&mldsa_key.public_key_bytes());
idcard.set_key_purposes(&mldsa_key.public_key_bytes(), &["sign"]);
idcard.set_key_purposes(&mlkem_key.public_key_bytes(), &["decrypt"]);
assert!(idcard
.test_key_purpose(&mldsa_key.public_key_bytes(), "sign")
.is_ok());
assert!(idcard
.test_key_purpose(&mlkem_key.public_key_bytes(), "decrypt")
.is_ok());
let sign_keys = idcard.get_keys("sign");
assert_eq!(sign_keys.len(), 1);
let decrypt_keys = idcard.get_keys("decrypt");
assert_eq!(decrypt_keys.len(), 1);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_pqc_idcard_signing() {
let rng = &mut OsRng;
let mldsa_key = MlDsa44Key::generate(rng);
let mut idcard = IDCard::new(&mldsa_key.public_key_bytes());
idcard.set_metadata("name", "PQC Entity");
idcard.set_key_purposes(&mldsa_key.public_key_bytes(), &["sign"]);
let signed_bytes = idcard.sign(rng, &mldsa_key).unwrap();
assert!(!signed_bytes.is_empty());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem_key_bytes() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
let pub_bytes = key.public_key_bytes();
let priv_bytes = key.private_key_bytes();
assert!(!pub_bytes.is_empty());
assert!(!priv_bytes.is_empty());
assert_ne!(pub_bytes, priv_bytes);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_mldsa_key_bytes() {
let rng = &mut OsRng;
let key = MlDsa44Key::generate(rng);
let pub_bytes = key.public_key_bytes();
let priv_bytes = key.private_key_bytes();
assert!(!pub_bytes.is_empty());
assert!(!priv_bytes.is_empty());
assert_ne!(pub_bytes, priv_bytes);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_slhdsa_key_bytes() {
let rng = &mut OsRng;
let key = SlhDsa128sKey::generate(rng);
let pub_bytes = key.public_key_bytes();
let priv_bytes = key.private_key_bytes();
assert!(!pub_bytes.is_empty());
assert!(!priv_bytes.is_empty());
assert_ne!(pub_bytes, priv_bytes);
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem_wrong_key_decrypt() {
let rng = &mut OsRng;
let alice_key = MlKem768Key::generate(rng);
let bob_key = MlKem768Key::generate(rng);
let plaintext = b"Secret message";
let ciphertext = mlkem768_encrypt(rng, plaintext, &bob_key.public_key_bytes()).unwrap();
assert!(mlkem768_decrypt(&ciphertext, &alice_key.private_key_bytes()).is_err());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_mldsa_wrong_signature() {
let rng = &mut OsRng;
let key = MlDsa44Key::generate(rng);
let message = b"Message";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(b"Wrong message", &signature).is_err());
let wrong_sig = vec![0u8; signature.len()];
assert!(key.verify(message, &wrong_sig).is_err());
assert!(key.verify(message, &[]).is_err());
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem_invalid_ciphertext() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
let invalid_ciphertext = vec![0u8; 100];
assert!(mlkem768_decrypt(&invalid_ciphertext, &key.private_key_bytes()).is_err());
assert!(mlkem768_decrypt(&[], &key.private_key_bytes()).is_err());
}
#[cfg(all(feature = "post-quantum", feature = "ml-kem"))]
#[test]
fn test_pqc_classical_mixed_bottle() {
let rng = &mut OsRng;
let mut bottle = Bottle::new(b"Mixed classical and PQC".to_vec());
let x25519_key = X25519Key::generate(rng);
bottle.encrypt(rng, &x25519_key.public_key_bytes()).unwrap();
let mldsa_key = MlDsa44Key::generate(rng);
let pub_key = mldsa_key.public_key_bytes();
bottle.sign(rng, &mldsa_key, &pub_key).unwrap();
let opener = Opener::new();
let decrypted = opener
.open(&bottle, Some(&x25519_key.private_key_bytes()))
.unwrap();
assert_eq!(decrypted, b"Mixed classical and PQC");
let info = opener.open_info(&bottle).unwrap();
assert!(info.is_signed_by(&pub_key));
}
#[cfg(all(feature = "post-quantum", feature = "ml-kem"))]
#[test]
fn test_pqc_classical_mixed_keychain() {
let rng = &mut OsRng;
let mut keychain = Keychain::new();
let ed25519_key = Ed25519Key::generate(rng);
let mldsa_key = MlDsa44Key::generate(rng);
let mldsa65_key = MlDsa65Key::generate(rng);
keychain.add_key(ed25519_key);
keychain.add_key(mldsa_key);
keychain.add_key(mldsa65_key);
assert_eq!(keychain.signers().count(), 3);
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem_empty_message() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
let plaintext = b"";
let ciphertext = mlkem768_encrypt(rng, plaintext, &key.public_key_bytes()).unwrap();
let decrypted = mlkem768_decrypt(&ciphertext, &key.private_key_bytes()).unwrap();
assert_eq!(decrypted, plaintext);
}
#[cfg(feature = "ml-kem")]
#[test]
fn test_mlkem_large_message() {
let rng = &mut OsRng;
let key = MlKem768Key::generate(rng);
let plaintext = vec![0u8; 10000];
let ciphertext = mlkem768_encrypt(rng, &plaintext, &key.public_key_bytes()).unwrap();
let decrypted = mlkem768_decrypt(&ciphertext, &key.private_key_bytes()).unwrap();
assert_eq!(decrypted, plaintext);
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_mldsa_empty_message() {
let rng = &mut OsRng;
let key = MlDsa44Key::generate(rng);
let message = b"";
let signature = key.sign(rng, message).unwrap();
assert!(key.verify(message, &signature).is_ok());
}
#[cfg(feature = "post-quantum")]
#[test]
fn test_mldsa_large_message() {
let rng = &mut OsRng;
let key = MlDsa44Key::generate(rng);
let message = vec![0u8; 10000];
let signature = key.sign(rng, &message).unwrap();
assert!(key.verify(&message, &signature).is_ok());
}