lambdaworks_math/field/
traits.rs1use super::{element::FieldElement, errors::FieldError};
2use crate::traits::ByteConversion;
3use crate::{errors::CreationError, unsigned_integer::traits::IsUnsignedInteger};
4use core::fmt::Debug;
5
6#[derive(Clone, Copy)]
9pub enum RootsConfig {
10 Natural, NaturalInversed, BitReverse, BitReverseInversed, }
15
16pub trait IsSubFieldOf<F: IsField>: IsField {
18 fn mul(a: &Self::BaseType, b: &F::BaseType) -> F::BaseType;
19 fn add(a: &Self::BaseType, b: &F::BaseType) -> F::BaseType;
20 fn div(a: &Self::BaseType, b: &F::BaseType) -> Result<F::BaseType, FieldError>;
21 fn sub(a: &Self::BaseType, b: &F::BaseType) -> F::BaseType;
22 fn embed(a: Self::BaseType) -> F::BaseType;
23 #[cfg(feature = "alloc")]
24 fn to_subfield_vec(b: F::BaseType) -> alloc::vec::Vec<Self::BaseType>;
25}
26
27impl<F> IsSubFieldOf<F> for F
28where
29 F: IsField,
30{
31 #[inline(always)]
32 fn mul(a: &Self::BaseType, b: &F::BaseType) -> F::BaseType {
33 F::mul(a, b)
34 }
35
36 #[inline(always)]
37 fn add(a: &Self::BaseType, b: &F::BaseType) -> F::BaseType {
38 F::add(a, b)
39 }
40
41 #[inline(always)]
42 fn sub(a: &Self::BaseType, b: &F::BaseType) -> F::BaseType {
43 F::sub(a, b)
44 }
45
46 #[inline(always)]
47 fn div(a: &Self::BaseType, b: &F::BaseType) -> Result<Self::BaseType, FieldError> {
48 F::div(a, b)
49 }
50
51 #[inline(always)]
52 fn embed(a: Self::BaseType) -> F::BaseType {
53 a
54 }
55
56 #[cfg(feature = "alloc")]
57 fn to_subfield_vec(b: F::BaseType) -> alloc::vec::Vec<Self::BaseType> {
58 alloc::vec![b]
59 }
60}
61
62pub trait IsFFTField: IsField {
71 const TWO_ADICITY: u64;
72 const TWO_ADIC_PRIMITVE_ROOT_OF_UNITY: Self::BaseType;
73
74 fn field_name() -> &'static str {
77 ""
78 }
79
80 fn get_primitive_root_of_unity(order: u64) -> Result<FieldElement<Self>, FieldError> {
84 let two_adic_primitive_root_of_unity =
85 FieldElement::new(Self::TWO_ADIC_PRIMITVE_ROOT_OF_UNITY);
86 if order == 0 {
87 return Ok(FieldElement::one());
88 }
89 if order > Self::TWO_ADICITY {
90 return Err(FieldError::RootOfUnityError(order));
91 }
92 let log_power = Self::TWO_ADICITY - order;
93 let root = (0..log_power).fold(two_adic_primitive_root_of_unity, |acc, _| acc.square());
94 Ok(root)
95 }
96}
97
98pub trait IsField: Debug + Clone {
100 type BaseType: Clone + Debug + Unpin + ByteConversion + Default;
103
104 fn add(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType;
106
107 fn double(a: &Self::BaseType) -> Self::BaseType {
109 Self::add(a, a)
110 }
111
112 fn mul(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType;
114
115 fn square(a: &Self::BaseType) -> Self::BaseType {
117 Self::mul(a, a)
118 }
119
120 fn pow<T>(a: &Self::BaseType, mut exponent: T) -> Self::BaseType
124 where
125 T: IsUnsignedInteger,
126 {
127 let zero = T::from(0);
128 let one = T::from(1);
129
130 if exponent == zero {
131 Self::one()
132 } else if exponent == one {
133 a.clone()
134 } else {
135 let mut result = a.clone();
136
137 while exponent & one == zero {
138 result = Self::square(&result);
139 exponent >>= 1;
140 }
141
142 if exponent == zero {
143 result
144 } else {
145 let mut base = result.clone();
146 exponent >>= 1;
147
148 while exponent != zero {
149 base = Self::square(&base);
150 if exponent & one == one {
151 result = Self::mul(&result, &base);
152 }
153 exponent >>= 1;
154 }
155
156 result
157 }
158 }
159 }
160
161 fn sub(a: &Self::BaseType, b: &Self::BaseType) -> Self::BaseType;
163
164 fn neg(a: &Self::BaseType) -> Self::BaseType;
166
167 fn inv(a: &Self::BaseType) -> Result<Self::BaseType, FieldError>;
169
170 fn div(a: &Self::BaseType, b: &Self::BaseType) -> Result<Self::BaseType, FieldError>;
172
173 fn eq(a: &Self::BaseType, b: &Self::BaseType) -> bool;
175
176 fn zero() -> Self::BaseType {
178 Self::BaseType::default()
179 }
180
181 fn one() -> Self::BaseType;
183
184 fn from_u64(x: u64) -> Self::BaseType;
186
187 fn from_base_type(x: Self::BaseType) -> Self::BaseType;
190}
191
192#[derive(PartialEq)]
199pub enum LegendreSymbol {
200 MinusOne,
201 Zero,
202 One,
203}
204
205pub trait IsPrimeField: IsField {
206 type RepresentativeType: IsUnsignedInteger;
207
208 fn representative(a: &Self::BaseType) -> Self::RepresentativeType;
211
212 fn modulus_minus_one() -> Self::RepresentativeType {
214 Self::representative(&Self::neg(&Self::one()))
215 }
216
217 fn from_hex(hex_string: &str) -> Result<Self::BaseType, CreationError>;
221
222 #[cfg(feature = "std")]
223 fn to_hex(a: &Self::BaseType) -> String;
225
226 fn field_bit_size() -> usize;
229
230 fn legendre_symbol(a: &Self::BaseType) -> LegendreSymbol {
233 let symbol = Self::pow(a, Self::modulus_minus_one() >> 1);
234
235 match symbol {
236 x if Self::eq(&x, &Self::zero()) => LegendreSymbol::Zero,
237 x if Self::eq(&x, &Self::one()) => LegendreSymbol::One,
238 _ => LegendreSymbol::MinusOne,
239 }
240 }
241
242 fn sqrt(a: &Self::BaseType) -> Option<(Self::BaseType, Self::BaseType)> {
245 match Self::legendre_symbol(a) {
246 LegendreSymbol::Zero => return Some((Self::zero(), Self::zero())),
247 LegendreSymbol::MinusOne => return None,
248 LegendreSymbol::One => (),
249 };
250
251 let integer_one = Self::RepresentativeType::from(1_u16);
252 let mut s: usize = 0;
253 let mut q = Self::modulus_minus_one();
254
255 while q & integer_one != integer_one {
256 s += 1;
257 q >>= 1;
258 }
259
260 let mut c = {
261 let mut non_qr = Self::from_u64(2);
263 while Self::legendre_symbol(&non_qr) != LegendreSymbol::MinusOne {
264 non_qr = Self::add(&non_qr, &Self::one());
265 }
266
267 Self::pow(&non_qr, q)
268 };
269
270 let mut x = Self::pow(a, (q + integer_one) >> 1);
271 let mut t = Self::pow(a, q);
272 let mut m = s;
273
274 let one = Self::one();
275 while !Self::eq(&t, &one) {
276 let i = {
277 let mut i = 0;
278 let mut t = t.clone();
279 let minus_one = Self::neg(&Self::one());
280 while !Self::eq(&t, &minus_one) {
281 i += 1;
282 t = Self::mul(&t, &t);
283 }
284 i + 1
285 };
286
287 let b = (0..(m - i - 1)).fold(c, |acc, _| Self::square(&acc));
288
289 c = Self::mul(&b, &b);
290 x = Self::mul(&x, &b);
291 t = Self::mul(&t, &c);
292 m = i;
293 }
294
295 let neg_x = Self::neg(&x);
296 Some((x, neg_x))
297 }
298}
299
300pub trait HasDefaultTranscript: IsField {
302 fn get_random_field_element_from_rng(rng: &mut impl rand::Rng) -> FieldElement<Self>;
305}