use qssh::vault::{QuantumVault, VaultConfig};
use qssh::vault::lamport::{LamportKeypair, LamportSignature};
use qssh::vault::ratchet::{DoubleRatchet, RatchetHeader};
#[tokio::test]
async fn test_quantum_vault_creation() {
let config = VaultConfig {
enable_qrng: false, enable_lamport: true,
enable_ratchet: true,
storage_path: None,
};
let vault = QuantumVault::new(config).await;
assert!(vault.is_ok(), "Failed to create quantum vault");
}
#[tokio::test]
async fn test_vault_store_retrieve() {
let config = VaultConfig {
enable_qrng: false,
enable_lamport: true,
enable_ratchet: true,
storage_path: None,
};
let mut vault = QuantumVault::new(config).await.expect("Failed to create vault");
let key = "test-key";
let secret = vec![1, 2, 3, 4, 5, 6, 7, 8];
vault.store_secret(key, secret.clone()).await.expect("Failed to store secret");
let retrieved = vault.get_secret(key).await.expect("Failed to get secret");
assert_eq!(retrieved, Some(secret));
let missing = vault.get_secret("missing-key").await.expect("Failed to get secret");
assert_eq!(missing, None);
}
#[test]
fn test_lamport_signature() {
let keypair = LamportKeypair::generate();
let message = b"Test message for Lamport signature";
let signature = keypair.sign(message);
assert!(keypair.verify(message, &signature));
assert!(!keypair.verify(b"Wrong message", &signature));
let mut bad_sig = signature.clone();
if !bad_sig.signature_parts.is_empty() && !bad_sig.signature_parts[0].is_empty() {
bad_sig.signature_parts[0][0] ^= 0xFF;
assert!(!keypair.verify(message, &bad_sig));
}
}
#[test]
fn test_lamport_public_key() {
let keypair = LamportKeypair::generate();
let public_key = keypair.public_key();
assert_eq!(public_key.verification_keys.len(), 256);
for key in &public_key.verification_keys {
assert_eq!(key.len(), 32); }
}
#[tokio::test]
async fn test_double_ratchet() {
let shared_secret = b"initial shared secret";
let mut alice_ratchet = DoubleRatchet::new(shared_secret, true);
let mut bob_ratchet = DoubleRatchet::new(shared_secret, false);
let plaintext1 = b"Hello Bob!";
let (header1, ciphertext1) = alice_ratchet.encrypt(plaintext1)
.await.expect("Failed to encrypt");
let decrypted1 = bob_ratchet.decrypt(&header1, &ciphertext1)
.await.expect("Failed to decrypt");
assert_eq!(decrypted1, plaintext1);
let plaintext2 = b"Hello Alice!";
let (header2, ciphertext2) = bob_ratchet.encrypt(plaintext2)
.await.expect("Failed to encrypt");
let decrypted2 = alice_ratchet.decrypt(&header2, &ciphertext2)
.await.expect("Failed to decrypt");
assert_eq!(decrypted2, plaintext2);
}
#[tokio::test]
async fn test_ratchet_forward_secrecy() {
let shared_secret = b"forward secrecy test";
let mut ratchet = DoubleRatchet::new(shared_secret, true);
let messages = vec![
b"Message 1".as_ref(),
b"Message 2".as_ref(),
b"Message 3".as_ref(),
];
let mut encrypted = Vec::new();
for msg in &messages {
let (header, ciphertext) = ratchet.encrypt(msg)
.await.expect("Failed to encrypt");
encrypted.push((header, ciphertext));
}
let (_, ct1) = ratchet.encrypt(b"Same message")
.await.expect("Failed to encrypt");
let (_, ct2) = ratchet.encrypt(b"Same message")
.await.expect("Failed to encrypt");
assert_ne!(ct1, ct2, "Ciphertexts should be different due to ratcheting");
}
#[cfg(test)]
mod vault_integration_tests {
use super::*;
#[tokio::test]
async fn test_vault_with_ratchet() {
let config = VaultConfig {
enable_qrng: false,
enable_lamport: true,
enable_ratchet: true,
storage_path: None,
};
let vault = QuantumVault::new(config).await.expect("Failed to create vault");
assert!(vault.get_ratchet().await.is_some());
}
#[tokio::test]
async fn test_vault_rotation() {
let config = VaultConfig {
enable_qrng: false,
enable_lamport: true,
enable_ratchet: true,
storage_path: None,
};
let mut vault = QuantumVault::new(config).await.expect("Failed to create vault");
let original_keypair = vault.get_current_lamport_keypair()
.await.expect("No Lamport keypair");
vault.rotate_keys().await.expect("Failed to rotate keys");
let new_keypair = vault.get_current_lamport_keypair()
.await.expect("No Lamport keypair after rotation");
assert_ne!(
original_keypair.public_key().verification_keys[0],
new_keypair.public_key().verification_keys[0]
);
}
}