aboutsummaryrefslogtreecommitdiff
path: root/src/block.rs
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2025-04-11 12:48:18 +0200
committerDaniel Schadt <kingdread@gmx.de>2025-04-11 12:48:18 +0200
commit5bd298ed568aca12a54f014a7b13f943379a5eb9 (patch)
tree911afd45baafe196517455f33ab89bc8a9f09355 /src/block.rs
parent34ed0189281fcca1921d4e3d762e6d9183d5230f (diff)
downloadzears-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.rs65
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;