Skip to main content

binius_field/arch/portable/
packed_ghash_128.rs

1// Copyright 2023-2025 Irreducible Inc.
2// Copyright 2026 The Binius Developers
3
4//! Portable implementation of packed GHASH field operations.
5
6use super::{
7	m128::M128,
8	univariate_mul_utils_128::{Underlier128bLanes, spread_bits_64},
9};
10
11/// Widening-multiply wrapper used by the `PackedGhash1x128b` packing.
12pub type GhashWideMul1x<T> = super::arithmetic::ghash::GhashWideMul<T>;
13
14/// Square wrapper for the `PackedGhash1x128b` packing: the shared software square.
15pub type GhashSquare1x<T> = super::arithmetic::ghash::GhashSoftMul<T>;
16
17/// Invert wrapper for the `PackedGhash1x128b` packing: the shared Itoh-Tsujii inversion.
18pub type GhashInvert1x<T> = super::arithmetic::itoh_tsujii::GhashItohTsujii<T>;
19
20/// Scaling wrapper for the `PackedGhash1x128b` packing: the shared lane walk.
21pub type GhashMulX1x<T> = super::arithmetic::ghash::GhashMulX<T>;
22
23// `M128` packs its GHASH 64-bit lanes the same way `u128` does — delegate through `u128`.
24impl Underlier128bLanes for M128 {
25	type U64 = u64;
26
27	#[inline(always)]
28	fn split_hi_lo_64(self) -> (u64, u64) {
29		u128::from(self).split_hi_lo_64()
30	}
31
32	#[inline(always)]
33	fn join_u64s(high: u64, low: u64) -> Self {
34		Self::from(u128::join_u64s(high, low))
35	}
36
37	#[inline(always)]
38	fn broadcast_64(val: u64) -> Self {
39		Self::from(u128::broadcast_64(val))
40	}
41
42	#[inline(always)]
43	fn spread_bits_128(self) -> (Self, Self) {
44		let (hi, lo) = self.split_hi_lo_64();
45		(Self::from(spread_bits_64(hi)), Self::from(spread_bits_64(lo)))
46	}
47}