Skip to main content

ark_ff/fields/
mod.rs

1use crate::UniformRand;
2use ark_serialize::{
3    CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize,
4    CanonicalSerializeWithFlags, EmptyFlags, Flags,
5};
6use ark_std::{
7    fmt::{Debug, Display},
8    hash::Hash,
9    iter::*,
10    ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
11    vec::*,
12};
13
14pub use ark_ff_macros;
15pub use ark_ff_macros::define_field;
16pub use num_traits::{One, Zero};
17use zeroize::Zeroize;
18
19pub mod utils;
20
21#[macro_use]
22pub mod arithmetic;
23
24#[macro_use]
25pub mod models;
26pub use self::models::*;
27
28pub mod field_hashers;
29
30mod prime;
31pub use prime::*;
32
33mod fft_friendly;
34pub use fft_friendly::*;
35
36mod cyclotomic;
37pub use cyclotomic::*;
38
39mod sqrt;
40pub use sqrt::*;
41
42#[cfg(feature = "parallel")]
43use ark_std::cmp::max;
44#[cfg(feature = "parallel")]
45use rayon::prelude::*;
46
47pub trait AdditiveGroup:
48    Eq
49    + 'static
50    + Sized
51    + CanonicalSerialize
52    + CanonicalDeserialize
53    + Copy
54    + Clone
55    + Default
56    + Send
57    + Sync
58    + Hash
59    + Debug
60    + Display
61    + UniformRand
62    + Zeroize
63    + Zero
64    + Neg<Output = Self>
65    + Add<Self, Output = Self>
66    + Sub<Self, Output = Self>
67    + Mul<<Self as AdditiveGroup>::Scalar, Output = Self>
68    + AddAssign<Self>
69    + SubAssign<Self>
70    + MulAssign<<Self as AdditiveGroup>::Scalar>
71    + for<'a> Add<&'a Self, Output = Self>
72    + for<'a> Sub<&'a Self, Output = Self>
73    + for<'a> Mul<&'a <Self as AdditiveGroup>::Scalar, Output = Self>
74    + for<'a> AddAssign<&'a Self>
75    + for<'a> SubAssign<&'a Self>
76    + for<'a> MulAssign<&'a <Self as AdditiveGroup>::Scalar>
77    + for<'a> Add<&'a mut Self, Output = Self>
78    + for<'a> Sub<&'a mut Self, Output = Self>
79    + for<'a> Mul<&'a mut <Self as AdditiveGroup>::Scalar, Output = Self>
80    + for<'a> AddAssign<&'a mut Self>
81    + for<'a> SubAssign<&'a mut Self>
82    + for<'a> MulAssign<&'a mut <Self as AdditiveGroup>::Scalar>
83    + ark_std::iter::Sum<Self>
84    + for<'a> ark_std::iter::Sum<&'a Self>
85{
86    type Scalar: Field;
87
88    /// The additive identity of the field.
89    const ZERO: Self;
90
91    /// Doubles `self`.
92    #[must_use]
93    fn double(&self) -> Self {
94        let mut copy = *self;
95        copy.double_in_place();
96        copy
97    }
98    /// Doubles `self` in place.
99    fn double_in_place(&mut self) -> &mut Self {
100        *self += *self;
101        self
102    }
103
104    /// Negates `self` in place.
105    fn neg_in_place(&mut self) -> &mut Self {
106        *self = -(*self);
107        self
108    }
109}
110
111/// The interface for a generic field.
112/// Types implementing [`Field`] support common field operations such as addition, subtraction, multiplication, and inverses.
113///
114/// ## Defining your own field
115/// To demonstrate the various field operations, we can first define a prime ordered field $\mathbb{F}_{p}$ with $p = 17$. When defining a field $\mathbb{F}_p$, we need to provide the modulus(the $p$ in $\mathbb{F}_p$) and a generator. Recall that a generator $g \in \mathbb{F}_p$ is a field element whose powers comprise the entire field: $\mathbb{F}_p =\\{g, g^1, \ldots, g^{p-1}\\}$.
116/// We can then manually construct the field element associated with an integer with `Fp::from` and perform field addition, subtraction, multiplication, and inversion on it.
117/// ```rust
118/// use ark_ff::{AdditiveGroup, fields::{Field, Fp64, MontBackend, MontConfig}};
119///
120/// #[derive(MontConfig)]
121/// #[modulus = "17"]
122/// #[generator = "3"]
123/// pub struct FqConfig;
124/// pub type Fq = Fp64<MontBackend<FqConfig, 1>>;
125///
126/// # fn main() {
127/// let a = Fq::from(9);
128/// let b = Fq::from(10);
129///
130/// assert_eq!(a, Fq::from(26));          // 26 =  9 mod 17
131/// assert_eq!(a - b, Fq::from(16));      // -1 = 16 mod 17
132/// assert_eq!(a + b, Fq::from(2));       // 19 =  2 mod 17
133/// assert_eq!(a * b, Fq::from(5));       // 90 =  5 mod 17
134/// assert_eq!(a.square(), Fq::from(13)); // 81 = 13 mod 17
135/// assert_eq!(b.double(), Fq::from(3));  // 20 =  3 mod 17
136/// assert_eq!(a / b, a * b.inverse().unwrap()); // need to unwrap since `b` could be 0 which is not invertible
137/// # }
138/// ```
139///
140/// ## Using pre-defined fields
141/// In the following example, we’ll use the field associated with the BLS12-381 pairing-friendly group.
142/// ```rust
143/// use ark_ff::{AdditiveGroup, Field};
144/// use ark_test_curves::bls12_381::Fq as F;
145/// use ark_std::{One, UniformRand, test_rng};
146///
147/// let mut rng = test_rng();
148/// // Let's sample uniformly random field elements:
149/// let a = F::rand(&mut rng);
150/// let b = F::rand(&mut rng);
151///
152/// let c = a + b;
153/// let d = a - b;
154/// assert_eq!(c + d, a.double());
155///
156/// let e = c * d;
157/// assert_eq!(e, a.square() - b.square());         // (a + b)(a - b) = a^2 - b^2
158/// assert_eq!(a.inverse().unwrap() * a, F::one()); // Euler-Fermat theorem tells us: a * a^{-1} = 1 mod p
159/// ```
160pub trait Field:
161    'static
162    + Copy
163    + Clone
164    + Debug
165    + Display
166    + Default
167    + Send
168    + Sync
169    + Eq
170    + Zero
171    + One
172    + Ord
173    + Neg<Output = Self>
174    + UniformRand
175    + Zeroize
176    + Sized
177    + Hash
178    + CanonicalSerialize
179    + CanonicalSerializeWithFlags
180    + CanonicalDeserialize
181    + CanonicalDeserializeWithFlags
182    + AdditiveGroup<Scalar = Self>
183    + Div<Self, Output = Self>
184    + DivAssign<Self>
185    + for<'a> Div<&'a Self, Output = Self>
186    + for<'a> DivAssign<&'a Self>
187    + for<'a> Div<&'a mut Self, Output = Self>
188    + for<'a> DivAssign<&'a mut Self>
189    + for<'a> core::iter::Product<&'a Self>
190    + From<u128>
191    + From<u64>
192    + From<u32>
193    + From<u16>
194    + From<u8>
195    + From<i128>
196    + From<i64>
197    + From<i32>
198    + From<i16>
199    + From<i8>
200    + From<bool>
201    + Product<Self>
202{
203    type BasePrimeField: PrimeField;
204
205    /// Determines the algorithm for computing square roots.
206    const SQRT_PRECOMP: Option<SqrtPrecomputation<Self>>;
207
208    /// The multiplicative identity of the field.
209    const ONE: Self;
210
211    /// Negation of the multiplicative identity of the field.
212    const NEG_ONE: Self;
213
214    /// Returns the characteristic of the field,
215    /// in little-endian representation.
216    fn characteristic() -> &'static [u64] {
217        Self::BasePrimeField::characteristic()
218    }
219
220    /// Returns the extension degree of this field with respect
221    /// to `Self::BasePrimeField`.
222    fn extension_degree() -> u64;
223
224    fn to_base_prime_field_elements(&self) -> impl Iterator<Item = Self::BasePrimeField>;
225
226    /// Convert a slice of base prime field elements into a field element.
227    /// If the slice length != Self::extension_degree(), must return None.
228    fn from_base_prime_field_elems(
229        elems: impl IntoIterator<Item = Self::BasePrimeField>,
230    ) -> Option<Self>;
231
232    /// Constructs a field element from a single base prime field elements.
233    /// ```
234    /// # use ark_ff::Field;
235    /// # use ark_test_curves::bls12_381::Fq as F;
236    /// # use ark_test_curves::bls12_381::Fq2 as F2;
237    /// # use ark_std::One;
238    /// assert_eq!(F2::from_base_prime_field(F::one()), F2::one());
239    /// ```
240    fn from_base_prime_field(elem: Self::BasePrimeField) -> Self;
241
242    /// Attempt to deserialize a field element. Returns `None` if the
243    /// deserialization fails.
244    ///
245    /// This function is primarily intended for sampling random field elements
246    /// from a hash-function or RNG output.
247    fn from_random_bytes(bytes: &[u8]) -> Option<Self> {
248        Self::from_random_bytes_with_flags::<EmptyFlags>(bytes).map(|f| f.0)
249    }
250
251    /// Attempt to deserialize a field element, splitting the bitflags metadata
252    /// according to `F` specification. Returns `None` if the deserialization
253    /// fails.
254    ///
255    /// This function is primarily intended for sampling random field elements
256    /// from a hash-function or RNG output.
257    fn from_random_bytes_with_flags<F: Flags>(bytes: &[u8]) -> Option<(Self, F)>;
258
259    /// Returns a `LegendreSymbol`, which indicates whether this field element
260    /// is  1 : a quadratic residue
261    ///  0 : equal to 0
262    /// -1 : a quadratic non-residue
263    fn legendre(&self) -> LegendreSymbol;
264
265    /// Returns the square root of self, if it exists.
266    #[must_use]
267    fn sqrt(&self) -> Option<Self> {
268        match Self::SQRT_PRECOMP {
269            Some(tv) => tv.sqrt(self),
270            None => unimplemented!(),
271        }
272    }
273
274    /// Sets `self` to be the square root of `self`, if it exists.
275    fn sqrt_in_place(&mut self) -> Option<&mut Self> {
276        (*self).sqrt().map(|sqrt| {
277            *self = sqrt;
278            self
279        })
280    }
281
282    /// Returns `self * self`.
283    #[must_use]
284    fn square(&self) -> Self;
285
286    /// Squares `self` in place.
287    fn square_in_place(&mut self) -> &mut Self;
288
289    /// Computes the multiplicative inverse of `self` if `self` is nonzero.
290    #[must_use]
291    fn inverse(&self) -> Option<Self>;
292
293    /// If `self.inverse().is_none()`, this just returns `None`. Otherwise, it sets
294    /// `self` to `self.inverse().unwrap()`.
295    fn inverse_in_place(&mut self) -> Option<&mut Self>;
296
297    /// Returns `sum([a_i * b_i])`.
298    #[inline]
299    fn sum_of_products<const T: usize>(a: &[Self; T], b: &[Self; T]) -> Self {
300        let mut sum = Self::zero();
301        for i in 0..a.len() {
302            sum += a[i] * b[i];
303        }
304        sum
305    }
306
307    /// Sets `self` to `self^s`, where `s = Self::BasePrimeField::MODULUS^power`.
308    /// This is also called the Frobenius automorphism.
309    fn frobenius_map_in_place(&mut self, power: usize);
310
311    /// Returns `self^s`, where `s = Self::BasePrimeField::MODULUS^power`.
312    /// This is also called the Frobenius automorphism.
313    #[must_use]
314    fn frobenius_map(&self, power: usize) -> Self {
315        let mut this = *self;
316        this.frobenius_map_in_place(power);
317        this
318    }
319
320    /// Returns `self^exp`, where `exp` is an integer represented with `u64` limbs,
321    /// least significant limb first.
322    #[must_use]
323    fn pow<S: AsRef<[u64]>>(&self, exp: S) -> Self {
324        let mut res = Self::one();
325
326        for i in crate::BitIteratorBE::without_leading_zeros(exp) {
327            res.square_in_place();
328
329            if i {
330                res *= self;
331            }
332        }
333        res
334    }
335
336    /// Exponentiates a field element `f` by a number represented with `u64`
337    /// limbs, using a precomputed table containing as many powers of 2 of
338    /// `f` as the 1 + the floor of log2 of the exponent `exp`, starting
339    /// from the 1st power. That is, `powers_of_2` should equal `&[p, p^2,
340    /// p^4, ..., p^(2^n)]` when `exp` has at most `n` bits.
341    ///
342    /// This returns `None` when a power is missing from the table.
343    #[inline]
344    fn pow_with_table<S: AsRef<[u64]>>(powers_of_2: &[Self], exp: S) -> Option<Self> {
345        let mut res = Self::one();
346        for (pow, bit) in crate::BitIteratorLE::without_trailing_zeros(exp).enumerate() {
347            if bit {
348                res *= powers_of_2.get(pow)?;
349            }
350        }
351        Some(res)
352    }
353
354    fn mul_by_base_prime_field(&self, elem: &Self::BasePrimeField) -> Self;
355}
356
357// Given a vector of field elements {v_i}, compute the vector {v_i^(-1)}
358pub fn batch_inversion<F: Field>(v: &mut [F]) {
359    batch_inversion_and_mul(v, &F::one());
360}
361
362#[cfg(not(feature = "parallel"))]
363// Given a vector of field elements {v_i}, compute the vector {coeff * v_i^(-1)}
364pub fn batch_inversion_and_mul<F: Field>(v: &mut [F], coeff: &F) {
365    serial_batch_inversion_and_mul(v, coeff);
366}
367
368#[cfg(feature = "parallel")]
369// Given a vector of field elements {v_i}, compute the vector {coeff * v_i^(-1)}
370pub fn batch_inversion_and_mul<F: Field>(v: &mut [F], coeff: &F) {
371    // Divide the vector v evenly between all available cores
372    let min_elements_per_thread = 1;
373    let num_cpus_available = rayon::current_num_threads();
374    let num_elems = v.len();
375    let num_elem_per_thread = max(num_elems / num_cpus_available, min_elements_per_thread);
376
377    // Batch invert in parallel, without copying the vector
378    v.par_chunks_mut(num_elem_per_thread).for_each(|chunk| {
379        serial_batch_inversion_and_mul(chunk, coeff);
380    });
381}
382
383/// Given a vector of field elements {v_i}, compute the vector {coeff * v_i^(-1)}.
384/// This method is explicitly single-threaded.
385pub fn serial_batch_inversion_and_mul<F: Field>(v: &mut [F], coeff: &F) {
386    // Montgomery’s Trick and Fast Implementation of Masked AES
387    // Genelle, Prouff and Quisquater
388    // Section 3.2
389    // but with an optimization to multiply every element in the returned vector by
390    // coeff
391
392    // First pass: compute [a, ab, abc, ...]
393    let mut prod = Vec::with_capacity(v.len());
394    let mut tmp = F::one();
395    for f in v.iter().filter(|f| !f.is_zero()) {
396        tmp *= f;
397        prod.push(tmp);
398    }
399
400    // Invert `tmp`.
401    tmp = tmp.inverse().unwrap(); // Guaranteed to be nonzero.
402
403    // Multiply product by coeff, so all inverses will be scaled by coeff
404    tmp *= coeff;
405
406    // Second pass: iterate backwards to compute inverses
407    for (f, s) in v.iter_mut()
408        // Backwards
409        .rev()
410        // Ignore normalized elements
411        .filter(|f| !f.is_zero())
412        // Backwards, skip last element, fill in one for last term.
413        .zip(prod.into_iter().rev().skip(1).chain(Some(F::one())))
414    {
415        // tmp := tmp * f; f := tmp * s = 1/f
416        let new_tmp = tmp * *f;
417        *f = tmp * &s;
418        tmp = new_tmp;
419    }
420}
421
422#[cfg(all(test, feature = "std"))]
423mod std_tests {
424    use crate::BitIteratorLE;
425
426    #[test]
427    fn bit_iterator_le() {
428        let bits = BitIteratorLE::new(&[0, 1 << 10]).collect::<Vec<_>>();
429        dbg!(&bits);
430        assert!(bits[74]);
431        for (i, bit) in bits.into_iter().enumerate() {
432            if i != 74 {
433                assert!(!bit)
434            } else {
435                assert!(bit)
436            }
437        }
438    }
439}
440
441#[cfg(test)]
442mod no_std_tests {
443    use super::*;
444    use ark_std::{str::FromStr, test_rng};
445    use num_bigint::*;
446
447    // TODO: only Fr & FrConfig should need to be imported.
448    // The rest of imports are caused by cargo not resolving the deps properly
449    // from this crate and from ark_test_curves
450    use ark_test_curves::{
451        ark_ff::{batch_inversion, batch_inversion_and_mul, PrimeField},
452        bls12_381::Fr,
453    };
454
455    #[test]
456    fn test_batch_inversion() {
457        let mut random_coeffs = Vec::new();
458        let vec_size = 1000;
459
460        for _ in 0..=vec_size {
461            random_coeffs.push(Fr::rand(&mut test_rng()));
462        }
463
464        let mut random_coeffs_inv = random_coeffs.clone();
465        batch_inversion(&mut random_coeffs_inv);
466        for i in 0..=vec_size {
467            assert_eq!(random_coeffs_inv[i] * random_coeffs[i], Fr::one());
468        }
469        let rand_multiplier = Fr::rand(&mut test_rng());
470        let mut random_coeffs_inv_shifted = random_coeffs.clone();
471        batch_inversion_and_mul(&mut random_coeffs_inv_shifted, &rand_multiplier);
472        for i in 0..=vec_size {
473            assert_eq!(
474                random_coeffs_inv_shifted[i] * random_coeffs[i],
475                rand_multiplier
476            );
477        }
478    }
479
480    #[test]
481    pub fn test_from_ints() {
482        let felt2 = Fr::one() + Fr::one();
483        let felt16 = felt2 * felt2 * felt2 * felt2;
484
485        assert_eq!(Fr::from(1u8), Fr::one());
486        assert_eq!(Fr::from(1u16), Fr::one());
487        assert_eq!(Fr::from(1u32), Fr::one());
488        assert_eq!(Fr::from(1u64), Fr::one());
489        assert_eq!(Fr::from(1u128), Fr::one());
490        assert_eq!(Fr::from(-1i8), -Fr::one());
491        assert_eq!(Fr::from(-1i64), -Fr::one());
492
493        assert_eq!(Fr::from(0), Fr::zero());
494
495        assert_eq!(Fr::from(-16i32), -felt16);
496        assert_eq!(Fr::from(16u32), felt16);
497        assert_eq!(Fr::from(16i64), felt16);
498
499        assert_eq!(Fr::from(-2i128), -felt2);
500        assert_eq!(Fr::from(2u16), felt2);
501    }
502
503    #[test]
504    fn test_from_into_biguint() {
505        let mut rng = ark_std::test_rng();
506
507        let modulus_bits = Fr::MODULUS_BIT_SIZE;
508        let modulus: num_bigint::BigUint = Fr::MODULUS.into();
509
510        let mut rand_bytes = Vec::new();
511        for _ in 0..(2 * modulus_bits / 8) {
512            rand_bytes.push(u8::rand(&mut rng));
513        }
514
515        let rand = BigUint::from_bytes_le(&rand_bytes);
516
517        let a: BigUint = Fr::from(rand.clone()).into();
518        let b = rand % modulus;
519
520        assert_eq!(a, b);
521    }
522
523    #[test]
524    fn test_from_be_bytes_mod_order() {
525        use ark_std::vec;
526        // Each test vector is a byte array,
527        // and its tested by parsing it with from_bytes_mod_order, and the num-bigint
528        // library. The bytes are currently generated from scripts/test_vectors.py.
529        // TODO: Eventually generate all the test vector bytes via computation with the
530        // modulus
531        use ark_std::{rand::Rng, string::ToString};
532        use ark_test_curves::ark_ff::BigInteger;
533        use num_bigint::BigUint;
534
535        let ref_modulus = BigUint::from_bytes_be(&Fr::MODULUS.to_bytes_be());
536
537        let mut test_vectors = vec![
538            // 0
539            vec![0u8],
540            // 1
541            vec![1u8],
542            // 255
543            vec![255u8],
544            // 256
545            vec![1u8, 0u8],
546            // 65791
547            vec![1u8, 0u8, 255u8],
548            // 204827637402836681560342736360101429053478720705186085244545541796635082752
549            vec![
550                115u8, 237u8, 167u8, 83u8, 41u8, 157u8, 125u8, 72u8, 51u8, 57u8, 216u8, 8u8, 9u8,
551                161u8, 216u8, 5u8, 83u8, 189u8, 164u8, 2u8, 255u8, 254u8, 91u8, 254u8, 255u8,
552                255u8, 255u8, 255u8, 0u8, 0u8, 0u8,
553            ],
554            // 204827637402836681560342736360101429053478720705186085244545541796635082753
555            vec![
556                115u8, 237u8, 167u8, 83u8, 41u8, 157u8, 125u8, 72u8, 51u8, 57u8, 216u8, 8u8, 9u8,
557                161u8, 216u8, 5u8, 83u8, 189u8, 164u8, 2u8, 255u8, 254u8, 91u8, 254u8, 255u8,
558                255u8, 255u8, 255u8, 0u8, 0u8, 1u8,
559            ],
560            // 52435875175126190479447740508185965837690552500527637822603658699938581184512
561            vec![
562                115u8, 237u8, 167u8, 83u8, 41u8, 157u8, 125u8, 72u8, 51u8, 57u8, 216u8, 8u8, 9u8,
563                161u8, 216u8, 5u8, 83u8, 189u8, 164u8, 2u8, 255u8, 254u8, 91u8, 254u8, 255u8,
564                255u8, 255u8, 255u8, 0u8, 0u8, 0u8, 0u8,
565            ],
566            // 52435875175126190479447740508185965837690552500527637822603658699938581184513
567            vec![
568                115u8, 237u8, 167u8, 83u8, 41u8, 157u8, 125u8, 72u8, 51u8, 57u8, 216u8, 8u8, 9u8,
569                161u8, 216u8, 5u8, 83u8, 189u8, 164u8, 2u8, 255u8, 254u8, 91u8, 254u8, 255u8,
570                255u8, 255u8, 255u8, 0u8, 0u8, 0u8, 1u8,
571            ],
572            // 52435875175126190479447740508185965837690552500527637822603658699938581184514
573            vec![
574                115u8, 237u8, 167u8, 83u8, 41u8, 157u8, 125u8, 72u8, 51u8, 57u8, 216u8, 8u8, 9u8,
575                161u8, 216u8, 5u8, 83u8, 189u8, 164u8, 2u8, 255u8, 254u8, 91u8, 254u8, 255u8,
576                255u8, 255u8, 255u8, 0u8, 0u8, 0u8, 2u8,
577            ],
578            // 104871750350252380958895481016371931675381105001055275645207317399877162369026
579            vec![
580                231u8, 219u8, 78u8, 166u8, 83u8, 58u8, 250u8, 144u8, 102u8, 115u8, 176u8, 16u8,
581                19u8, 67u8, 176u8, 10u8, 167u8, 123u8, 72u8, 5u8, 255u8, 252u8, 183u8, 253u8,
582                255u8, 255u8, 255u8, 254u8, 0u8, 0u8, 0u8, 2u8,
583            ],
584            // 13423584044832304762738621570095607254448781440135075282586536627184276783235328
585            vec![
586                115u8, 237u8, 167u8, 83u8, 41u8, 157u8, 125u8, 72u8, 51u8, 57u8, 216u8, 8u8, 9u8,
587                161u8, 216u8, 5u8, 83u8, 189u8, 164u8, 2u8, 255u8, 254u8, 91u8, 254u8, 255u8,
588                255u8, 255u8, 255u8, 0u8, 0u8, 0u8, 1u8, 0u8,
589            ],
590            // 115792089237316195423570985008687907853269984665640564039457584007913129639953
591            vec![
592                1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
593                0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8,
594                17u8,
595            ],
596            // 168227964412442385903018725516873873690960537166168201862061242707851710824468
597            vec![
598                1u8, 115u8, 237u8, 167u8, 83u8, 41u8, 157u8, 125u8, 72u8, 51u8, 57u8, 216u8, 8u8,
599                9u8, 161u8, 216u8, 5u8, 83u8, 189u8, 164u8, 2u8, 255u8, 254u8, 91u8, 254u8, 255u8,
600                255u8, 255u8, 255u8, 0u8, 0u8, 0u8, 20u8,
601            ],
602            // 29695210719928072218913619902732290376274806626904512031923745164725699769008210
603            vec![
604                1u8, 0u8, 115u8, 237u8, 167u8, 83u8, 41u8, 157u8, 125u8, 72u8, 51u8, 57u8, 216u8,
605                8u8, 9u8, 161u8, 216u8, 5u8, 83u8, 189u8, 164u8, 2u8, 255u8, 254u8, 91u8, 254u8,
606                255u8, 255u8, 255u8, 255u8, 0u8, 0u8, 0u8, 82u8,
607            ],
608        ];
609        // Add random bytestrings to the test vector list
610        for i in 1..512 {
611            let mut rng = test_rng();
612            let data: Vec<u8> = (0..i).map(|_| rng.gen()).collect();
613            test_vectors.push(data);
614        }
615        for i in test_vectors {
616            let mut expected_biguint = BigUint::from_bytes_be(&i);
617            // Reduce expected_biguint using modpow API
618            expected_biguint =
619                expected_biguint.modpow(&BigUint::from_bytes_be(&[1u8]), &ref_modulus);
620            let expected_string = expected_biguint.to_string();
621            let expected = Fr::from_str(&expected_string).unwrap();
622            let actual = Fr::from_be_bytes_mod_order(&i);
623            assert_eq!(expected, actual, "failed on test {:?}", i);
624        }
625    }
626}