1use std::{
4 fmt::{Debug, Display},
5 hash::Hash,
6 iter::{Product, Sum},
7 ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
8};
9
10use binius_utils::{DeserializeBytes, SerializeBytes};
11use bytemuck::Zeroable;
12
13use super::extension::ExtensionField;
14use crate::{
15 Random,
16 arithmetic_traits::{InvertOrZero, Square},
17};
18
19pub trait Field:
21 Sized
22 + Eq
23 + Copy
24 + Clone
25 + Default
26 + Send
27 + Sync
28 + Debug
29 + Display
30 + Hash
31 + 'static
32 + Neg<Output = Self>
33 + Add<Output = Self>
34 + Sub<Output = Self>
35 + Mul<Output = Self>
36 + for<'a> Add<&'a Self, Output = Self>
37 + for<'a> Sub<&'a Self, Output = Self>
38 + for<'a> Mul<&'a Self, Output = Self>
39 + Sum
40 + Product
41 + for<'a> Sum<&'a Self>
42 + for<'a> Product<&'a Self>
43 + AddAssign
44 + SubAssign
45 + MulAssign
46 + for<'a> AddAssign<&'a Self>
47 + for<'a> SubAssign<&'a Self>
48 + for<'a> MulAssign<&'a Self>
49 + Square
50 + InvertOrZero
51 + Random
52 + Zeroable
53 + SerializeBytes
54 + DeserializeBytes
55{
56 const ZERO: Self;
58
59 const ONE: Self;
61
62 const CHARACTERISTIC: usize;
64
65 const MULTIPLICATIVE_GENERATOR: Self;
67
68 fn is_zero(&self) -> bool {
70 *self == Self::ZERO
71 }
72
73 #[must_use]
75 fn double(&self) -> Self;
76
77 fn invert(&self) -> Option<Self> {
80 let inv = self.invert_or_zero();
81 (!inv.is_zero()).then_some(inv)
82 }
83
84 fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
93 let mut res = Self::ONE;
94 for e in exp.as_ref().iter().rev() {
95 for i in (0..64).rev() {
96 res = res.square();
97 let mut tmp = res;
98 tmp *= self;
99 if ((*e >> i) & 1) != 0 {
100 res = tmp;
101 }
102 }
103 }
104 res
105 }
106
107 fn pow_vartime<S: AsRef<[u64]>>(&self, exp: S) -> Self {
116 let mut res = Self::ONE;
117 for e in exp.as_ref().iter().rev() {
118 for i in (0..64).rev() {
119 res = res.square();
120
121 if ((*e >> i) & 1) == 1 {
122 res.mul_assign(self);
123 }
124 }
125 }
126
127 res
128 }
129}
130
131pub trait FieldOps:
148 Clone
149 + Neg<Output = Self>
150 + Add<Output = Self>
151 + Sub<Output = Self>
152 + Mul<Output = Self>
153 + Sum
154 + Product
155 + for<'a> Add<&'a Self, Output = Self>
156 + for<'a> Sub<&'a Self, Output = Self>
157 + for<'a> Mul<&'a Self, Output = Self>
158 + for<'a> Sum<&'a Self>
159 + for<'a> Product<&'a Self>
160 + AddAssign
161 + SubAssign
162 + MulAssign
163 + for<'a> AddAssign<&'a Self>
164 + for<'a> SubAssign<&'a Self>
165 + for<'a> MulAssign<&'a Self>
166 + Square
167 + InvertOrZero
168{
169 type Scalar: Field;
170
171 fn zero() -> Self;
173
174 fn one() -> Self;
176
177 fn square_transpose<FSub: Field>(elems: &mut [Self])
188 where
189 Self::Scalar: ExtensionField<FSub>;
190}
191
192impl<F: Field> FieldOps for F {
193 type Scalar = F;
194
195 fn zero() -> Self {
196 Self::ZERO
197 }
198
199 fn one() -> Self {
200 Self::ONE
201 }
202
203 fn square_transpose<FSub: Field>(elems: &mut [Self])
204 where
205 F: ExtensionField<FSub>,
206 {
207 <F as ExtensionField<FSub>>::square_transpose(elems)
208 }
209}