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 {
|
||||||
|
subkeys: Subkeys,
|
||||||
pub struct Aes {}
|
}
|
||||||
|
|
||||||
impl Aes {
|
impl Aes {
|
||||||
pub fn new(_key: impl Into<Key>) -> Self {
|
pub fn new(key: impl Into<Key>) -> Self {
|
||||||
todo!()
|
Self {
|
||||||
|
subkeys: Subkeys::from_key(&key.into()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,9 +25,46 @@ impl BlockCipher for Aes {
|
|||||||
|
|
||||||
fn transform_impl(
|
fn transform_impl(
|
||||||
&self,
|
&self,
|
||||||
_block: &[u8],
|
block: &[u8],
|
||||||
_action: cipher_core::CipherAction,
|
action: cipher_core::CipherAction,
|
||||||
) -> cipher_core::CipherResult<cipher_core::Output> {
|
) -> 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!()
|
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 cipher_core::{BlockError, InputBlock};
|
||||||
use std::{
|
use std::{
|
||||||
slice::{from_raw_parts, from_raw_parts_mut},
|
slice::{from_raw_parts, from_raw_parts_mut},
|
||||||
@ -37,6 +37,18 @@ impl Block128 {
|
|||||||
pub const fn to_le_bytes(self) -> [u8; 16] {
|
pub const fn to_le_bytes(self) -> [u8; 16] {
|
||||||
self.0.to_le_bytes()
|
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 {
|
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> {
|
impl From<Block128> for Vec<u8> {
|
||||||
fn from(value: Block128) -> Self {
|
fn from(value: Block128) -> Self {
|
||||||
value.0.to_be_bytes().to_vec()
|
value.to_be_bytes().to_vec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Block128> for Vec<u8> {
|
impl From<&Block128> for Vec<u8> {
|
||||||
fn from(value: &Block128) -> Self {
|
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 block128;
|
||||||
|
mod block32;
|
||||||
mod secret_block;
|
mod secret_block;
|
||||||
|
|
||||||
use crate::secret_block;
|
use crate::secret_block;
|
||||||
pub use block128::Block128;
|
pub use {block32::Block32, block128::Block128};
|
||||||
|
|||||||
@ -5,4 +5,4 @@ mod subkey;
|
|||||||
mod subkeys;
|
mod subkeys;
|
||||||
|
|
||||||
use crate::secret_key;
|
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 {
|
pub const fn rotate_right(self, n: u32) -> Self {
|
||||||
Self(self.0.rotate_right(n))
|
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 {
|
impl BitXor<ExpandedKey> for Subkey {
|
||||||
|
|||||||
@ -51,6 +51,11 @@ impl Subkeys {
|
|||||||
pub fn iter_mut(&mut self) -> IterMut<'_, Subkey> {
|
pub fn iter_mut(&mut self) -> IterMut<'_, Subkey> {
|
||||||
self.0.iter_mut()
|
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 {
|
impl<'a> IntoIterator for &'a Subkeys {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user