From 6d51e014b4d95a8bd8c82821867af47f25a7c01b Mon Sep 17 00:00:00 2001 From: Alexandr Kitaev Date: Thu, 1 Feb 2024 17:35:25 +0300 Subject: [PATCH] ghash+polyval: add `new_with_init_block` (#195) Adds customization for init_block, needed for `belt-dwp` AEAD --- ghash/src/lib.rs | 16 ++++++++++++---- polyval/src/backend/autodetect.rs | 19 ++++++++++++++----- polyval/src/backend/clmul.rs | 26 +++++++++++++++++--------- polyval/src/backend/pmull.rs | 19 ++++++++++++++----- polyval/src/backend/soft32.rs | 26 ++++++++++++++++++++++---- polyval/src/backend/soft64.rs | 25 ++++++++++++++++++++----- 6 files changed, 99 insertions(+), 32 deletions(-) diff --git a/ghash/src/lib.rs b/ghash/src/lib.rs index a38328d..d9b053e 100644 --- a/ghash/src/lib.rs +++ b/ghash/src/lib.rs @@ -61,10 +61,10 @@ impl KeySizeUser for GHash { type KeySize = U16; } -impl KeyInit for GHash { - /// Initialize GHASH with the given `H` field element +impl GHash { + /// Initialize GHASH with the given `H` field element and initial block #[inline] - fn new(h: &Key) -> Self { + pub fn new_with_init_block(h: &Key, init_block: u128) -> Self { let mut h = *h; h.reverse(); @@ -75,7 +75,7 @@ impl KeyInit for GHash { h.zeroize(); #[allow(clippy::let_and_return)] - let result = GHash(Polyval::new(&h_polyval)); + let result = GHash(Polyval::new_with_init_block(&h_polyval, init_block)); #[cfg(feature = "zeroize")] h_polyval.zeroize(); @@ -84,6 +84,14 @@ impl KeyInit for GHash { } } +impl KeyInit for GHash { + /// Initialize GHASH with the given `H` field element + #[inline] + fn new(h: &Key) -> Self { + Self::new_with_init_block(h, 0) + } +} + struct GHashBackend<'b, B: UhfBackend>(&'b mut B); impl<'b, B: UhfBackend> BlockSizeUser for GHashBackend<'b, B> { diff --git a/polyval/src/backend/autodetect.rs b/polyval/src/backend/autodetect.rs index e6091b4..7adb289 100644 --- a/polyval/src/backend/autodetect.rs +++ b/polyval/src/backend/autodetect.rs @@ -36,18 +36,20 @@ impl KeySizeUser for Polyval { type KeySize = U16; } -impl KeyInit for Polyval { - /// Initialize POLYVAL with the given `H` field element - fn new(h: &Key) -> Self { +impl Polyval { + /// Initialize POLYVAL with the given `H` field element and initial block + pub fn new_with_init_block(h: &Key, init_block: u128) -> Self { let (token, has_intrinsics) = mul_intrinsics::init_get(); let inner = if has_intrinsics { Inner { - intrinsics: ManuallyDrop::new(intrinsics::Polyval::new(h)), + intrinsics: ManuallyDrop::new(intrinsics::Polyval::new_with_init_block( + h, init_block, + )), } } else { Inner { - soft: ManuallyDrop::new(soft::Polyval::new(h)), + soft: ManuallyDrop::new(soft::Polyval::new_with_init_block(h, init_block)), } }; @@ -55,6 +57,13 @@ impl KeyInit for Polyval { } } +impl KeyInit for Polyval { + /// Initialize POLYVAL with the given `H` field element + fn new(h: &Key) -> Self { + Self::new_with_init_block(h, 0) + } +} + impl BlockSizeUser for Polyval { type BlockSize = U16; } diff --git a/polyval/src/backend/clmul.rs b/polyval/src/backend/clmul.rs index 1d6565f..1e891c2 100644 --- a/polyval/src/backend/clmul.rs +++ b/polyval/src/backend/clmul.rs @@ -1,17 +1,18 @@ //! Intel `CLMUL`-accelerated implementation for modern x86/x86_64 CPUs //! (i.e. Intel Sandy Bridge-compatible or newer) -use crate::{Block, Key, Tag}; +#[cfg(target_arch = "x86")] +use core::arch::x86::*; +#[cfg(target_arch = "x86_64")] +use core::arch::x86_64::*; + use universal_hash::{ consts::{U1, U16}, crypto_common::{BlockSizeUser, KeySizeUser, ParBlocksSizeUser}, KeyInit, Reset, UhfBackend, }; -#[cfg(target_arch = "x86")] -use core::arch::x86::*; -#[cfg(target_arch = "x86_64")] -use core::arch::x86_64::*; +use crate::{Block, Key, Tag}; /// **POLYVAL**: GHASH-like universal hash over GF(2^128). #[derive(Clone)] @@ -24,20 +25,27 @@ impl KeySizeUser for Polyval { type KeySize = U16; } -impl KeyInit for Polyval { - /// Initialize POLYVAL with the given `H` field element - fn new(h: &Key) -> Self { +impl Polyval { + /// Initialize POLYVAL with the given `H` field element and initial block + pub fn new_with_init_block(h: &Key, init_block: u128) -> Self { unsafe { // `_mm_loadu_si128` performs an unaligned load #[allow(clippy::cast_ptr_alignment)] Self { h: _mm_loadu_si128(h.as_ptr() as *const __m128i), - y: _mm_setzero_si128(), + y: _mm_loadu_si128(&init_block.to_be_bytes()[..] as *const _ as *const __m128i), } } } } +impl KeyInit for Polyval { + /// Initialize POLYVAL with the given `H` field element + fn new(h: &Key) -> Self { + Self::new_with_init_block(h, 0) + } +} + impl BlockSizeUser for Polyval { type BlockSize = U16; } diff --git a/polyval/src/backend/pmull.rs b/polyval/src/backend/pmull.rs index 9d99316..82ad6bc 100644 --- a/polyval/src/backend/pmull.rs +++ b/polyval/src/backend/pmull.rs @@ -11,14 +11,16 @@ //! - //! - -use crate::{Block, Key, Tag}; use core::{arch::aarch64::*, mem}; + use universal_hash::{ consts::{U1, U16}, crypto_common::{BlockSizeUser, KeySizeUser, ParBlocksSizeUser}, KeyInit, Reset, UhfBackend, }; +use crate::{Block, Key, Tag}; + /// **POLYVAL**: GHASH-like universal hash over GF(2^128). #[derive(Clone)] pub struct Polyval { @@ -30,18 +32,25 @@ impl KeySizeUser for Polyval { type KeySize = U16; } -impl KeyInit for Polyval { - /// Initialize POLYVAL with the given `H` field element - fn new(h: &Key) -> Self { +impl Polyval { + /// Initialize POLYVAL with the given `H` field element and initial block + pub fn new_with_init_block(h: &Key, init_block: u128) -> Self { unsafe { Self { h: vld1q_u8(h.as_ptr()), - y: vdupq_n_u8(0), // all zeroes + y: vld1q_u8(init_block.to_be_bytes()[..].as_ptr()), } } } } +impl KeyInit for Polyval { + /// Initialize POLYVAL with the given `H` field element + fn new(h: &Key) -> Self { + Self::new_with_init_block(h, 0) + } +} + impl BlockSizeUser for Polyval { type BlockSize = U16; } diff --git a/polyval/src/backend/soft32.rs b/polyval/src/backend/soft32.rs index a52231f..259c771 100644 --- a/polyval/src/backend/soft32.rs +++ b/polyval/src/backend/soft32.rs @@ -53,16 +53,23 @@ impl KeySizeUser for Polyval { type KeySize = U16; } -impl KeyInit for Polyval { - /// Initialize POLYVAL with the given `H` field element - fn new(h: &Key) -> Self { +impl Polyval { + /// Initialize POLYVAL with the given `H` field element and initial block + pub fn new_with_init_block(h: &Key, init_block: u128) -> Self { Self { h: h.into(), - s: U32x4::default(), + s: init_block.into(), } } } +impl KeyInit for Polyval { + /// Initialize POLYVAL with the given `H` field element + fn new(h: &Key) -> Self { + Self::new_with_init_block(h, 0) + } +} + impl BlockSizeUser for Polyval { type BlockSize = U16; } @@ -130,6 +137,17 @@ impl From<&Block> for U32x4 { } } +impl From for U32x4 { + fn from(x: u128) -> Self { + U32x4( + x as u32, + (x >> 32) as u32, + (x >> 64) as u32, + (x >> 96) as u32, + ) + } +} + #[allow(clippy::suspicious_arithmetic_impl)] impl Add for U32x4 { type Output = Self; diff --git a/polyval/src/backend/soft64.rs b/polyval/src/backend/soft64.rs index b4462d6..9af1e97 100644 --- a/polyval/src/backend/soft64.rs +++ b/polyval/src/backend/soft64.rs @@ -5,11 +5,11 @@ //! //! Copyright (c) 2016 Thomas Pornin -use crate::{Block, Key, Tag}; use core::{ num::Wrapping, ops::{Add, Mul}, }; + use universal_hash::{ consts::{U1, U16}, crypto_common::{BlockSizeUser, KeySizeUser, ParBlocksSizeUser}, @@ -19,6 +19,8 @@ use universal_hash::{ #[cfg(feature = "zeroize")] use zeroize::Zeroize; +use crate::{Block, Key, Tag}; + /// **POLYVAL**: GHASH-like universal hash over GF(2^128). #[derive(Clone)] pub struct Polyval { @@ -29,6 +31,16 @@ pub struct Polyval { s: U64x2, } +impl Polyval { + /// Initialize POLYVAL with the given `H` field element and initial block + pub fn new_with_init_block(h: &Key, init_block: u128) -> Self { + Self { + h: h.into(), + s: init_block.into(), + } + } +} + impl KeySizeUser for Polyval { type KeySize = U16; } @@ -36,10 +48,7 @@ impl KeySizeUser for Polyval { impl KeyInit for Polyval { /// Initialize POLYVAL with the given `H` field element fn new(h: &Key) -> Self { - Self { - h: h.into(), - s: U64x2::default(), - } + Self::new_with_init_block(h, 0) } } @@ -105,6 +114,12 @@ impl From<&Block> for U64x2 { } } +impl From for U64x2 { + fn from(x: u128) -> Self { + U64x2((x >> 64) as u64, (x) as u64) + } +} + #[allow(clippy::suspicious_arithmetic_impl)] impl Add for U64x2 { type Output = Self;