diff --git a/src/tea3.rs b/src/tea3.rs index 081cdd2..c8fdff3 100644 --- a/src/tea3.rs +++ b/src/tea3.rs @@ -1,3 +1,5 @@ +use crate::Lfsr; + #[derive(Debug, Clone)] pub struct Tea3 { /// Cipher key register k0..k9 @@ -89,14 +91,48 @@ mod tests { assert_eq!(tea3.key_register(), &[0x70, 1, 2, 3, 4, 5, 6, 7, 8, 9]); } - // #[test] - // fn test_decompose() { - // // key register should be able to be decomposed into 2 registers g and h, - // // both register of 5 bytes. - // // let's note the bytes of g, a0 to a4 - // // and the bytes of h, r0 to r4 - // // h feedback function should be r0 ^ s(r2) - // // g feedback function should be a0 ^ h.next_custom - // // then the byte a0 should be outputed - // } + #[test] + fn test_decompose() { + fn p(x: u8) -> u8 { + TEA3_P[x as usize] + } + + let k = vec![1u8, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + let mut tea3 = Tea3::new(k, vec![0; 8]); + + let mut full_outputs = Vec::new(); + for _ in 0..20 { + let kout = tea3.step_key_register(); + full_outputs.push(kout); + } + + let s = &full_outputs[0..10]; + + let g_orig = [s[0], s[1], s[2], s[3], s[4]]; + let h_orig = [ + s[5] ^ s[0], + s[6] ^ s[1], + s[7] ^ s[2], + s[8] ^ s[3], + s[9] ^ s[4], + ]; + + let g_rev: Vec = g_orig.iter().rev().copied().collect(); + let h_rev: Vec = h_orig.iter().rev().copied().collect(); + + let mut g_lfsr = Lfsr::new(5, vec![], g_rev); + let mut h_lfsr = Lfsr::new(5, vec![], h_rev); + + let mut decomposed_outputs = Vec::new(); + for _ in 0..20 { + let h_out = h_lfsr.next_custom([4, 2], |[h0, h2]| h0 ^ p(h2)); + let g_out = g_lfsr.next_custom([4], |[g0]| g0 ^ h_out); + decomposed_outputs.push(g_out); + } + + assert_eq!( + decomposed_outputs, full_outputs, + "g + h LFSRs must reproduce the exact output sequence" + ); + } }