binius_field/
binary_field_arithmetic.rs1use super::{arithmetic_traits::InvertOrZero, binary_field::*};
4use crate::{PackedField, arithmetic_traits::MulAlpha};
5
6pub(crate) trait TowerFieldArithmetic: TowerField {
7 fn multiply(self, rhs: Self) -> Self;
8
9 fn multiply_alpha(self) -> Self;
10
11 fn square(self) -> Self;
12}
13
14macro_rules! impl_arithmetic_using_packed {
15 ($name:ident) => {
16 impl InvertOrZero for $name {
17 #[inline]
18 fn invert_or_zero(self) -> Self {
19 use $crate::packed_extension::PackedSubfield;
20
21 $crate::binary_field_arithmetic::invert_or_zero_using_packed::<
22 PackedSubfield<Self, Self>,
23 >(self)
24 }
25 }
26
27 impl TowerFieldArithmetic for $name {
28 #[inline]
29 fn multiply(self, rhs: Self) -> Self {
30 use $crate::packed_extension::PackedSubfield;
31
32 $crate::binary_field_arithmetic::multiple_using_packed::<PackedSubfield<Self, Self>>(
33 self, rhs,
34 )
35 }
36
37 #[inline]
38 fn multiply_alpha(self) -> Self {
39 use $crate::packed_extension::PackedSubfield;
40
41 $crate::binary_field_arithmetic::mul_alpha_using_packed::<PackedSubfield<Self, Self>>(
42 self,
43 )
44 }
45
46 #[inline]
47 fn square(self) -> Self {
48 use $crate::packed_extension::PackedSubfield;
49
50 $crate::binary_field_arithmetic::square_using_packed::<PackedSubfield<Self, Self>>(
51 self,
52 )
53 }
54 }
55 };
56}
57
58pub(crate) use impl_arithmetic_using_packed;
59
60impl TowerField for BinaryField1b {
62 fn min_tower_level(self) -> usize {
63 0
64 }
65
66 #[inline]
67 fn mul_primitive(self, _: usize) -> Result<Self, crate::Error> {
68 Err(crate::Error::ExtensionDegreeMismatch)
69 }
70}
71
72impl InvertOrZero for BinaryField1b {
73 #[inline]
74 fn invert_or_zero(self) -> Self {
75 self
76 }
77}
78
79impl TowerFieldArithmetic for BinaryField1b {
80 #[inline]
81 fn multiply(self, rhs: Self) -> Self {
82 Self(self.0 & rhs.0)
83 }
84
85 #[inline]
86 fn multiply_alpha(self) -> Self {
87 self
88 }
89
90 #[inline]
91 fn square(self) -> Self {
92 self
93 }
94}
95
96#[inline]
99pub(super) fn multiple_using_packed<P: PackedField>(lhs: P::Scalar, rhs: P::Scalar) -> P::Scalar {
100 (P::set_single(lhs) * P::set_single(rhs)).get(0)
101}
102
103#[inline]
104pub(super) fn square_using_packed<P: PackedField>(value: P::Scalar) -> P::Scalar {
105 P::set_single(value).square().get(0)
106}
107
108#[inline]
109pub(super) fn invert_or_zero_using_packed<P: PackedField>(value: P::Scalar) -> P::Scalar {
110 P::set_single(value).invert_or_zero().get(0)
111}
112
113#[inline]
114pub(super) fn mul_alpha_using_packed<P: PackedField + MulAlpha>(value: P::Scalar) -> P::Scalar {
115 P::set_single(value).mul_alpha().get(0)
116}