include!(concat!(env!("OUT_DIR"), "/tables.rs"));
pub const BLOCKSIZE_IN_BYTES: usize = 16;
pub const KEY_BYTES_128BIT: usize = 16;
pub const KEY_BYTES_192BIT: usize = 24;
pub const KEY_BYTES_256BIT: usize = 32;
pub const N_SUBKEYS_128BIT: usize = 44;
pub const N_SUBKEYS_192BIT: usize = 52;
pub const N_SUBKEYS_256BIT: usize = 60;
macro_rules! four_u8_to_u32 {
($b0:expr, $b1:expr, $b2:expr, $b3:expr) => {
($b3 as u32) << 24 | ($b2 as u32) << 16 | ($b1 as u32) << 8 | $b0 as u32
};
}
macro_rules! u8_b3_of_u32 {
($w:expr) => {
($w >> 24) as u8
};
}
macro_rules! u8_b2_of_u32 {
($w:expr) => {
($w >> 16) as u8
};
}
macro_rules! u8_b1_of_u32 {
($w:expr) => {
($w >> 8) as u8
};
}
macro_rules! u8_b0_of_u32 {
($w:expr) => {
$w as u8
};
}
macro_rules! usize_b3_of_u32 {
($w:expr) => {
($w >> 24) as usize
};
}
macro_rules! usize_b2_of_u32 {
($w:expr) => {
u8_b2_of_u32!($w) as usize
};
}
macro_rules! usize_b1_of_u32 {
($w:expr) => {
u8_b1_of_u32!($w) as usize
};
}
macro_rules! usize_b0_of_u32 {
($w:expr) => {
u8_b0_of_u32!($w) as usize
};
}
macro_rules! round_g_function {
($word:expr, $round:expr) => {
four_u8_to_u32!(
SBOX[usize_b1_of_u32!($word)] ^ RC[$round],
SBOX[usize_b2_of_u32!($word)],
SBOX[usize_b3_of_u32!($word)],
SBOX[usize_b0_of_u32!($word)]
)
};
}
macro_rules! round_h_function {
($word:expr) => {
four_u8_to_u32!(
SBOX[usize_b0_of_u32!($word)],
SBOX[usize_b1_of_u32!($word)],
SBOX[usize_b2_of_u32!($word)],
SBOX[usize_b3_of_u32!($word)]
)
};
}
macro_rules! key_schedule_128_function {
($origin:ident, $subkeys:ident) => {{
::std::assert_eq!($subkeys.len(), N_SUBKEYS_128BIT);
for i in 0..4 {
$subkeys[i] = four_u8_to_u32!(
$origin[4 * i],
$origin[4 * i + 1],
$origin[4 * i + 2],
$origin[4 * i + 3]
);
}
for i in 0..10 {
$subkeys[4 * i + 4] = $subkeys[4 * i] ^ round_g_function!($subkeys[4 * i + 3], i);
$subkeys[4 * i + 5] = $subkeys[4 * i + 1] ^ $subkeys[4 * i + 4];
$subkeys[4 * i + 6] = $subkeys[4 * i + 2] ^ $subkeys[4 * i + 5];
$subkeys[4 * i + 7] = $subkeys[4 * i + 3] ^ $subkeys[4 * i + 6];
}
}};
}
macro_rules! key_schedule_192_function {
($origin:ident, $subkeys:ident) => {{
::std::assert_eq!($subkeys.len(), N_SUBKEYS_192BIT);
for i in 0..6 {
$subkeys[i] = four_u8_to_u32!(
$origin[4 * i],
$origin[4 * i + 1],
$origin[4 * i + 2],
$origin[4 * i + 3]
);
}
for i in 0..7 {
$subkeys[6 * i + 6] = $subkeys[6 * i] ^ round_g_function!($subkeys[6 * i + 5], i);
$subkeys[6 * i + 7] = $subkeys[6 * i + 1] ^ $subkeys[6 * i + 6];
$subkeys[6 * i + 8] = $subkeys[6 * i + 2] ^ $subkeys[6 * i + 7];
$subkeys[6 * i + 9] = $subkeys[6 * i + 3] ^ $subkeys[6 * i + 8];
$subkeys[6 * i + 10] = $subkeys[6 * i + 4] ^ $subkeys[6 * i + 9];
$subkeys[6 * i + 11] = $subkeys[6 * i + 5] ^ $subkeys[6 * i + 10];
}
$subkeys[48] = $subkeys[42] ^ round_g_function!($subkeys[47], 7);
$subkeys[49] = $subkeys[43] ^ $subkeys[48];
$subkeys[50] = $subkeys[44] ^ $subkeys[49];
$subkeys[51] = $subkeys[45] ^ $subkeys[50];
}};
}
macro_rules! key_schedule_256_function {
($origin:ident, $subkeys:ident) => {{
::std::assert_eq!($subkeys.len(), N_SUBKEYS_256BIT);
for i in 0..8 {
$subkeys[i] = four_u8_to_u32!(
$origin[4 * i],
$origin[4 * i + 1],
$origin[4 * i + 2],
$origin[4 * i + 3]
);
}
for i in 0..6 {
$subkeys[8 * i + 8] = $subkeys[8 * i] ^ round_g_function!($subkeys[8 * i + 7], i);
$subkeys[8 * i + 9] = $subkeys[8 * i + 1] ^ $subkeys[8 * i + 8];
$subkeys[8 * i + 10] = $subkeys[8 * i + 2] ^ $subkeys[8 * i + 9];
$subkeys[8 * i + 11] = $subkeys[8 * i + 3] ^ $subkeys[8 * i + 10];
$subkeys[8 * i + 12] = $subkeys[8 * i + 4] ^ round_h_function!($subkeys[8 * i + 11]);
$subkeys[8 * i + 13] = $subkeys[8 * i + 5] ^ $subkeys[8 * i + 12];
$subkeys[8 * i + 14] = $subkeys[8 * i + 6] ^ $subkeys[8 * i + 13];
$subkeys[8 * i + 15] = $subkeys[8 * i + 7] ^ $subkeys[8 * i + 14];
}
$subkeys[56] = $subkeys[48] ^ round_g_function!($subkeys[55], 6);
$subkeys[57] = $subkeys[49] ^ $subkeys[56];
$subkeys[58] = $subkeys[50] ^ $subkeys[57];
$subkeys[59] = $subkeys[51] ^ $subkeys[58];
}};
}
macro_rules! dkey_mixcolumn {
($subkeys:ident, $length:expr) => {{
for i in 4..($length - 4) {
$subkeys[i] = TD0[SBOX[usize_b0_of_u32!($subkeys[i])] as usize]
^ TD1[SBOX[usize_b1_of_u32!($subkeys[i])] as usize]
^ TD2[SBOX[usize_b2_of_u32!($subkeys[i])] as usize]
^ TD3[SBOX[usize_b3_of_u32!($subkeys[i])] as usize];
}
}};
}
macro_rules! encryption_function {
($input:ident, $output:ident, $subkeys:ident, $inner_rounds:expr, $subkeys_length:expr) => {
::std::assert_eq!($output.len(), 128 / 8);
::std::assert_eq!($input.len(), 128 / 8);
::std::assert_eq!($subkeys.len(), $subkeys_length);
let mut wa0 = four_u8_to_u32!($input[0], $input[1], $input[2], $input[3]) ^ $subkeys[0];
let mut wa1 = four_u8_to_u32!($input[4], $input[5], $input[6], $input[7]) ^ $subkeys[1];
let mut wa2 = four_u8_to_u32!($input[8], $input[9], $input[10], $input[11]) ^ $subkeys[2];
let mut wa3 = four_u8_to_u32!($input[12], $input[13], $input[14], $input[15]) ^ $subkeys[3];
let mut wb0 = TE0[usize_b0_of_u32!(wa0)]
^ TE1[usize_b1_of_u32!(wa1)]
^ TE2[usize_b2_of_u32!(wa2)]
^ TE3[usize_b3_of_u32!(wa3)]
^ $subkeys[4];
let mut wb1 = TE0[usize_b0_of_u32!(wa1)]
^ TE1[usize_b1_of_u32!(wa2)]
^ TE2[usize_b2_of_u32!(wa3)]
^ TE3[usize_b3_of_u32!(wa0)]
^ $subkeys[5];
let mut wb2 = TE0[usize_b0_of_u32!(wa2)]
^ TE1[usize_b1_of_u32!(wa3)]
^ TE2[usize_b2_of_u32!(wa0)]
^ TE3[usize_b3_of_u32!(wa1)]
^ $subkeys[6];
let mut wb3 = TE0[usize_b0_of_u32!(wa3)]
^ TE1[usize_b1_of_u32!(wa0)]
^ TE2[usize_b2_of_u32!(wa1)]
^ TE3[usize_b3_of_u32!(wa2)]
^ $subkeys[7];
for i in 1..$inner_rounds {
wa0 = TE0[usize_b0_of_u32!(wb0)]
^ TE1[usize_b1_of_u32!(wb1)]
^ TE2[usize_b2_of_u32!(wb2)]
^ TE3[usize_b3_of_u32!(wb3)]
^ $subkeys[8 * i];
wa1 = TE0[usize_b0_of_u32!(wb1)]
^ TE1[usize_b1_of_u32!(wb2)]
^ TE2[usize_b2_of_u32!(wb3)]
^ TE3[usize_b3_of_u32!(wb0)]
^ $subkeys[8 * i + 1];
wa2 = TE0[usize_b0_of_u32!(wb2)]
^ TE1[usize_b1_of_u32!(wb3)]
^ TE2[usize_b2_of_u32!(wb0)]
^ TE3[usize_b3_of_u32!(wb1)]
^ $subkeys[8 * i + 2];
wa3 = TE0[usize_b0_of_u32!(wb3)]
^ TE1[usize_b1_of_u32!(wb0)]
^ TE2[usize_b2_of_u32!(wb1)]
^ TE3[usize_b3_of_u32!(wb2)]
^ $subkeys[8 * i + 3];
wb0 = TE0[usize_b0_of_u32!(wa0)]
^ TE1[usize_b1_of_u32!(wa1)]
^ TE2[usize_b2_of_u32!(wa2)]
^ TE3[usize_b3_of_u32!(wa3)]
^ $subkeys[8 * i + 4];
wb1 = TE0[usize_b0_of_u32!(wa1)]
^ TE1[usize_b1_of_u32!(wa2)]
^ TE2[usize_b2_of_u32!(wa3)]
^ TE3[usize_b3_of_u32!(wa0)]
^ $subkeys[8 * i + 5];
wb2 = TE0[usize_b0_of_u32!(wa2)]
^ TE1[usize_b1_of_u32!(wa3)]
^ TE2[usize_b2_of_u32!(wa0)]
^ TE3[usize_b3_of_u32!(wa1)]
^ $subkeys[8 * i + 6];
wb3 = TE0[usize_b0_of_u32!(wa3)]
^ TE1[usize_b1_of_u32!(wa0)]
^ TE2[usize_b2_of_u32!(wa1)]
^ TE3[usize_b3_of_u32!(wa2)]
^ $subkeys[8 * i + 7];
}
$output[15] = SBOX[usize_b3_of_u32!(wb2)] ^ u8_b3_of_u32!($subkeys[$subkeys_length - 1]);
$output[14] = SBOX[usize_b2_of_u32!(wb1)] ^ u8_b2_of_u32!($subkeys[$subkeys_length - 1]);
$output[13] = SBOX[usize_b1_of_u32!(wb0)] ^ u8_b1_of_u32!($subkeys[$subkeys_length - 1]);
$output[12] = SBOX[usize_b0_of_u32!(wb3)] ^ u8_b0_of_u32!($subkeys[$subkeys_length - 1]);
$output[11] = SBOX[usize_b3_of_u32!(wb1)] ^ u8_b3_of_u32!($subkeys[$subkeys_length - 2]);
$output[10] = SBOX[usize_b2_of_u32!(wb0)] ^ u8_b2_of_u32!($subkeys[$subkeys_length - 2]);
$output[9] = SBOX[usize_b1_of_u32!(wb3)] ^ u8_b1_of_u32!($subkeys[$subkeys_length - 2]);
$output[8] = SBOX[usize_b0_of_u32!(wb2)] ^ u8_b0_of_u32!($subkeys[$subkeys_length - 2]);
$output[7] = SBOX[usize_b3_of_u32!(wb0)] ^ u8_b3_of_u32!($subkeys[$subkeys_length - 3]);
$output[6] = SBOX[usize_b2_of_u32!(wb3)] ^ u8_b2_of_u32!($subkeys[$subkeys_length - 3]);
$output[5] = SBOX[usize_b1_of_u32!(wb2)] ^ u8_b1_of_u32!($subkeys[$subkeys_length - 3]);
$output[4] = SBOX[usize_b0_of_u32!(wb1)] ^ u8_b0_of_u32!($subkeys[$subkeys_length - 3]);
$output[3] = SBOX[usize_b3_of_u32!(wb3)] ^ u8_b3_of_u32!($subkeys[$subkeys_length - 4]);
$output[2] = SBOX[usize_b2_of_u32!(wb2)] ^ u8_b2_of_u32!($subkeys[$subkeys_length - 4]);
$output[1] = SBOX[usize_b1_of_u32!(wb1)] ^ u8_b1_of_u32!($subkeys[$subkeys_length - 4]);
$output[0] = SBOX[usize_b0_of_u32!(wb0)] ^ u8_b0_of_u32!($subkeys[$subkeys_length - 4]);
};
}
macro_rules! decryption_function {
($input:ident, $output:ident, $subkeys:ident, $inner_rounds:expr, $subkeys_length:expr) => {{
::std::assert_eq!($output.len(), 128 / 8);
::std::assert_eq!($input.len(), 128 / 8);
::std::assert_eq!($subkeys.len(), $subkeys_length);
let mut wa0 = four_u8_to_u32!($input[0], $input[1], $input[2], $input[3])
^ $subkeys[$subkeys_length - 4];
let mut wa1 = four_u8_to_u32!($input[4], $input[5], $input[6], $input[7])
^ $subkeys[$subkeys_length - 3];
let mut wa2 = four_u8_to_u32!($input[8], $input[9], $input[10], $input[11])
^ $subkeys[$subkeys_length - 2];
let mut wa3 = four_u8_to_u32!($input[12], $input[13], $input[14], $input[15])
^ $subkeys[$subkeys_length - 1];
let mut wb0 = TD0[usize_b0_of_u32!(wa0)]
^ TD1[usize_b1_of_u32!(wa3)]
^ TD2[usize_b2_of_u32!(wa2)]
^ TD3[usize_b3_of_u32!(wa1)]
^ $subkeys[$subkeys_length - 8];
let mut wb1 = TD0[usize_b0_of_u32!(wa1)]
^ TD1[usize_b1_of_u32!(wa0)]
^ TD2[usize_b2_of_u32!(wa3)]
^ TD3[usize_b3_of_u32!(wa2)]
^ $subkeys[$subkeys_length - 7];
let mut wb2 = TD0[usize_b0_of_u32!(wa2)]
^ TD1[usize_b1_of_u32!(wa1)]
^ TD2[usize_b2_of_u32!(wa0)]
^ TD3[usize_b3_of_u32!(wa3)]
^ $subkeys[$subkeys_length - 6];
let mut wb3 = TD0[usize_b0_of_u32!(wa3)]
^ TD1[usize_b1_of_u32!(wa2)]
^ TD2[usize_b2_of_u32!(wa1)]
^ TD3[usize_b3_of_u32!(wa0)]
^ $subkeys[$subkeys_length - 5];
for i in 1..$inner_rounds {
wa0 = TD0[usize_b0_of_u32!(wb0)]
^ TD1[usize_b1_of_u32!(wb3)]
^ TD2[usize_b2_of_u32!(wb2)]
^ TD3[usize_b3_of_u32!(wb1)]
^ $subkeys[$subkeys_length - 4 - (8 * i)];
wa1 = TD0[usize_b0_of_u32!(wb1)]
^ TD1[usize_b1_of_u32!(wb0)]
^ TD2[usize_b2_of_u32!(wb3)]
^ TD3[usize_b3_of_u32!(wb2)]
^ $subkeys[$subkeys_length - 3 - (8 * i)];
wa2 = TD0[usize_b0_of_u32!(wb2)]
^ TD1[usize_b1_of_u32!(wb1)]
^ TD2[usize_b2_of_u32!(wb0)]
^ TD3[usize_b3_of_u32!(wb3)]
^ $subkeys[$subkeys_length - 2 - (8 * i)];
wa3 = TD0[usize_b0_of_u32!(wb3)]
^ TD1[usize_b1_of_u32!(wb2)]
^ TD2[usize_b2_of_u32!(wb1)]
^ TD3[usize_b3_of_u32!(wb0)]
^ $subkeys[$subkeys_length - 1 - (8 * i)];
wb0 = TD0[usize_b0_of_u32!(wa0)]
^ TD1[usize_b1_of_u32!(wa3)]
^ TD2[usize_b2_of_u32!(wa2)]
^ TD3[usize_b3_of_u32!(wa1)]
^ $subkeys[$subkeys_length - 8 - (8 * i)];
wb1 = TD0[usize_b0_of_u32!(wa1)]
^ TD1[usize_b1_of_u32!(wa0)]
^ TD2[usize_b2_of_u32!(wa3)]
^ TD3[usize_b3_of_u32!(wa2)]
^ $subkeys[$subkeys_length - 7 - (8 * i)];
wb2 = TD0[usize_b0_of_u32!(wa2)]
^ TD1[usize_b1_of_u32!(wa1)]
^ TD2[usize_b2_of_u32!(wa0)]
^ TD3[usize_b3_of_u32!(wa3)]
^ $subkeys[$subkeys_length - 6 - (8 * i)];
wb3 = TD0[usize_b0_of_u32!(wa3)]
^ TD1[usize_b1_of_u32!(wa2)]
^ TD2[usize_b2_of_u32!(wa1)]
^ TD3[usize_b3_of_u32!(wa0)]
^ $subkeys[$subkeys_length - 5 - (8 * i)];
}
$output[15] = SINV[usize_b3_of_u32!(wb0)] ^ u8_b3_of_u32!($subkeys[3]);
$output[14] = SINV[usize_b2_of_u32!(wb1)] ^ u8_b2_of_u32!($subkeys[3]);
$output[13] = SINV[usize_b1_of_u32!(wb2)] ^ u8_b1_of_u32!($subkeys[3]);
$output[12] = SINV[usize_b0_of_u32!(wb3)] ^ u8_b0_of_u32!($subkeys[3]);
$output[11] = SINV[usize_b3_of_u32!(wb3)] ^ u8_b3_of_u32!($subkeys[2]);
$output[10] = SINV[usize_b2_of_u32!(wb0)] ^ u8_b2_of_u32!($subkeys[2]);
$output[9] = SINV[usize_b1_of_u32!(wb1)] ^ u8_b1_of_u32!($subkeys[2]);
$output[8] = SINV[usize_b0_of_u32!(wb2)] ^ u8_b0_of_u32!($subkeys[2]);
$output[7] = SINV[usize_b3_of_u32!(wb2)] ^ u8_b3_of_u32!($subkeys[1]);
$output[6] = SINV[usize_b2_of_u32!(wb3)] ^ u8_b2_of_u32!($subkeys[1]);
$output[5] = SINV[usize_b1_of_u32!(wb0)] ^ u8_b1_of_u32!($subkeys[1]);
$output[4] = SINV[usize_b0_of_u32!(wb1)] ^ u8_b0_of_u32!($subkeys[1]);
$output[3] = SINV[usize_b3_of_u32!(wb1)] ^ u8_b3_of_u32!($subkeys[0]);
$output[2] = SINV[usize_b2_of_u32!(wb2)] ^ u8_b2_of_u32!($subkeys[0]);
$output[1] = SINV[usize_b1_of_u32!(wb3)] ^ u8_b1_of_u32!($subkeys[0]);
$output[0] = SINV[usize_b0_of_u32!(wb0)] ^ u8_b0_of_u32!($subkeys[0]);
}};
}
pub fn key_schedule_encrypt_auto(origin: &[u8], buffer: &mut [u32]) {
match origin.len() {
KEY_BYTES_128BIT => key_schedule_128_function!(origin, buffer),
KEY_BYTES_192BIT => key_schedule_192_function!(origin, buffer),
KEY_BYTES_256BIT => key_schedule_256_function!(origin, buffer),
_ => panic!("Invalid key length."),
}
}
pub fn key_schedule_encrypt128(origin: &[u8], buffer: &mut [u32]) {
assert_eq!(origin.len(), 128 / 8);
key_schedule_128_function!(origin, buffer);
}
pub fn key_schedule_encrypt192(origin: &[u8], buffer: &mut [u32]) {
assert_eq!(origin.len(), 192 / 8);
key_schedule_192_function!(origin, buffer);
}
pub fn key_schedule_encrypt256(origin: &[u8], buffer: &mut [u32]) {
assert_eq!(origin.len(), 256 / 8);
key_schedule_256_function!(origin, buffer);
}
pub fn key_schedule_decrypt_auto(origin: &[u8], buffer: &mut [u32]) {
match origin.len() {
KEY_BYTES_128BIT => {
key_schedule_128_function!(origin, buffer);
dkey_mixcolumn!(buffer, N_SUBKEYS_128BIT);
}
KEY_BYTES_192BIT => {
key_schedule_192_function!(origin, buffer);
dkey_mixcolumn!(buffer, N_SUBKEYS_192BIT);
}
KEY_BYTES_256BIT => {
key_schedule_256_function!(origin, buffer);
dkey_mixcolumn!(buffer, N_SUBKEYS_256BIT);
}
_ => panic!("Invalid key length."),
}
}
pub fn key_schedule_decrypt128(origin: &[u8], buffer: &mut [u32]) {
assert_eq!(origin.len(), KEY_BYTES_128BIT);
key_schedule_128_function!(origin, buffer);
dkey_mixcolumn!(buffer, N_SUBKEYS_128BIT);
}
pub fn key_schedule_decrypt192(origin: &[u8], buffer: &mut [u32]) {
assert_eq!(origin.len(), KEY_BYTES_192BIT);
key_schedule_192_function!(origin, buffer);
dkey_mixcolumn!(buffer, N_SUBKEYS_192BIT);
}
pub fn key_schedule_decrypt256(origin: &[u8], buffer: &mut [u32]) {
assert_eq!(origin.len(), KEY_BYTES_256BIT);
key_schedule_256_function!(origin, buffer);
dkey_mixcolumn!(buffer, N_SUBKEYS_256BIT);
}
pub fn block_encrypt128_inplace(block: &mut [u8], subkeys: &[u32]) {
encryption_function!(block, block, subkeys, 5, N_SUBKEYS_128BIT);
}
pub fn block_encrypt192_inplace(block: &mut [u8], subkeys: &[u32]) {
encryption_function!(block, block, subkeys, 6, N_SUBKEYS_192BIT);
}
pub fn block_encrypt256_inplace(block: &mut [u8], subkeys: &[u32]) {
encryption_function!(block, block, subkeys, 7, N_SUBKEYS_256BIT);
}
pub fn block_decrypt128_inplace(block: &mut [u8], subkeys: &[u32]) {
decryption_function!(block, block, subkeys, 5, N_SUBKEYS_128BIT);
}
pub fn block_decrypt192_inplace(block: &mut [u8], subkeys: &[u32]) {
decryption_function!(block, block, subkeys, 6, N_SUBKEYS_192BIT);
}
pub fn block_decrypt256_inplace(block: &mut [u8], subkeys: &[u32]) {
decryption_function!(block, block, subkeys, 7, N_SUBKEYS_256BIT);
}
pub fn block_encrypt128(input: &[u8], output: &mut [u8], subkeys: &[u32]) {
encryption_function!(input, output, subkeys, 5, N_SUBKEYS_128BIT);
}
pub fn block_encrypt192(input: &[u8], output: &mut [u8], subkeys: &[u32]) {
encryption_function!(input, output, subkeys, 6, N_SUBKEYS_192BIT);
}
pub fn block_encrypt256(input: &[u8], output: &mut [u8], subkeys: &[u32]) {
encryption_function!(input, output, subkeys, 7, N_SUBKEYS_256BIT);
}
pub fn block_decrypt128(input: &[u8], output: &mut [u8], subkeys: &[u32]) {
decryption_function!(input, output, subkeys, 5, N_SUBKEYS_128BIT);
}
pub fn block_decrypt192(input: &[u8], output: &mut [u8], subkeys: &[u32]) {
decryption_function!(input, output, subkeys, 6, N_SUBKEYS_192BIT);
}
pub fn block_decrypt256(input: &[u8], output: &mut [u8], subkeys: &[u32]) {
decryption_function!(input, output, subkeys, 7, N_SUBKEYS_256BIT);
}
#[cfg(test)]
mod tests {
use super::*;
use crate::misc::hex;
#[test]
fn key_schedule_decrypt128_works() {
let origin_key: [u8; KEY_BYTES_128BIT] = [
0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF,
0x4F, 0x3C,
];
let mut subkeys: [u32; N_SUBKEYS_128BIT] = [0; N_SUBKEYS_128BIT];
key_schedule_decrypt128(&origin_key, &mut subkeys);
let expected: [u32; N_SUBKEYS_128BIT] = [
hex("2B7E1516"),
hex("28AED2A6"),
hex("ABF71588"),
hex("09CF4F3C"),
hex("2B3708A7"),
hex("F262D405"),
hex("BC3EBDBF"),
hex("4B617D62"),
hex("CC7505EB"),
hex("3E17D1EE"),
hex("82296C51"),
hex("C9481133"),
hex("7C1F13F7"),
hex("4208C219"),
hex("C021AE48"),
hex("0969BF7B"),
hex("90884413"),
hex("D280860A"),
hex("12A12842"),
hex("1BC89739"),
hex("6EA30AFC"),
hex("BC238CF6"),
hex("AE82A4B4"),
hex("B54A338D"),
hex("6EFCD876"),
hex("D2DF5480"),
hex("7C5DF034"),
hex("C917C3B9"),
hex("12C07647"),
hex("C01F22C7"),
hex("BC42D2F3"),
hex("7555114A"),
hex("DF7D925A"),
hex("1F62B09D"),
hex("A320626E"),
hex("D6757324"),
hex("0C7B5A63"),
hex("1319EAFE"),
hex("B0398890"),
hex("664CFBB4"),
hex("D014F9A8"),
hex("C9EE2589"),
hex("E13F0CC8"),
hex("B6630CA6"),
];
for i in 0..N_SUBKEYS_128BIT {
assert_eq!(subkeys[i], expected[i]);
}
}
#[test]
fn key_schedule_decrypt192_works() {
let origin_key: [u8; KEY_BYTES_192BIT] = [
0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90,
0x79, 0xE5, 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B,
];
let mut subkeys: [u32; N_SUBKEYS_192BIT] = [0; N_SUBKEYS_192BIT];
key_schedule_decrypt192(&origin_key, &mut subkeys);
let expected: [u32; N_SUBKEYS_192BIT] = [
hex("8E73B0F7"),
hex("DA0E6452"),
hex("C810F32B"),
hex("809079E5"),
hex("9EB149C4"),
hex("79D69C5D"),
hex("FEB4A27C"),
hex("EAB6D7FD"),
hex("659763E7"),
hex("8C817087"),
hex("12303943"),
hex("6BE6A51E"),
hex("41B34544"),
hex("AB0592B9"),
hex("CE92F15E"),
hex("421381D9"),
hex("5023B89A"),
hex("3BC51D84"),
hex("D04B1937"),
hex("7B4E8B8E"),
hex("B5DC7AD0"),
hex("F7CFFB09"),
hex("A7EC4393"),
hex("9C295E17"),
hex("C5DDB7F8"),
hex("BE933C76"),
hex("0B4F46A6"),
hex("FC80BDAF"),
hex("5B6CFE3C"),
hex("C745A02B"),
hex("F8B9A572"),
hex("462A9904"),
hex("4D65DFA2"),
hex("B1E5620D"),
hex("EA899C31"),
hex("2DCC3C1A"),
hex("F3B42258"),
hex("B59EBB5C"),
hex("F8FB64FE"),
hex("491E06F3"),
hex("A3979AC2"),
hex("8E5BA6D8"),
hex("E12CC9E6"),
hex("54B272BA"),
hex("AC491644"),
hex("E55710B7"),
hex("46C08A75"),
hex("C89B2CAD"),
hex("E98BA06F"),
hex("448C773C"),
hex("8ECC7204"),
hex("01002202"),
];
for i in 0..N_SUBKEYS_192BIT {
assert_eq!(subkeys[i], expected[i]);
}
}
#[test]
fn key_schedule_decrypt256_works() {
let origin_key: [u8; KEY_BYTES_256BIT] = [
0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D,
0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3,
0x09, 0x14, 0xDF, 0xF4,
];
let mut subkeys: [u32; N_SUBKEYS_256BIT] = [0; N_SUBKEYS_256BIT];
key_schedule_decrypt256(&origin_key, &mut subkeys);
let expected: [u32; N_SUBKEYS_256BIT] = [
hex("603DEB10"),
hex("15CA71BE"),
hex("2B73AEF0"),
hex("857D7781"),
hex("8EC6BFF6"),
hex("829CA03B"),
hex("9E49AF7E"),
hex("DBA96125"),
hex("42107758"),
hex("E9EC98F0"),
hex("66329EA1"),
hex("93F8858B"),
hex("4A7459F9"),
hex("C8E8F9C2"),
hex("56A156BC"),
hex("8D083799"),
hex("6C3D6329"),
hex("85D1FBD9"),
hex("E3E36578"),
hex("701BE0F3"),
hex("54FB808B"),
hex("9C137949"),
hex("CAB22FF5"),
hex("47BA186C"),
hex("25BA3C22"),
hex("A06BC7FB"),
hex("4388A283"),
hex("33934270"),
hex("D669A733"),
hex("4A7ADE7A"),
hex("80C8F18F"),
hex("C772E9E3"),
hex("C440B289"),
hex("642B7572"),
hex("27A3D7F1"),
hex("14309581"),
hex("32526C36"),
hex("7828B24C"),
hex("F8E043C3"),
hex("3F92AA20"),
hex("34AD1E44"),
hex("50866B36"),
hex("7725BCC7"),
hex("63152946"),
hex("B668B621"),
hex("CE40046D"),
hex("36A047AE"),
hex("0932ED8E"),
hex("57C96CF6"),
hex("074F07C0"),
hex("706ABB07"),
hex("137F9241"),
hex("ADA23F49"),
hex("63E23B24"),
hex("55427C8A"),
hex("5C709104"),
hex("FE4890D1"),
hex("E6188D0B"),
hex("046DF344"),
hex("706C631E"),
];
for i in 0..N_SUBKEYS_256BIT {
assert_eq!(subkeys[i], expected[i]);
}
}
#[test]
fn key_schedule_encrypt_auto_works() {
let origin128: [u8; KEY_BYTES_128BIT] = [
0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF,
0x4F, 0x3C,
];
let mut scheduled128a: [u32; N_SUBKEYS_128BIT] = [0; N_SUBKEYS_128BIT];
let mut scheduled128b: [u32; N_SUBKEYS_128BIT] = [0; N_SUBKEYS_128BIT];
key_schedule_encrypt_auto(&origin128, &mut scheduled128a);
key_schedule_encrypt128(&origin128, &mut scheduled128b);
for i in 0..N_SUBKEYS_128BIT {
assert_eq!(scheduled128a[i], scheduled128b[i]);
}
let origin192: [u8; KEY_BYTES_192BIT] = [
0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90,
0x79, 0xE5, 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B,
];
let mut scheduled192a: [u32; N_SUBKEYS_192BIT] = [0; N_SUBKEYS_192BIT];
let mut scheduled192b: [u32; N_SUBKEYS_192BIT] = [0; N_SUBKEYS_192BIT];
key_schedule_encrypt_auto(&origin192, &mut scheduled192a);
key_schedule_encrypt192(&origin192, &mut scheduled192b);
for i in 0..N_SUBKEYS_192BIT {
assert_eq!(scheduled192a[i], scheduled192b[i]);
}
let origin256: [u8; KEY_BYTES_256BIT] = [
0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D,
0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3,
0x09, 0x14, 0xDF, 0xF4,
];
let mut scheduled256a: [u32; N_SUBKEYS_256BIT] = [0; N_SUBKEYS_256BIT];
let mut scheduled256b: [u32; N_SUBKEYS_256BIT] = [0; N_SUBKEYS_256BIT];
key_schedule_encrypt_auto(&origin256, &mut scheduled256a);
key_schedule_encrypt256(&origin256, &mut scheduled256b);
for i in 0..N_SUBKEYS_256BIT {
assert_eq!(scheduled256a[i], scheduled256b[i]);
}
}
#[test]
fn key_schedule_decrypt_auto_works() {
let origin128: [u8; KEY_BYTES_128BIT] = [
0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF,
0x4F, 0x3C,
];
let mut scheduled128a: [u32; N_SUBKEYS_128BIT] = [0; N_SUBKEYS_128BIT];
let mut scheduled128b: [u32; N_SUBKEYS_128BIT] = [0; N_SUBKEYS_128BIT];
key_schedule_decrypt_auto(&origin128, &mut scheduled128a);
key_schedule_decrypt128(&origin128, &mut scheduled128b);
for i in 0..N_SUBKEYS_128BIT {
assert_eq!(scheduled128a[i], scheduled128b[i]);
}
let origin192: [u8; KEY_BYTES_192BIT] = [
0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90,
0x79, 0xE5, 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B,
];
let mut scheduled192a: [u32; N_SUBKEYS_192BIT] = [0; N_SUBKEYS_192BIT];
let mut scheduled192b: [u32; N_SUBKEYS_192BIT] = [0; N_SUBKEYS_192BIT];
key_schedule_decrypt_auto(&origin192, &mut scheduled192a);
key_schedule_decrypt192(&origin192, &mut scheduled192b);
for i in 0..N_SUBKEYS_192BIT {
assert_eq!(scheduled192a[i], scheduled192b[i]);
}
let origin256: [u8; KEY_BYTES_256BIT] = [
0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D,
0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3,
0x09, 0x14, 0xDF, 0xF4,
];
let mut scheduled256a: [u32; N_SUBKEYS_256BIT] = [0; N_SUBKEYS_256BIT];
let mut scheduled256b: [u32; N_SUBKEYS_256BIT] = [0; N_SUBKEYS_256BIT];
key_schedule_decrypt_auto(&origin256, &mut scheduled256a);
key_schedule_decrypt256(&origin256, &mut scheduled256b);
for i in 0..N_SUBKEYS_256BIT {
assert_eq!(scheduled256a[i], scheduled256b[i]);
}
}
}