lambdaworks_math/field/
element.rs

1use crate::errors::{ByteConversionError, CreationError};
2use crate::field::errors::FieldError;
3use crate::field::traits::IsField;
4use crate::traits::ByteConversion;
5use crate::unsigned_integer::element::UnsignedInteger;
6use crate::unsigned_integer::montgomery::MontgomeryAlgorithms;
7use crate::unsigned_integer::traits::IsUnsignedInteger;
8#[cfg(feature = "alloc")]
9use alloc::{
10    format,
11    string::{String, ToString},
12};
13use core::fmt;
14use core::fmt::Debug;
15use core::iter::Sum;
16#[cfg(any(
17    feature = "lambdaworks-serde-binary",
18    feature = "lambdaworks-serde-string"
19))]
20use core::marker::PhantomData;
21use core::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub};
22use num_bigint::BigUint;
23use num_traits::Num;
24#[cfg(any(
25    feature = "lambdaworks-serde-binary",
26    feature = "lambdaworks-serde-string"
27))]
28use serde::de::{self, Deserializer, MapAccess, SeqAccess, Visitor};
29#[cfg(any(
30    feature = "lambdaworks-serde-binary",
31    feature = "lambdaworks-serde-string"
32))]
33use serde::ser::{Serialize, SerializeStruct, Serializer};
34#[cfg(any(
35    feature = "lambdaworks-serde-binary",
36    feature = "lambdaworks-serde-string"
37))]
38use serde::Deserialize;
39
40use super::fields::montgomery_backed_prime_fields::{IsModulus, MontgomeryBackendPrimeField};
41use super::traits::{IsPrimeField, IsSubFieldOf, LegendreSymbol};
42
43/// A field element with operations algorithms defined in `F`
44#[allow(clippy::derived_hash_with_manual_eq)]
45#[derive(Debug, Clone, Hash, Copy)]
46pub struct FieldElement<F: IsField> {
47    value: F::BaseType,
48}
49
50#[cfg(feature = "alloc")]
51impl<F: IsField> FieldElement<F> {
52    // Source: https://en.wikipedia.org/wiki/Modular_multiplicative_inverse#Multiple_inverses
53    /// Computes the multiplicative inverses of a slice of field elements
54    /// The algorithm just performs one inversion and several multiplications and should be used
55    /// when wanting to invert several elements together
56    pub fn inplace_batch_inverse(numbers: &mut [Self]) -> Result<(), FieldError> {
57        if numbers.is_empty() {
58            return Ok(());
59        }
60        let count = numbers.len();
61        let mut prod_prefix = alloc::vec::Vec::with_capacity(count);
62        prod_prefix.push(numbers[0].clone());
63        for i in 1..count {
64            prod_prefix.push(&prod_prefix[i - 1] * &numbers[i]);
65        }
66        let mut bi_inv = prod_prefix[count - 1].inv()?;
67        for i in (1..count).rev() {
68            let ai_inv = &bi_inv * &prod_prefix[i - 1];
69            bi_inv = &bi_inv * &numbers[i];
70            numbers[i] = ai_inv;
71        }
72        numbers[0] = bi_inv;
73        Ok(())
74    }
75
76    #[inline(always)]
77    pub fn to_subfield_vec<S>(self) -> alloc::vec::Vec<FieldElement<S>>
78    where
79        S: IsSubFieldOf<F>,
80    {
81        S::to_subfield_vec(self.value)
82            .into_iter()
83            .map(|x| FieldElement::from_raw(x))
84            .collect()
85    }
86}
87
88/// From overloading for field elements
89impl<F> From<&F::BaseType> for FieldElement<F>
90where
91    F::BaseType: Clone,
92    F: IsField,
93{
94    fn from(value: &F::BaseType) -> Self {
95        Self {
96            value: F::from_base_type(value.clone()),
97        }
98    }
99}
100
101/// From overloading for U64
102impl<F> From<u64> for FieldElement<F>
103where
104    F: IsField,
105{
106    fn from(value: u64) -> Self {
107        Self {
108            value: F::from_u64(value),
109        }
110    }
111}
112
113#[cfg(feature = "alloc")]
114/// From overloading for BigUint.
115/// Creates a field element from a BigUint that is smaller than the modulus.
116/// Returns error if the BigUint value is bigger than the modulus.
117impl<F> TryFrom<BigUint> for FieldElement<F>
118where
119    Self: ByteConversion,
120    F: IsPrimeField,
121{
122    type Error = ByteConversionError;
123    fn try_from(value: BigUint) -> Result<Self, ByteConversionError> {
124        FieldElement::<F>::from_reduced_big_uint(&value)
125    }
126}
127
128impl<F> FieldElement<F>
129where
130    F::BaseType: Clone,
131    F: IsField,
132{
133    pub fn from_raw(value: F::BaseType) -> Self {
134        Self { value }
135    }
136
137    pub const fn const_from_raw(value: F::BaseType) -> Self {
138        Self { value }
139    }
140}
141
142/// Equality operator overloading for field elements
143impl<F> PartialEq<FieldElement<F>> for FieldElement<F>
144where
145    F: IsField,
146{
147    fn eq(&self, other: &FieldElement<F>) -> bool {
148        F::eq(&self.value, &other.value)
149    }
150}
151
152impl<F> Eq for FieldElement<F> where F: IsField {}
153
154/// Addition operator overloading for field elements
155impl<F, L> Add<&FieldElement<L>> for &FieldElement<F>
156where
157    F: IsSubFieldOf<L>,
158    L: IsField,
159{
160    type Output = FieldElement<L>;
161
162    fn add(self, rhs: &FieldElement<L>) -> Self::Output {
163        Self::Output {
164            value: <F as IsSubFieldOf<L>>::add(&self.value, &rhs.value),
165        }
166    }
167}
168
169impl<F, L> Add<FieldElement<L>> for FieldElement<F>
170where
171    F: IsSubFieldOf<L>,
172    L: IsField,
173{
174    type Output = FieldElement<L>;
175
176    fn add(self, rhs: FieldElement<L>) -> Self::Output {
177        &self + &rhs
178    }
179}
180
181impl<F, L> Add<&FieldElement<L>> for FieldElement<F>
182where
183    F: IsSubFieldOf<L>,
184    L: IsField,
185{
186    type Output = FieldElement<L>;
187
188    fn add(self, rhs: &FieldElement<L>) -> Self::Output {
189        &self + rhs
190    }
191}
192
193impl<F, L> Add<FieldElement<L>> for &FieldElement<F>
194where
195    F: IsSubFieldOf<L>,
196    L: IsField,
197{
198    type Output = FieldElement<L>;
199
200    fn add(self, rhs: FieldElement<L>) -> Self::Output {
201        self + &rhs
202    }
203}
204
205/// AddAssign operator overloading for field elements
206impl<F, L> AddAssign<FieldElement<F>> for FieldElement<L>
207where
208    F: IsSubFieldOf<L>,
209    L: IsField,
210{
211    fn add_assign(&mut self, rhs: FieldElement<F>) {
212        self.value = <F as IsSubFieldOf<L>>::add(&rhs.value, &self.value);
213    }
214}
215
216/// Sum operator for field elements
217impl<F> Sum<FieldElement<F>> for FieldElement<F>
218where
219    F: IsField,
220{
221    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
222        iter.fold(Self::zero(), |augend, addend| augend + addend)
223    }
224}
225
226/// Subtraction operator overloading for field elements*/
227impl<F, L> Sub<&FieldElement<L>> for &FieldElement<F>
228where
229    F: IsSubFieldOf<L>,
230    L: IsField,
231{
232    type Output = FieldElement<L>;
233
234    fn sub(self, rhs: &FieldElement<L>) -> Self::Output {
235        Self::Output {
236            value: <F as IsSubFieldOf<L>>::sub(&self.value, &rhs.value),
237        }
238    }
239}
240
241impl<F, L> Sub<FieldElement<L>> for FieldElement<F>
242where
243    F: IsSubFieldOf<L>,
244    L: IsField,
245{
246    type Output = FieldElement<L>;
247
248    fn sub(self, rhs: FieldElement<L>) -> Self::Output {
249        &self - &rhs
250    }
251}
252
253impl<F, L> Sub<&FieldElement<L>> for FieldElement<F>
254where
255    F: IsSubFieldOf<L>,
256    L: IsField,
257{
258    type Output = FieldElement<L>;
259
260    fn sub(self, rhs: &FieldElement<L>) -> Self::Output {
261        &self - rhs
262    }
263}
264
265impl<F, L> Sub<FieldElement<L>> for &FieldElement<F>
266where
267    F: IsSubFieldOf<L>,
268    L: IsField,
269{
270    type Output = FieldElement<L>;
271
272    fn sub(self, rhs: FieldElement<L>) -> Self::Output {
273        self - &rhs
274    }
275}
276
277/// Multiplication operator overloading for field elements*/
278impl<F, L> Mul<&FieldElement<L>> for &FieldElement<F>
279where
280    F: IsSubFieldOf<L>,
281    L: IsField,
282{
283    type Output = FieldElement<L>;
284
285    fn mul(self, rhs: &FieldElement<L>) -> Self::Output {
286        Self::Output {
287            value: <F as IsSubFieldOf<L>>::mul(&self.value, &rhs.value),
288        }
289    }
290}
291
292impl<F, L> Mul<FieldElement<L>> for FieldElement<F>
293where
294    F: IsSubFieldOf<L>,
295    L: IsField,
296{
297    type Output = FieldElement<L>;
298
299    fn mul(self, rhs: FieldElement<L>) -> Self::Output {
300        &self * &rhs
301    }
302}
303
304impl<F, L> Mul<&FieldElement<L>> for FieldElement<F>
305where
306    F: IsSubFieldOf<L>,
307    L: IsField,
308{
309    type Output = FieldElement<L>;
310
311    fn mul(self, rhs: &FieldElement<L>) -> Self::Output {
312        &self * rhs
313    }
314}
315
316impl<F, L> Mul<FieldElement<L>> for &FieldElement<F>
317where
318    F: IsSubFieldOf<L>,
319    L: IsField,
320{
321    type Output = FieldElement<L>;
322
323    fn mul(self, rhs: FieldElement<L>) -> Self::Output {
324        self * &rhs
325    }
326}
327
328/// MulAssign operator overloading for field elements
329impl<F, L> MulAssign<FieldElement<F>> for FieldElement<L>
330where
331    F: IsSubFieldOf<L>,
332    L: IsField,
333{
334    fn mul_assign(&mut self, rhs: FieldElement<F>) {
335        self.value = <F as IsSubFieldOf<L>>::mul(&rhs.value, &self.value);
336    }
337}
338
339/// MulAssign operator overloading for field elements
340impl<F, L> MulAssign<&FieldElement<F>> for FieldElement<L>
341where
342    F: IsSubFieldOf<L>,
343    L: IsField,
344{
345    fn mul_assign(&mut self, rhs: &FieldElement<F>) {
346        self.value = <F as IsSubFieldOf<L>>::mul(&rhs.value, &self.value);
347    }
348}
349
350/// Division operator overloading for field elements*/
351impl<F, L> Div<&FieldElement<L>> for &FieldElement<F>
352where
353    F: IsSubFieldOf<L>,
354    L: IsField,
355{
356    type Output = Result<FieldElement<L>, FieldError>;
357
358    fn div(self, rhs: &FieldElement<L>) -> Self::Output {
359        let value = <F as IsSubFieldOf<L>>::div(&self.value, &rhs.value)?;
360        Ok(FieldElement::<L> { value })
361    }
362}
363
364impl<F, L> Div<FieldElement<L>> for FieldElement<F>
365where
366    F: IsSubFieldOf<L>,
367    L: IsField,
368{
369    type Output = Result<FieldElement<L>, FieldError>;
370
371    fn div(self, rhs: FieldElement<L>) -> Self::Output {
372        &self / &rhs
373    }
374}
375
376impl<F, L> Div<&FieldElement<L>> for FieldElement<F>
377where
378    F: IsSubFieldOf<L>,
379    L: IsField,
380{
381    type Output = Result<FieldElement<L>, FieldError>;
382
383    fn div(self, rhs: &FieldElement<L>) -> Self::Output {
384        &self / rhs
385    }
386}
387
388impl<F, L> Div<FieldElement<L>> for &FieldElement<F>
389where
390    F: IsSubFieldOf<L>,
391    L: IsField,
392{
393    type Output = Result<FieldElement<L>, FieldError>;
394
395    fn div(self, rhs: FieldElement<L>) -> Self::Output {
396        self / &rhs
397    }
398}
399
400/// Negation operator overloading for field elements*/
401impl<F> Neg for &FieldElement<F>
402where
403    F: IsField,
404{
405    type Output = FieldElement<F>;
406
407    fn neg(self) -> Self::Output {
408        Self::Output {
409            value: F::neg(&self.value),
410        }
411    }
412}
413
414impl<F> Neg for FieldElement<F>
415where
416    F: IsField,
417{
418    type Output = FieldElement<F>;
419
420    fn neg(self) -> Self::Output {
421        -&self
422    }
423}
424
425impl<F> Default for FieldElement<F>
426where
427    F: IsField,
428{
429    fn default() -> Self {
430        Self { value: F::zero() }
431    }
432}
433
434/// FieldElement general implementation
435/// Most of this is delegated to the trait `F` that
436/// implements the field operations.
437impl<F> FieldElement<F>
438where
439    F: IsField,
440{
441    /// Creates a field element from `value`
442    #[inline(always)]
443    pub fn new(value: F::BaseType) -> Self {
444        Self {
445            value: F::from_base_type(value),
446        }
447    }
448
449    /// Returns the underlying `value`
450    #[inline(always)]
451    pub fn value(&self) -> &F::BaseType {
452        &self.value
453    }
454
455    /// Returns the multiplicative inverse of `self`
456    #[inline(always)]
457    pub fn inv(&self) -> Result<Self, FieldError> {
458        let value = F::inv(&self.value)?;
459        Ok(Self { value })
460    }
461
462    /// Returns the square of `self`
463    #[inline(always)]
464    pub fn square(&self) -> Self {
465        Self {
466            value: F::square(&self.value),
467        }
468    }
469
470    /// Returns the double of `self`
471    #[inline(always)]
472    pub fn double(&self) -> Self {
473        Self {
474            value: F::double(&self.value),
475        }
476    }
477
478    /// Returns `self` raised to the power of `exponent`
479    #[inline(always)]
480    pub fn pow<T>(&self, exponent: T) -> Self
481    where
482        T: IsUnsignedInteger,
483    {
484        Self {
485            value: F::pow(&self.value, exponent),
486        }
487    }
488
489    /// Returns the multiplicative neutral element of the field.
490    #[inline(always)]
491    pub fn one() -> Self {
492        Self { value: F::one() }
493    }
494
495    /// Returns the additive neutral element of the field.
496    #[inline(always)]
497    pub fn zero() -> Self {
498        Self { value: F::zero() }
499    }
500
501    /// Returns the raw base type
502    pub fn to_raw(self) -> F::BaseType {
503        self.value
504    }
505
506    #[inline(always)]
507    pub fn to_extension<L: IsField>(self) -> FieldElement<L>
508    where
509        F: IsSubFieldOf<L>,
510    {
511        FieldElement {
512            value: <F as IsSubFieldOf<L>>::embed(self.value),
513        }
514    }
515
516    #[cfg(feature = "alloc")]
517    /// Creates a field element from a BigUint that is smaller than the modulus.
518    /// Returns error if the value is bigger than the modulus.
519    pub fn from_reduced_big_uint(value: &BigUint) -> Result<Self, ByteConversionError>
520    where
521        Self: ByteConversion,
522        F: IsPrimeField,
523    {
524        let mod_minus_one = F::modulus_minus_one().to_string();
525
526        // We check if `mod_minus_one` is a hex string or a decimal string.
527        // In case it is a hex we remove the prefix `0x`.
528        let (digits, radix) = if let Some(hex) = mod_minus_one
529            .strip_prefix("0x")
530            .or_else(|| mod_minus_one.strip_prefix("0X"))
531        {
532            (hex, 16)
533        } else {
534            (mod_minus_one.as_str(), 10)
535        };
536
537        let modulus =
538            BigUint::from_str_radix(digits, radix).expect("invalid modulus representation") + 1u32;
539
540        if value >= &modulus {
541            Err(ByteConversionError::ValueNotReduced)
542        } else {
543            let mut bytes = value.to_bytes_le();
544            // We pad the bytes to the size of the base type to be able to apply `from_bytes_le`.
545            bytes.resize(core::mem::size_of::<F::BaseType>(), 0);
546            Self::from_bytes_le(&bytes)
547        }
548    }
549
550    #[cfg(feature = "alloc")]
551    /// Converts a field element into a BigUint.
552    pub fn to_big_uint(&self) -> BigUint
553    where
554        Self: ByteConversion,
555    {
556        BigUint::from_bytes_be(&self.to_bytes_be())
557    }
558
559    #[cfg(feature = "alloc")]
560    /// Converts a hex string into a field element.
561    /// It returns error if the hex value is larger than the modulus.
562    pub fn from_hex_str(hex: &str) -> Result<Self, CreationError>
563    where
564        Self: ByteConversion,
565        F: IsPrimeField,
566    {
567        let hex_str = hex.strip_prefix("0x").unwrap_or(hex);
568        if hex_str.is_empty() {
569            return Err(CreationError::EmptyString);
570        }
571
572        let value =
573            BigUint::from_str_radix(hex_str, 16).map_err(|_| CreationError::InvalidHexString)?;
574
575        Self::from_reduced_big_uint(&value).map_err(|_| CreationError::InvalidHexString)
576    }
577
578    #[cfg(feature = "alloc")]
579    /// Converts a field element into a hex string.
580    pub fn to_hex_str(&self) -> String
581    where
582        Self: ByteConversion,
583    {
584        format!("0x{:02X}", self.to_big_uint())
585    }
586}
587
588impl<F: IsPrimeField> FieldElement<F> {
589    /// Returns the representative of the value stored
590    pub fn representative(&self) -> F::RepresentativeType {
591        F::representative(self.value())
592    }
593
594    /// Returns the two square roots of a field element, provided it exists
595    /// The function returns the roots whenever the field element is a quadratic residue modulo p
596    pub fn sqrt(&self) -> Option<(Self, Self)> {
597        let sqrts = F::sqrt(&self.value);
598        sqrts.map(|(sqrt1, sqrt2)| (Self { value: sqrt1 }, Self { value: sqrt2 }))
599    }
600
601    /// Returns the Legendre symbol of a field element modulo p
602    pub fn legendre_symbol(&self) -> LegendreSymbol {
603        F::legendre_symbol(&self.value)
604    }
605
606    /// Creates a `FieldElement` from a hexstring. It can contain `0x` or not.
607    /// Returns an `CreationError::InvalidHexString`if the value is not a hexstring.
608    /// Returns a `CreationError::EmptyString` if the input string is empty.
609    /// Returns a `CreationError::HexStringIsTooBig` if the the input hex string is bigger than the
610    /// maximum amount of characters for this element.
611    /// Returns a `CreationError::RepresentativeOutOfRange` if the representative of the value is
612    /// out of the range [0, p-1] where p is the modulus.
613    pub fn from_hex(hex_string: &str) -> Result<Self, CreationError> {
614        if hex_string.is_empty() {
615            return Err(CreationError::EmptyString);
616        }
617        let value = F::from_hex(hex_string)?;
618        Ok(Self { value })
619    }
620
621    #[cfg(feature = "std")]
622    /// Creates a hexstring from a `FieldElement` without `0x`.
623    pub fn to_hex(&self) -> String {
624        F::to_hex(&self.value)
625    }
626}
627
628#[cfg(feature = "lambdaworks-serde-binary")]
629impl<F> Serialize for FieldElement<F>
630where
631    F: IsField,
632    F::BaseType: ByteConversion,
633{
634    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
635    where
636        S: Serializer,
637    {
638        let mut state = serializer.serialize_struct("FieldElement", 1)?;
639        let data = self.value().to_bytes_be();
640        state.serialize_field("value", &data)?;
641        state.end()
642    }
643}
644
645#[cfg(all(
646    feature = "lambdaworks-serde-string",
647    not(feature = "lambdaworks-serde-binary")
648))]
649impl<F: IsPrimeField> Serialize for FieldElement<F> {
650    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
651    where
652        S: Serializer,
653    {
654        use crate::alloc::string::ToString;
655        let mut state = serializer.serialize_struct("FieldElement", 1)?;
656        state.serialize_field("value", &F::representative(self.value()).to_string())?;
657        state.end()
658    }
659}
660
661#[cfg(feature = "lambdaworks-serde-binary")]
662impl<'de, F> Deserialize<'de> for FieldElement<F>
663where
664    F: IsField,
665    F::BaseType: ByteConversion,
666{
667    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
668    where
669        D: Deserializer<'de>,
670    {
671        #[derive(Deserialize)]
672        #[serde(field_identifier, rename_all = "lowercase")]
673        enum Field {
674            Value,
675        }
676
677        struct FieldElementVisitor<F>(PhantomData<fn() -> F>);
678
679        impl<'de, F: IsField> Visitor<'de> for FieldElementVisitor<F> {
680            type Value = FieldElement<F>;
681
682            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
683                formatter.write_str("struct FieldElement")
684            }
685
686            fn visit_map<M>(self, mut map: M) -> Result<FieldElement<F>, M::Error>
687            where
688                M: MapAccess<'de>,
689            {
690                let mut value: Option<alloc::vec::Vec<u8>> = None;
691                while let Some(key) = map.next_key()? {
692                    match key {
693                        Field::Value => {
694                            if value.is_some() {
695                                return Err(de::Error::duplicate_field("value"));
696                            }
697                            value = Some(map.next_value()?);
698                        }
699                    }
700                }
701                let value = value.ok_or_else(|| de::Error::missing_field("value"))?;
702                let val = F::BaseType::from_bytes_be(&value).unwrap();
703                Ok(FieldElement::from_raw(val))
704            }
705
706            fn visit_seq<S>(self, mut seq: S) -> Result<FieldElement<F>, S::Error>
707            where
708                S: SeqAccess<'de>,
709            {
710                let mut value: Option<alloc::vec::Vec<u8>> = None;
711                while let Some(val) = seq.next_element()? {
712                    if value.is_some() {
713                        return Err(de::Error::duplicate_field("value"));
714                    }
715                    value = Some(val);
716                }
717                let value = value.ok_or_else(|| de::Error::missing_field("value"))?;
718                let val = F::BaseType::from_bytes_be(&value).unwrap();
719                Ok(FieldElement::from_raw(val))
720            }
721        }
722
723        const FIELDS: &[&str] = &["value"];
724        deserializer.deserialize_struct("FieldElement", FIELDS, FieldElementVisitor(PhantomData))
725    }
726}
727
728#[cfg(all(
729    feature = "lambdaworks-serde-string",
730    not(feature = "lambdaworks-serde-binary")
731))]
732impl<'de, F: IsPrimeField> Deserialize<'de> for FieldElement<F> {
733    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
734    where
735        D: Deserializer<'de>,
736    {
737        #[derive(Deserialize)]
738        #[serde(field_identifier, rename_all = "lowercase")]
739        enum Field {
740            Value,
741        }
742
743        struct FieldElementVisitor<F>(PhantomData<fn() -> F>);
744
745        impl<'de, F: IsPrimeField> Visitor<'de> for FieldElementVisitor<F> {
746            type Value = FieldElement<F>;
747
748            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
749                formatter.write_str("struct FieldElement")
750            }
751
752            fn visit_map<M>(self, mut map: M) -> Result<FieldElement<F>, M::Error>
753            where
754                M: MapAccess<'de>,
755            {
756                let mut value: Option<&str> = None;
757                while let Some(key) = map.next_key()? {
758                    match key {
759                        Field::Value => {
760                            if value.is_some() {
761                                return Err(de::Error::duplicate_field("value"));
762                            }
763                            value = Some(map.next_value()?);
764                        }
765                    }
766                }
767                let value = value.ok_or_else(|| de::Error::missing_field("value"))?;
768                FieldElement::from_hex(&value).map_err(|_| de::Error::custom("invalid hex"))
769            }
770
771            fn visit_seq<S>(self, mut seq: S) -> Result<FieldElement<F>, S::Error>
772            where
773                S: SeqAccess<'de>,
774            {
775                let mut value: Option<&str> = None;
776                while let Some(val) = seq.next_element()? {
777                    if value.is_some() {
778                        return Err(de::Error::duplicate_field("value"));
779                    }
780                    value = Some(val);
781                }
782                let value = value.ok_or_else(|| de::Error::missing_field("value"))?;
783                FieldElement::from_hex(&value).map_err(|_| de::Error::custom("invalid hex"))
784            }
785        }
786
787        const FIELDS: &[&str] = &["value"];
788        deserializer.deserialize_struct("FieldElement", FIELDS, FieldElementVisitor(PhantomData))
789    }
790}
791
792impl<M, const NUM_LIMBS: usize> fmt::Display
793    for FieldElement<MontgomeryBackendPrimeField<M, NUM_LIMBS>>
794where
795    M: IsModulus<UnsignedInteger<NUM_LIMBS>> + Clone + Debug,
796{
797    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
798        let value: UnsignedInteger<NUM_LIMBS> = self.representative();
799        write!(f, "{value}")
800    }
801}
802
803impl<M, const NUM_LIMBS: usize> FieldElement<MontgomeryBackendPrimeField<M, NUM_LIMBS>>
804where
805    M: IsModulus<UnsignedInteger<NUM_LIMBS>> + Clone + Debug,
806{
807    /// Creates a `FieldElement` from a hexstring. It can contain `0x` or not.
808    /// # Panics
809    /// Panics if value is not a hexstring
810    pub const fn from_hex_unchecked(hex: &str) -> Self {
811        let integer = UnsignedInteger::<NUM_LIMBS>::from_hex_unchecked(hex);
812        Self {
813            value: MontgomeryAlgorithms::cios(
814                &integer,
815                &MontgomeryBackendPrimeField::<M, NUM_LIMBS>::R2,
816                &M::MODULUS,
817                &MontgomeryBackendPrimeField::<M, NUM_LIMBS>::MU,
818            ),
819        }
820    }
821}
822
823#[cfg(test)]
824mod tests {
825    use super::*;
826    use crate::elliptic_curve::short_weierstrass::curves::bn_254::field_extension::BN254PrimeField;
827    use crate::field::fields::fft_friendly::{
828        babybear_u32::Babybear31PrimeField, stark_252_prime_field::Stark252PrimeField,
829    };
830    use crate::field::fields::montgomery_backed_prime_fields::U384PrimeField;
831    use crate::field::fields::u64_prime_field::U64PrimeField;
832    use crate::field::test_fields::u64_test_field::U64TestField;
833    #[cfg(feature = "alloc")]
834    use crate::unsigned_integer::element::UnsignedInteger;
835    use crate::unsigned_integer::element::U384;
836    #[cfg(feature = "alloc")]
837    use alloc::vec::Vec;
838    use num_bigint::BigUint;
839    #[cfg(feature = "alloc")]
840    use proptest::collection;
841    use proptest::{prelude::*, prop_compose, proptest, strategy::Strategy};
842
843    #[test]
844    fn test_std_iter_sum_field_element() {
845        let n = 164;
846        const MODULUS: u64 = 18446744069414584321;
847        assert_eq!(
848            (0..n)
849                .map(|x| { FieldElement::<U64TestField>::from(x) })
850                .sum::<FieldElement<U64TestField>>()
851                .value,
852            ((n - 1) as f64 / 2. * ((n - 1) as f64 + 1.)) as u64 % MODULUS
853        );
854    }
855
856    #[test]
857    fn test_std_iter_sum_field_element_zero_length() {
858        let n = 0;
859        assert_eq!(
860            (0..n)
861                .map(|x| { FieldElement::<U64TestField>::from(x) })
862                .sum::<FieldElement<U64TestField>>()
863                .value,
864            0
865        );
866    }
867
868    #[cfg(feature = "alloc")]
869    #[test]
870    fn test_display_montgomery_field() {
871        use alloc::format;
872
873        let zero_field_element = FieldElement::<Stark252PrimeField>::from(0);
874        assert_eq!(format!("{zero_field_element}"), "0x0");
875
876        let some_field_element =
877            FieldElement::<Stark252PrimeField>::from(&UnsignedInteger::from_limbs([
878                0x0, 0x1, 0x0, 0x1,
879            ]));
880
881        // it should start with the first non-zero digit. Each limb has 16 digits in hex.
882        assert_eq!(
883            format!("{some_field_element}"),
884            format!("0x{}{}{}{}", "1", "0".repeat(16), "0".repeat(15), "1")
885        );
886    }
887
888    #[test]
889    fn one_of_sqrt_roots_for_4_is_2() {
890        type FrField = Stark252PrimeField;
891        type FrElement = FieldElement<FrField>;
892
893        let input = FrElement::from(4);
894        let sqrt = input.sqrt().unwrap();
895        let result = FrElement::from(2);
896        assert_eq!(sqrt.0, result);
897    }
898
899    #[test]
900    fn one_of_sqrt_roots_for_5_is_28_mod_41() {
901        let input = FieldElement::<U64PrimeField<41>>::from(5);
902        let sqrt = input.sqrt().unwrap();
903        let result = FieldElement::from(28);
904        assert_eq!(sqrt.0, result);
905        assert_eq!(sqrt.1, -result);
906    }
907
908    #[test]
909    fn one_of_sqrt_roots_for_25_is_5() {
910        type FrField = Stark252PrimeField;
911        type FrElement = FieldElement<FrField>;
912        let input = FrElement::from(25);
913        let sqrt = input.sqrt().unwrap();
914        let five = FrElement::from(5);
915        assert!(sqrt.1 == five || sqrt.0 == five);
916    }
917
918    #[test]
919    fn sqrt_works_for_prime_minus_one() {
920        type FrField = Stark252PrimeField;
921        type FrElement = FieldElement<FrField>;
922
923        let input = -FrElement::from(1);
924        let sqrt = input.sqrt().unwrap();
925        assert_eq!(sqrt.0.square(), input);
926        assert_eq!(sqrt.1.square(), input);
927        assert_ne!(sqrt.0, sqrt.1);
928    }
929
930    #[test]
931    fn one_of_sqrt_roots_for_25_is_5_in_stark_field() {
932        type FrField = Stark252PrimeField;
933        type FrElement = FieldElement<FrField>;
934
935        let input = FrElement::from(25);
936        let sqrt = input.sqrt().unwrap();
937        let result = FrElement::from(5);
938        assert_eq!(sqrt.0, result);
939        assert_eq!(sqrt.1, -result);
940    }
941
942    #[test]
943    fn sqrt_roots_for_0_are_0_in_stark_field() {
944        type FrField = Stark252PrimeField;
945        type FrElement = FieldElement<FrField>;
946
947        let input = FrElement::from(0);
948        let sqrt = input.sqrt().unwrap();
949        let result = FrElement::from(0);
950        assert_eq!(sqrt.0, result);
951        assert_eq!(sqrt.1, result);
952    }
953
954    #[test]
955    fn sqrt_of_27_for_stark_field_does_not_exist() {
956        type FrField = Stark252PrimeField;
957        type FrElement = FieldElement<FrField>;
958
959        let input = FrElement::from(27);
960        let sqrt = input.sqrt();
961        assert!(sqrt.is_none());
962    }
963
964    #[test]
965    fn from_hex_1a_is_26_for_stark252_prime_field_element() {
966        type F = Stark252PrimeField;
967        type FE = FieldElement<F>;
968        assert_eq!(FE::from_hex("1a").unwrap(), FE::from(26))
969    }
970
971    #[test]
972    fn from_hex_unchecked_zero_x_1a_is_26_for_stark252_prime_field_element() {
973        type F = Stark252PrimeField;
974        type FE = FieldElement<F>;
975        assert_eq!(FE::from_hex_unchecked("0x1a"), FE::from(26))
976    }
977
978    #[test]
979    fn construct_new_field_element_from_empty_string_errs() {
980        type F = Stark252PrimeField;
981        type FE = FieldElement<F>;
982        assert!(FE::from_hex("").is_err());
983    }
984
985    #[test]
986    fn construct_new_field_element_from_value_bigger_than_modulus() {
987        type F = Stark252PrimeField;
988        type FE = FieldElement<F>;
989        // A number that consists of 255 1s is bigger than the `Stark252PrimeField` modulus
990        assert!(FE::from_hex(&format!("0x{}", "f".repeat(65))).is_err());
991    }
992
993    prop_compose! {
994        fn field_element()(num in any::<u64>().prop_filter("Avoid null coefficients", |x| x != &0)) -> FieldElement::<Stark252PrimeField> {
995            FieldElement::<Stark252PrimeField>::from(num)
996        }
997    }
998
999    prop_compose! {
1000        #[cfg(feature = "alloc")]
1001        fn field_vec(max_exp: u8)(vec in collection::vec(field_element(), 0..1 << max_exp)) -> Vec<FieldElement::<Stark252PrimeField>> {
1002            vec
1003        }
1004    }
1005
1006    proptest! {
1007        #[cfg(feature = "alloc")]
1008        #[test]
1009        fn test_inplace_batch_inverse_returns_inverses(vec in field_vec(10)) {
1010            let input: Vec<_> = vec.into_iter().filter(|x| x != &FieldElement::<Stark252PrimeField>::zero()).collect();
1011            let mut inverses = input.clone();
1012            FieldElement::inplace_batch_inverse(&mut inverses).unwrap();
1013
1014            for (i, x) in inverses.into_iter().enumerate() {
1015                prop_assert_eq!(x * input[i], FieldElement::<Stark252PrimeField>::one());
1016            }
1017        }
1018    }
1019
1020    // Tests for BigUint conversion.
1021    // We define different fields to test the conversion.
1022
1023    // Prime field with modulus 17 and base type u64.
1024    type U64F17 = U64PrimeField<17>;
1025    type U64F17Element = FieldElement<U64F17>;
1026
1027    // Baby Bear Prime field with u32 montgomery backend.
1028    type BabyBear = Babybear31PrimeField;
1029    type BabyBearElement = FieldElement<BabyBear>;
1030
1031    // Prime field with modulus 23, using u64 montgomery backend of 6 limbs.
1032    #[derive(Clone, Debug)]
1033    struct U384Modulus23;
1034    impl IsModulus<U384> for U384Modulus23 {
1035        const MODULUS: U384 = UnsignedInteger::from_u64(23);
1036    }
1037    type U384F23 = U384PrimeField<U384Modulus23>;
1038    type U384F23Element = FieldElement<U384F23>;
1039
1040    #[test]
1041    fn test_reduced_biguint_conversion_u64_field() {
1042        let value = BigUint::from(10u32);
1043        let fe = U64F17Element::try_from(value.clone()).unwrap();
1044        let back_to_biguint = fe.to_big_uint();
1045        assert_eq!(value, back_to_biguint);
1046    }
1047
1048    #[test]
1049    fn test_reduced_biguint_conversion_baby_bear() {
1050        let value = BigUint::from(1000u32);
1051        let fe = BabyBearElement::from_reduced_big_uint(&value).unwrap();
1052        assert_eq!(fe, BabyBearElement::from(1000));
1053        let back_to_biguint = fe.to_big_uint();
1054        assert_eq!(value, back_to_biguint);
1055    }
1056
1057    #[test]
1058    fn test_reduced_biguint_conversion_u384_field() {
1059        let value = BigUint::from(22u32);
1060        let fe = U384F23Element::from_reduced_big_uint(&value).unwrap();
1061        let back_to_biguint = fe.to_big_uint();
1062        assert_eq!(value, back_to_biguint);
1063    }
1064    #[test]
1065    fn test_bn254_field_biguint_conversion() {
1066        type BN254Element = FieldElement<BN254PrimeField>;
1067        let value = BigUint::from(1001u32);
1068        let fe = BN254Element::from_reduced_big_uint(&value).unwrap();
1069        let back_to_biguint = fe.to_big_uint();
1070        assert_eq!(value, back_to_biguint);
1071    }
1072
1073    #[test]
1074    fn non_reduced_biguint_value_conversion_errors_u64_field() {
1075        let value = BigUint::from(17u32);
1076        let result = U64F17Element::from_reduced_big_uint(&value);
1077        assert_eq!(result, Err(ByteConversionError::ValueNotReduced));
1078    }
1079
1080    #[test]
1081    fn non_reduced_biguint_value_conversion_errors_baby_bear() {
1082        let value = BigUint::from(2013265921u32);
1083        let result = BabyBearElement::try_from(value);
1084        assert_eq!(result, Err(ByteConversionError::ValueNotReduced));
1085    }
1086
1087    #[test]
1088    fn non_reduced_biguint_value_conversion_errors_u384_field() {
1089        let value = BigUint::from(30u32);
1090        let result = U384F23Element::try_from(value);
1091        assert_eq!(result, Err(ByteConversionError::ValueNotReduced));
1092    }
1093
1094    #[test]
1095    fn test_hex_string_conversion_u64_field() {
1096        let hex_str = "0x0a";
1097        let fe = U64F17Element::from_hex_str(hex_str).unwrap();
1098        assert_eq!(fe, U64F17Element::from(10));
1099        assert_eq!(fe.to_hex_str(), "0x0A");
1100    }
1101
1102    #[test]
1103    fn test_hex_string_conversion_baby_bear() {
1104        let hex_str = "0x77FFFFFF"; // 2013265919
1105        let fe = BabyBearElement::from_hex_str(hex_str).unwrap();
1106        assert_eq!(fe, BabyBearElement::from(2013265919));
1107        assert_eq!(fe.to_hex_str(), "0x77FFFFFF");
1108    }
1109
1110    #[test]
1111    fn test_hex_string_conversion_u384_field() {
1112        let hex_str = "0x14"; // 20
1113        let fe = U384F23Element::from_hex_str(hex_str).unwrap();
1114        assert_eq!(fe, U384F23Element::from(20));
1115        assert_eq!(fe.to_hex_str(), "0x14");
1116    }
1117
1118    #[test]
1119    fn test_invalid_hex_string_u64_field() {
1120        let hex_str = "0xzz";
1121        let result = U64F17Element::from_hex_str(hex_str);
1122        assert!(result.is_err());
1123    }
1124
1125    #[test]
1126    fn test_invalid_hex_string_baby_bear() {
1127        // modulus = 0x78000001
1128        let hex_str = "0x78000001";
1129        let result = BabyBearElement::from_hex_str(hex_str);
1130        assert!(result.is_err());
1131    }
1132
1133    #[test]
1134    fn test_empty_hex_string() {
1135        let hex_str = "";
1136        let result = U64F17Element::from_hex_str(hex_str);
1137        assert!(result.is_err());
1138    }
1139}