reverse key schedule test
This commit is contained in:
parent
9cbbc0ff79
commit
8091bb33ed
194
src/aes.rs
194
src/aes.rs
@ -139,7 +139,7 @@ static INVERSE_SBOX: [[u8; 16]; 16] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
// for key schedule
|
// for key schedule
|
||||||
static RC: [u8; 11] = [
|
pub static RC: [u8; 11] = [
|
||||||
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
|
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36,
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ where
|
|||||||
a
|
a
|
||||||
}
|
}
|
||||||
|
|
||||||
fn xor(bits1: &[u8; 4], bits2: &[u8; 4]) -> [u8; 4] {
|
pub fn xor(bits1: &[u8; 4], bits2: &[u8; 4]) -> [u8; 4] {
|
||||||
let mut result = [0u8; 4];
|
let mut result = [0u8; 4];
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
result[i] = bits1[i] ^ bits2[i];
|
result[i] = bits1[i] ^ bits2[i];
|
||||||
@ -161,7 +161,7 @@ fn xor(bits1: &[u8; 4], bits2: &[u8; 4]) -> [u8; 4] {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn substitute_word(bytes: &[u8; 4]) -> [u8; 4] {
|
pub fn substitute_word(bytes: &[u8; 4]) -> [u8; 4] {
|
||||||
let mut result = [0u8; 4];
|
let mut result = [0u8; 4];
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
result[i] = substitute(bytes[i], true);
|
result[i] = substitute(bytes[i], true);
|
||||||
@ -184,7 +184,7 @@ fn substitute_state(state: &mut [[u8; 4]; 4]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inverse_substitute_state(state: &mut [[u8; 4]; 4]) {
|
pub fn inverse_substitute_state(state: &mut [[u8; 4]; 4]) {
|
||||||
for row in state.iter_mut().take(4) {
|
for row in state.iter_mut().take(4) {
|
||||||
for item in row.iter_mut().take(4) {
|
for item in row.iter_mut().take(4) {
|
||||||
*item = substitute(*item, false);
|
*item = substitute(*item, false);
|
||||||
@ -202,7 +202,7 @@ pub fn substitute(byte: u8, encryption: bool) -> u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shift_word(bytes: &[u8; 4]) -> [u8; 4] {
|
pub fn shift_word(bytes: &[u8; 4]) -> [u8; 4] {
|
||||||
let mut result = [0u8; 4];
|
let mut result = [0u8; 4];
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
result[i] = bytes[(i + 1) % 4];
|
result[i] = bytes[(i + 1) % 4];
|
||||||
@ -443,172 +443,6 @@ impl Aes {
|
|||||||
|
|
||||||
expanded_key
|
expanded_key
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn reverse_key_schedule(round_key: &mut [u8; 16], aes_round: usize) -> [[u8; 4]; 4] {
|
|
||||||
// let mut round_keys = [[0u8; 4]; 4]; // Array to store the round keys
|
|
||||||
// let n = 4;
|
|
||||||
//
|
|
||||||
// // Extract the original key from the provided round key
|
|
||||||
// let mut original_key = [[0u8; 4]; 4];
|
|
||||||
// for i in 0..16 {
|
|
||||||
// original_key[i / 4][i % 4] = round_key[i];
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Reverse the key expansion process for the first 4 rounds
|
|
||||||
// for i in (0..16).rev() {
|
|
||||||
// if i % n == 0 {
|
|
||||||
// // Reverse the addition of the round constant
|
|
||||||
// let mut rcon = [0u8; 4];
|
|
||||||
// rcon[0] = RC[i / n];
|
|
||||||
// round_keys[i / n] = xor(
|
|
||||||
// &original_key[i / n],
|
|
||||||
// &inverse_shift_word(&inverse_substitute_word(&xor(&original_key[i / n], &rcon))),
|
|
||||||
// );
|
|
||||||
// } else if i >= n {
|
|
||||||
// // Reverse the XOR operation
|
|
||||||
// round_keys[i / n] = xor(&original_key[i / n], &original_key[i / n - 1]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Update the provided round key array with the round keys for the specified AES rounds
|
|
||||||
// for i in 0..16 {
|
|
||||||
// round_key[i] = round_keys[aes_round / n][i % n];
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// round_keys
|
|
||||||
// }
|
|
||||||
pub fn reverse_key_schedule(round_key: &mut [u8; 16], aes_round: usize) -> [u8; 16] {
|
|
||||||
let mut rcon = [0u8; 4];
|
|
||||||
// let n = 4;
|
|
||||||
// let indexes = [1,2,3,4];
|
|
||||||
|
|
||||||
for i in (0..aes_round).rev() {
|
|
||||||
rcon[0] = RC[i + 1];
|
|
||||||
let a2: [u8; 4] = round_key[0..4].try_into().unwrap();
|
|
||||||
let b2: [u8; 4] = round_key[4..8].try_into().unwrap();
|
|
||||||
let c2: [u8; 4] = round_key[8..12].try_into().unwrap();
|
|
||||||
let d2: [u8; 4] = round_key[12..16].try_into().unwrap();
|
|
||||||
|
|
||||||
let d1 = xor(&d2, &c2);
|
|
||||||
let c1 = xor(&c2, &b2);
|
|
||||||
let b1 = xor(&b2, &a2);
|
|
||||||
let a1 = xor(&xor(&a2, &shift_word(&substitute_word(&d1))), &rcon);
|
|
||||||
|
|
||||||
round_key[0..4].copy_from_slice(&a1);
|
|
||||||
round_key[4..8].copy_from_slice(&b1);
|
|
||||||
round_key[8..12].copy_from_slice(&c1);
|
|
||||||
round_key[12..16].copy_from_slice(&d1);
|
|
||||||
}
|
|
||||||
*round_key
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn aes_reduced(&key: &[u8; 16], &block: &[u8; 16]) -> [u8; 16] {
|
|
||||||
let nturn = 4;
|
|
||||||
let aescipher = Self::new(&key, &nturn);
|
|
||||||
aescipher.encrypt_block(&block)
|
|
||||||
}
|
|
||||||
pub fn aes_reduced_gen_texts(&key: &[u8; 16], &const_byte: &u8) -> [[u8; 16]; 256] {
|
|
||||||
let mut cleartext: [u8; 16];
|
|
||||||
let mut ciphertexts: [[u8; 16]; 256] = [[0; 16]; 256];
|
|
||||||
for i in 0..=255 {
|
|
||||||
cleartext = [
|
|
||||||
i, const_byte, const_byte, const_byte, const_byte, const_byte, const_byte,
|
|
||||||
const_byte, const_byte, const_byte, const_byte, const_byte, const_byte, const_byte,
|
|
||||||
const_byte, const_byte,
|
|
||||||
];
|
|
||||||
ciphertexts[i as usize] = Aes::aes_reduced(&key, &cleartext);
|
|
||||||
}
|
|
||||||
ciphertexts
|
|
||||||
}
|
|
||||||
pub fn decrypt_block_reduced_1_step(&self, block: &[u8; 16]) -> [u8; 16] {
|
|
||||||
let mut result = [0u8; 16];
|
|
||||||
|
|
||||||
let mut state = [[0u8; 4]; 4];
|
|
||||||
for i in 0..16 {
|
|
||||||
state[i % 4][i / 4] = block[i];
|
|
||||||
}
|
|
||||||
add_round_key(&mut state, &clone_into_array(&self.expanded_key[16..20]));
|
|
||||||
inverse_shift_rows(&mut state);
|
|
||||||
inverse_substitute_state(&mut state);
|
|
||||||
|
|
||||||
for i in 0..4 {
|
|
||||||
for j in 0..4 {
|
|
||||||
result[4 * j + i] = state[i][j]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
pub fn guessroundkey(&texts: &[[u8; 16]; 256]) -> [Vec<u8>; 16] {
|
|
||||||
let mut key: [Vec<u8>; 16] = Default::default();
|
|
||||||
let mut s: u8;
|
|
||||||
let mut matrix: [[u8; 4]; 4] = [[0; 4]; 4];
|
|
||||||
let mut array: [u8; 16] = [0; 16];
|
|
||||||
for j in 0..16 {
|
|
||||||
for i in 0..=255 {
|
|
||||||
s = 0x00;
|
|
||||||
for ciphertext in texts {
|
|
||||||
for i in 0..4 {
|
|
||||||
for j in 0..4 {
|
|
||||||
matrix[j][i] = ciphertext[j * 4 + i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// aes::inverse_shift_rows(&mut matrix);
|
|
||||||
for i in 0..4 {
|
|
||||||
for j in 0..4 {
|
|
||||||
array[j * 4 + i] = matrix[j][i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s ^= substitute(array[j] ^ i, false);
|
|
||||||
}
|
|
||||||
if s == 0x00 {
|
|
||||||
println!("found: {:02x} for byte {}", i, j);
|
|
||||||
key[j].push(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
key
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn findroundkey(&key: &[u8; 16]) -> [u8; 16] {
|
|
||||||
let mut found_key: [u8; 16] = [0x00; 16];
|
|
||||||
let mut const_byte: u8 = 0x00;
|
|
||||||
let mut ciphertexts: [[u8; 16]; 256] = Self::aes_reduced_gen_texts(&key, &const_byte);
|
|
||||||
let mut key_guesses: [Vec<u8>; 16] = Self::guessroundkey(&ciphertexts);
|
|
||||||
let mut more_key_guesses: [Vec<u8>; 16];
|
|
||||||
let mut result: [Vec<u8>; 16] = Default::default();
|
|
||||||
while key_guesses.iter().any(|vec| vec.len() > 1) {
|
|
||||||
const_byte += 1_u8;
|
|
||||||
ciphertexts = Self::aes_reduced_gen_texts(&key, &const_byte);
|
|
||||||
more_key_guesses = Self::guessroundkey(&ciphertexts);
|
|
||||||
for ((vec1, vec2), result_vec) in more_key_guesses
|
|
||||||
.iter()
|
|
||||||
.zip(key_guesses.iter())
|
|
||||||
.zip(result.iter_mut())
|
|
||||||
{
|
|
||||||
let common_elements: Vec<u8> = vec1
|
|
||||||
.iter()
|
|
||||||
.filter(|&byte| vec2.contains(byte))
|
|
||||||
.copied()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
*result_vec = common_elements;
|
|
||||||
}
|
|
||||||
for (source, target) in result.iter().zip(key_guesses.iter_mut()) {
|
|
||||||
*target = source.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (index, vec) in key_guesses.iter().enumerate() {
|
|
||||||
if let Some(&first_byte) = vec.first() {
|
|
||||||
found_key[index] = first_byte;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
found_key
|
|
||||||
}
|
|
||||||
// pub fn findkey(&key: &[u8; 16]) -> [u8; 16] {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -704,24 +538,6 @@ mod tests {
|
|||||||
assert_eq!(cleartext, expected_cleartext);
|
assert_eq!(cleartext, expected_cleartext);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn findroundkey_test() {
|
|
||||||
let key: [u8; 16] = [
|
|
||||||
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf,
|
|
||||||
0x4f, 0x3c,
|
|
||||||
];
|
|
||||||
let nturn = 4; // doesn't matter for this test
|
|
||||||
let aescipher = Aes::new(&key, &nturn);
|
|
||||||
let expected: [u8; 16] = aescipher.expanded_key[16..20] // 5th key (1st is the pre_whitenning, 2nd, 3rd and 4th the 3 previous round key)
|
|
||||||
.iter()
|
|
||||||
.flat_map(|subarray| subarray.iter())
|
|
||||||
.copied()
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.try_into()
|
|
||||||
.unwrap();
|
|
||||||
let found_key: [u8; 16] = Aes::findroundkey(&key);
|
|
||||||
assert_eq!(found_key, expected);
|
|
||||||
}
|
|
||||||
#[test]
|
|
||||||
fn inverse_shift_word_test() {
|
fn inverse_shift_word_test() {
|
||||||
let word: [u8; 4] = [0x01, 0x34, 0x76, 0x49];
|
let word: [u8; 4] = [0x01, 0x34, 0x76, 0x49];
|
||||||
let inverse_word: [u8; 4] = shift_word(&word);
|
let inverse_word: [u8; 4] = shift_word(&word);
|
||||||
|
46
src/main.rs
46
src/main.rs
@ -1,34 +1,44 @@
|
|||||||
mod aes;
|
mod aes;
|
||||||
use aes::Aes;
|
mod square;
|
||||||
|
use crate::aes::Aes;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let key: [u8; 16] = [
|
let key: [u8; 16] = [
|
||||||
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f,
|
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f,
|
||||||
0x3c,
|
0x3c,
|
||||||
];
|
];
|
||||||
let mut found_key: [u8; 16] = Aes::findroundkey(&key);
|
let found_key: [u8; 16] = Aes::findroundkey(&key);
|
||||||
for &byte in &found_key {
|
for &byte in &found_key {
|
||||||
print!("{:02x}", byte);
|
print!("{:02x}", byte);
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
// should be
|
let found_key_origininal = Aes::reverse_key_schedule(&found_key, 4);
|
||||||
// ef44a541
|
|
||||||
// a8525b7f
|
|
||||||
// b671253b
|
|
||||||
// db0bad00
|
|
||||||
let found_key_origininal = Aes::reverse_key_schedule(&mut found_key, 4);
|
|
||||||
for &byte in &found_key_origininal {
|
for &byte in &found_key_origininal {
|
||||||
print!("{:02x}", byte);
|
print!("{:02x}", byte);
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
|
|
||||||
// 247e156b 22aed2a6 a7f71588 01cf4f3c
|
let nturn = 4;
|
||||||
// 2b7e1516, 28aed2a6, abf71588, 09cf4f3c, EXPECTED
|
let aescipher = Aes::new(&key, &nturn);
|
||||||
// 2b7e1574 27aed2a6 a4f71588 00cf4f3c
|
let mut output = [[0u8; 16]; 11];
|
||||||
// 2b7e1516 28aed2a6 abf71588 09cf4f3c
|
for i in 0..11 {
|
||||||
|
for j in 0..4 {
|
||||||
// 2b7e1516, 28aed2a6, abf71588, 09cf4f3c,
|
output[i][4 * j..4 * (j + 1)].copy_from_slice(&aescipher.expanded_key[4 * i + j]);
|
||||||
// a0fafe17, 88542cb1, 23a33939, 2a6c7605,
|
}
|
||||||
// f2c295f2, 7a96b943, 5935807a, 7359f67f,
|
}
|
||||||
// 3d80477d, 4716fe3e, 1e237e44, 6d7a883b,
|
for &key in &output {
|
||||||
// ef44a541, a8525b7f, b671253b, db0bad00
|
for &byte in &key {
|
||||||
|
print!("{:02x}", byte);
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("test");
|
||||||
|
for i in 0..11 {
|
||||||
|
for &byte in &Aes::reverse_key_schedule(&output[i], i) {
|
||||||
|
print!("{:02x}", byte);
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
println!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
179
src/square.rs
Normal file
179
src/square.rs
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
use crate::aes::*;
|
||||||
|
|
||||||
|
impl Aes {
|
||||||
|
pub fn reverse_key_schedule(original_round_key: &[u8; 16], aes_round: usize) -> [u8; 16] {
|
||||||
|
let mut rcon = [0u8; 4];
|
||||||
|
let mut round_key: [u8; 16] = [0u8; 16];
|
||||||
|
round_key.copy_from_slice(original_round_key);
|
||||||
|
|
||||||
|
for i in (0..aes_round).rev() {
|
||||||
|
// println!("{}", i);
|
||||||
|
rcon[0] = RC[i + 1];
|
||||||
|
// println!("{:02x}", rcon[0]);
|
||||||
|
let a2: [u8; 4] = round_key[0..4].try_into().unwrap();
|
||||||
|
let b2: [u8; 4] = round_key[4..8].try_into().unwrap();
|
||||||
|
let c2: [u8; 4] = round_key[8..12].try_into().unwrap();
|
||||||
|
let d2: [u8; 4] = round_key[12..16].try_into().unwrap();
|
||||||
|
|
||||||
|
let d1 = xor(&d2, &c2);
|
||||||
|
let c1 = xor(&c2, &b2);
|
||||||
|
let b1 = xor(&b2, &a2);
|
||||||
|
let a1 = xor(&xor(&a2, &shift_word(&substitute_word(&d1))), &rcon);
|
||||||
|
|
||||||
|
round_key[0..4].copy_from_slice(&a1);
|
||||||
|
round_key[4..8].copy_from_slice(&b1);
|
||||||
|
round_key[8..12].copy_from_slice(&c1);
|
||||||
|
round_key[12..16].copy_from_slice(&d1);
|
||||||
|
}
|
||||||
|
round_key
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn aes_reduced(&key: &[u8; 16], &block: &[u8; 16]) -> [u8; 16] {
|
||||||
|
let nturn = 4;
|
||||||
|
let aescipher = Self::new(&key, &nturn);
|
||||||
|
aescipher.encrypt_block(&block)
|
||||||
|
}
|
||||||
|
pub fn aes_reduced_gen_texts(&key: &[u8; 16], &const_byte: &u8) -> [[u8; 16]; 256] {
|
||||||
|
let mut cleartext: [u8; 16];
|
||||||
|
let mut ciphertexts: [[u8; 16]; 256] = [[0; 16]; 256];
|
||||||
|
for i in 0..=255 {
|
||||||
|
cleartext = [
|
||||||
|
i, const_byte, const_byte, const_byte, const_byte, const_byte, const_byte,
|
||||||
|
const_byte, const_byte, const_byte, const_byte, const_byte, const_byte, const_byte,
|
||||||
|
const_byte, const_byte,
|
||||||
|
];
|
||||||
|
ciphertexts[i as usize] = Aes::aes_reduced(&key, &cleartext);
|
||||||
|
}
|
||||||
|
ciphertexts
|
||||||
|
}
|
||||||
|
pub fn decrypt_block_reduced_1_step(&self, block: &[u8; 16]) -> [u8; 16] {
|
||||||
|
let mut result = [0u8; 16];
|
||||||
|
|
||||||
|
let mut state = [[0u8; 4]; 4];
|
||||||
|
for i in 0..16 {
|
||||||
|
state[i % 4][i / 4] = block[i];
|
||||||
|
}
|
||||||
|
add_round_key(&mut state, &clone_into_array(&self.expanded_key[16..20]));
|
||||||
|
inverse_shift_rows(&mut state);
|
||||||
|
inverse_substitute_state(&mut state);
|
||||||
|
|
||||||
|
for i in 0..4 {
|
||||||
|
for j in 0..4 {
|
||||||
|
result[4 * j + i] = state[i][j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
pub fn guessroundkey(&texts: &[[u8; 16]; 256]) -> [Vec<u8>; 16] {
|
||||||
|
let mut key: [Vec<u8>; 16] = Default::default();
|
||||||
|
let mut s: u8;
|
||||||
|
let mut matrix: [[u8; 4]; 4] = [[0; 4]; 4];
|
||||||
|
let mut array: [u8; 16] = [0; 16];
|
||||||
|
for j in 0..16 {
|
||||||
|
for i in 0..=255 {
|
||||||
|
s = 0x00;
|
||||||
|
for ciphertext in texts {
|
||||||
|
for i in 0..4 {
|
||||||
|
for j in 0..4 {
|
||||||
|
matrix[j][i] = ciphertext[j * 4 + i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in 0..4 {
|
||||||
|
for j in 0..4 {
|
||||||
|
array[j * 4 + i] = matrix[j][i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s ^= substitute(array[j] ^ i, false);
|
||||||
|
}
|
||||||
|
if s == 0x00 {
|
||||||
|
println!("found: {:02x} for byte {}", i, j);
|
||||||
|
key[j].push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
key
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn findroundkey(&key: &[u8; 16]) -> [u8; 16] {
|
||||||
|
let mut found_key: [u8; 16] = [0x00; 16];
|
||||||
|
let mut const_byte: u8 = 0x00;
|
||||||
|
let mut ciphertexts: [[u8; 16]; 256] = Self::aes_reduced_gen_texts(&key, &const_byte);
|
||||||
|
let mut key_guesses: [Vec<u8>; 16] = Self::guessroundkey(&ciphertexts);
|
||||||
|
let mut more_key_guesses: [Vec<u8>; 16];
|
||||||
|
let mut result: [Vec<u8>; 16] = Default::default();
|
||||||
|
while key_guesses.iter().any(|vec| vec.len() > 1) {
|
||||||
|
const_byte += 1_u8;
|
||||||
|
ciphertexts = Self::aes_reduced_gen_texts(&key, &const_byte);
|
||||||
|
more_key_guesses = Self::guessroundkey(&ciphertexts);
|
||||||
|
for ((vec1, vec2), result_vec) in more_key_guesses
|
||||||
|
.iter()
|
||||||
|
.zip(key_guesses.iter())
|
||||||
|
.zip(result.iter_mut())
|
||||||
|
{
|
||||||
|
let common_elements: Vec<u8> = vec1
|
||||||
|
.iter()
|
||||||
|
.filter(|&byte| vec2.contains(byte))
|
||||||
|
.copied()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
*result_vec = common_elements;
|
||||||
|
}
|
||||||
|
for (source, target) in result.iter().zip(key_guesses.iter_mut()) {
|
||||||
|
*target = source.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (index, vec) in key_guesses.iter().enumerate() {
|
||||||
|
if let Some(&first_byte) = vec.first() {
|
||||||
|
found_key[index] = first_byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found_key
|
||||||
|
}
|
||||||
|
// pub fn findkey(&key: &[u8; 16]) -> [u8; 16] {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn findroundkey_test() {
|
||||||
|
let key: [u8; 16] = [
|
||||||
|
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf,
|
||||||
|
0x4f, 0x3c,
|
||||||
|
];
|
||||||
|
let nturn = 4; // doesn't matter for this test
|
||||||
|
let aescipher = Aes::new(&key, &nturn);
|
||||||
|
let expected: [u8; 16] = aescipher.expanded_key[16..20] // 5th key (1st is the pre_whitenning, 2nd, 3rd and 4th the 3 previous round key)
|
||||||
|
.iter()
|
||||||
|
.flat_map(|subarray| subarray.iter())
|
||||||
|
.copied()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.try_into()
|
||||||
|
.unwrap();
|
||||||
|
let found_key: [u8; 16] = Aes::findroundkey(&key);
|
||||||
|
assert_eq!(found_key, expected);
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn reverse_key_schedule_test() {
|
||||||
|
let key: [u8; 16] = [
|
||||||
|
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf,
|
||||||
|
0x4f, 0x3c,
|
||||||
|
];
|
||||||
|
let nturn = 4; // doesn't matter for this test
|
||||||
|
let aescipher = Aes::new(&key, &nturn);
|
||||||
|
let mut round_keys: [[u8; 16]; 11] = [[0u8; 16]; 11];
|
||||||
|
for i in 0..11 {
|
||||||
|
for j in 0..4 {
|
||||||
|
round_keys[i][4 * j..4 * (j + 1)]
|
||||||
|
.copy_from_slice(&aescipher.expanded_key[4 * i + j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in 0..11 {
|
||||||
|
assert_eq!(Aes::reverse_key_schedule(&round_keys[i], i), key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user