use mini_enigma::state_machine::Enigma; use mini_enigma::utils::M3; mod common; use common::{kat, load_enigma_settings}; #[test] fn test_instruction_manual() { kat::("tests/data/instruction_manual.json"); } #[test] fn test_barbossa_a() { kat::("tests/data/operation_barbossa_a.json"); } #[test] fn test_barbossa_b() { kat::("tests/data/operation_barbossa_b.json"); } #[test] fn test_scharnhorst() { // The Scharnhorst message actually starts with the rotors ready to double step. // Since our double step implementation is not mechanical and does not 'look backwards' // this test adds an extra ignored char to the front of the message so the machine is in a position to double step let mut settings = load_enigma_settings("tests/data/scharnhorst.json"); settings.grundstellung[2] = (settings.grundstellung[2] as u8 - 1) as char; settings.plaintext = "A".to_owned() + &settings.plaintext; settings.ciphertext = "A".to_owned() + &settings.ciphertext; println!("Testing {} [{}]", settings.name, settings.date.unwrap_or(0)); let mut enigma = Enigma::new::(&settings.clone().into()); print!("input: "); let mut ct = String::new(); for (i, ch) in settings.plaintext.chars().enumerate() { let bit = enigma.encrypt_char(ch); if i == 0 { continue; } ct.push(bit); print!("{ch}"); if settings.ciphertext.as_bytes()[i] as char != bit { println!("\noutput: {ct}"); println!("pos: {:?}", enigma.get_grundstellung()); } assert_eq!(settings.ciphertext.as_bytes()[i] as char, bit) } } #[test] fn test_practical_crypto() { kat::("tests/data/practical_cryptography.json"); } #[test] fn test_norrkoping() { kat::("tests/data/norrkoping.json"); }