feistelnet 0.1.0-alpha.2

Symetric block split Feistel Network
Documentation
use super::super::{FeistelNetwork, ReverseKeySchedule};
use super::*;

#[test]
fn test_magma_encryption_decryption() {
   // 256bitový klíč (8 x u32)
   let master_key: [u32; 8] = [
      0xffeeddcc, 0xbbaa9988, 0x77665544, 0x33221100, 0xf0f1f2f3, 0xf4f5f6f7, 0xf8f9fafb, 0xfcfdfeff,
   ];

   // 64bitový blok (L, R)
   let l: u32 = 0xfedcba98;
   let r: u32 = 0x76543210;

   let rounds = 32;

   // Nastavení sítě pro šifrování
   let magma_encryptor = FeistelNetwork::new(MagmaKeySchedule, MagmaRF, rounds);

   // Šifrování
   let (enc_l, enc_r) = magma_encryptor.process(l, r, &master_key);
   assert_ne!((l, r), (enc_l, enc_r));

   // Nastavení sítě pro dešifrování
   let rev_ks = ReverseKeySchedule::from(MagmaKeySchedule, rounds);
   let magma_decryptor = FeistelNetwork::new(rev_ks, MagmaRF, rounds);

   // Dešifrování
   let (dec_l, dec_r) = magma_decryptor.process(enc_l, enc_r, &master_key);

   // Ověření
   assert_eq!(l, dec_l, "Dešifrovaná levá část nesouhlasí");
   assert_eq!(r, dec_r, "Dešifrovaná pravá část nesouhlasí");

   println!("Magma test úspěšný!");
   println!("Původní: {:08x} {:08x}", l, r);
   println!("Zašifrované: {:08x} {:08x}", enc_l, enc_r);
}

#[test]
fn test_magma_key_schedule_rfc8891_compliance() {
   // Master Key K rozdělený na 8 slov (K_0 až K_7) podle RFC 8891
   let master_key: [u32; 8] = [
      0xffeeddcc, 0xbbaa9988, 0x77665544, 0x33221100, 0xf0f1f2f3, 0xf4f5f6f7, 0xf8f9fafb, 0xfcfdfeff,
   ];

   // Definice všech 32 očekávaných klíčů podle sekce A.3
   let expected_keys: [u32; 32] = [
      // Rundy 1-8 (K_1..K_8)
      0xffeeddcc, 0xbbaa9988, 0x77665544, 0x33221100, 0xf0f1f2f3, 0xf4f5f6f7, 0xf8f9fafb, 0xfcfdfeff,
      // Rundy 9-16 (K_9..K_16) - opakování
      0xffeeddcc, 0xbbaa9988, 0x77665544, 0x33221100, 0xf0f1f2f3, 0xf4f5f6f7, 0xf8f9fafb, 0xfcfdfeff,
      // Rundy 17-24 (K_17..K_24) - opakování
      0xffeeddcc, 0xbbaa9988, 0x77665544, 0x33221100, 0xf0f1f2f3, 0xf4f5f6f7, 0xf8f9fafb, 0xfcfdfeff,
      // Rundy 25-32 (K_25..K_32) - obrácené pořadí!
      0xfcfdfeff, 0xf8f9fafb, 0xf4f5f6f7, 0xf0f1f2f3, 0x33221100, 0x77665544, 0xbbaa9988, 0xffeeddcc,
   ];

   let ks = MagmaKeySchedule;
   let mut state = ks.new_state(&master_key);

   for (i, &expected) in expected_keys.iter().enumerate() {
      let generated = ks.next_key(&master_key, &mut state);
      assert_eq!(
         generated,
         expected,
         "Chyba v rundě {}: generováno {:08x}, očekáváno {:08x}",
         i + 1,
         generated,
         expected
      );
   }
}

#[test]
fn test_magma_rfc8891_big_endian() {
   // Klíč zapsaný jako Big-Endian u32 (přesně jak je v RFC)
   let master_key: [u32; 8] = [
      0xffeeddcc, 0xbbaa9988, 0x77665544, 0x33221100, 0xf0f1f2f3, 0xf4f5f6f7, 0xf8f9fafb, 0xfcfdfeff,
   ];

   let l_plain = 0xfedcba98_u32;
   let r_plain = 0x76543210_u32;

   let magma = FeistelNetwork::new(MagmaKeySchedule, MagmaRF, 32);

   // Šifrování
   let (enc_l, enc_r) = magma.process(l_plain, r_plain, &master_key);

   println!("Původní: {:08x} {:08x}", l_plain, r_plain);
   println!("Zašifrované: {:08x} {:08x}", enc_l, enc_r);

   // Očekávaný ciphertext (Big-Endian): 4ee901e5c2d8ca3d
   assert_eq!(enc_l, 0x4ee901e5);
   assert_eq!(enc_r, 0xc2d8ca3d);

   // Dešifrování
   let rev_ks = ReverseKeySchedule::from(MagmaKeySchedule, 32);
   let magma_dec = FeistelNetwork::new(rev_ks, MagmaRF, 32);

   let (dec_l, dec_r) = magma_dec.process(enc_l, enc_r, &master_key);

   assert_eq!(dec_l, l_plain);
   assert_eq!(dec_r, r_plain);
}

#[cfg(test)]
mod sbox_tests {
   use super::*;

   #[test]
   fn test_magma_sbox_substitution_vectors() {
      let cases = [
         (0xfdb97531, 0x2a196f34),
         (0x2a196f34, 0xebd9f03a),
         (0xebd9f03a, 0xb039bb3d),
         (0xb039bb3d, 0x68695433),
      ];

      for (input, expected) in cases {
         let result = MagmaRF::t(input);
         assert_eq!(
            result, expected,
            "S-Box selhal: t({:08x}) má být {:08x}, ale vyšlo {:08x}",
            input, expected, result
         );
      }
      println!("S-Box testy z RFC 8891 Appendix A.2 prošly!");
   }
}