diff options
author | Daniel Schadt <kingdread@gmx.de> | 2025-04-11 12:48:18 +0200 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2025-04-11 12:48:18 +0200 |
commit | 5bd298ed568aca12a54f014a7b13f943379a5eb9 (patch) | |
tree | 911afd45baafe196517455f33ab89bc8a9f09355 /src/block.rs | |
parent | 34ed0189281fcca1921d4e3d762e6d9183d5230f (diff) | |
download | zears-5bd298ed568aca12a54f014a7b13f943379a5eb9.tar.gz zears-5bd298ed568aca12a54f014a7b13f943379a5eb9.tar.bz2 zears-5bd298ed568aca12a54f014a7b13f943379a5eb9.zip |
use simd instructions
(requires nightly compiler)
Diffstat (limited to 'src/block.rs')
-rw-r--r-- | src/block.rs | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/src/block.rs b/src/block.rs index c294aab..b485b17 100644 --- a/src/block.rs +++ b/src/block.rs @@ -1,12 +1,34 @@ use std::ops::{BitAnd, BitOr, BitXor, Index, IndexMut, Mul, Shl, Shr}; +use std::simd::prelude::*; /// A block, the unit of work that AEZ divides the message into. #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct Block(pub [u8; 16]); +pub struct Block(u8x16); impl Block { - pub const NULL: Block = Block([0; 16]); - pub const ONE: Block = Block([0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + pub fn null() -> Block { + Block([0; 16].into()) + } + + pub fn one() -> Block { + Block([0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0].into()) + } + + pub fn bytes(&self) -> [u8; 16] { + self.0.into() + } + + pub fn write_to(&self, output: &mut [u8; 16]) { + self.0.copy_to_slice(output); + } + + pub(crate) fn simd(&self) -> u8x16 { + self.0 + } + + pub(crate) fn from_simd(value: u8x16) -> Self { + Block(value) + } /// Create a block from a slice. /// @@ -16,18 +38,18 @@ impl Block { let len = value.len().min(16); let mut array = [0; 16]; array[..len].copy_from_slice(&value[..len]); - Block(array) + Block(array.into()) } /// Constructs a block representing the given integer. /// /// This corresponds to [x]_128 in the paper. pub fn from_int<I: Into<u128>>(value: I) -> Self { - Block(value.into().to_be_bytes()) + Block(value.into().to_be_bytes().into()) } pub fn to_int(&self) -> u128 { - u128::from_be_bytes(self.0) + u128::from_be_bytes(self.0.into()) } /// Pad the block to full length. @@ -62,43 +84,26 @@ impl Block { impl From<[u8; 16]> for Block { fn from(value: [u8; 16]) -> Block { - Block(value) + Block(value.into()) } } impl From<&[u8; 16]> for Block { fn from(value: &[u8; 16]) -> Block { - Block(*value) + Block((*value).into()) } } impl From<u128> for Block { fn from(value: u128) -> Block { - Block(value.to_be_bytes()) + Block(value.to_be_bytes().into()) } } impl BitXor<Block> for Block { type Output = Block; fn bitxor(self, rhs: Block) -> Block { - Block([ - self.0[0] ^ rhs.0[0], - self.0[1] ^ rhs.0[1], - self.0[2] ^ rhs.0[2], - self.0[3] ^ rhs.0[3], - self.0[4] ^ rhs.0[4], - self.0[5] ^ rhs.0[5], - self.0[6] ^ rhs.0[6], - self.0[7] ^ rhs.0[7], - self.0[8] ^ rhs.0[8], - self.0[9] ^ rhs.0[9], - self.0[10] ^ rhs.0[10], - self.0[11] ^ rhs.0[11], - self.0[12] ^ rhs.0[12], - self.0[13] ^ rhs.0[13], - self.0[14] ^ rhs.0[14], - self.0[15] ^ rhs.0[15], - ]) + Block(self.0 ^ rhs.0) } } @@ -119,14 +124,14 @@ impl Shr<u32> for Block { impl BitAnd<Block> for Block { type Output = Block; fn bitand(self, rhs: Block) -> Block { - Block::from(self.to_int() & rhs.to_int()) + Block(self.0 & rhs.0) } } impl BitOr<Block> for Block { type Output = Block; fn bitor(self, rhs: Block) -> Block { - Block::from(self.to_int() | rhs.to_int()) + Block(self.0 | rhs.0) } } @@ -147,7 +152,7 @@ impl Mul<u32> for Block { type Output = Block; fn mul(self, rhs: u32) -> Block { match rhs { - 0 => Block::NULL, + 0 => Block::null(), 1 => self, 2 => { let mut result = self << 1; |