feat(block): add secret_block! macro

This commit is contained in:
Kristofers Solo 2025-10-17 20:46:04 +03:00
parent db52714d52
commit 14ccb2288d
Signed by: kristoferssolo
GPG Key ID: 8687F2D3EEE6F0ED
7 changed files with 145 additions and 89 deletions

View File

@ -1,34 +1,9 @@
use std::ops::BitXor; use std::ops::BitXor;
#[derive(Debug, Clone, Copy, PartialEq, Eq)] use crate::secret_block;
pub struct Block32(u32);
impl Block32 { secret_block! {
const MASK: u32 = 0xFFFF_FFFF; pub struct Block32(u32, 32, 0xFFFF_FFFF);
#[inline]
#[must_use]
pub const fn new(value: u32) -> Self {
Self(value)
}
#[inline]
#[must_use]
pub const fn as_u32(self) -> u32 {
self.0
}
#[inline]
#[must_use]
pub const fn as_u64(self) -> u64 {
self.0 as u64
}
}
impl From<u32> for Block32 {
fn from(value: u32) -> Self {
Self(value)
}
} }
impl From<u64> for Block32 { impl From<u64> for Block32 {

View File

@ -1,24 +1,11 @@
use crate::{block::Block6, key::Subkey, secret_block};
use std::{array, ops::BitXor}; use std::{array, ops::BitXor};
use crate::{block::Block6, key::Subkey}; secret_block! {
pub struct Block48(u64, 48, 0xFFFF_FFFF_FFFF);
#[derive(Debug, Clone, Copy, PartialEq, Eq)] }
pub struct Block48(u64);
impl Block48 { impl Block48 {
const MASK: u64 = 0xFFFF_FFFF_FFFF;
#[inline]
#[must_use]
pub const fn new(value: u64) -> Self {
Self(value & Self::MASK)
}
#[inline]
#[must_use]
pub const fn as_u64(self) -> u64 {
self.0
}
#[must_use] #[must_use]
pub fn as_block6_array(self) -> [Block6; 8] { pub fn as_block6_array(self) -> [Block6; 8] {
array::from_fn(|idx| { array::from_fn(|idx| {
@ -29,12 +16,6 @@ impl Block48 {
} }
} }
impl From<u64> for Block48 {
fn from(value: u64) -> Self {
Self::new(value)
}
}
impl BitXor for Block48 { impl BitXor for Block48 {
type Output = Self; type Output = Self;
fn bitxor(self, rhs: Self) -> Self::Output { fn bitxor(self, rhs: Self) -> Self::Output {

View File

@ -1,27 +1,16 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq)] use crate::secret_block;
pub struct Block6(u8);
secret_block! {
pub struct Block6(u8, 6, 0x3F);
}
impl Block6 { impl Block6 {
const MASK: u8 = 0x3F;
#[inline]
#[must_use]
pub const fn new(value: u8) -> Self {
Self(value & Self::MASK)
}
#[inline] #[inline]
#[must_use] #[must_use]
pub const fn zero() -> Self { pub const fn zero() -> Self {
Self(0) Self(0)
} }
#[inline]
#[must_use]
pub const fn as_u8(self) -> u8 {
self.0
}
#[inline] #[inline]
#[must_use] #[must_use]
pub const fn to_row(self) -> usize { pub const fn to_row(self) -> usize {

View File

@ -1,21 +1,10 @@
use crate::block::lr::LR; use crate::block::{lr::LR, secret_block};
#[derive(Debug, Clone, Copy, PartialEq, Eq)] secret_block! {
pub struct Block64(u64); pub struct Block64(u64, 64, 0xFFFF_FFFF_FFFF_FFFF);
}
impl Block64 { impl Block64 {
#[inline]
#[must_use]
pub const fn new(value: u64) -> Self {
Self(value)
}
#[inline]
#[must_use]
pub const fn as_u64(self) -> u64 {
self.0
}
#[inline] #[inline]
#[must_use] #[must_use]
pub const fn from_be_bytes(bytes: [u8; 8]) -> Self { pub const fn from_be_bytes(bytes: [u8; 8]) -> Self {
@ -47,12 +36,6 @@ impl From<[u8; 8]> for Block64 {
} }
} }
impl From<u64> for Block64 {
fn from(value: u64) -> Self {
Self::new(value)
}
}
impl From<Block64> for LR { impl From<Block64> for LR {
fn from(block: Block64) -> Self { fn from(block: Block64) -> Self {
let left = (block.0 >> 32) as u32; let left = (block.0 >> 32) as u32;

View File

@ -3,5 +3,7 @@ mod block48;
mod block6; mod block6;
mod block64; mod block64;
mod lr; mod lr;
mod secret_block;
use crate::secret_block;
pub use {block6::Block6, block32::Block32, block48::Block48, block64::Block64, lr::LR}; pub use {block6::Block6, block32::Block32, block48::Block48, block64::Block64, lr::LR};

View File

@ -0,0 +1,126 @@
/// Macro to generate a masked, zeroizable integer wrapper type.
///
/// Usage:
/// ```
/// secret_block! {
/// /// docs...
/// pub struct Block48(u64, 48, 0x0000_FFFF_FFFF_FFFFu64);
/// }
/// ```
#[macro_export]
macro_rules! secret_block {
(
$(#[$meta:meta])*
$vis:vis struct $name:ident ( $int:tt, $bits:expr, $mask:expr );
) => {
$(#[$meta])*
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
$vis struct $name($int);
impl $name {
/// Mask to restrict the underlying integer to valid bits.
pub const MASK: $int = $mask;
#[inline]
#[must_use]
pub const fn new(value: $int) -> Self {
Self(value & Self::MASK)
}
secret_block!(@conversions_as $int);
secret_block!(@conversions_from $int $int);
}
impl From<$int> for $name {
fn from(v: $int) -> Self {
Self(v & Self::MASK)
}
}
};
// Helper: generate conversions_as based on type
(@conversions_as u8) => {
/// Return value as u8
#[allow(dead_code)]
#[inline]
#[must_use]
pub const fn as_u8(&self) -> u8 {
self.0 as u8
}
secret_block!(@conversions_as u16);
};
(@conversions_as u16) => {
/// Return value as u16
#[allow(dead_code)]
#[inline]
#[must_use]
pub const fn as_u16(&self) -> u16 {
self.0 as u16
}
secret_block!(@conversions_as u32);
};
(@conversions_as u32) => {
/// Return value as u32
#[allow(dead_code)]
#[inline]
#[must_use]
pub const fn as_u32(&self) -> u32 {
self.0 as u32
}
secret_block!(@conversions_as u64);
};
(@conversions_as u64) => {
/// Return value as u64
#[allow(dead_code)]
#[inline]
#[must_use]
pub const fn as_u64(&self) -> u64 {
self.0 as u64
}
};
// Helper: generate conversions_from based on type
(@conversions_from u8 $int:tt) => {
/// Create value from u8
#[allow(dead_code)]
#[inline]
#[must_use]
pub const fn from_u8(key: u8) -> Self {
Self(key as $int & Self::MASK)
}
};
(@conversions_from u16 $int:tt) => {
/// Create value from u16
#[allow(dead_code)]
#[inline]
#[must_use]
pub const fn from_u16(key: u16) -> Self {
Self(key as $int & Self::MASK)
}
secret_block!(@conversions_from u8 $int);
};
(@conversions_from u32 $int:tt) => {
/// Create value from u32
#[allow(dead_code)]
#[inline]
#[must_use]
pub const fn from_u32(key: u32) -> Self {
Self(key as $int & Self::MASK)
}
secret_block!(@conversions_from u16 $int);
};
(@conversions_from u64 $int:tt) => {
/// Create value from u64
#[allow(dead_code)]
#[inline]
#[must_use]
pub const fn from_u64(key: u64) -> Self {
Self(key & Self::MASK)
}
secret_block!(@conversions_from u32 $int);
}
}

View File

@ -15,7 +15,6 @@ macro_rules! secret_key {
) => { ) => {
$(#[$meta])* $(#[$meta])*
#[derive(::zeroize::ZeroizeOnDrop, Default)] #[derive(::zeroize::ZeroizeOnDrop, Default)]
#[zeroize(drop)]
$vis struct $name($int); $vis struct $name($int);
impl $name { impl $name {
@ -81,6 +80,7 @@ macro_rules! secret_key {
self.0 as u64 self.0 as u64
} }
}; };
// Helper: generate conversions_from based on type
(@conversions_from u8 $int:tt) => { (@conversions_from u8 $int:tt) => {
/// Create value from u8 /// Create value from u8
#[allow(dead_code)] #[allow(dead_code)]