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:
25 Sized
26 + Eq
27 + Copy
28 + Clone
29 + Default
30 + Send
31 + Sync
32 + Debug
33 + Display
34 + Hash
35 + 'static
36 + Neg<Output = Self>
37 + Add<Output = Self>
38 + Sub<Output = Self>
39 + Mul<Output = Self>
40 + for<'a> Add<&'a Self, Output = Self>
41 + for<'a> Sub<&'a Self, Output = Self>
42 + for<'a> Mul<&'a Self, Output = Self>
43 + Sum
44 + Product
45 + for<'a> Sum<&'a Self>
46 + for<'a> Product<&'a Self>
47 + AddAssign
48 + SubAssign
49 + MulAssign
50 + for<'a> AddAssign<&'a Self>
51 + for<'a> SubAssign<&'a Self>
52 + for<'a> MulAssign<&'a Self>
53 + Square
54 + InvertOrZero
55 + Random
56 + Zeroable
57 + SerializeBytes
58 + DeserializeBytes
59{
60 const ZERO: Self;
62
63 const ONE: Self;
65
66 const CHARACTERISTIC: usize;
69
70 const ORDER_EXPONENT: usize;
72
73 const MULTIPLICATIVE_GENERATOR: Self;
75
76 fn is_zero(&self) -> bool {
78 *self == Self::ZERO
79 }
80
81 #[must_use]
83 fn double(&self) -> Self;
84
85 fn invert(&self) -> Option<Self> {
88 let inv = self.invert_or_zero();
89 (!inv.is_zero()).then_some(inv)
90 }
91
92 fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
95 let mut res = Self::ONE;
96 for e in exp.as_ref().iter().rev() {
97 for i in (0..64).rev() {
98 res = res.square();
99
100 if ((*e >> i) & 1) == 1 {
101 res.mul_assign(self);
102 }
103 }
104 }
105
106 res
107 }
108}
109
110pub trait FieldOps:
127 Clone
128 + Neg<Output = Self>
129 + Add<Output = Self>
130 + Sub<Output = Self>
131 + Mul<Output = Self>
132 + Sum
133 + Product
134 + for<'a> Add<&'a Self, Output = Self>
135 + for<'a> Sub<&'a Self, Output = Self>
136 + for<'a> Mul<&'a Self, Output = Self>
137 + for<'a> Sum<&'a Self>
138 + for<'a> Product<&'a Self>
139 + AddAssign
140 + SubAssign
141 + MulAssign
142 + for<'a> AddAssign<&'a Self>
143 + for<'a> SubAssign<&'a Self>
144 + for<'a> MulAssign<&'a Self>
145 + Square
146 + InvertOrZero
147{
148 type Scalar: Field;
149
150 fn zero() -> Self;
152
153 fn one() -> Self;
155
156 fn square_transpose<FSub: Field>(elems: &mut [Self])
167 where
168 Self::Scalar: ExtensionField<FSub>;
169}
170
171impl<F: Field> FieldOps for F {
172 type Scalar = F;
173
174 fn zero() -> Self {
175 Self::ZERO
176 }
177
178 fn one() -> Self {
179 Self::ONE
180 }
181
182 fn square_transpose<FSub: Field>(elems: &mut [Self])
183 where
184 F: ExtensionField<FSub>,
185 {
186 <F as ExtensionField<FSub>>::square_transpose(elems)
187 }
188}