use aes::{Aes128, Aes192, Aes256}; use cipher::{generic_array::GenericArray, KeyInit}; use hctr2::Cipher; use serde::{Deserialize, Serialize}; use std::{fs, path::PathBuf}; #[derive(Serialize, Deserialize, Debug)] pub struct TestVector { cipher: TestVectorCipher, description: String, input: TestVectorInput, ciphertext_hex: String, plaintext_hex: String, hash_hex: Option, } #[derive(Serialize, Deserialize, Debug)] pub struct TestVectorCipher { blockcipher: TestVectorBlockCipher, } #[derive(Serialize, Deserialize, Debug)] pub struct TestVectorBlockCipher { cipher: String, lengths: TestVectorBlockCipherLengths, } #[derive(Serialize, Deserialize, Debug)] pub struct TestVectorBlockCipherLengths { block: usize, key: usize, nonce: Option, } #[derive(Serialize, Deserialize, Debug)] pub struct TestVectorInput { key_hex: String, tweak_hex: String, nonce_hex: Option, } static MFST_DIR: &str = env!("CARGO_MANIFEST_DIR"); macro_rules! hctr2_test { ($name:ident, $C:ident, $fname:expr) => { #[test] fn $name() { let mut path = PathBuf::from(MFST_DIR); path.push("tests"); path.push("testdata"); path.push($fname); let data = fs::read(path).unwrap(); let vecs: Vec = serde_json::from_slice(&data[..]).unwrap(); for v in &vecs { let key = &hex::decode(&v.input.key_hex).unwrap(); let mut c = Cipher::<$C>::new(GenericArray::from_slice(&key[..])); let tweak = hex::decode(&v.input.tweak_hex).unwrap(); let plaintext = hex::decode(&v.plaintext_hex).unwrap(); let ciphertext = hex::decode(&v.ciphertext_hex).unwrap(); let mut got = &mut vec![0u8; plaintext.len()][..]; c.encrypt(&mut got, &plaintext, &tweak); assert_eq!(got, ciphertext); c.decrypt(&mut got, &ciphertext, &tweak); assert_eq!(got, plaintext); c.encrypt_in_place(&mut got, &tweak); assert_eq!(got, ciphertext); c.decrypt_in_place(&mut got, &tweak); assert_eq!(got, plaintext); } } }; } hctr2_test!(test_hctr2_aes256, Aes256, "HCTR2_AES256.json"); hctr2_test!(test_hctr2_aes192, Aes192, "HCTR2_AES192.json"); hctr2_test!(test_hctr2_aes128, Aes128, "HCTR2_AES128.json");