lambdaworks_math/field/test_fields/
u64_test_field.rs1use crate::{
2 errors::CreationError,
3 field::{
4 element::FieldElement,
5 extensions::quadratic::QuadraticExtensionField,
6 traits::{IsFFTField, IsField, IsPrimeField},
7 },
8 field::{errors::FieldError, extensions::quadratic::HasQuadraticNonResidue},
9};
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct U64Field<const MODULUS: u64>;
13
14impl<const MODULUS: u64> IsField for U64Field<MODULUS> {
15 type BaseType = u64;
16
17 fn add(a: &u64, b: &u64) -> u64 {
18 ((*a as u128 + *b as u128) % MODULUS as u128) as u64
19 }
20
21 fn sub(a: &u64, b: &u64) -> u64 {
22 (((*a as u128 + MODULUS as u128) - *b as u128) % MODULUS as u128) as u64
23 }
24
25 fn neg(a: &u64) -> u64 {
26 MODULUS - a
27 }
28
29 fn mul(a: &u64, b: &u64) -> u64 {
30 ((*a as u128 * *b as u128) % MODULUS as u128) as u64
31 }
32
33 fn div(a: &u64, b: &u64) -> Result<u64, FieldError> {
34 let b_inv = &Self::inv(b)?;
35 Ok(Self::mul(a, b_inv))
36 }
37
38 fn inv(a: &u64) -> Result<u64, FieldError> {
39 if *a == 0 {
40 return Err(FieldError::InvZeroError);
41 }
42 Ok(Self::pow(a, MODULUS - 2))
43 }
44
45 fn eq(a: &u64, b: &u64) -> bool {
46 Self::from_u64(*a) == Self::from_u64(*b)
47 }
48
49 fn zero() -> u64 {
50 0
51 }
52
53 fn one() -> u64 {
54 1
55 }
56
57 fn from_u64(x: u64) -> u64 {
58 x % MODULUS
59 }
60
61 fn from_base_type(x: u64) -> u64 {
62 Self::from_u64(x)
63 }
64}
65
66impl<const MODULUS: u64> IsPrimeField for U64Field<MODULUS> {
67 type RepresentativeType = u64;
68
69 fn representative(x: &u64) -> u64 {
70 *x
71 }
72
73 fn field_bit_size() -> usize {
76 ((MODULUS - 1).ilog2() + 1) as usize
77 }
78
79 fn from_hex(hex_string: &str) -> Result<Self::BaseType, crate::errors::CreationError> {
80 let mut hex_string = hex_string;
81 let mut char_iterator = hex_string.chars();
83 if hex_string.len() > 2
84 && char_iterator.next().unwrap() == '0'
85 && char_iterator.next().unwrap() == 'x'
86 {
87 hex_string = &hex_string[2..];
88 }
89
90 u64::from_str_radix(hex_string, 16).map_err(|_| CreationError::InvalidHexString)
91 }
92
93 #[cfg(feature = "std")]
94 fn to_hex(x: &u64) -> String {
95 format!("{x:X}")
96 }
97}
98
99pub type U64TestField = U64Field<18446744069414584321>;
100
101impl IsFFTField for U64TestField {
103 const TWO_ADICITY: u64 = 32;
104 const TWO_ADIC_PRIMITVE_ROOT_OF_UNITY: u64 = 1753635133440165772;
105}
106
107#[derive(Clone, Debug)]
108pub struct TestNonResidue;
109impl HasQuadraticNonResidue<U64TestField> for TestNonResidue {
110 fn residue() -> FieldElement<U64TestField> {
111 FieldElement::from(7)
112 }
113}
114
115pub type U64TestFieldExtension = QuadraticExtensionField<U64TestField, TestNonResidue>;
116
117#[cfg(test)]
118mod tests_u64_test_field {
119 use crate::field::{
120 element::FieldElement,
121 test_fields::u64_test_field::{U64TestField, U64TestFieldExtension},
122 traits::IsPrimeField,
123 };
124
125 #[test]
126 fn from_hex_for_b_is_11() {
127 assert_eq!(U64TestField::from_hex("B").unwrap(), 11);
128 }
129
130 #[test]
131 fn bit_size_of_test_field_is_64() {
132 assert_eq!(
133 <U64TestField as crate::field::traits::IsPrimeField>::field_bit_size(),
134 64
135 );
136 }
137
138 #[cfg(feature = "alloc")]
139 #[test]
140 fn test_to_subfield_vec() {
141 let a = FieldElement::<U64TestFieldExtension>::from(&[
142 FieldElement::from(1),
143 FieldElement::from(3),
144 ]);
145 let b = a.to_subfield_vec::<U64TestField>();
146 assert_eq!(b, alloc::vec![FieldElement::from(1), FieldElement::from(3)]);
147 }
148
149 #[cfg(feature = "std")]
150 #[test]
151 fn to_hex_test() {
152 let num = U64TestField::from_hex("B").unwrap();
153 assert_eq!(U64TestField::to_hex(&num), "B");
154 }
155}