Skip to content

Commit

Permalink
ghash+polyval: add new_with_init_block (RustCrypto#195)
Browse files Browse the repository at this point in the history
Adds customization for init_block, needed for `belt-dwp` AEAD
  • Loading branch information
makavity authored Feb 1, 2024
1 parent 5920b06 commit 6d51e01
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 32 deletions.
16 changes: 12 additions & 4 deletions ghash/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand All @@ -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();
Expand All @@ -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> {
Expand Down
19 changes: 14 additions & 5 deletions polyval/src/backend/autodetect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,34 @@ 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)),
}
};

Self { inner, token }
}
}

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;
}
Expand Down
26 changes: 17 additions & 9 deletions polyval/src/backend/clmul.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand All @@ -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;
}
Expand Down
19 changes: 14 additions & 5 deletions polyval/src/backend/pmull.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@
//! - <https://developer.arm.com/documentation/100069/0608/A64-SIMD-Vector-Instructions/PMULL--PMULL2--vector->
//! - <https://eprint.iacr.org/2015/688.pdf>

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 {
Expand All @@ -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;
}
Expand Down
26 changes: 22 additions & 4 deletions polyval/src/backend/soft32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -130,6 +137,17 @@ impl From<&Block> for U32x4 {
}
}

impl From<u128> 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;
Expand Down
25 changes: 20 additions & 5 deletions polyval/src/backend/soft64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
//!
//! Copyright (c) 2016 Thomas Pornin <[email protected]>

use crate::{Block, Key, Tag};
use core::{
num::Wrapping,
ops::{Add, Mul},
};

use universal_hash::{
consts::{U1, U16},
crypto_common::{BlockSizeUser, KeySizeUser, ParBlocksSizeUser},
Expand All @@ -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 {
Expand All @@ -29,17 +31,24 @@ 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;
}

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)
}
}

Expand Down Expand Up @@ -105,6 +114,12 @@ impl From<&Block> for U64x2 {
}
}

impl From<u128> 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;
Expand Down

0 comments on commit 6d51e01

Please sign in to comment.