binius_field/arch/x86_64/
packed_ghash_128.rs1use cfg_if::cfg_if;
11
12use super::m128::M128;
13use crate::{
14 BinaryField128bGhash,
15 arch::portable::packed_macros::{portable_macros::*, *},
16 arithmetic_traits::{
17 InvertOrZero, TaggedInvertOrZero, TaggedMul, TaggedSquare, impl_invert_with, impl_mul_with,
18 impl_square_with,
19 },
20};
21#[cfg(target_feature = "pclmulqdq")]
23use crate::{arch::shared::ghash, arithmetic_traits::WideMul};
24
25#[cfg(target_feature = "pclmulqdq")]
26impl ghash::ClMulUnderlier for M128 {
27 #[inline]
28 fn clmulepi64<const IMM8: i32>(a: Self, b: Self) -> Self {
29 unsafe { std::arch::x86_64::_mm_clmulepi64_si128::<IMM8>(a.into(), b.into()) }.into()
30 }
31
32 #[inline]
33 fn move_64_to_hi(a: Self) -> Self {
34 unsafe { std::arch::x86_64::_mm_slli_si128::<8>(a.into()) }.into()
35 }
36}
37
38pub struct GhashStrategy;
40
41define_packed_binary_field!(
43 PackedBinaryGhash1x128b,
44 BinaryField128bGhash,
45 M128,
46 (GhashStrategy),
47 (GhashStrategy),
48 (GhashStrategy),
49 (None)
50);
51
52cfg_if! {
54 if #[cfg(target_feature = "pclmulqdq")] {
55 impl TaggedMul<GhashStrategy> for PackedBinaryGhash1x128b {
56 #[inline]
57 fn mul(self, rhs: Self) -> Self {
58 Self::from_underlier(crate::arch::shared::ghash::mul_clmul(
59 self.to_underlier(),
60 rhs.to_underlier(),
61 ))
62 }
63 }
64 } else {
65 impl TaggedMul<GhashStrategy> for PackedBinaryGhash1x128b {
66 #[inline]
67 fn mul(self, rhs: Self) -> Self {
68 use super::super::portable::packed_ghash_128::PackedBinaryGhash1x128b as PortablePackedBinaryGhash1x128b;
69
70 let portable_lhs = PortablePackedBinaryGhash1x128b::from(u128::from(self.to_underlier()));
71 let portable_rhs = PortablePackedBinaryGhash1x128b::from(u128::from(rhs.to_underlier()));
72
73 Self::from_underlier(std::ops::Mul::mul(portable_lhs, portable_rhs).to_underlier().into())
74 }
75 }
76 }
77}
78
79cfg_if! {
81 if #[cfg(target_feature = "pclmulqdq")] {
82 impl TaggedSquare<GhashStrategy> for PackedBinaryGhash1x128b {
83 #[inline]
84 fn square(self) -> Self {
85 Self::from_underlier(crate::arch::shared::ghash::square_clmul(
86 self.to_underlier(),
87 ))
88 }
89 }
90 } else {
91 impl TaggedSquare<GhashStrategy> for PackedBinaryGhash1x128b {
92 #[inline]
93 fn square(self) -> Self {
94 use super::super::portable::packed_ghash_128::PackedBinaryGhash1x128b as PortablePackedBinaryGhash1x128b;
95
96 let portable_val = PortablePackedBinaryGhash1x128b::from(u128::from(self.to_underlier()));
97
98 Self::from_underlier(crate::arithmetic_traits::Square::square(portable_val).to_underlier().into())
99 }
100 }
101 }
102}
103
104cfg_if! {
106 if #[cfg(target_feature = "pclmulqdq")] {
107 impl WideMul for PackedBinaryGhash1x128b {
108 type Output = ghash::WideGhashProduct<M128>;
109
110 #[inline]
111 fn wide_mul(a: Self, b: Self) -> Self::Output {
112 ghash::WideGhashProduct::wide_mul(a.to_underlier(), b.to_underlier())
113 }
114
115 #[inline]
116 fn reduce(wide: Self::Output) -> Self {
117 Self::from_underlier(wide.reduce())
118 }
119 }
120 } else {
121 crate::arithmetic_traits::impl_trivial_wide_mul!(PackedBinaryGhash1x128b);
122 }
123}
124
125impl TaggedInvertOrZero<GhashStrategy> for PackedBinaryGhash1x128b {
127 fn invert_or_zero(self) -> Self {
128 let portable = super::super::portable::packed_ghash_128::PackedBinaryGhash1x128b::from(
129 u128::from(self.to_underlier()),
130 );
131
132 Self::from_underlier(InvertOrZero::invert_or_zero(portable).to_underlier().into())
133 }
134}