mirror of
https://github.com/kristoferssolo/cipher-workshop.git
synced 2025-12-20 11:04:38 +00:00
refactor(aes): operate on custom values
This commit is contained in:
parent
37f8a97a11
commit
a8ccd3d294
@ -26,7 +26,7 @@ impl Aes {
|
|||||||
&self.subkeys
|
&self.subkeys
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encryot_block(&self, mut state: Block128) -> Block128 {
|
fn encrypt_block(&self, mut state: Block128) -> Block128 {
|
||||||
let mut keys = self.subkeys.chunks();
|
let mut keys = self.subkeys.chunks();
|
||||||
state = add_round_key(state, keys.next().expect("Round key 0"));
|
state = add_round_key(state, keys.next().expect("Round key 0"));
|
||||||
|
|
||||||
@ -45,8 +45,8 @@ impl Aes {
|
|||||||
state
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decryot_block(&self, mut state: Block128) -> Block128 {
|
fn decrypt_block(&self, mut state: Block128) -> Block128 {
|
||||||
let mut keys = self.subkeys.chunks();
|
let mut keys = self.subkeys.chunks_rev();
|
||||||
state = add_round_key(state, keys.next().expect("Final round key"));
|
state = add_round_key(state, keys.next().expect("Final round key"));
|
||||||
|
|
||||||
for _ in 1..10 {
|
for _ in 1..10 {
|
||||||
@ -83,8 +83,8 @@ impl BlockCipher for Aes {
|
|||||||
let block128 = Block128::from_be_bytes(block_arr);
|
let block128 = Block128::from_be_bytes(block_arr);
|
||||||
|
|
||||||
let result = match action {
|
let result = match action {
|
||||||
CipherAction::Encrypt => self.encryot_block(block128),
|
CipherAction::Encrypt => self.encrypt_block(block128),
|
||||||
CipherAction::Decrypt => self.decryot_block(block128),
|
CipherAction::Decrypt => self.decrypt_block(block128),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(result.into())
|
Ok(result.into())
|
||||||
|
|||||||
@ -4,6 +4,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use cipher_core::{BlockError, InputBlock};
|
use cipher_core::{BlockError, InputBlock};
|
||||||
use std::{
|
use std::{
|
||||||
|
ops::BitXor,
|
||||||
slice::{from_raw_parts, from_raw_parts_mut},
|
slice::{from_raw_parts, from_raw_parts_mut},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
@ -147,3 +148,10 @@ impl From<&Block128> for Vec<u8> {
|
|||||||
value.to_be_bytes().to_vec()
|
value.to_be_bytes().to_vec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl BitXor<u128> for Block128 {
|
||||||
|
type Output = Self;
|
||||||
|
fn bitxor(self, rhs: u128) -> Self::Output {
|
||||||
|
Self(self.0 ^ rhs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::key::secret_key;
|
use crate::key::secret_key;
|
||||||
use std::ops::BitXor;
|
use std::ops::{BitOr, BitXor, Shl};
|
||||||
|
|
||||||
secret_key! {
|
secret_key! {
|
||||||
/// A single AES round subkey
|
/// A single AES round subkey
|
||||||
@ -47,3 +47,17 @@ impl BitXor for Subkey {
|
|||||||
Self(self.0 ^ rhs.as_u32())
|
Self(self.0 ^ rhs.as_u32())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Shl<i32> for Subkey {
|
||||||
|
type Output = u128;
|
||||||
|
fn shl(self, rhs: i32) -> Self::Output {
|
||||||
|
self.as_u128() << rhs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitOr<Subkey> for u128 {
|
||||||
|
type Output = Self;
|
||||||
|
fn bitor(self, rhs: Subkey) -> Self::Output {
|
||||||
|
self | rhs.as_u128()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,12 +1,9 @@
|
|||||||
use crate::{Block128, key::Subkey};
|
use crate::{Block128, key::Subkey};
|
||||||
|
|
||||||
pub const fn add_round_key(state: Block128, subkeys: &[Subkey; 4]) -> Block128 {
|
pub fn add_round_key(state: Block128, subkeys: &[Subkey; 4]) -> Block128 {
|
||||||
let k0 = subkeys[0].as_u128();
|
let [k0, k1, k2, k3] = [subkeys[0], subkeys[1], subkeys[2], subkeys[3]];
|
||||||
let k1 = subkeys[1].as_u128();
|
|
||||||
let k2 = subkeys[2].as_u128();
|
|
||||||
let k3 = subkeys[3].as_u128();
|
|
||||||
let key_block = (k0 << 96) | (k1 << 64) | (k2 << 32) | k3;
|
let key_block = (k0 << 96) | (k1 << 64) | (k2 << 32) | k3;
|
||||||
Block128::new(state.as_u128() ^ key_block)
|
state ^ key_block
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -15,11 +12,28 @@ mod tests {
|
|||||||
use rstest::rstest;
|
use rstest::rstest;
|
||||||
|
|
||||||
const TEST_KEY: u128 = 0x0F15_71C9_47D9_E859_1CB7_ADD6_AF7F_6798;
|
const TEST_KEY: u128 = 0x0F15_71C9_47D9_E859_1CB7_ADD6_AF7F_6798;
|
||||||
|
const TEST_MESSAGE: u128 = 0x0123_4567_89AB_CDEF_FEDC_BA98_7654_3210;
|
||||||
|
|
||||||
#[rstest]
|
#[rstest]
|
||||||
|
#[case(
|
||||||
|
0x0123_4567_89AB_CDEF_FEDC_BA98_7654_3210,
|
||||||
|
[0x0F15_71C9, 0x47D9_E859, 0x1CB7_ADD6, 0xAF7F_6798],
|
||||||
|
0x0E36_34AE_CE72_25B6_E26B_174E_D92B_5588
|
||||||
|
)]
|
||||||
|
fn round_key_addition(#[case] input: u128, #[case] subkeys: [u32; 4], #[case] expected: u128) {
|
||||||
|
let block = Block128::new(input);
|
||||||
|
let subkeys = subkeys.map(Subkey::from_u32);
|
||||||
|
let result = add_round_key(block, &subkeys).as_u128();
|
||||||
|
assert_eq!(
|
||||||
|
result, expected,
|
||||||
|
"Adding Round Key failed. Expected 0x{expected:032X}, got 0x{result:032X}",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rstest]
|
||||||
|
#[case(TEST_MESSAGE)]
|
||||||
#[case(0x0000_0000_0000_0000_0000_0000_0000_0000)]
|
#[case(0x0000_0000_0000_0000_0000_0000_0000_0000)]
|
||||||
#[case(0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF)]
|
#[case(0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF)]
|
||||||
#[case(0x1234_5678_9ABC_DEF0_1234_5678_9ABC_DEF0)]
|
|
||||||
fn add_round_key_roundtrip(#[case] plaintext: u128) {
|
fn add_round_key_roundtrip(#[case] plaintext: u128) {
|
||||||
use crate::Aes;
|
use crate::Aes;
|
||||||
|
|
||||||
|
|||||||
@ -2,50 +2,36 @@ use aes::Aes;
|
|||||||
use cipher_core::BlockCipher;
|
use cipher_core::BlockCipher;
|
||||||
use rstest::rstest;
|
use rstest::rstest;
|
||||||
|
|
||||||
const TEST_KEY: u128 = 0x2B7E_1516_28AE_D2A6_ABF7_1588_09CF_4F3C;
|
const TEST_KEY: u128 = 0x0F15_71C9_47D9_E859_1CB7_ADD6_AF7F_6798;
|
||||||
const TEST_PLAINTEXT: u128 = 0x6BC1_BEE2_2E40_9F96_E93D_7E11_7393_1728;
|
const TEST_PLAINTEXT: u128 = 0x0123_4567_89AB_CDEF_FEDC_BA98_7654_3210;
|
||||||
const TEST_CIPHERTEXT: u128 = 0x79BD_98A6_CB0F_D3AE_3D7D_C1A3_3CD3_6E2F;
|
const TEST_CIPHERTEXT: u128 = 0x34D3_F0EE_CB4D_FA16_CB8B_F07F_29A0_CB79;
|
||||||
|
|
||||||
// #[rstest]
|
#[rstest]
|
||||||
// #[case(TEST_PLAINTEXT, TEST_CIPHERTEXT, TEST_KEY)]
|
#[case(TEST_PLAINTEXT, TEST_CIPHERTEXT, TEST_KEY)]
|
||||||
// #[case(
|
fn encrypt_decrypt_roundtrip(
|
||||||
// 0xAE2D_8A57_1E03_AC9C_9EB7_6FAC_45AF_8E51,
|
#[case] plaintext: u128,
|
||||||
// 0xBC14_003D_01C9_B46C_AC63_D481_5210_E80B,
|
#[case] expected_ciphertext: u128,
|
||||||
// 0xF5D3_D585_03B9_699D_E785_895A_96FD_BAAF
|
#[case] key: u128,
|
||||||
// )]
|
) {
|
||||||
// #[case(
|
let aes = Aes::new(key);
|
||||||
// 0x30C8_1C46_A35C_E411_E5FB_C119_1A0A_52EF,
|
|
||||||
// 0xB9AF_FEE2_98CD_0F4A_6708_44A6_D6CE_EF87,
|
// Encrypt
|
||||||
// 0x43B1_CD7F_598E_CE23_881B_00E3_ED03_0688
|
let ciphertext = aes
|
||||||
// )]
|
.encrypt(&plaintext.to_be_bytes())
|
||||||
// #[case(
|
.expect("Encryption failed");
|
||||||
// 0xF69F_2445_DF4F_9B17_AD2B_417B_E66C_3710,
|
let ciphertext_u128 = u128::from_be_bytes(ciphertext.as_slice().try_into().unwrap());
|
||||||
// 0xA279_FA71_A91B_9FA9_213C_E13E_659D_5C3B,
|
|
||||||
// 0x7B0C_785E_27E8_AD3F_8223_2071_0472_5DD4
|
assert_eq!(
|
||||||
// )]
|
ciphertext_u128, expected_ciphertext,
|
||||||
// fn encrypt_decrypt_roundtrip(
|
"Encryption failed. Expected 0x{expected_ciphertext:032X}, got 0x{ciphertext_u128:032X}"
|
||||||
// #[case] plaintext: u128,
|
);
|
||||||
// #[case] expected_ciphertext: u128,
|
|
||||||
// #[case] key: u128,
|
// Decrypt
|
||||||
// ) {
|
let decrypted = aes.decrypt(&ciphertext).expect("Decryption failed");
|
||||||
// let aes = Aes::new(key);
|
let decrypted_u128 = u128::from_be_bytes(decrypted.as_slice().try_into().unwrap());
|
||||||
// let pt_bytes = plaintext.to_be_bytes();
|
|
||||||
//
|
assert_eq!(
|
||||||
// // Test Encrypt
|
decrypted_u128, plaintext,
|
||||||
// let ciphertext = aes.encrypt(&pt_bytes).expect("Encryption failed");
|
"Decryption failed. Expected 0x{plaintext:032X}, got 0x{decrypted_u128:032X}"
|
||||||
// let ciphertext_u128 = u128::from_be_bytes(ciphertext.as_slice().try_into().unwrap());
|
);
|
||||||
//
|
}
|
||||||
// assert_eq!(
|
|
||||||
// ciphertext_u128, expected_ciphertext,
|
|
||||||
// "Encryption mismatch. Expected 0x{expected_ciphertext:032X}, got 0x{ciphertext_u128:032X}"
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// // Test Decrypt
|
|
||||||
// let decrypted = aes.decrypt(&ciphertext).expect("Decryption failed");
|
|
||||||
// let decrypted_u128 = u128::from_be_bytes(decrypted.as_slice().try_into().unwrap());
|
|
||||||
//
|
|
||||||
// assert_eq!(
|
|
||||||
// decrypted_u128, plaintext,
|
|
||||||
// "Decryption mismatch. Expected 0x{plaintext:032X}, got 0x{decrypted_u128:032X}"
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user