vector test from C implementation
This commit is contained in:
+109
@@ -414,4 +414,113 @@ mod tests {
|
|||||||
|
|
||||||
assert_ne!(predicted, cipher.next_byte());
|
assert_ne!(predicted, cipher.next_byte());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//###################
|
||||||
|
// C vector test
|
||||||
|
//###################
|
||||||
|
|
||||||
|
const LUT_A: [u16; 8] = [
|
||||||
|
0x92A7, 0xA761, 0x974C, 0x6B8C,
|
||||||
|
0x29CE, 0x176C, 0x39D4, 0x7463,
|
||||||
|
];
|
||||||
|
|
||||||
|
const LUT_B: [u16; 8] = [
|
||||||
|
0x9D58, 0xA46D, 0x176C, 0x79C4,
|
||||||
|
0xC62B, 0xB2C9, 0x4D93, 0x2E93,
|
||||||
|
];
|
||||||
|
|
||||||
|
fn compute_iv(dw_frame_numbers: u32) -> u64 {
|
||||||
|
let mut dw_xorred = dw_frame_numbers ^ 0xC43A7D51;
|
||||||
|
dw_xorred = dw_xorred.rotate_left(8);
|
||||||
|
let qw_iv = ((dw_frame_numbers as u64) << 32) | (dw_xorred as u64);
|
||||||
|
qw_iv.rotate_right(8)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tea3_reorder_state_byte(b_st_byte: u8) -> u8 {
|
||||||
|
let mut b_out = 0u8;
|
||||||
|
b_out |= (b_st_byte << 6) & 0x40;
|
||||||
|
b_out |= (b_st_byte << 1) & 0x20;
|
||||||
|
b_out |= (b_st_byte << 2) & 0x98;
|
||||||
|
b_out |= (b_st_byte >> 4) & 0x04;
|
||||||
|
b_out |= (b_st_byte >> 3) & 0x01;
|
||||||
|
b_out |= (b_st_byte >> 6) & 0x02;
|
||||||
|
b_out
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tea3_state_word_to_newbyte(w_st: u16, aw_lut: &[u16; 8]) -> u8 {
|
||||||
|
let mut b_st0 = (w_st & 0x00FF) as u8;
|
||||||
|
let mut b_st1 = (w_st >> 8) as u8;
|
||||||
|
|
||||||
|
let mut b_out = 0u8;
|
||||||
|
|
||||||
|
for i in 0..8 {
|
||||||
|
let b_dist = ((b_st0 >> 5) & 0x03) | ((b_st1 >> 3) & 0x0C);
|
||||||
|
if (aw_lut[i] & (1 << b_dist)) != 0 {
|
||||||
|
b_out |= 1 << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_st0 = b_st0.rotate_right(1);
|
||||||
|
b_st1 = b_st1.rotate_right(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
b_out
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tea3_reference(dw_frame_numbers: u32, key: &[u8; 10], out_len: usize) -> Vec<u8> {
|
||||||
|
let mut key_reg = *key;
|
||||||
|
let mut iv = compute_iv(dw_frame_numbers);
|
||||||
|
let mut out = Vec::with_capacity(out_len);
|
||||||
|
|
||||||
|
let mut num_skip_rounds = 51usize;
|
||||||
|
|
||||||
|
for _ in 0..out_len {
|
||||||
|
for _ in 0..num_skip_rounds {
|
||||||
|
// Step 1: key register
|
||||||
|
let sbox_out = TEA3_P[(key_reg[7] ^ key_reg[2]) as usize] ^ key_reg[0];
|
||||||
|
key_reg.copy_within(1..10, 0);
|
||||||
|
key_reg[9] = sbox_out;
|
||||||
|
|
||||||
|
// Step 2: state derived bytes
|
||||||
|
let deriv_byte12 =
|
||||||
|
tea3_state_word_to_newbyte(((iv >> 8) & 0xFFFF) as u16, &LUT_A);
|
||||||
|
let deriv_byte56 =
|
||||||
|
tea3_state_word_to_newbyte(((iv >> 40) & 0xFFFF) as u16, &LUT_B);
|
||||||
|
let reord_byte4 = tea3_reorder_state_byte(((iv >> 32) & 0xFF) as u8);
|
||||||
|
|
||||||
|
// Step 3: combine
|
||||||
|
let new_byte = (((iv >> 56) as u8) ^ reord_byte4 ^ deriv_byte12 ^ sbox_out) & 0xFF;
|
||||||
|
let mix_byte = deriv_byte56 as u64;
|
||||||
|
|
||||||
|
// Step 4: update IV, state
|
||||||
|
iv = ((iv << 8) ^ (mix_byte << 40)) | (new_byte as u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
out.push((iv >> 56) as u8);
|
||||||
|
num_skip_rounds = 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tea3_c_vectors() {
|
||||||
|
let cases: [([u8; 10], u32, [u8; 10]); 2] = [
|
||||||
|
(
|
||||||
|
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
|
||||||
|
0x11111111,
|
||||||
|
[0x06, 0xA6, 0x58, 0x8C, 0x5D, 0x9A, 0x99, 0x6D, 0xD2, 0x5E],
|
||||||
|
),
|
||||||
|
(
|
||||||
|
[0xA7, 0x98, 0x39, 0xE4, 0xBA, 0x88, 0xEE, 0x54, 0xA0, 0x29],
|
||||||
|
0x01234567,
|
||||||
|
[0x02, 0x49, 0x1E, 0xF5, 0x57, 0xC5, 0x1C, 0x17, 0x73, 0x0C],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (key, frame, expected) in cases {
|
||||||
|
let got = tea3_reference(frame, &key, 10);
|
||||||
|
assert_eq!(got.as_slice(), &expected, "frame = {frame:#010X}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user