1use std::{
5 fmt::{Debug, Display},
6 hash::Hash,
7 iter::{Product, Sum},
8 ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
9};
10
11use binius_utils::{DeserializeBytes, FixedSizeSerializeBytes, SerializeBytes};
12use bytemuck::Zeroable;
13
14use super::extension::ExtensionField;
15use crate::{
16 Random, WideMul,
17 arithmetic_traits::{InvertOrZero, Square},
18};
19
20pub trait Field:
26 Sized
27 + Eq
28 + Copy
29 + Clone
30 + Default
31 + Send
32 + Sync
33 + Debug
34 + Display
35 + Hash
36 + 'static
37 + Neg<Output = Self>
38 + Add<Output = Self>
39 + Sub<Output = Self>
40 + Mul<Output = Self>
41 + for<'a> Add<&'a Self, Output = Self>
42 + for<'a> Sub<&'a Self, Output = Self>
43 + for<'a> Mul<&'a Self, Output = Self>
44 + Sum
45 + Product
46 + for<'a> Sum<&'a Self>
47 + for<'a> Product<&'a Self>
48 + AddAssign
49 + SubAssign
50 + MulAssign
51 + for<'a> AddAssign<&'a Self>
52 + for<'a> SubAssign<&'a Self>
53 + for<'a> MulAssign<&'a Self>
54 + Square
55 + InvertOrZero
56 + Random
57 + Zeroable
58 + SerializeBytes
59 + DeserializeBytes
60 + FixedSizeSerializeBytes
61 + WideMul<Output: Debug + Send + Sync + 'static>
62{
63 const ZERO: Self;
65
66 const ONE: Self;
68
69 const CHARACTERISTIC: usize;
72
73 const ORDER_EXPONENT: usize;
75
76 const MULTIPLICATIVE_GENERATOR: Self;
78
79 fn is_zero(&self) -> bool {
81 *self == Self::ZERO
82 }
83
84 #[must_use]
86 fn double(&self) -> Self;
87
88 fn invert(&self) -> Option<Self> {
91 let inv = self.invert_or_zero();
92 (!inv.is_zero()).then_some(inv)
93 }
94
95 fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
98 let mut res = Self::ONE;
99 for e in exp.as_ref().iter().rev() {
100 for i in (0..64).rev() {
101 res = res.square();
102
103 if ((*e >> i) & 1) == 1 {
104 res.mul_assign(self);
105 }
106 }
107 }
108
109 res
110 }
111}
112
113pub trait FieldOps:
130 Clone
131 + Neg<Output = Self>
132 + Add<Output = Self>
133 + Sub<Output = Self>
134 + Mul<Output = Self>
135 + Sum
136 + Product
137 + for<'a> Add<&'a Self, Output = Self>
138 + for<'a> Sub<&'a Self, Output = Self>
139 + for<'a> Mul<&'a Self, Output = Self>
140 + for<'a> Sum<&'a Self>
141 + for<'a> Product<&'a Self>
142 + AddAssign
143 + SubAssign
144 + MulAssign
145 + for<'a> AddAssign<&'a Self>
146 + for<'a> SubAssign<&'a Self>
147 + for<'a> MulAssign<&'a Self>
148 + Square
149 + InvertOrZero
150{
151 type Scalar: Field;
152
153 fn zero() -> Self;
155
156 fn one() -> Self;
158
159 fn square_transpose<FSub: Field>(elems: &mut [Self])
170 where
171 Self::Scalar: ExtensionField<FSub>;
172}
173
174impl<F: Field> FieldOps for F {
175 type Scalar = F;
176
177 fn zero() -> Self {
178 Self::ZERO
179 }
180
181 fn one() -> Self {
182 Self::ONE
183 }
184
185 fn square_transpose<FSub: Field>(elems: &mut [Self])
186 where
187 F: ExtensionField<FSub>,
188 {
189 <F as ExtensionField<FSub>>::square_transpose(elems)
190 }
191}