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 Divisible, Maskable, 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 + Divisible<Self>
65 + Maskable<Self>
68{
69 const ZERO: Self;
71
72 const ONE: Self;
74
75 const CHARACTERISTIC: usize;
78
79 const ORDER_EXPONENT: usize;
81
82 const MULTIPLICATIVE_GENERATOR: Self;
84
85 fn is_zero(&self) -> bool {
87 *self == Self::ZERO
88 }
89
90 #[must_use]
92 fn double(&self) -> Self;
93
94 fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
97 let mut res = Self::ONE;
98 for e in exp.as_ref().iter().rev() {
99 for i in (0..64).rev() {
100 res = res.square();
101
102 if ((*e >> i) & 1) == 1 {
103 res.mul_assign(self);
104 }
105 }
106 }
107
108 res
109 }
110}
111
112pub trait FieldOps:
129 Clone
130 + Neg<Output = Self>
131 + Add<Output = Self>
132 + Sub<Output = Self>
133 + Mul<Output = Self>
134 + Sum
135 + Product
136 + for<'a> Add<&'a Self, Output = Self>
137 + for<'a> Sub<&'a Self, Output = Self>
138 + for<'a> Mul<&'a Self, Output = Self>
139 + for<'a> Sum<&'a Self>
140 + for<'a> Product<&'a Self>
141 + AddAssign
142 + SubAssign
143 + MulAssign
144 + for<'a> AddAssign<&'a Self>
145 + for<'a> SubAssign<&'a Self>
146 + for<'a> MulAssign<&'a Self>
147 + Square
148 + InvertOrZero
149{
150 type Scalar: Field;
151
152 fn zero() -> Self;
154
155 fn one() -> Self;
157
158 fn square_transpose<FSub: Field>(elems: &mut [Self])
169 where
170 Self::Scalar: ExtensionField<FSub>;
171}
172
173impl<F: Field> FieldOps for F {
174 type Scalar = F;
175
176 fn zero() -> Self {
177 Self::ZERO
178 }
179
180 fn one() -> Self {
181 Self::ONE
182 }
183
184 fn square_transpose<FSub: Field>(elems: &mut [Self])
185 where
186 F: ExtensionField<FSub>,
187 {
188 <F as ExtensionField<FSub>>::square_transpose(elems)
189 }
190}