use chie_crypto::{KeyPair, constant_time_eq, decrypt, encrypt};
#[test]
fn verify_ct_eq_same_inputs() {
let a = [0x42u8; 32];
let b = [0x42u8; 32];
assert!(constant_time_eq(&a, &b));
}
#[test]
fn verify_ct_eq_different_inputs() {
let a = [0x42u8; 32];
let b = [0x43u8; 32];
assert!(!constant_time_eq(&a, &b));
}
#[test]
fn verify_ct_eq_difference_positions() {
let base = [0x42u8; 32];
for pos in 0..32 {
let mut modified = base;
modified[pos] ^= 0x01;
assert!(!constant_time_eq(&base, &modified));
}
}
#[test]
fn verify_decrypt_ct_auth_failure() {
let key = [0x42u8; 32];
let nonce = [0x24u8; 12];
let plaintext = b"test message for constant-time verification";
let mut ciphertext = encrypt(plaintext, &key, &nonce).unwrap();
let len = ciphertext.len();
if len >= 16 {
ciphertext[len - 1] ^= 0x01;
assert!(decrypt(&ciphertext, &key, &nonce).is_err());
}
}
#[test]
fn verify_signature_ct_invalid() {
let keypair = KeyPair::generate();
let message = b"test message";
let signature = keypair.sign(message);
for pos in 0..signature.len() {
let mut modified_sig = signature;
modified_sig[pos] ^= 0x01;
assert!(!keypair.verify(message, &modified_sig));
}
}
#[test]
fn verify_ct_eq_extremes() {
let zeros = [0x00u8; 32];
let ones = [0xFFu8; 32];
assert!(!constant_time_eq(&zeros, &ones));
assert!(constant_time_eq(&zeros, &zeros));
assert!(constant_time_eq(&ones, &ones));
}
#[test]
fn verify_ct_eq_single_bit() {
let a = [0x00u8; 32];
let mut b = [0x00u8; 32];
b[0] = 0x01;
assert!(!constant_time_eq(&a, &b));
b[0] = 0x00;
b[31] = 0x80;
assert!(!constant_time_eq(&a, &b));
}
#[test]
fn verify_decrypt_ct_plaintext_independent() {
let key = [0x42u8; 32];
let nonce = [0x24u8; 12];
let plaintexts = [
vec![0x00u8; 64], vec![0xFFu8; 64], vec![0xAAu8; 64], (0..64).map(|i| i as u8).collect(), ];
for plaintext in &plaintexts {
let ciphertext = encrypt(plaintext, &key, &nonce).unwrap();
let decrypted = decrypt(&ciphertext, &key, &nonce).unwrap();
assert_eq!(&decrypted[..], &plaintext[..]);
}
}
#[test]
fn verify_signature_ct_message_independent() {
let keypair = KeyPair::generate();
let messages = [
vec![0x00u8; 64], vec![0xFFu8; 64], vec![0xAAu8; 64], (0..64).map(|i| i as u8).collect(), ];
for message in &messages {
let signature = keypair.sign(message);
assert!(keypair.verify(message, &signature));
}
}
#[test]
fn verify_ct_eq_heap_allocated() {
let a = vec![0x42u8; 32];
let b = vec![0x42u8; 32];
let c = vec![0x43u8; 32];
assert!(constant_time_eq(&a, &b));
assert!(!constant_time_eq(&a, &c));
}
#[test]
fn verify_ct_eq_timing_property() {
let base = [0xAAu8; 32];
for first_diff_pos in [0, 8, 16, 24, 31] {
let mut test = base;
test[first_diff_pos] ^= 0x01;
assert!(!constant_time_eq(&base, &test));
}
}
#[test]
fn verify_encryption_output_different() {
let key = [0x42u8; 32];
let nonce = [0x24u8; 12];
let plaintext1 = b"message one";
let plaintext2 = b"message two";
let ciphertext1 = encrypt(plaintext1, &key, &nonce).unwrap();
let ciphertext2 = encrypt(plaintext2, &key, &nonce).unwrap();
assert_ne!(ciphertext1, ciphertext2);
}
#[test]
fn verify_ct_eq_uniform_arrays() {
for byte_value in [0x00, 0x55, 0xAA, 0xFF] {
let a = [byte_value; 32];
let b = [byte_value; 32];
let c = [byte_value ^ 0x01; 32];
assert!(constant_time_eq(&a, &b));
assert!(!constant_time_eq(&a, &c));
}
}