#![no_std]
struct State {
state: [[u8;4];4], }
impl State {
const fn new(input: [u8;16]) -> Self {
Self{state: [
[input[0], input[1], input[2], input[3]],
[input[4], input[5], input[6], input[7]],
[input[8], input[9], input[10], input[11]],
[input[12], input[13], input[14], input[15]],
]}
}
const fn xor_roundkey(self, input: [u8;16]) -> Self {
Self{state: [
[
self.state[0][0] ^ input[0],
self.state[0][1] ^ input[1],
self.state[0][2] ^ input[2],
self.state[0][3] ^ input[3],
],
[
self.state[1][0] ^ input[4],
self.state[1][1] ^ input[5],
self.state[1][2] ^ input[6],
self.state[1][3] ^ input[7],
],
[
self.state[2][0] ^ input[8],
self.state[2][1] ^ input[9],
self.state[2][2] ^ input[10],
self.state[2][3] ^ input[11],
],
[
self.state[3][0] ^ input[12],
self.state[3][1] ^ input[13],
self.state[3][2] ^ input[14],
self.state[3][3] ^ input[15],
],
]}
}
const fn sub_bytes(self, inverse: bool) -> Self {
let mut state = [[0;4];4];
let mut outer_index = 0;
while outer_index != 4 {
let column = self.state[outer_index];
let mut inner_index = 0;
while inner_index != 4 {
state[outer_index][inner_index] = substitute_byte(column[inner_index], inverse);
inner_index += 1;
}
outer_index += 1;
}
Self{state}
}
const fn shift_rows(self, i: bool) -> Self { Self{state: [
[self.state[0][0], self.state[if i {3} else {1}][1], self.state[2][2], self.state[if i {1} else {3}][3]],
[self.state[1][0], self.state[if i {0} else {2}][1], self.state[3][2], self.state[if i {2} else {0}][3]],
[self.state[2][0], self.state[if i {1} else {3}][1], self.state[0][2], self.state[if i {3} else {1}][3]],
[self.state[3][0], self.state[if i {2} else {0}][1], self.state[1][2], self.state[if i {0} else {2}][3]],
]}
}
const fn mix_cols(self, inverse: bool) -> Self {
let mut state = [[0;4];4];
let mut i = 0; while i != 4 {
let copy = self.state[i];
if inverse {
state[i][0] = MUL14[copy[0] as usize]^MUL11[copy[1] as usize]^MUL13[copy[2] as usize]^MUL9[copy[3] as usize];
state[i][1] = MUL9[copy[0] as usize]^MUL14[copy[1] as usize]^MUL11[copy[2] as usize]^MUL13[copy[3] as usize];
state[i][2] = MUL13[copy[0] as usize]^MUL9[copy[1] as usize]^MUL14[copy[2] as usize]^MUL11[copy[3] as usize];
state[i][3] = MUL11[copy[0] as usize]^MUL13[copy[1] as usize]^MUL9[copy[2] as usize]^MUL14[copy[3] as usize];
} else {
state[i][0] = MUL2[copy[0] as usize]^MUL3[copy[1] as usize]^copy[2]^copy[3];
state[i][1] = copy[0]^MUL2[copy[1] as usize]^MUL3[copy[2] as usize]^copy[3];
state[i][2] = copy[0]^copy[1]^MUL2[copy[2] as usize]^MUL3[copy[3] as usize];
state[i][3] = MUL3[copy[0] as usize]^copy[1]^copy[2]^MUL2[copy[3] as usize];
}
i += 1;
}
Self{state}
}
}
const R: [u8;10] = [0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
enum KeyInput {
L128([u8;16]),
L192([u8;24]),
L256([u8;32]),
}
impl KeyInput {
const fn get(&self, index: usize) -> u8 {
match self {
Self::L128(inner) => inner[index],
Self::L192(inner) => inner[index],
Self::L256(inner) => inner[index],
}
}
}
#[derive(Debug, PartialEq)]
enum KeySchedule {
Ks128([[u8;16];11]),
Ks192([[u8;16];13]),
Ks256([[u8;16];15]),
}
impl KeySchedule {
const fn new(input: &KeyInput) -> Self {
let mut all = [[0;4];60];
let mut index = 0;
let (lower_bound, upper_bound) = match input {
KeyInput::L128(_) => (4, 44),
KeyInput::L192(_) => (6, 52),
KeyInput::L256(_) => (8, 60),
};
let (mut byte_one, mut byte_two, mut byte_three, mut byte_four) = (0,1,2,3);
while index != lower_bound {
all[index] = [input.get(byte_one), input.get(byte_two), input.get(byte_three), input.get(byte_four)];
byte_one += 4; byte_two += 4; byte_three += 4; byte_four += 4;
index += 1;
}
let mut word;
let mut r_index = 0;
while index != upper_bound {
word = all[index-1];
if index % lower_bound == 0 {
let mut temp = sub_word(rot_word(word), false);
temp[0] ^= R[r_index];
word = temp;
r_index += 1;
} else if lower_bound == 8 && index % 4 == 0 {
word = sub_word(word, false);
}
all[index] = [
all[index-lower_bound][0]^word[0],
all[index-lower_bound][1]^word[1],
all[index-lower_bound][2]^word[2],
all[index-lower_bound][3]^word[3]
];
index += 1;
}
let mut keys = [[0;16];15];
let mut counter = 0;
let mut key_counter = 0;
index = 0;
while index != 60 {
if counter == 0 {
keys[key_counter][0] = all[index][0];
keys[key_counter][1] = all[index][1];
keys[key_counter][2] = all[index][2];
keys[key_counter][3] = all[index][3];
} else if counter == 1 {
keys[key_counter][4] = all[index][0];
keys[key_counter][5] = all[index][1];
keys[key_counter][6] = all[index][2];
keys[key_counter][7] = all[index][3];
} else if counter == 2 {
keys[key_counter][8] = all[index][0];
keys[key_counter][9] = all[index][1];
keys[key_counter][10] = all[index][2];
keys[key_counter][11] = all[index][3];
} else {
keys[key_counter][12] = all[index][0];
keys[key_counter][13] = all[index][1];
keys[key_counter][14] = all[index][2];
keys[key_counter][15] = all[index][3];
key_counter += 1;
}
if counter < 3 {counter += 1;} else {counter = 0;}
index += 1;
}
match input {
KeyInput::L128(_) => Self::Ks128([keys[0], keys[1], keys[2], keys[3], keys[4], keys[5], keys[6], keys[7],
keys[8], keys[9], keys[10]]),
KeyInput::L192(_) => Self::Ks192([keys[0], keys[1], keys[2], keys[3], keys[4], keys[5], keys[6], keys[7],
keys[8], keys[9], keys[10], keys[11], keys[12]]),
KeyInput::L256(_) => Self::Ks256(keys),
}
}
const fn reverse(self) -> Self {
match self {
Self::Ks128(i) => Self::Ks128([i[10],i[9],i[8],i[7],i[6],i[5],i[4],i[3],i[2],i[1],i[0]]),
Self::Ks192(i) => Self::Ks192([i[12],i[11],i[10],i[9],i[8],i[7],i[6],i[5],i[4],i[3],i[2],i[1],i[0]]),
Self::Ks256(i) => Self::Ks256([i[14],i[13],i[12],i[11],i[10],i[9],i[8],i[7],i[6],i[5],i[4],i[3],i[2],i[1],i[0]]),
}
}
const fn get(&self, index: usize) -> [u8;16] {
match self {
Self::Ks128(inner) => inner[index],
Self::Ks192(inner) => inner[index],
Self::Ks256(inner) => inner[index],
}
}
}
const fn rot_word(input: [u8;4]) -> [u8;4] {
[input[1], input[2], input[3], input[0]]
}
const fn sub_word(input: [u8;4], inverse: bool) -> [u8;4] {
[substitute_byte(input[0], inverse),
substitute_byte(input[1], inverse),
substitute_byte(input[2], inverse),
substitute_byte(input[3], inverse)]
}
const SUB_BOX: [(u8,u8); 256] = [ (0x52, 0x63), (0x09, 0x7c), (0x6a, 0x77), (0xd5, 0x7b), (0x30, 0xf2), (0x36, 0x6b), (0xa5, 0x6f), (0x38, 0xc5),
(0xbf, 0x30), (0x40, 0x01), (0xa3, 0x67), (0x9e, 0x2b), (0x81, 0xfe), (0xf3, 0xd7), (0xd7, 0xab), (0xfb, 0x76),
(0x7c, 0xca), (0xe3, 0x82), (0x39, 0xc9), (0x82, 0x7d), (0x9b, 0xfa), (0x2f, 0x59), (0xff, 0x47), (0x87, 0xf0),
(0x34, 0xad), (0x8e, 0xd4), (0x43, 0xa2), (0x44, 0xaf), (0xc4, 0x9c), (0xde, 0xa4), (0xe9, 0x72), (0xcb, 0xc0),
(0x54, 0xb7), (0x7b, 0xfd), (0x94, 0x93), (0x32, 0x26), (0xa6, 0x36), (0xc2, 0x3f), (0x23, 0xf7), (0x3d, 0xcc),
(0xee, 0x34), (0x4c, 0xa5), (0x95, 0xe5), (0x0b, 0xf1), (0x42, 0x71), (0xfa, 0xd8), (0xc3, 0x31), (0x4e, 0x15),
(0x08, 0x04), (0x2e, 0xc7), (0xa1, 0x23), (0x66, 0xc3), (0x28, 0x18), (0xd9, 0x96), (0x24, 0x05), (0xb2, 0x9a),
(0x76, 0x07), (0x5b, 0x12), (0xa2, 0x80), (0x49, 0xe2), (0x6d, 0xeb), (0x8b, 0x27), (0xd1, 0xb2), (0x25, 0x75),
(0x72, 0x09), (0xf8, 0x83), (0xf6, 0x2c), (0x64, 0x1a), (0x86, 0x1b), (0x68, 0x6e), (0x98, 0x5a), (0x16, 0xa0),
(0xd4, 0x52), (0xa4, 0x3b), (0x5c, 0xd6), (0xcc, 0xb3), (0x5d, 0x29), (0x65, 0xe3), (0xb6, 0x2f), (0x92, 0x84),
(0x6c, 0x53), (0x70, 0xd1), (0x48, 0x00), (0x50, 0xed), (0xfd, 0x20), (0xed, 0xfc), (0xb9, 0xb1), (0xda, 0x5b),
(0x5e, 0x6a), (0x15, 0xcb), (0x46, 0xbe), (0x57, 0x39), (0xa7, 0x4a), (0x8d, 0x4c), (0x9d, 0x58), (0x84, 0xcf),
(0x90, 0xd0), (0xd8, 0xef), (0xab, 0xaa), (0x00, 0xfb), (0x8c, 0x43), (0xbc, 0x4d), (0xd3, 0x33), (0x0a, 0x85),
(0xf7, 0x45), (0xe4, 0xf9), (0x58, 0x02), (0x05, 0x7f), (0xb8, 0x50), (0xb3, 0x3c), (0x45, 0x9f), (0x06, 0xa8),
(0xd0, 0x51), (0x2c, 0xa3), (0x1e, 0x40), (0x8f, 0x8f), (0xca, 0x92), (0x3f, 0x9d), (0x0f, 0x38), (0x02, 0xf5),
(0xc1, 0xbc), (0xaf, 0xb6), (0xbd, 0xda), (0x03, 0x21), (0x01, 0x10), (0x13, 0xff), (0x8a, 0xf3), (0x6b, 0xd2),
(0x3a, 0xcd), (0x91, 0x0c), (0x11, 0x13), (0x41, 0xec), (0x4f, 0x5f), (0x67, 0x97), (0xdc, 0x44), (0xea, 0x17),
(0x97, 0xc4), (0xf2, 0xa7), (0xcf, 0x7e), (0xce, 0x3d), (0xf0, 0x64), (0xb4, 0x5d), (0xe6, 0x19), (0x73, 0x73),
(0x96, 0x60), (0xac, 0x81), (0x74, 0x4f), (0x22, 0xdc), (0xe7, 0x22), (0xad, 0x2a), (0x35, 0x90), (0x85, 0x88),
(0xe2, 0x46), (0xf9, 0xee), (0x37, 0xb8), (0xe8, 0x14), (0x1c, 0xde), (0x75, 0x5e), (0xdf, 0x0b), (0x6e, 0xdb),
(0x47, 0xe0), (0xf1, 0x32), (0x1a, 0x3a), (0x71, 0x0a), (0x1d, 0x49), (0x29, 0x06), (0xc5, 0x24), (0x89, 0x5c),
(0x6f, 0xc2), (0xb7, 0xd3), (0x62, 0xac), (0x0e, 0x62), (0xaa, 0x91), (0x18, 0x95), (0xbe, 0xe4), (0x1b, 0x79),
(0xfc, 0xe7), (0x56, 0xc8), (0x3e, 0x37), (0x4b, 0x6d), (0xc6, 0x8d), (0xd2, 0xd5), (0x79, 0x4e), (0x20, 0xa9),
(0x9a, 0x6c), (0xdb, 0x56), (0xc0, 0xf4), (0xfe, 0xea), (0x78, 0x65), (0xcd, 0x7a), (0x5a, 0xae), (0xf4, 0x08),
(0x1f, 0xba), (0xdd, 0x78), (0xa8, 0x25), (0x33, 0x2e), (0x88, 0x1c), (0x07, 0xa6), (0xc7, 0xb4), (0x31, 0xc6),
(0xb1, 0xe8), (0x12, 0xdd), (0x10, 0x74), (0x59, 0x1f), (0x27, 0x4b), (0x80, 0xbd), (0xec, 0x8b), (0x5f, 0x8a),
(0x60, 0x70), (0x51, 0x3e), (0x7f, 0xb5), (0xa9, 0x66), (0x19, 0x48), (0xb5, 0x03), (0x4a, 0xf6), (0x0d, 0x0e),
(0x2d, 0x61), (0xe5, 0x35), (0x7a, 0x57), (0x9f, 0xb9), (0x93, 0x86), (0xc9, 0xc1), (0x9c, 0x1d), (0xef, 0x9e),
(0xa0, 0xe1), (0xe0, 0xf8), (0x3b, 0x98), (0x4d, 0x11), (0xae, 0x69), (0x2a, 0xd9), (0xf5, 0x8e), (0xb0, 0x94),
(0xc8, 0x9b), (0xeb, 0x1e), (0xbb, 0x87), (0x3c, 0xe9), (0x83, 0xce), (0x53, 0x55), (0x99, 0x28), (0x61, 0xdf),
(0x17, 0x8c), (0x2b, 0xa1), (0x04, 0x89), (0x7e, 0x0d), (0xba, 0xbf), (0x77, 0xe6), (0xd6, 0x42), (0x26, 0x68),
(0xe1, 0x41), (0x69, 0x99), (0x14, 0x2d), (0x63, 0x0f), (0x55, 0xb0), (0x21, 0x54), (0x0c, 0xbb), (0x7d, 0x16),
];
const MUL2: [u8; 256] = [
0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e,
0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e,0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e,
0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e,0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e,
0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e,0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e,
0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,
0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae,0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe,
0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce,0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde,
0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee,0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe,
0x1b,0x19,0x1f,0x1d,0x13,0x11,0x17,0x15,0x0b,0x09,0x0f,0x0d,0x03,0x01,0x07,0x05,
0x3b,0x39,0x3f,0x3d,0x33,0x31,0x37,0x35,0x2b,0x29,0x2f,0x2d,0x23,0x21,0x27,0x25,
0x5b,0x59,0x5f,0x5d,0x53,0x51,0x57,0x55,0x4b,0x49,0x4f,0x4d,0x43,0x41,0x47,0x45,
0x7b,0x79,0x7f,0x7d,0x73,0x71,0x77,0x75,0x6b,0x69,0x6f,0x6d,0x63,0x61,0x67,0x65,
0x9b,0x99,0x9f,0x9d,0x93,0x91,0x97,0x95,0x8b,0x89,0x8f,0x8d,0x83,0x81,0x87,0x85,
0xbb,0xb9,0xbf,0xbd,0xb3,0xb1,0xb7,0xb5,0xab,0xa9,0xaf,0xad,0xa3,0xa1,0xa7,0xa5,
0xdb,0xd9,0xdf,0xdd,0xd3,0xd1,0xd7,0xd5,0xcb,0xc9,0xcf,0xcd,0xc3,0xc1,0xc7,0xc5,
0xfb,0xf9,0xff,0xfd,0xf3,0xf1,0xf7,0xf5,0xeb,0xe9,0xef,0xed,0xe3,0xe1,0xe7,0xe5
];
const MUL3: [u8; 256] = [
0x00,0x03,0x06,0x05,0x0c,0x0f,0x0a,0x09,0x18,0x1b,0x1e,0x1d,0x14,0x17,0x12,0x11,
0x30,0x33,0x36,0x35,0x3c,0x3f,0x3a,0x39,0x28,0x2b,0x2e,0x2d,0x24,0x27,0x22,0x21,
0x60,0x63,0x66,0x65,0x6c,0x6f,0x6a,0x69,0x78,0x7b,0x7e,0x7d,0x74,0x77,0x72,0x71,
0x50,0x53,0x56,0x55,0x5c,0x5f,0x5a,0x59,0x48,0x4b,0x4e,0x4d,0x44,0x47,0x42,0x41,
0xc0,0xc3,0xc6,0xc5,0xcc,0xcf,0xca,0xc9,0xd8,0xdb,0xde,0xdd,0xd4,0xd7,0xd2,0xd1,
0xf0,0xf3,0xf6,0xf5,0xfc,0xff,0xfa,0xf9,0xe8,0xeb,0xee,0xed,0xe4,0xe7,0xe2,0xe1,
0xa0,0xa3,0xa6,0xa5,0xac,0xaf,0xaa,0xa9,0xb8,0xbb,0xbe,0xbd,0xb4,0xb7,0xb2,0xb1,
0x90,0x93,0x96,0x95,0x9c,0x9f,0x9a,0x99,0x88,0x8b,0x8e,0x8d,0x84,0x87,0x82,0x81,
0x9b,0x98,0x9d,0x9e,0x97,0x94,0x91,0x92,0x83,0x80,0x85,0x86,0x8f,0x8c,0x89,0x8a,
0xab,0xa8,0xad,0xae,0xa7,0xa4,0xa1,0xa2,0xb3,0xb0,0xb5,0xb6,0xbf,0xbc,0xb9,0xba,
0xfb,0xf8,0xfd,0xfe,0xf7,0xf4,0xf1,0xf2,0xe3,0xe0,0xe5,0xe6,0xef,0xec,0xe9,0xea,
0xcb,0xc8,0xcd,0xce,0xc7,0xc4,0xc1,0xc2,0xd3,0xd0,0xd5,0xd6,0xdf,0xdc,0xd9,0xda,
0x5b,0x58,0x5d,0x5e,0x57,0x54,0x51,0x52,0x43,0x40,0x45,0x46,0x4f,0x4c,0x49,0x4a,
0x6b,0x68,0x6d,0x6e,0x67,0x64,0x61,0x62,0x73,0x70,0x75,0x76,0x7f,0x7c,0x79,0x7a,
0x3b,0x38,0x3d,0x3e,0x37,0x34,0x31,0x32,0x23,0x20,0x25,0x26,0x2f,0x2c,0x29,0x2a,
0x0b,0x08,0x0d,0x0e,0x07,0x04,0x01,0x02,0x13,0x10,0x15,0x16,0x1f,0x1c,0x19,0x1a
];
const MUL9: [u8; 256] = [
0x00,0x09,0x12,0x1b,0x24,0x2d,0x36,0x3f,0x48,0x41,0x5a,0x53,0x6c,0x65,0x7e,0x77,
0x90,0x99,0x82,0x8b,0xb4,0xbd,0xa6,0xaf,0xd8,0xd1,0xca,0xc3,0xfc,0xf5,0xee,0xe7,
0x3b,0x32,0x29,0x20,0x1f,0x16,0x0d,0x04,0x73,0x7a,0x61,0x68,0x57,0x5e,0x45,0x4c,
0xab,0xa2,0xb9,0xb0,0x8f,0x86,0x9d,0x94,0xe3,0xea,0xf1,0xf8,0xc7,0xce,0xd5,0xdc,
0x76,0x7f,0x64,0x6d,0x52,0x5b,0x40,0x49,0x3e,0x37,0x2c,0x25,0x1a,0x13,0x08,0x01,
0xe6,0xef,0xf4,0xfd,0xc2,0xcb,0xd0,0xd9,0xae,0xa7,0xbc,0xb5,0x8a,0x83,0x98,0x91,
0x4d,0x44,0x5f,0x56,0x69,0x60,0x7b,0x72,0x05,0x0c,0x17,0x1e,0x21,0x28,0x33,0x3a,
0xdd,0xd4,0xcf,0xc6,0xf9,0xf0,0xeb,0xe2,0x95,0x9c,0x87,0x8e,0xb1,0xb8,0xa3,0xaa,
0xec,0xe5,0xfe,0xf7,0xc8,0xc1,0xda,0xd3,0xa4,0xad,0xb6,0xbf,0x80,0x89,0x92,0x9b,
0x7c,0x75,0x6e,0x67,0x58,0x51,0x4a,0x43,0x34,0x3d,0x26,0x2f,0x10,0x19,0x02,0x0b,
0xd7,0xde,0xc5,0xcc,0xf3,0xfa,0xe1,0xe8,0x9f,0x96,0x8d,0x84,0xbb,0xb2,0xa9,0xa0,
0x47,0x4e,0x55,0x5c,0x63,0x6a,0x71,0x78,0x0f,0x06,0x1d,0x14,0x2b,0x22,0x39,0x30,
0x9a,0x93,0x88,0x81,0xbe,0xb7,0xac,0xa5,0xd2,0xdb,0xc0,0xc9,0xf6,0xff,0xe4,0xed,
0x0a,0x03,0x18,0x11,0x2e,0x27,0x3c,0x35,0x42,0x4b,0x50,0x59,0x66,0x6f,0x74,0x7d,
0xa1,0xa8,0xb3,0xba,0x85,0x8c,0x97,0x9e,0xe9,0xe0,0xfb,0xf2,0xcd,0xc4,0xdf,0xd6,
0x31,0x38,0x23,0x2a,0x15,0x1c,0x07,0x0e,0x79,0x70,0x6b,0x62,0x5d,0x54,0x4f,0x46
];
const MUL11: [u8; 256] = [
0x00,0x0b,0x16,0x1d,0x2c,0x27,0x3a,0x31,0x58,0x53,0x4e,0x45,0x74,0x7f,0x62,0x69,
0xb0,0xbb,0xa6,0xad,0x9c,0x97,0x8a,0x81,0xe8,0xe3,0xfe,0xf5,0xc4,0xcf,0xd2,0xd9,
0x7b,0x70,0x6d,0x66,0x57,0x5c,0x41,0x4a,0x23,0x28,0x35,0x3e,0x0f,0x04,0x19,0x12,
0xcb,0xc0,0xdd,0xd6,0xe7,0xec,0xf1,0xfa,0x93,0x98,0x85,0x8e,0xbf,0xb4,0xa9,0xa2,
0xf6,0xfd,0xe0,0xeb,0xda,0xd1,0xcc,0xc7,0xae,0xa5,0xb8,0xb3,0x82,0x89,0x94,0x9f,
0x46,0x4d,0x50,0x5b,0x6a,0x61,0x7c,0x77,0x1e,0x15,0x08,0x03,0x32,0x39,0x24,0x2f,
0x8d,0x86,0x9b,0x90,0xa1,0xaa,0xb7,0xbc,0xd5,0xde,0xc3,0xc8,0xf9,0xf2,0xef,0xe4,
0x3d,0x36,0x2b,0x20,0x11,0x1a,0x07,0x0c,0x65,0x6e,0x73,0x78,0x49,0x42,0x5f,0x54,
0xf7,0xfc,0xe1,0xea,0xdb,0xd0,0xcd,0xc6,0xaf,0xa4,0xb9,0xb2,0x83,0x88,0x95,0x9e,
0x47,0x4c,0x51,0x5a,0x6b,0x60,0x7d,0x76,0x1f,0x14,0x09,0x02,0x33,0x38,0x25,0x2e,
0x8c,0x87,0x9a,0x91,0xa0,0xab,0xb6,0xbd,0xd4,0xdf,0xc2,0xc9,0xf8,0xf3,0xee,0xe5,
0x3c,0x37,0x2a,0x21,0x10,0x1b,0x06,0x0d,0x64,0x6f,0x72,0x79,0x48,0x43,0x5e,0x55,
0x01,0x0a,0x17,0x1c,0x2d,0x26,0x3b,0x30,0x59,0x52,0x4f,0x44,0x75,0x7e,0x63,0x68,
0xb1,0xba,0xa7,0xac,0x9d,0x96,0x8b,0x80,0xe9,0xe2,0xff,0xf4,0xc5,0xce,0xd3,0xd8,
0x7a,0x71,0x6c,0x67,0x56,0x5d,0x40,0x4b,0x22,0x29,0x34,0x3f,0x0e,0x05,0x18,0x13,
0xca,0xc1,0xdc,0xd7,0xe6,0xed,0xf0,0xfb,0x92,0x99,0x84,0x8f,0xbe,0xb5,0xa8,0xa3
];
const MUL13: [u8; 256] = [
0x00,0x0d,0x1a,0x17,0x34,0x39,0x2e,0x23,0x68,0x65,0x72,0x7f,0x5c,0x51,0x46,0x4b,
0xd0,0xdd,0xca,0xc7,0xe4,0xe9,0xfe,0xf3,0xb8,0xb5,0xa2,0xaf,0x8c,0x81,0x96,0x9b,
0xbb,0xb6,0xa1,0xac,0x8f,0x82,0x95,0x98,0xd3,0xde,0xc9,0xc4,0xe7,0xea,0xfd,0xf0,
0x6b,0x66,0x71,0x7c,0x5f,0x52,0x45,0x48,0x03,0x0e,0x19,0x14,0x37,0x3a,0x2d,0x20,
0x6d,0x60,0x77,0x7a,0x59,0x54,0x43,0x4e,0x05,0x08,0x1f,0x12,0x31,0x3c,0x2b,0x26,
0xbd,0xb0,0xa7,0xaa,0x89,0x84,0x93,0x9e,0xd5,0xd8,0xcf,0xc2,0xe1,0xec,0xfb,0xf6,
0xd6,0xdb,0xcc,0xc1,0xe2,0xef,0xf8,0xf5,0xbe,0xb3,0xa4,0xa9,0x8a,0x87,0x90,0x9d,
0x06,0x0b,0x1c,0x11,0x32,0x3f,0x28,0x25,0x6e,0x63,0x74,0x79,0x5a,0x57,0x40,0x4d,
0xda,0xd7,0xc0,0xcd,0xee,0xe3,0xf4,0xf9,0xb2,0xbf,0xa8,0xa5,0x86,0x8b,0x9c,0x91,
0x0a,0x07,0x10,0x1d,0x3e,0x33,0x24,0x29,0x62,0x6f,0x78,0x75,0x56,0x5b,0x4c,0x41,
0x61,0x6c,0x7b,0x76,0x55,0x58,0x4f,0x42,0x09,0x04,0x13,0x1e,0x3d,0x30,0x27,0x2a,
0xb1,0xbc,0xab,0xa6,0x85,0x88,0x9f,0x92,0xd9,0xd4,0xc3,0xce,0xed,0xe0,0xf7,0xfa,
0xb7,0xba,0xad,0xa0,0x83,0x8e,0x99,0x94,0xdf,0xd2,0xc5,0xc8,0xeb,0xe6,0xf1,0xfc,
0x67,0x6a,0x7d,0x70,0x53,0x5e,0x49,0x44,0x0f,0x02,0x15,0x18,0x3b,0x36,0x21,0x2c,
0x0c,0x01,0x16,0x1b,0x38,0x35,0x22,0x2f,0x64,0x69,0x7e,0x73,0x50,0x5d,0x4a,0x47,
0xdc,0xd1,0xc6,0xcb,0xe8,0xe5,0xf2,0xff,0xb4,0xb9,0xae,0xa3,0x80,0x8d,0x9a,0x97
];
const MUL14: [u8; 256] = [
0x00,0x0e,0x1c,0x12,0x38,0x36,0x24,0x2a,0x70,0x7e,0x6c,0x62,0x48,0x46,0x54,0x5a,
0xe0,0xee,0xfc,0xf2,0xd8,0xd6,0xc4,0xca,0x90,0x9e,0x8c,0x82,0xa8,0xa6,0xb4,0xba,
0xdb,0xd5,0xc7,0xc9,0xe3,0xed,0xff,0xf1,0xab,0xa5,0xb7,0xb9,0x93,0x9d,0x8f,0x81,
0x3b,0x35,0x27,0x29,0x03,0x0d,0x1f,0x11,0x4b,0x45,0x57,0x59,0x73,0x7d,0x6f,0x61,
0xad,0xa3,0xb1,0xbf,0x95,0x9b,0x89,0x87,0xdd,0xd3,0xc1,0xcf,0xe5,0xeb,0xf9,0xf7,
0x4d,0x43,0x51,0x5f,0x75,0x7b,0x69,0x67,0x3d,0x33,0x21,0x2f,0x05,0x0b,0x19,0x17,
0x76,0x78,0x6a,0x64,0x4e,0x40,0x52,0x5c,0x06,0x08,0x1a,0x14,0x3e,0x30,0x22,0x2c,
0x96,0x98,0x8a,0x84,0xae,0xa0,0xb2,0xbc,0xe6,0xe8,0xfa,0xf4,0xde,0xd0,0xc2,0xcc,
0x41,0x4f,0x5d,0x53,0x79,0x77,0x65,0x6b,0x31,0x3f,0x2d,0x23,0x09,0x07,0x15,0x1b,
0xa1,0xaf,0xbd,0xb3,0x99,0x97,0x85,0x8b,0xd1,0xdf,0xcd,0xc3,0xe9,0xe7,0xf5,0xfb,
0x9a,0x94,0x86,0x88,0xa2,0xac,0xbe,0xb0,0xea,0xe4,0xf6,0xf8,0xd2,0xdc,0xce,0xc0,
0x7a,0x74,0x66,0x68,0x42,0x4c,0x5e,0x50,0x0a,0x04,0x16,0x18,0x32,0x3c,0x2e,0x20,
0xec,0xe2,0xf0,0xfe,0xd4,0xda,0xc8,0xc6,0x9c,0x92,0x80,0x8e,0xa4,0xaa,0xb8,0xb6,
0x0c,0x02,0x10,0x1e,0x34,0x3a,0x28,0x26,0x7c,0x72,0x60,0x6e,0x44,0x4a,0x58,0x56,
0x37,0x39,0x2b,0x25,0x0f,0x01,0x13,0x1d,0x47,0x49,0x5b,0x55,0x7f,0x71,0x63,0x6d,
0xd7,0xd9,0xcb,0xc5,0xef,0xe1,0xf3,0xfd,0xa7,0xa9,0xbb,0xb5,0x9f,0x91,0x83,0x8d
];
const fn substitute_byte(index: u8, inverse: bool) -> u8 {
if inverse {SUB_BOX[index as usize].0} else {SUB_BOX[index as usize].1}
}
const fn cipher(input: [u8;16], rounds: usize, mut key_schedule: KeySchedule, inverse: bool) -> [u8;16] {
let mut internal = State::new(input);
if inverse {key_schedule = key_schedule.reverse();}
internal = internal.xor_roundkey(key_schedule.get(0));
let mut index = 1;
while index != rounds {
if inverse {
internal = internal.shift_rows(inverse);
internal = internal.sub_bytes(inverse);
internal = internal.xor_roundkey(key_schedule.get(index));
internal = internal.mix_cols(inverse);
} else {
internal = internal.sub_bytes(inverse);
internal = internal.shift_rows(inverse);
internal = internal.mix_cols(inverse);
internal = internal.xor_roundkey(key_schedule.get(index));
}
index += 1;
}
if inverse {
internal = internal.shift_rows(inverse);
internal = internal.sub_bytes(inverse);
} else {
internal = internal.sub_bytes(inverse);
internal = internal.shift_rows(inverse);
}
internal = internal.xor_roundkey(key_schedule.get(rounds));
[
internal.state[0][0], internal.state[0][1], internal.state[0][2], internal.state[0][3],
internal.state[1][0], internal.state[1][1], internal.state[1][2], internal.state[1][3],
internal.state[2][0], internal.state[2][1], internal.state[2][2], internal.state[2][3],
internal.state[3][0], internal.state[3][1], internal.state[3][2], internal.state[3][3],
]
}
#[must_use]
pub const fn aes128(input: [u8;16], cipher_key: [u8;16]) -> [u8;16] {
cipher(input, 10, KeySchedule::new(&KeyInput::L128(cipher_key)), false)
}
#[must_use]
pub const fn aes128_inverse(input: [u8;16], cipher_key: [u8;16]) -> [u8;16] {
cipher(input, 10, KeySchedule::new(&KeyInput::L128(cipher_key)), true)
}
#[must_use]
pub const fn aes192(input: [u8;16], cipher_key: [u8;24]) -> [u8;16] {
cipher(input, 12, KeySchedule::new(&KeyInput::L192(cipher_key)), false)
}
#[must_use]
pub const fn aes192_inverse(input: [u8;16], cipher_key: [u8;24]) -> [u8;16] {
cipher(input, 12, KeySchedule::new(&KeyInput::L192(cipher_key)), true)
}
#[must_use]
pub const fn aes256(input: [u8;16], cipher_key: [u8;32]) -> [u8;16] {
cipher(input, 14, KeySchedule::new(&KeyInput::L256(cipher_key)), false)
}
#[must_use]
pub const fn aes256_inverse(input: [u8;16], cipher_key: [u8;32]) -> [u8;16] {
cipher(input, 14, KeySchedule::new(&KeyInput::L256(cipher_key)), true)
}
#[cfg(test)]
mod tests {
use super::{KeySchedule, KeyInput, State, sub_word, rot_word, aes128, aes128_inverse, aes192, aes192_inverse,
aes256, aes256_inverse};
#[test]
fn initial_state() {
let input = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34];
let internal = State::new(input);
assert_eq!(internal.state, [
[0x32, 0x43, 0xf6, 0xa8],
[0x88, 0x5a, 0x30, 0x8d],
[0x31, 0x31, 0x98, 0xa2],
[0xe0, 0x37, 0x07, 0x34]
]);
}
#[test]
fn xor_roundkey() {
let input = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34];
let cipher_key = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c];
let internal = State::new(input);
let output = internal.xor_roundkey(cipher_key);
assert_eq!(output.state, [
[0x19, 0x3d, 0xe3, 0xbe],
[0xa0, 0xf4, 0xe2, 0x2b],
[0x9a, 0xc6, 0x8d, 0x2a],
[0xe9, 0xf8, 0x48, 0x08]
]);
}
#[test]
fn sub_bytes() {
let input = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34];
let cipher_key = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c];
let mut internal = State::new(input);
internal = internal.xor_roundkey(cipher_key);
internal = internal.sub_bytes(false);
assert_eq!(internal.state, [
[0xd4, 0x27, 0x11, 0xae],
[0xe0, 0xbf, 0x98, 0xf1],
[0xb8, 0xb4, 0x5d, 0xe5],
[0x1e, 0x41, 0x52, 0x30]
]);
}
#[test]
fn shift_rows() {
let input = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34];
let cipher_key = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c];
let mut internal = State::new(input);
internal = internal.xor_roundkey(cipher_key);
internal = internal.sub_bytes(false);
internal = internal.shift_rows(false);
assert_eq!(internal.state, [
[0xd4, 0xbf, 0x5d, 0x30],
[0xe0, 0xb4, 0x52, 0xae],
[0xb8, 0x41, 0x11, 0xf1],
[0x1e, 0x27, 0x98, 0xe5]
]);
}
#[test]
fn mix_cols() {
let input = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34];
let cipher_key = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c];
let mut internal = State::new(input);
internal = internal.xor_roundkey(cipher_key);
internal = internal.sub_bytes(false);
internal = internal.shift_rows(false);
internal = internal.mix_cols(false);
assert_eq!(internal.state, [
[0x04, 0x66, 0x81, 0xe5],
[0xe0, 0xcb, 0x19, 0x9a],
[0x48, 0xf8, 0xd3, 0x7a],
[0x28, 0x06, 0x26, 0x4c]
]);
}
#[test]
fn substitute_word() {
let word = sub_word([0x32, 0x43, 0xf6, 0xa8], false);
assert_eq!(word, [0x23, 0x1a, 0x42, 0xc2]);
}
#[test]
fn rotate_word() {
let word = rot_word([0x32, 0x43, 0xf6, 0xa8]);
assert_eq!(word, [0x43, 0xf6, 0xa8, 0x32]);
}
#[test]
fn key_schedule128() {
let cipher_key = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c];
let schedule = KeySchedule::new(&KeyInput::L128(cipher_key));
assert_eq!(schedule, KeySchedule::Ks128([
[0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c],
[0xa0, 0xfa, 0xfe, 0x17, 0x88, 0x54, 0x2c, 0xb1, 0x23, 0xa3, 0x39, 0x39, 0x2a, 0x6c, 0x76, 0x05],
[0xf2, 0xc2, 0x95, 0xf2, 0x7a, 0x96, 0xb9, 0x43, 0x59, 0x35, 0x80, 0x7a, 0x73, 0x59, 0xf6, 0x7f],
[0x3d, 0x80, 0x47, 0x7d, 0x47, 0x16, 0xfe, 0x3e, 0x1e, 0x23, 0x7e, 0x44, 0x6d, 0x7a, 0x88, 0x3b],
[0xef, 0x44, 0xa5, 0x41, 0xa8, 0x52, 0x5b, 0x7f, 0xb6, 0x71, 0x25, 0x3b, 0xdb, 0x0b, 0xad, 0x00],
[0xd4, 0xd1, 0xc6, 0xf8, 0x7c, 0x83, 0x9d, 0x87, 0xca, 0xf2, 0xb8, 0xbc, 0x11, 0xf9, 0x15, 0xbc],
[0x6d, 0x88, 0xa3, 0x7a, 0x11, 0x0b, 0x3e, 0xfd, 0xdb, 0xf9, 0x86, 0x41, 0xca, 0x00, 0x93, 0xfd],
[0x4e, 0x54, 0xf7, 0x0e, 0x5f, 0x5f, 0xc9, 0xf3, 0x84, 0xa6, 0x4f, 0xb2, 0x4e, 0xa6, 0xdc, 0x4f],
[0xea, 0xd2, 0x73, 0x21, 0xb5, 0x8d, 0xba, 0xd2, 0x31, 0x2b, 0xf5, 0x60, 0x7f, 0x8d, 0x29, 0x2f],
[0xac, 0x77, 0x66, 0xf3, 0x19, 0xfa, 0xdc, 0x21, 0x28, 0xd1, 0x29, 0x41, 0x57, 0x5c, 0x00, 0x6e],
[0xd0, 0x14, 0xf9, 0xa8, 0xc9, 0xee, 0x25, 0x89, 0xe1, 0x3f, 0x0c, 0xc8, 0xb6, 0x63, 0x0c, 0xa6]
]));
}
#[test]
fn key_schedule192() {
let cipher_key = [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 schedule = KeySchedule::new(&KeyInput::L192(cipher_key));
assert_eq!(schedule, KeySchedule::Ks192([
[0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5],
[0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b, 0xfe, 0x0c, 0x91, 0xf7, 0x24, 0x02, 0xf5, 0xa5],
[0xec, 0x12, 0x06, 0x8e, 0x6c, 0x82, 0x7f, 0x6b, 0x0e, 0x7a, 0x95, 0xb9, 0x5c, 0x56, 0xfe, 0xc2],
[0x4d, 0xb7, 0xb4, 0xbd, 0x69, 0xb5, 0x41, 0x18, 0x85, 0xa7, 0x47, 0x96, 0xe9, 0x25, 0x38, 0xfd],
[0xe7, 0x5f, 0xad, 0x44, 0xbb, 0x09, 0x53, 0x86, 0x48, 0x5a, 0xf0, 0x57, 0x21, 0xef, 0xb1, 0x4f],
[0xa4, 0x48, 0xf6, 0xd9, 0x4d, 0x6d, 0xce, 0x24, 0xaa, 0x32, 0x63, 0x60, 0x11, 0x3b, 0x30, 0xe6],
[0xa2, 0x5e, 0x7e, 0xd5, 0x83, 0xb1, 0xcf, 0x9a, 0x27, 0xf9, 0x39, 0x43, 0x6a, 0x94, 0xf7, 0x67],
[0xc0, 0xa6, 0x94, 0x07, 0xd1, 0x9d, 0xa4, 0xe1, 0xec, 0x17, 0x86, 0xeb, 0x6f, 0xa6, 0x49, 0x71],
[0x48, 0x5f, 0x70, 0x32, 0x22, 0xcb, 0x87, 0x55, 0xe2, 0x6d, 0x13, 0x52, 0x33, 0xf0, 0xb7, 0xb3],
[0x40, 0xbe, 0xeb, 0x28, 0x2f, 0x18, 0xa2, 0x59, 0x67, 0x47, 0xd2, 0x6b, 0x45, 0x8c, 0x55, 0x3e],
[0xa7, 0xe1, 0x46, 0x6c, 0x94, 0x11, 0xf1, 0xdf, 0x82, 0x1f, 0x75, 0x0a, 0xad, 0x07, 0xd7, 0x53],
[0xca, 0x40, 0x05, 0x38, 0x8f, 0xcc, 0x50, 0x06, 0x28, 0x2d, 0x16, 0x6a, 0xbc, 0x3c, 0xe7, 0xb5],
[0xe9, 0x8b, 0xa0, 0x6f, 0x44, 0x8c, 0x77, 0x3c, 0x8e, 0xcc, 0x72, 0x04, 0x01, 0x00, 0x22, 0x02],
]));
}
#[test]
fn key_schedule256() {
let cipher_key = [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 schedule = KeySchedule::new(&KeyInput::L256(cipher_key));
assert_eq!(schedule, KeySchedule::Ks256([
[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],
[0x9b, 0xa3, 0x54, 0x11, 0x8e, 0x69, 0x25, 0xaf, 0xa5, 0x1a, 0x8b, 0x5f, 0x20, 0x67, 0xfc, 0xde],
[0xa8, 0xb0, 0x9c, 0x1a, 0x93, 0xd1, 0x94, 0xcd, 0xbe, 0x49, 0x84, 0x6e, 0xb7, 0x5d, 0x5b, 0x9a],
[0xd5, 0x9a, 0xec, 0xb8, 0x5b, 0xf3, 0xc9, 0x17, 0xfe, 0xe9, 0x42, 0x48, 0xde, 0x8e, 0xbe, 0x96],
[0xb5, 0xa9, 0x32, 0x8a, 0x26, 0x78, 0xa6, 0x47, 0x98, 0x31, 0x22, 0x29, 0x2f, 0x6c, 0x79, 0xb3],
[0x81, 0x2c, 0x81, 0xad, 0xda, 0xdf, 0x48, 0xba, 0x24, 0x36, 0x0a, 0xf2, 0xfa, 0xb8, 0xb4, 0x64],
[0x98, 0xc5, 0xbf, 0xc9, 0xbe, 0xbd, 0x19, 0x8e, 0x26, 0x8c, 0x3b, 0xa7, 0x09, 0xe0, 0x42, 0x14],
[0x68, 0x00, 0x7b, 0xac, 0xb2, 0xdf, 0x33, 0x16, 0x96, 0xe9, 0x39, 0xe4, 0x6c, 0x51, 0x8d, 0x80],
[0xc8, 0x14, 0xe2, 0x04, 0x76, 0xa9, 0xfb, 0x8a, 0x50, 0x25, 0xc0, 0x2d, 0x59, 0xc5, 0x82, 0x39],
[0xde, 0x13, 0x69, 0x67, 0x6c, 0xcc, 0x5a, 0x71, 0xfa, 0x25, 0x63, 0x95, 0x96, 0x74, 0xee, 0x15],
[0x58, 0x86, 0xca, 0x5d, 0x2e, 0x2f, 0x31, 0xd7, 0x7e, 0x0a, 0xf1, 0xfa, 0x27, 0xcf, 0x73, 0xc3],
[0x74, 0x9c, 0x47, 0xab, 0x18, 0x50, 0x1d, 0xda, 0xe2, 0x75, 0x7e, 0x4f, 0x74, 0x01, 0x90, 0x5a],
[0xca, 0xfa, 0xaa, 0xe3, 0xe4, 0xd5, 0x9b, 0x34, 0x9a, 0xdf, 0x6a, 0xce, 0xbd, 0x10, 0x19, 0x0d],
[0xfe, 0x48, 0x90, 0xd1, 0xe6, 0x18, 0x8d, 0x0b, 0x04, 0x6d, 0xf3, 0x44, 0x70, 0x6c, 0x63, 0x1e],
]));
}
#[test]
fn sample_aes128_run() {
let input = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34];
let cipher_key = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c];
let output = aes128(input, cipher_key);
assert_eq!(output, [0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32]);
}
#[test]
fn inverse_aes128_run() {
let input = [0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34];
let cipher_key = [0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c];
let output = aes128(input, cipher_key);
assert_eq!(input, aes128_inverse(output, cipher_key));
}
#[test]
fn sample_aes192_run() {
let input = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a];
let cipher_key = [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 output = aes192(input, cipher_key);
assert_eq!(output, [0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc]);
}
#[test]
fn inverse_aes192_run() {
let input = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a];
let cipher_key = [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 output = aes192(input, cipher_key);
assert_eq!(input, aes192_inverse(output, cipher_key));
}
#[test]
fn sample_aes256_run() {
let input = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a];
let cipher_key = [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 output = aes256(input, cipher_key);
assert_eq!(output, [0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8]);
}
#[test]
fn inverse_aes256_run() {
let input = [0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a];
let cipher_key = [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 output = aes256(input, cipher_key);
assert_eq!(input, aes256_inverse(output, cipher_key));
}
}