1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Copyright 2024 Ulvetanna Inc.

use super::{super::portable::packed::PackedPrimitiveType, m128::M128};
use crate::{
	arch::{cfg_if, ReuseMultiplyStrategy, SimdStrategy},
	arithmetic_traits::{impl_square_with, impl_transformation_with_strategy, InvertOrZero},
	packed::PackedField,
	BinaryField128bPolyval,
};
use std::ops::Mul;

pub type PackedBinaryPolyval1x128b = PackedPrimitiveType<M128, BinaryField128bPolyval>;

// Define multiply
cfg_if! {
	if #[cfg(target_feature = "pclmulqdq")] {
		impl Mul for PackedBinaryPolyval1x128b {
			type Output = Self;

			fn mul(self, rhs: Self) -> Self::Output {
				crate::tracing::trace_multiplication!(PackedBinaryPolyval1x128b);

				unsafe { super::pclmul::montgomery_mul::simd_montgomery_multiply(self.0, rhs.0) }.into()
			}
		}
	} else {
		impl Mul for PackedBinaryPolyval1x128b {
			type Output = Self;

			fn mul(self, rhs: Self) -> Self::Output {
				use super::super::portable::packed_polyval_128::PackedBinaryPolyval1x128b;

				crate::tracing::trace_multiplication!(PackedBinaryPolyval1x128b);

				let portable_lhs = PackedBinaryPolyval1x128b::from(
					u128::from(self.0),
				);
				let portable_rhs = PackedBinaryPolyval1x128b::from(
					u128::from(rhs.0),
				);

				Self::from_underlier(Mul::mul(portable_lhs, portable_rhs).0.into())
			}
		}
	}
}

// Define square
// TODO: implement a more optimal version for square case
impl_square_with!(PackedBinaryPolyval1x128b @ ReuseMultiplyStrategy);

// Define invert
// TODO: implement vectorized version that uses packed multiplication
impl InvertOrZero for PackedBinaryPolyval1x128b {
	fn invert_or_zero(self) -> Self {
		let portable = super::super::portable::packed_polyval_128::PackedBinaryPolyval1x128b::from(
			u128::from(self.0),
		);

		Self::from_underlier(PackedField::invert_or_zero(portable).0.into())
	}
}

// Define linear transformations
impl_transformation_with_strategy!(PackedBinaryPolyval1x128b, SimdStrategy);