binius_field/arch/x86_64/
packed_ghash_128.rs1use std::ops::Mul;
10
11use cfg_if::cfg_if;
12
13use super::{super::portable::packed::PackedPrimitiveType, m128::M128};
14use crate::{
15 BinaryField128bGhash,
16 arch::portable::packed_macros::impl_serialize_deserialize_for_packed_binary_field,
17 arithmetic_traits::{InvertOrZero, Square},
18 packed::PackedField,
19};
20
21#[cfg(target_feature = "pclmulqdq")]
22impl crate::arch::shared::ghash::ClMulUnderlier for M128 {
23 #[inline]
24 fn clmulepi64<const IMM8: i32>(a: Self, b: Self) -> Self {
25 unsafe { std::arch::x86_64::_mm_clmulepi64_si128::<IMM8>(a.into(), b.into()) }.into()
26 }
27
28 #[inline]
29 fn move_64_to_hi(a: Self) -> Self {
30 unsafe { std::arch::x86_64::_mm_slli_si128::<8>(a.into()) }.into()
31 }
32}
33
34pub type PackedBinaryGhash1x128b = PackedPrimitiveType<M128, BinaryField128bGhash>;
35
36cfg_if! {
38 if #[cfg(target_feature = "pclmulqdq")] {
39 impl Mul for PackedBinaryGhash1x128b {
40 type Output = Self;
41
42 #[inline]
43 fn mul(self, rhs: Self) -> Self::Output {
44 crate::tracing::trace_multiplication!(PackedBinaryGhash1x128b);
45
46 Self::from_underlier(crate::arch::shared::ghash::mul_clmul(
47 self.to_underlier(),
48 rhs.to_underlier(),
49 ))
50 }
51 }
52
53 impl Square for PackedBinaryGhash1x128b {
54 #[inline]
55 fn square(self) -> Self {
56 Self::from_underlier(crate::arch::shared::ghash::square_clmul(
57 self.to_underlier(),
58 ))
59 }
60 }
61
62 } else {
63 impl Mul for PackedBinaryGhash1x128b {
64 type Output = Self;
65
66 #[inline]
67 fn mul(self, rhs: Self) -> Self::Output {
68 use super::super::portable::packed_ghash_128::PackedBinaryGhash1x128b as PortablePackedBinaryGhash1x128b;
69
70 crate::tracing::trace_multiplication!(PackedBinaryGhash1x128b);
71
72 let portable_lhs = PortablePackedBinaryGhash1x128b::from(u128::from(self.to_underlier()));
73 let portable_rhs = PortablePackedBinaryGhash1x128b::from(u128::from(rhs.to_underlier()));
74
75 Self::from_underlier(Mul::mul(portable_lhs, portable_rhs).to_underlier().into())
76 }
77 }
78
79 impl Square for PackedBinaryGhash1x128b {
80 #[inline]
81 fn square(self) -> Self {
82 use super::super::portable::packed_ghash_128::PackedBinaryGhash1x128b as PortablePackedBinaryGhash1x128b;
83
84 let portable_val = PortablePackedBinaryGhash1x128b::from(u128::from(self.to_underlier()));
85
86 Self::from_underlier(Square::square(portable_val).to_underlier().into())
87 }
88 }
89 }
90}
91
92impl InvertOrZero for PackedBinaryGhash1x128b {
94 fn invert_or_zero(self) -> Self {
95 let portable = super::super::portable::packed_ghash_128::PackedBinaryGhash1x128b::from(
96 u128::from(self.to_underlier()),
97 );
98
99 Self::from_underlier(PackedField::invert_or_zero(portable).to_underlier().into())
100 }
101}
102
103cfg_if! {
104 if #[cfg(target_feature = "gfni")] {
105 use crate::arch::x86_64::gfni::gfni_arithmetics::impl_transformation_with_gfni_nxn;
106 impl_transformation_with_gfni_nxn!(PackedBinaryGhash1x128b, 16);
107 } else {
108 crate::arithmetic_traits::impl_transformation_with_strategy!(
109 PackedBinaryGhash1x128b,
110 crate::arch::SimdStrategy
111 );
112 }
113}
114
115impl_serialize_deserialize_for_packed_binary_field!(PackedBinaryGhash1x128b);