mirror of
https://github.com/kristoferssolo/cipher-workshop.git
synced 2025-12-20 11:04:38 +00:00
feat(aes): add round key
This commit is contained in:
parent
4007a9a04d
commit
7e5162fb44
@ -1,12 +1,19 @@
|
||||
use cipher_core::BlockCipher;
|
||||
use crate::{
|
||||
Block128,
|
||||
block::Block32,
|
||||
key::{Key, Subkey, Subkeys},
|
||||
};
|
||||
use cipher_core::{BlockCipher, CipherError};
|
||||
|
||||
use crate::key::Key;
|
||||
|
||||
pub struct Aes {}
|
||||
pub struct Aes {
|
||||
subkeys: Subkeys,
|
||||
}
|
||||
|
||||
impl Aes {
|
||||
pub fn new(_key: impl Into<Key>) -> Self {
|
||||
todo!()
|
||||
pub fn new(key: impl Into<Key>) -> Self {
|
||||
Self {
|
||||
subkeys: Subkeys::from_key(&key.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,9 +25,46 @@ impl BlockCipher for Aes {
|
||||
|
||||
fn transform_impl(
|
||||
&self,
|
||||
_block: &[u8],
|
||||
_action: cipher_core::CipherAction,
|
||||
block: &[u8],
|
||||
action: cipher_core::CipherAction,
|
||||
) -> cipher_core::CipherResult<cipher_core::Output> {
|
||||
let block_arr: [u8; Self::BLOCK_SIZE] = block
|
||||
.try_into()
|
||||
.map_err(|_| CipherError::invalid_block_size(Self::BLOCK_SIZE, block.len()))?;
|
||||
|
||||
let block128 = Block128::from_be_bytes(block_arr);
|
||||
|
||||
let round_key = add_round_key(
|
||||
*self.subkeys.first().unwrap(),
|
||||
*block128.as_block32_array().first().unwrap(),
|
||||
);
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
fn add_round_key(subkey: Subkey, block: Block32) -> Block32 {
|
||||
block ^ subkey
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rstest::rstest;
|
||||
|
||||
use super::*;
|
||||
|
||||
const TEST_MESSAGE: u128 = 0x0123_4567_89AB_CDEF_FEDC_BA98_7654_3210;
|
||||
|
||||
#[rstest]
|
||||
#[case(0x0123_4567, 0x0F15_71C9, 0x0E36_34AE)]
|
||||
#[case(0x89AB_CDEF, 0x47D9_E859, 0xCE72_25B6)]
|
||||
#[case(0xFEDC_BA98, 0x1CB7_ADD6, 0xE26B_174E)]
|
||||
#[case(0x7654_3210, 0xAF7F_6798, 0xD92B_5588)]
|
||||
fn round_key(#[case] block: u32, #[case] subkey: u32, #[case] expected: u32) {
|
||||
let block = Block32::new(block);
|
||||
let subkey = Subkey::from_u32(subkey);
|
||||
|
||||
let result = add_round_key(subkey, block);
|
||||
|
||||
assert_eq!(result.as_u32(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::block::secret_block;
|
||||
use crate::block::{Block32, secret_block};
|
||||
use cipher_core::{BlockError, InputBlock};
|
||||
use std::{
|
||||
slice::{from_raw_parts, from_raw_parts_mut},
|
||||
@ -37,6 +37,18 @@ impl Block128 {
|
||||
pub const fn to_le_bytes(self) -> [u8; 16] {
|
||||
self.0.to_le_bytes()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub const fn as_block32_array(self) -> [Block32; 4] {
|
||||
let val = self.0;
|
||||
[
|
||||
Block32::from_u32((val >> 96) as u32),
|
||||
Block32::from_u32((val >> 64) as u32),
|
||||
Block32::from_u32((val >> 32) as u32),
|
||||
Block32::from_u32(val as u32),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Block128 {
|
||||
@ -105,14 +117,20 @@ impl From<[u8; 16]> for Block128 {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Block128> for [Block32; 4] {
|
||||
fn from(block: Block128) -> Self {
|
||||
block.as_block32_array()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Block128> for Vec<u8> {
|
||||
fn from(value: Block128) -> Self {
|
||||
value.0.to_be_bytes().to_vec()
|
||||
value.to_be_bytes().to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Block128> for Vec<u8> {
|
||||
fn from(value: &Block128) -> Self {
|
||||
value.0.to_be_bytes().to_vec()
|
||||
value.to_be_bytes().to_vec()
|
||||
}
|
||||
}
|
||||
|
||||
27
aes/src/block/block32.rs
Normal file
27
aes/src/block/block32.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use std::ops::BitXor;
|
||||
|
||||
use crate::{block::secret_block, key::Subkey};
|
||||
|
||||
secret_block! {
|
||||
pub struct Block32(u32, 32, 0xFFFF_FFFF);
|
||||
}
|
||||
impl Block32 {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub const fn to_be_bytes(self) -> [u8; 4] {
|
||||
self.0.to_be_bytes()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub const fn to_le_bytes(self) -> [u8; 4] {
|
||||
self.0.to_le_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl BitXor<Subkey> for Block32 {
|
||||
type Output = Self;
|
||||
fn bitxor(self, rhs: Subkey) -> Self::Output {
|
||||
Self(self.0 ^ rhs.as_u32())
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
mod block128;
|
||||
mod block32;
|
||||
mod secret_block;
|
||||
|
||||
use crate::secret_block;
|
||||
pub use block128::Block128;
|
||||
pub use {block32::Block32, block128::Block128};
|
||||
|
||||
@ -5,4 +5,4 @@ mod subkey;
|
||||
mod subkeys;
|
||||
|
||||
use crate::secret_key;
|
||||
pub use aes_key::Key;
|
||||
pub use {aes_key::Key, subkey::Subkey, subkeys::Subkeys};
|
||||
|
||||
@ -27,6 +27,18 @@ impl Subkey {
|
||||
pub const fn rotate_right(self, n: u32) -> Self {
|
||||
Self(self.0.rotate_right(n))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub const fn to_be_bytes(self) -> [u8; 4] {
|
||||
self.0.to_be_bytes()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub const fn to_le_bytes(self) -> [u8; 4] {
|
||||
self.0.to_le_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl BitXor<ExpandedKey> for Subkey {
|
||||
|
||||
@ -51,6 +51,11 @@ impl Subkeys {
|
||||
pub fn iter_mut(&mut self) -> IterMut<'_, Subkey> {
|
||||
self.0.iter_mut()
|
||||
}
|
||||
|
||||
/// Returns the first element of the slice, or `None` if it is empty.
|
||||
pub fn first(&self) -> Option<&Subkey> {
|
||||
self.0.first()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a Subkeys {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user