binius_field/arch/x86_64/
packed_polyval_128.rs

1// Copyright 2024-2025 Irreducible Inc.
2
3use std::ops::Mul;
4
5use super::{super::portable::packed::PackedPrimitiveType, m128::M128};
6use crate::{
7	arch::{cfg_if, ReuseMultiplyStrategy},
8	arithmetic_traits::{impl_square_with, InvertOrZero},
9	packed::PackedField,
10	BinaryField128bPolyval,
11};
12
13pub type PackedBinaryPolyval1x128b = PackedPrimitiveType<M128, BinaryField128bPolyval>;
14
15// Define multiply
16cfg_if! {
17	if #[cfg(target_feature = "pclmulqdq")] {
18		impl Mul for PackedBinaryPolyval1x128b {
19			type Output = Self;
20
21			fn mul(self, rhs: Self) -> Self::Output {
22				crate::tracing::trace_multiplication!(PackedBinaryPolyval1x128b);
23
24				unsafe { super::pclmul::montgomery_mul::simd_montgomery_multiply(self.0, rhs.0) }.into()
25			}
26		}
27	} else {
28		impl Mul for PackedBinaryPolyval1x128b {
29			type Output = Self;
30
31			fn mul(self, rhs: Self) -> Self::Output {
32				use super::super::portable::packed_polyval_128::PackedBinaryPolyval1x128b;
33
34				crate::tracing::trace_multiplication!(PackedBinaryPolyval1x128b);
35
36				let portable_lhs = PackedBinaryPolyval1x128b::from(
37					u128::from(self.0),
38				);
39				let portable_rhs = PackedBinaryPolyval1x128b::from(
40					u128::from(rhs.0),
41				);
42
43				Self::from_underlier(Mul::mul(portable_lhs, portable_rhs).0.into())
44			}
45		}
46	}
47}
48
49// Define square
50// TODO: implement a more optimal version for square case
51impl_square_with!(PackedBinaryPolyval1x128b @ ReuseMultiplyStrategy);
52
53// Define invert
54// TODO: implement vectorized version that uses packed multiplication
55impl InvertOrZero for PackedBinaryPolyval1x128b {
56	fn invert_or_zero(self) -> Self {
57		let portable = super::super::portable::packed_polyval_128::PackedBinaryPolyval1x128b::from(
58			u128::from(self.0),
59		);
60
61		Self::from_underlier(PackedField::invert_or_zero(portable).0.into())
62	}
63}
64
65// Define linear transformations
66cfg_if! {
67	if #[cfg(target_feature = "gfni")] {
68		use crate::arch::x86_64::gfni::gfni_arithmetics::impl_transformation_with_gfni_nxn;
69
70		impl_transformation_with_gfni_nxn!(PackedBinaryPolyval1x128b, 16);
71	} else {
72		crate::arithmetic_traits::impl_transformation_with_strategy!(PackedBinaryPolyval1x128b, crate::arch::SimdStrategy);
73	}
74}