1#[cfg(feature = "alloc")]
2mod alloc_impls;
3#[cfg(feature = "arbitrary")]
4mod arbitrary;
5#[cfg(test)]
6mod felt_arbitrary;
7mod non_zero;
8#[cfg(feature = "num-traits")]
9mod num_traits_impl;
10#[cfg(feature = "papyrus-serialization")]
11mod papyrus_serialization;
12#[cfg(feature = "parity-scale-codec")]
13mod parity_scale_codec;
14#[cfg(feature = "prime-bigint")]
15mod prime_bigint;
16mod primitive_conversions;
17#[cfg(feature = "serde")]
18mod serde;
19#[cfg(feature = "zeroize")]
20mod zeroize;
21
22use lambdaworks_math::errors::CreationError;
23pub use non_zero::{FeltIsZeroError, NonZeroFelt};
24
25#[cfg(feature = "prime-bigint")]
26pub use prime_bigint::CAIRO_PRIME_BIGINT;
27
28use core::ops::{Add, Mul, Neg};
29use core::str::FromStr;
30
31use num_bigint::{BigInt, BigUint, Sign};
32use num_integer::Integer;
33use num_traits::{One, Zero};
34pub use primitive_conversions::PrimitiveFromFeltError;
35
36#[cfg(feature = "alloc")]
37pub extern crate alloc;
38
39use lambdaworks_math::{
40 field::{
41 element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField,
42 },
43 traits::ByteConversion,
44 unsigned_integer::element::UnsignedInteger,
45};
46
47#[repr(transparent)]
49#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
50pub struct Felt(pub(crate) FieldElement<Stark252PrimeField>);
51
52#[derive(Debug)]
53pub struct FromStrError(CreationError);
54
55#[cfg(feature = "std")]
56impl std::error::Error for FromStrError {}
57
58impl core::fmt::Display for FromStrError {
59 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
60 write!(f, "failed to create Felt from string: ")?;
61 match self.0 {
62 CreationError::InvalidHexString => write!(f, "invalid hex string"),
63 CreationError::InvalidDecString => write!(f, "invalid dec string"),
64 CreationError::HexStringIsTooBig => write!(f, "hex string too big"),
65 CreationError::EmptyString => write!(f, "empty string"),
66 }
67 }
68}
69
70impl Felt {
71 pub const ZERO: Self = Self(FieldElement::<Stark252PrimeField>::from_hex_unchecked("0"));
73
74 pub const ONE: Self = Self(FieldElement::<Stark252PrimeField>::from_hex_unchecked("1"));
76
77 pub const TWO: Self = Self(FieldElement::<Stark252PrimeField>::from_hex_unchecked("2"));
79
80 pub const THREE: Self = Self(FieldElement::<Stark252PrimeField>::from_hex_unchecked("3"));
82
83 pub const MAX: Self = Self(FieldElement::<Stark252PrimeField>::const_from_raw(
85 UnsignedInteger::from_limbs([544, 0, 0, 32]),
86 ));
87
88 pub const ELEMENT_UPPER_BOUND: Felt = Felt::from_raw([
90 576459263475450960,
91 18446744073709255680,
92 160989183,
93 18446743986131435553,
94 ]);
95
96 pub const fn from_raw(val: [u64; 4]) -> Self {
99 Self(FieldElement::<Stark252PrimeField>::const_from_raw(
100 UnsignedInteger::from_limbs(val),
101 ))
102 }
103
104 pub const fn from_hex_unchecked(val: &str) -> Self {
105 Self(FieldElement::<Stark252PrimeField>::from_hex_unchecked(val))
106 }
107
108 pub fn from_bytes_be(bytes: &[u8; 32]) -> Self {
111 FieldElement::from_bytes_be(bytes)
112 .map(Self)
113 .expect("from_bytes_be shouldn't fail for these many bytes")
114 }
115
116 pub fn from_bytes_le(bytes: &[u8; 32]) -> Self {
119 FieldElement::from_bytes_le(bytes)
120 .map(Self)
121 .expect("from_bytes_le shouldn't fail for these many bytes")
122 }
123
124 pub fn from_bytes_be_slice(bytes: &[u8]) -> Self {
129 const BASE: Felt = Felt(FieldElement::<Stark252PrimeField>::const_from_raw(
134 UnsignedInteger::from_limbs([
135 576413109808302096,
136 18446744073700081664,
137 5151653887,
138 18446741271209837569,
139 ]),
140 ));
141 debug_assert_eq!(BASE, Felt::TWO.pow(256u32));
143
144 let mut factor = Self::ONE;
145 let mut res = Self::ZERO;
146 let chunks = bytes.rchunks_exact(32);
147 let remainder = chunks.remainder();
148
149 for chunk in chunks {
150 let digit =
151 Self::from_bytes_be(&chunk.try_into().expect("conversion to same-sized array"));
152 res += digit * factor;
153 factor *= BASE;
154 }
155
156 if remainder.is_empty() {
157 return res;
158 }
159
160 let mut remainder = remainder.iter().rev().cloned();
161 let buf: [u8; 32] = core::array::from_fn(move |_| remainder.next().unwrap_or_default());
162 let digit = Self::from_bytes_le(&buf);
163 res += digit * factor;
164
165 res
166 }
167
168 pub fn from_bytes_le_slice(bytes: &[u8]) -> Self {
173 const BASE: Felt = Felt(FieldElement::<Stark252PrimeField>::const_from_raw(
178 UnsignedInteger::from_limbs([
179 576413109808302096,
180 18446744073700081664,
181 5151653887,
182 18446741271209837569,
183 ]),
184 ));
185 debug_assert_eq!(BASE, Felt::TWO.pow(256u32));
187
188 let mut factor = Self::ONE;
189 let mut res = Self::ZERO;
190 let chunks = bytes.chunks_exact(32);
191 let remainder = chunks.remainder();
192
193 for chunk in chunks {
194 let digit =
195 Self::from_bytes_le(&chunk.try_into().expect("conversion to same-sized array"));
196 res += digit * factor;
197 factor *= BASE;
198 }
199
200 if remainder.is_empty() {
201 return res;
202 }
203
204 let mut remainder = remainder.iter().cloned();
205 let buf: [u8; 32] = core::array::from_fn(move |_| remainder.next().unwrap_or_default());
206 let digit = Self::from_bytes_le(&buf);
207 res += digit * factor;
208
209 res
210 }
211
212 pub fn to_bytes_be(&self) -> [u8; 32] {
215 self.0.to_bytes_be()
216 }
217
218 pub fn to_bytes_le(&self) -> [u8; 32] {
221 self.0.to_bytes_le()
222 }
223
224 pub fn to_bits_le(&self) -> [bool; 256] {
226 self.0.to_bits_le()
227 }
228
229 pub fn to_bits_be(&self) -> [bool; 256] {
231 let mut bits = self.0.to_bits_le();
232 bits.reverse();
233 bits
234 }
235
236 pub fn field_div(&self, rhs: &NonZeroFelt) -> Self {
238 Self(self.0 / rhs.0)
239 }
240
241 pub fn floor_div(&self, rhs: &NonZeroFelt) -> Self {
243 Self(FieldElement::from(
244 &(self.0.representative().div_rem(&rhs.0.representative())).0,
245 ))
246 }
247
248 pub fn div_rem(&self, rhs: &NonZeroFelt) -> (Self, Self) {
250 let (q, r) = self.0.representative().div_rem(&rhs.0.representative());
251 (Self(FieldElement::from(&q)), Self(FieldElement::from(&r)))
252 }
253
254 pub fn inverse(&self) -> Option<Self> {
256 self.0.inv().map(Self).ok()
257 }
258
259 pub fn sqrt(&self) -> Option<Self> {
261 let (root_1, root_2) = self.0.sqrt()?;
262 Some(Self(core::cmp::min(root_1, root_2)))
263 }
264
265 pub fn square(&self) -> Self {
267 Self(self.0.square())
268 }
269
270 pub fn double(&self) -> Self {
272 Self(self.0.double())
273 }
274
275 pub fn pow(&self, exponent: impl Into<u128>) -> Self {
277 Self(self.0.pow(exponent.into()))
278 }
279
280 pub fn pow_felt(&self, exponent: &Felt) -> Self {
282 Self(self.0.pow(exponent.0.representative()))
283 }
284
285 pub fn mul_mod(&self, rhs: &Self, p: &NonZeroFelt) -> Self {
289 let multiplicand = BigInt::from_bytes_be(num_bigint::Sign::Plus, &self.to_bytes_be());
290 let multiplier = BigInt::from_bytes_be(num_bigint::Sign::Plus, &rhs.to_bytes_be());
291 let modulus = BigInt::from_bytes_be(num_bigint::Sign::Plus, &p.0.to_bytes_be());
292
293 let result = multiplicand.mul(multiplier).mod_floor(&modulus);
294
295 let (_, buffer) = result.to_bytes_be();
296 let mut result = [0u8; 32];
297
298 result[(32 - buffer.len())..].copy_from_slice(&buffer[..]);
299
300 Felt::from_bytes_be(&result)
301 }
302
303 pub fn mod_inverse(&self, p: &NonZeroFelt) -> Option<Self> {
307 let operand = BigInt::from_bytes_be(num_bigint::Sign::Plus, &self.0.to_bytes_be());
308 let modulus = BigInt::from_bytes_be(num_bigint::Sign::Plus, &p.0.to_bytes_be());
309
310 let extended_gcd = operand.extended_gcd(&modulus);
311 if extended_gcd.gcd != BigInt::one() {
312 return None;
313 }
314 let result = if extended_gcd.x < BigInt::zero() {
315 extended_gcd.x + modulus
316 } else {
317 extended_gcd.x
318 };
319
320 let (_, buffer) = result.to_bytes_be();
321 let mut result = [0u8; 32];
322 result[(32 - buffer.len())..].copy_from_slice(&buffer[..]);
323
324 Some(Felt::from_bytes_be(&result))
325 }
326
327 pub fn mod_floor(&self, n: &NonZeroFelt) -> Self {
329 self.div_rem(n).1
330 }
331
332 pub fn from_hex(hex_string: &str) -> Result<Self, FromStrError> {
334 FieldElement::from_hex(hex_string)
335 .map(Self)
336 .map_err(FromStrError)
337 }
338
339 pub fn from_dec_str(dec_string: &str) -> Result<Self, FromStrError> {
341 if dec_string.starts_with('-') {
342 UnsignedInteger::from_dec_str(dec_string.strip_prefix('-').unwrap())
343 .map(|x| Self(FieldElement::from(&x)).neg())
344 .map_err(FromStrError)
345 } else {
346 UnsignedInteger::from_dec_str(dec_string)
347 .map(|x| Self(FieldElement::from(&x)))
348 .map_err(FromStrError)
349 }
350 }
351
352 pub fn to_raw_reversed(&self) -> [u64; 4] {
355 let mut res = self.0.to_raw().limbs;
356 res.reverse();
357 res
358 }
359
360 pub fn to_raw(&self) -> [u64; 4] {
362 self.0.to_raw().limbs
363 }
364 pub fn to_le_digits(&self) -> [u64; 4] {
367 let mut limbs = self.0.representative().limbs;
368 limbs.reverse();
369 limbs
370 }
371
372 pub fn to_be_digits(&self) -> [u64; 4] {
375 self.0.representative().limbs
376 }
377
378 pub fn bits(&self) -> usize {
380 self.0.representative().bits_le()
381 }
382
383 pub fn to_biguint(&self) -> BigUint {
384 let big_digits = self
385 .to_le_digits()
386 .into_iter()
387 .flat_map(|limb| [limb as u32, (limb >> 32) as u32])
388 .collect();
389 BigUint::new(big_digits)
390 }
391
392 pub fn to_bigint(&self) -> BigInt {
393 self.to_biguint().into()
394 }
395}
396
397impl Default for Felt {
399 fn default() -> Self {
400 Self(FieldElement::<Stark252PrimeField>::zero())
401 }
402}
403
404impl AsRef<Felt> for Felt {
405 fn as_ref(&self) -> &Felt {
406 self
407 }
408}
409
410impl From<&BigInt> for Felt {
411 fn from(bigint: &BigInt) -> Felt {
412 let (sign, bytes) = bigint.to_bytes_le();
413 let felt = Felt::from_bytes_le_slice(&bytes);
414 if sign == Sign::Minus {
415 felt.neg()
416 } else {
417 felt
418 }
419 }
420}
421
422impl From<BigInt> for Felt {
423 fn from(bigint: BigInt) -> Felt {
424 Self::from(&bigint)
425 }
426}
427
428impl From<&BigUint> for Felt {
429 fn from(biguint: &BigUint) -> Felt {
430 Felt::from_bytes_le_slice(&biguint.to_bytes_le())
431 }
432}
433
434impl From<BigUint> for Felt {
435 fn from(biguint: BigUint) -> Felt {
436 Self::from(&biguint)
437 }
438}
439
440impl FromStr for Felt {
441 type Err = FromStrError;
442
443 fn from_str(s: &str) -> Result<Self, Self::Err> {
446 if s.starts_with("0x") {
447 Felt::from_hex(s)
448 } else {
449 Felt::from_dec_str(s)
450 }
451 }
452}
453
454impl Add<&Felt> for u64 {
455 type Output = Option<u64>;
456
457 fn add(self, rhs: &Felt) -> Option<u64> {
458 const PRIME_DIGITS_BE_HI: [u64; 3] =
459 [0x0800000000000011, 0x0000000000000000, 0x0000000000000000];
460 const PRIME_MINUS_U64_MAX_DIGITS_BE_HI: [u64; 3] =
461 [0x0800000000000010, 0xffffffffffffffff, 0xffffffffffffffff];
462
463 match rhs.to_be_digits() {
466 [0, 0, 0, 0] => Some(self),
468 [0, 0, 0, low] => self.checked_add(low),
470 [hi @ .., _] if hi == PRIME_DIGITS_BE_HI => self.checked_sub(1),
477
478 [hi @ .., low] if hi == PRIME_MINUS_U64_MAX_DIGITS_BE_HI && low >= 2 => {
489 (self).checked_sub(u64::MAX - (low - 2))
490 }
491 _ => None,
494 }
495 }
496}
497
498mod arithmetic {
499 use core::{
500 iter,
501 ops::{self, Neg},
502 };
503
504 use super::*;
505
506 impl ops::AddAssign<Felt> for Felt {
508 fn add_assign(&mut self, rhs: Felt) {
509 self.0 += rhs.0
510 }
511 }
512
513 impl ops::AddAssign<&Felt> for Felt {
515 fn add_assign(&mut self, rhs: &Felt) {
516 self.0 += rhs.0
517 }
518 }
519
520 impl ops::Add<Felt> for Felt {
522 type Output = Felt;
523
524 fn add(self, rhs: Felt) -> Self::Output {
525 Self(self.0 + rhs.0)
526 }
527 }
528
529 impl ops::Add<&Felt> for Felt {
531 type Output = Felt;
532
533 fn add(self, rhs: &Felt) -> Self::Output {
534 Self(self.0 + rhs.0)
535 }
536 }
537
538 impl ops::Add<Felt> for &Felt {
540 type Output = Felt;
541
542 fn add(self, rhs: Felt) -> Self::Output {
543 Felt(self.0 + rhs.0)
544 }
545 }
546
547 impl ops::Add<&Felt> for &Felt {
549 type Output = Felt;
550
551 fn add(self, rhs: &Felt) -> Self::Output {
552 Felt(self.0 + rhs.0)
553 }
554 }
555
556 impl ops::Add<u64> for Felt {
558 type Output = Felt;
559
560 fn add(self, rhs: u64) -> Self::Output {
561 self + Felt::from(rhs)
562 }
563 }
564
565 impl ops::Add<u64> for &Felt {
567 type Output = Felt;
568
569 fn add(self, rhs: u64) -> Self::Output {
570 self + Felt::from(rhs)
571 }
572 }
573
574 impl ops::SubAssign<Felt> for Felt {
576 fn sub_assign(&mut self, rhs: Felt) {
577 self.0 = self.0 - rhs.0
578 }
579 }
580
581 impl ops::SubAssign<&Felt> for Felt {
583 fn sub_assign(&mut self, rhs: &Felt) {
584 self.0 = self.0 - rhs.0
585 }
586 }
587
588 impl ops::Sub<Felt> for Felt {
590 type Output = Felt;
591
592 fn sub(self, rhs: Felt) -> Self::Output {
593 Self(self.0 - rhs.0)
594 }
595 }
596
597 impl ops::Sub<&Felt> for Felt {
599 type Output = Felt;
600
601 fn sub(self, rhs: &Felt) -> Self::Output {
602 Self(self.0 - rhs.0)
603 }
604 }
605
606 impl ops::Sub<Felt> for &Felt {
608 type Output = Felt;
609
610 fn sub(self, rhs: Felt) -> Self::Output {
611 Felt(self.0 - rhs.0)
612 }
613 }
614
615 impl ops::Sub<&Felt> for &Felt {
617 type Output = Felt;
618
619 fn sub(self, rhs: &Felt) -> Self::Output {
620 Felt(self.0 - rhs.0)
621 }
622 }
623
624 #[allow(clippy::suspicious_arithmetic_impl)]
626 impl ops::Sub<Felt> for u64 {
627 type Output = Option<u64>;
628 fn sub(self, rhs: Felt) -> Self::Output {
629 self + &rhs.neg()
630 }
631 }
632
633 #[allow(clippy::suspicious_arithmetic_impl)]
635 impl ops::Sub<&Felt> for u64 {
636 type Output = Option<u64>;
637 fn sub(self, rhs: &Felt) -> Self::Output {
638 self + &rhs.neg()
639 }
640 }
641
642 impl ops::Sub<u64> for Felt {
644 type Output = Felt;
645 fn sub(self, rhs: u64) -> Self::Output {
646 self - Self::from(rhs)
647 }
648 }
649
650 impl ops::Sub<u64> for &Felt {
652 type Output = Felt;
653 fn sub(self, rhs: u64) -> Self::Output {
654 self - Felt::from(rhs)
655 }
656 }
657
658 impl ops::MulAssign<Felt> for Felt {
660 fn mul_assign(&mut self, rhs: Felt) {
661 self.0 = self.0 * rhs.0
662 }
663 }
664
665 impl ops::MulAssign<&Felt> for Felt {
667 fn mul_assign(&mut self, rhs: &Felt) {
668 self.0 = self.0 * rhs.0
669 }
670 }
671
672 impl ops::Mul<Felt> for Felt {
674 type Output = Felt;
675
676 fn mul(self, rhs: Felt) -> Self::Output {
677 Self(self.0 * rhs.0)
678 }
679 }
680
681 impl ops::Mul<&Felt> for Felt {
683 type Output = Felt;
684
685 fn mul(self, rhs: &Felt) -> Self::Output {
686 Self(self.0 * rhs.0)
687 }
688 }
689
690 impl ops::Mul<Felt> for &Felt {
692 type Output = Felt;
693
694 fn mul(self, rhs: Felt) -> Self::Output {
695 Felt(self.0 * rhs.0)
696 }
697 }
698
699 impl ops::Mul<&Felt> for &Felt {
701 type Output = Felt;
702
703 fn mul(self, rhs: &Felt) -> Self::Output {
704 Felt(self.0 * rhs.0)
705 }
706 }
707
708 impl ops::Neg for Felt {
712 type Output = Felt;
713
714 fn neg(self) -> Self::Output {
715 Self(self.0.neg())
716 }
717 }
718
719 impl ops::Neg for &Felt {
720 type Output = Felt;
721
722 fn neg(self) -> Self::Output {
723 Felt(self.0.neg())
724 }
725 }
726
727 impl iter::Sum for Felt {
728 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
729 let mut base = Self::ZERO;
730 iter.for_each(|addend| base += addend);
731 base
732 }
733 }
734
735 impl<'a> iter::Sum<&'a Felt> for Felt {
736 fn sum<I: Iterator<Item = &'a Felt>>(iter: I) -> Self {
737 let mut base = Self::ZERO;
738 iter.for_each(|addend| base += addend);
739 base
740 }
741 }
742}
743
744mod formatting {
745
746 use core::fmt;
747
748 use super::*;
749
750 impl fmt::Display for Felt {
752 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
753 write!(f, "{}", self.to_biguint())
754 }
755 }
756
757 impl fmt::Debug for Felt {
758 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
759 write!(f, "{}", self.0)
760 }
761 }
762}
763
764#[cfg(test)]
765mod test {
766 use super::alloc::{format, string::String, vec::Vec};
767 use super::felt_arbitrary::nonzero_felt;
768 use super::*;
769 use core::ops::Shl;
770 use num_traits::Num;
771 use proptest::prelude::*;
772 use regex::Regex;
773
774 #[test]
775 fn test_debug_format() {
776 assert_eq!(format!("{:?}", Felt::ONE), "0x1");
777 assert_eq!(format!("{:?}", Felt::from(2)), "0x2");
778 assert_eq!(format!("{:?}", Felt::from(12345)), "0x3039");
779 }
780
781 fn generate_be_bits(x: &Felt) -> Vec<bool> {
783 let mut bits = Vec::new();
785
786 for limb in x.0.representative().limbs {
788 let bytes = limb.to_be_bytes();
790
791 for byte in &bytes {
793 for i in 0..8 {
795 let bit = (*byte >> (7 - i)) & 1;
797
798 bits.push(bit == 1);
800 }
801 }
802 }
803
804 bits
805 }
806
807 proptest! {
808 #[test]
809 fn new_in_range(ref x in any::<[u8; 32]>()) {
810 let x_be = Felt::from_bytes_be(x);
811 prop_assert!(x_be < Felt::MAX);
812 let x_le = Felt::from_bytes_le(x);
813 prop_assert!(x_le < Felt::MAX);
814 }
815
816 #[test]
817 fn to_be_bytes(ref x in any::<Felt>()) {
818 let bytes = x.to_bytes_be();
819 let y = &Felt::from_bytes_be(&bytes);
820 prop_assert_eq!(x, y);
821 }
822
823 #[test]
824 fn to_le_bytes(ref x in any::<Felt>()) {
825 let bytes = x.to_bytes_le();
826 let y = &Felt::from_bytes_le(&bytes);
827 prop_assert_eq!(x, y);
828 }
829
830 #[test]
831 fn to_bits_le(ref x in any::<Felt>()) {
832 let bits: Vec<bool> = x.to_bits_le().into_iter().collect();
834
835 let mut expected_bits = generate_be_bits(x);
837
838 expected_bits.reverse();
840
841 prop_assert_eq!(bits, expected_bits);
843 }
844
845 #[test]
846 fn to_bits_be(ref x in any::<Felt>()) {
847 let bits: Vec<bool> = x.to_bits_be().into_iter().collect();
849
850 let expected_bits = generate_be_bits(x);
852
853 prop_assert_eq!(bits, expected_bits);
855 }
856
857 #[test]
858 fn from_bytes_le_slice_works_for_all_lengths(x in 0..1000usize) {
859 let bytes: [u8; 1000] = core::array::from_fn(|i| i as u8);
860 let expected = bytes.iter()
861 .enumerate()
862 .map(|(i, x)| Felt::from(*x) * Felt::from(256).pow(i as u64))
863 .take(x)
864 .sum::<Felt>();
865 let x = Felt::from_bytes_le_slice(&bytes[0..x]);
866 prop_assert_eq!(x, expected, "x={:x} expected={:x}", x, expected);
867 }
868
869 #[test]
870 fn from_bytes_be_slice_works_for_all_lengths(x in 0..1000usize) {
871 let bytes: [u8; 1000] = core::array::from_fn(|i| i as u8);
872 let expected = bytes.iter()
873 .rev()
874 .enumerate()
875 .map(|(i, x)| Felt::from(*x) * Felt::from(256).pow(i as u64))
876 .take(x)
877 .sum::<Felt>();
878 let x = Felt::from_bytes_be_slice(&bytes[1000-x..1000]);
879 prop_assert_eq!(x, expected, "x={:x} expected={:x}", x, expected);
880 }
881
882 #[test]
883 fn from_bytes_le_in_range(ref x in any::<[u8; 32]>()) {
884 let x = Felt::from_bytes_le(x);
885 prop_assert!(x <= Felt::MAX);
886 }
887
888 #[test]
889 fn from_bytes_be_in_range(ref x in any::<[u8; 32]>()) {
890 let x = Felt::from_bytes_be(x);
891 prop_assert!(x <= Felt::MAX);
892 }
893
894 #[test]
895 fn neg_in_range(x in any::<Felt>()) {
896 prop_assert!(-x <= Felt::MAX);
897 }
898
899 #[test]
900 fn sub(ref x in any::<Felt>(), ref y in any::<Felt>()) {
901 prop_assert!(x - y <= Felt::MAX);
903 prop_assert_eq!(Felt::MAX + x - y + Felt::ONE, x - y);
904 prop_assert!(y - x <= Felt::MAX);
906 prop_assert_eq!(Felt::MAX + y - x + Felt::ONE, y - x);
907 }
908
909 #[test]
910 fn sub_assign_in_range(mut x in any::<Felt>(), y in any::<Felt>()) {
911 x -= y;
912 prop_assert!(x <= Felt::MAX);
913 x -= &y;
915 prop_assert!(x <= Felt::MAX);
916 }
917
918 #[test]
919 fn mul(ref x in any::<Felt>(), ref y in any::<Felt>()) {
920 prop_assert_eq!(x * y, y * x);
921 prop_assert!(x * y <= Felt::MAX);
922 }
923
924 #[test]
925 fn mul_assign_in_range(mut x in any::<Felt>(), y in any::<Felt>()) {
926 x *= y;
927 prop_assert!(x <= Felt::MAX);
928 x *= &y;
930 prop_assert!(x <= Felt::MAX);
931 }
932
933 #[test]
934 fn mod_floor_in_range(x in any::<Felt>(), n in nonzero_felt()) {
935 let nzn = NonZeroFelt(n.0);
936 let x_mod_n = x.mod_floor(&nzn);
937 prop_assert!(x_mod_n <= Felt::MAX);
938 prop_assert!(x_mod_n < n);
939 }
940
941 #[test]
942 fn field_div_is_mul_inv(x in any::<Felt>(), y in nonzero_felt()) {
943 let q = x.field_div(&NonZeroFelt(y.0));
944 prop_assert!(q <= Felt::MAX);
945 prop_assert_eq!(q * y, x);
946 }
947
948 #[test]
949 fn floor_div_is_mul_inv(x in any::<Felt>(), y in nonzero_felt()) {
950 let x = Felt(FieldElement::from(&x.0.representative().shl(127)));
951 let y = Felt(FieldElement::from(&y.0.representative().shl(127)));
952 let q = x.field_div(&NonZeroFelt(y.0));
953 prop_assert!(q <= Felt::MAX);
954 prop_assert_eq!(q * y, x);
955 }
956
957 #[test]
958 fn pow_in_range(base in any::<Felt>(), exp in 0..u128::MAX){
959 prop_assert!(base.pow(exp) <= Felt::MAX);
960 }
961
962 #[test]
963 fn add_in_range(x in any::<Felt>(), y in any::<Felt>()){
964 prop_assert!(x + y <= Felt::MAX);
965 }
966
967 #[test]
968 fn zero_additive_identity(x in any::<Felt>()) {
969 prop_assert_eq!(x, x + Felt::ZERO);
970 prop_assert_eq!(x, Felt::ZERO + x);
971 }
972
973 #[test]
974 fn one_multiplicative_identity(x in any::<Felt>()) {
975 prop_assert_eq!(x, x * Felt::ONE);
976 prop_assert_eq!(x, Felt::ONE * x);
977 }
978
979 #[test]
980 fn sqrt_in_range(x in any::<Felt>()) {
981 prop_assert!((x * x).sqrt().unwrap() <= Felt::MAX);
983 }
984
985 #[test]
986 fn sqrt_is_inv_square(x in any::<Felt>()) {
987 let sqrt = (x * x).sqrt().unwrap();
989 prop_assert!( sqrt == x || -sqrt == x)
990 }
991
992 #[test]
993 fn double_in_range(x in any::<Felt>()) {
994 prop_assert!(x.double() == x + x);
995 }
996
997 #[test]
998 fn square_in_range(x in any::<Felt>()) {
999 prop_assert!(x.square() <= Felt::MAX);
1000 }
1001
1002 #[test]
1003 fn square_x_is_x_mul_x(x in any::<Felt>()) {
1004 prop_assert_eq!(x.square(), x * x);
1005 }
1006
1007 #[test]
1008 fn square_is_inv_sqrt(x in any::<Felt>()) {
1009 let sqrt = x.square().sqrt().unwrap();
1010 prop_assert!( sqrt == x || -sqrt == x)
1011 }
1012
1013 #[test]
1014 fn multiplying_by_inverse_yields_multiplicative_neutral(x in nonzero_felt()) {
1015 prop_assert_eq!(x * x.inverse().unwrap(), Felt::ONE )
1016 }
1017
1018 #[test]
1019 fn inverse_mod_of_zero_is_none(p in nonzero_felt()) {
1020 let nzp = NonZeroFelt(p.0);
1021 prop_assert!(Felt::ZERO.mod_inverse(&nzp).is_none());
1022 }
1023
1024 #[test]
1025 fn inverse_mod_in_range(x in nonzero_felt(), p in nonzero_felt()) {
1026 let nzp = NonZeroFelt(p.0);
1027 let Some(result) = x.mod_inverse(&nzp) else { return Ok(()) };
1028
1029 prop_assert!(result <= Felt::MAX);
1030 prop_assert!(result < p);
1031 prop_assert!(result.mul_mod(&x, &nzp) == Felt::ONE);
1032 }
1033
1034 #[test]
1035 fn mul_mod_in_range(x in any::<Felt>(), y in any::<Felt>(), p in nonzero_felt()) {
1036 let nzp = NonZeroFelt(p.0);
1037 prop_assert!(x.mul_mod(&y, &nzp) <= Felt::MAX);
1038 prop_assert!(x.mul_mod(&y, &nzp) < p);
1039 }
1040
1041 #[test]
1042 fn to_raw_reversed(mut x in any::<[u64; 4]>()) {
1043 let felt = Felt::from_raw(x);
1044 x.reverse();
1045 prop_assert_eq!(felt.to_raw_reversed(), x);
1046 }
1047
1048 #[test]
1049 fn to_raw(x in any::<[u64; 4]>()) {
1050 let felt = Felt::from_raw(x);
1051 prop_assert_eq!(felt.to_raw(), x);
1052 }
1053 #[test]
1054 fn felt_from_bigint(mut x in any::<[u8; 32]>()) {
1055 x[0] = 0;
1056 let bigint = BigInt::from_bytes_be(Sign::Plus, &x);
1057 let felt_from_ref: Felt = (&bigint).into();
1058 let felt: Felt = bigint.into();
1059 prop_assert_eq!(felt_from_ref, felt);
1060 prop_assert_eq!(felt_from_ref.to_bytes_be(), x);
1061 prop_assert_eq!(felt.to_bytes_be(), x);
1062 }
1063
1064 #[test]
1065 fn felt_from_biguint(mut x in any::<[u8; 32]>()) {
1066 x[0] = 0;
1067 let biguint = BigUint::from_bytes_be( &x);
1068 let felt_from_ref: Felt = (&biguint).into();
1069 let felt: Felt = biguint.into();
1070 prop_assert_eq!(felt_from_ref, felt);
1071 prop_assert_eq!(felt_from_ref.to_bytes_be(), x);
1072 prop_assert_eq!(felt.to_bytes_be(), x);
1073 }
1074 #[test]
1075 fn iter_sum(a in any::<Felt>(), b in any::<Felt>(), c in any::<Felt>()) {
1076 prop_assert_eq!([a, b, c].iter().sum::<Felt>(), a + b + c);
1077 prop_assert_eq!([a, b, c].iter().map(Clone::clone).sum::<Felt>(), a + b + c);
1078 }
1079
1080 #[test]
1081 fn felt_to_fixed_hex_string(a in any::<Felt>()) {
1082 prop_assert_eq!(a.to_fixed_hex_string().len(), 66);
1083 let re = Regex::new(r"^0x([0-9a-fA-F]{64})$").unwrap();
1084 prop_assert!(re.is_match(&a.to_fixed_hex_string()));
1085 }
1086 }
1087
1088 #[test]
1089 fn constant_zero() {
1090 let mut zero_bytes = 0_u64.to_le_bytes().to_vec();
1091 zero_bytes.extend_from_slice(&[0; 24]);
1092 assert_eq!(Felt::ZERO.to_bytes_le().to_vec(), zero_bytes);
1093 }
1094
1095 #[test]
1096 fn constant_one() {
1097 let mut one_bytes = 1_u64.to_le_bytes().to_vec();
1098 one_bytes.extend_from_slice(&[0; 24]);
1099 assert_eq!(Felt::ONE.to_bytes_le().to_vec(), one_bytes);
1100 }
1101
1102 #[test]
1103 fn constant_two() {
1104 let mut two_bytes = 2_u64.to_le_bytes().to_vec();
1105 two_bytes.extend_from_slice(&[0; 24]);
1106 assert_eq!(Felt::TWO.to_bytes_le().to_vec(), two_bytes);
1107 }
1108
1109 #[test]
1110 fn constant_three() {
1111 let mut three_bytes = 3_u64.to_le_bytes().to_vec();
1112 three_bytes.extend_from_slice(&[0; 24]);
1113 assert_eq!(Felt::THREE.to_bytes_le().to_vec(), three_bytes);
1114 }
1115
1116 #[test]
1117 fn constant_max() {
1118 let max_bytes = [
1119 8, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1120 0, 0, 0,
1121 ];
1122 assert_eq!(Felt::MAX.to_bytes_be(), max_bytes);
1123 }
1124
1125 #[test]
1126 fn felt_from_raw() {
1127 let zero_bytes = [0; 4];
1128 assert_eq!(Felt::from_raw(zero_bytes), Felt::ZERO);
1129 let one_raw = [
1130 576460752303422960,
1131 18446744073709551615,
1132 18446744073709551615,
1133 18446744073709551585,
1134 ];
1135 assert_eq!(Felt::from_raw(one_raw), Felt::ONE);
1136 let nineteen_raw = [
1137 576460752303413168,
1138 18446744073709551615,
1139 18446744073709551615,
1140 18446744073709551009,
1141 ];
1142 assert_eq!(Felt::from_raw(nineteen_raw), Felt::from(19));
1143 }
1144
1145 #[test]
1146 fn felt_from_hex_unchecked() {
1147 assert_eq!(Felt::from_hex_unchecked("0"), Felt::from(0));
1148 assert_eq!(Felt::from_hex_unchecked("1"), Felt::from(1));
1149 assert_eq!(Felt::from_hex_unchecked("0x2"), Felt::from(2));
1150 assert_eq!(Felt::from_hex_unchecked("0x0000000003"), Felt::from(3));
1151 assert_eq!(Felt::from_hex_unchecked("000004"), Felt::from(4));
1152 assert_eq!(Felt::from_hex_unchecked("0x05b"), Felt::from(91));
1153 assert_eq!(Felt::from_hex_unchecked("A"), Felt::from(10));
1154 }
1155 #[test]
1156 fn mul_operations() {
1157 assert_eq!(Felt::ONE * Felt::THREE, Felt::THREE);
1158 assert_eq!(Felt::ZERO * Felt::MAX, Felt::ZERO);
1159 assert_eq!(
1160 Felt(FieldElement::from(200)) * Felt::THREE,
1161 Felt(FieldElement::from(600))
1162 );
1163 assert_eq!(Felt::MAX * Felt::TWO, Felt::MAX - Felt::ONE);
1164 }
1165
1166 #[test]
1167 fn add_operations() {
1168 assert_eq!(Felt::ONE + Felt::TWO, Felt::THREE);
1169 assert_eq!(Felt::ZERO + Felt::MAX, Felt::MAX);
1170 assert_eq!(
1171 Felt(FieldElement::from(200)) + Felt::THREE,
1172 Felt(FieldElement::from(203))
1173 );
1174 assert_eq!(Felt::MAX + Felt::TWO, Felt::ONE);
1175 }
1176
1177 #[test]
1178 fn sub_operations() {
1179 assert_eq!(Felt::TWO - Felt::ONE, Felt::ONE);
1180 assert_eq!(Felt::MAX - Felt::ZERO, Felt::MAX);
1181 assert_eq!(
1182 Felt(FieldElement::from(200)) - Felt::THREE,
1183 Felt(FieldElement::from(197))
1184 );
1185 assert_eq!(Felt::ZERO - Felt::ONE, Felt::MAX);
1186 }
1187
1188 #[test]
1189 fn pow_operations() {
1190 assert_eq!(Felt::ONE.pow(5u32), Felt::ONE);
1191 assert_eq!(Felt::ZERO.pow(5u32), Felt::ZERO);
1192 assert_eq!(Felt::THREE.pow(0u32), Felt::ONE);
1193 assert_eq!(
1194 Felt(FieldElement::from(200)).pow(4u32),
1195 Felt(FieldElement::from(1600000000))
1196 );
1197 assert_eq!(Felt::MAX.pow(9u32), Felt::MAX);
1198 }
1199
1200 #[test]
1201 fn display_lower_hex() {
1202 assert_eq!(format!("{:#x}", Felt::ZERO), format!("{:#x}", 0_u64));
1203 assert_eq!(format!("{:#x}", Felt::TWO), format!("{:#x}", 2_u64));
1204 assert_eq!(format!("{:#x}", Felt::THREE), format!("{:#x}", 3_u64));
1205 assert_eq!(
1206 format!("{:#x}", Felt(FieldElement::from(200))),
1207 format!("{:#x}", 200_u64)
1208 );
1209 assert_eq!(
1210 format!("{:#x}", Felt::MAX),
1211 String::from("0x800000000000011000000000000000000000000000000000000000000000000")
1212 );
1213 }
1214
1215 #[test]
1216 fn display_upper_hex() {
1217 assert_eq!(format!("{:#X}", Felt::ZERO), format!("{:#X}", 0_u64));
1218 assert_eq!(format!("{:#X}", Felt::TWO), format!("{:#X}", 2_u64));
1219 assert_eq!(format!("{:#X}", Felt::THREE), format!("{:#X}", 3_u64));
1220 assert_eq!(
1221 format!("{:#X}", Felt(FieldElement::from(200))),
1222 format!("{:#X}", 200_u64)
1223 );
1224 assert_eq!(
1225 format!("{:#X}", Felt::MAX),
1226 String::from("0x800000000000011000000000000000000000000000000000000000000000000")
1227 );
1228 }
1229
1230 #[test]
1231 fn display_decimal() {
1232 assert_eq!(format!("{}", Felt::ZERO), format!("{}", 0_u64));
1233 assert_eq!(format!("{}", Felt::TWO), format!("{}", 2_u64));
1234 assert_eq!(format!("{}", Felt::THREE), format!("{}", 3_u64));
1235 assert_eq!(
1236 format!("{}", Felt(FieldElement::from(200))),
1237 format!("{}", 200_u64)
1238 );
1239 assert_eq!(
1240 format!("{}", Felt::MAX),
1241 String::from(
1242 "3618502788666131213697322783095070105623107215331596699973092056135872020480"
1243 )
1244 );
1245 }
1246
1247 #[test]
1248 fn inverse_and_mul_mod() {
1249 let nzps: Vec<NonZeroFelt> = [
1250 Felt::from(5_i32).try_into().unwrap(),
1251 Felt::from_hex("0x5").unwrap().try_into().unwrap(),
1252 Felt::from_hex("0x1234").unwrap().try_into().unwrap(),
1253 Felt::from_hex("0xabcdef123").unwrap().try_into().unwrap(),
1254 Felt::from_hex("0xffffffffffffff")
1255 .unwrap()
1256 .try_into()
1257 .unwrap(),
1258 Felt::from_hex("0xfffffffffffffffffffffffffffffff")
1259 .unwrap()
1260 .try_into()
1261 .unwrap(),
1262 Felt::MAX.try_into().unwrap(),
1263 ]
1264 .to_vec();
1265 let nums = [
1266 Felt::from_hex("0x0").unwrap(),
1267 Felt::from_hex("0x1").unwrap(),
1268 Felt::from_hex("0x2").unwrap(),
1269 Felt::from_hex("0x5").unwrap(),
1270 Felt::from_hex("0x123abc").unwrap(),
1271 Felt::from_hex("0xabcdef9812367312").unwrap(),
1272 Felt::from_hex("0xffffffffffffffffffffffffffffff").unwrap(),
1273 Felt::from_hex("0xffffffffffffffffffffffffffffffffffffffffff").unwrap(),
1274 Felt::MAX,
1275 ];
1276
1277 for felt in nums {
1278 for nzp in nzps.iter() {
1279 let result = felt.mod_inverse(nzp);
1280 if result.is_some() {
1281 assert_eq!(result.unwrap().mul_mod(&felt, nzp), Felt::ONE);
1282 }
1283 }
1284 }
1285 }
1286
1287 #[test]
1288 fn check_mul_mod() {
1289 let x = Felt::from_dec_str(
1290 "3618502788666131213697322783095070105623107215331596699973092056135872020480",
1291 )
1292 .unwrap();
1293 let y = Felt::from_dec_str("46118400291").unwrap();
1294 let p: NonZeroFelt = Felt::from_dec_str("123987312893120893724347692364")
1295 .unwrap()
1296 .try_into()
1297 .unwrap();
1298 let expected_result = Felt::from_dec_str("68082278891996790254001523512").unwrap();
1299
1300 assert_eq!(x.mul_mod(&y, &p), expected_result);
1301 }
1302
1303 #[test]
1304 fn felt_to_bigints() {
1305 let numbers_str = [
1306 "0x0",
1307 "0x1",
1308 "0x10",
1309 "0x8000000000000110000000000",
1310 "0xffffffffffffff",
1311 "0xffffffffefff12380777abcd",
1312 ];
1313
1314 for number_str in numbers_str {
1315 assert_eq!(
1316 Felt::from_hex(number_str).unwrap().to_bigint(),
1317 BigInt::from_str_radix(&number_str[2..], 16).unwrap()
1318 );
1319
1320 assert_eq!(
1321 Felt::from_hex(number_str).unwrap().to_biguint(),
1322 BigUint::from_str_radix(&number_str[2..], 16).unwrap()
1323 );
1324 }
1325 }
1326
1327 #[test]
1328 fn bool_into_felt() {
1329 let zero: Felt = false.into();
1330 let one: Felt = true.into();
1331 assert_eq!(one, Felt::ONE);
1332 assert_eq!(zero, Felt::ZERO);
1333 }
1334}