lambdaworks_math/field/fields/fft_friendly/
u64_goldilocks.rs

1use crate::{
2    field::{
3        element::FieldElement,
4        fields::montgomery_backed_prime_fields::{IsModulus, MontgomeryBackendPrimeField},
5    },
6    unsigned_integer::element::U64,
7};
8
9pub type U64MontgomeryBackendPrimeField<T> = MontgomeryBackendPrimeField<T, 1>;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12pub struct MontgomeryConfigU64GoldilocksPrimeField;
13impl IsModulus<U64> for MontgomeryConfigU64GoldilocksPrimeField {
14    //Babybear Prime p = 2^64 - 2^32 + 1
15    const MODULUS: U64 = U64::from_u64(18446744069414584321);
16}
17
18pub type U64GoldilocksPrimeField =
19    U64MontgomeryBackendPrimeField<MontgomeryConfigU64GoldilocksPrimeField>;
20
21impl FieldElement<U64GoldilocksPrimeField> {
22    pub fn to_bytes_le(&self) -> [u8; 8] {
23        let limbs = self.representative().limbs;
24        limbs[0].to_le_bytes()
25    }
26
27    pub fn to_bytes_be(&self) -> [u8; 8] {
28        let limbs = self.representative().limbs;
29        limbs[0].to_be_bytes()
30    }
31}
32
33#[allow(clippy::non_canonical_partial_ord_impl)]
34impl PartialOrd for FieldElement<U64GoldilocksPrimeField> {
35    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
36        self.representative().partial_cmp(&other.representative())
37    }
38}
39
40impl Ord for FieldElement<U64GoldilocksPrimeField> {
41    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
42        self.representative().cmp(&other.representative())
43    }
44}
45
46#[cfg(test)]
47mod test_u64_goldilocks_bytes_ops {
48    use super::U64GoldilocksPrimeField;
49    use crate::{field::element::FieldElement, traits::ByteConversion};
50
51    #[test]
52    #[cfg(feature = "alloc")]
53    fn byte_serialization_for_a_number_matches_with_byte_conversion_implementation_le() {
54        let element = FieldElement::<U64GoldilocksPrimeField>::from_hex_unchecked(
55            "\
56            0123456701234567\
57        ",
58        );
59        let bytes = element.to_bytes_le();
60        let expected_bytes: [u8; 8] = ByteConversion::to_bytes_le(&element).try_into().unwrap();
61        assert_eq!(bytes, expected_bytes);
62    }
63
64    #[test]
65    #[cfg(feature = "alloc")]
66    fn byte_serialization_for_a_number_matches_with_byte_conversion_implementation_be() {
67        let element = FieldElement::<U64GoldilocksPrimeField>::from_hex_unchecked(
68            "\
69            0123456701234567\
70        ",
71        );
72        let bytes = element.to_bytes_be();
73        let expected_bytes: [u8; 8] = ByteConversion::to_bytes_be(&element).try_into().unwrap();
74        assert_eq!(bytes, expected_bytes);
75    }
76
77    #[test]
78
79    fn byte_serialization_and_deserialization_works_le() {
80        let element = FieldElement::<U64GoldilocksPrimeField>::from_hex_unchecked(
81            "\
82            7654321076543210\
83        ",
84        );
85        let bytes = element.to_bytes_le();
86        let from_bytes = FieldElement::<U64GoldilocksPrimeField>::from_bytes_le(&bytes).unwrap();
87        assert_eq!(element, from_bytes);
88    }
89
90    #[test]
91
92    fn byte_serialization_and_deserialization_works_be() {
93        let element = FieldElement::<U64GoldilocksPrimeField>::from_hex_unchecked(
94            "\
95            7654321076543210\
96        ",
97        );
98        let bytes = element.to_bytes_be();
99        let from_bytes = FieldElement::<U64GoldilocksPrimeField>::from_bytes_be(&bytes).unwrap();
100        assert_eq!(element, from_bytes);
101    }
102}