1use ark_ff::{BigInt, FftField, Field, LegendreSymbol, One, PrimeField, SqrtPrecomputation, Zero};
12use ark_serialize::{
13 buffer_byte_size, CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize,
14 CanonicalSerializeWithFlags, Compress, EmptyFlags, Flags, SerializationError, Valid, Validate,
15};
16use ark_std::string::ToString;
17use core::{
18 fmt::{Debug, Display, Formatter},
19 hash::Hash,
20 iter::{Product, Sum},
21 ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign},
22 str::FromStr,
23};
24
25const MODULUS: u32 = 2_147_483_647;
27
28const MODULUS_BIT_SIZE: u32 = 31;
29
30#[derive(Clone, Copy, Default)]
31pub struct Fp(pub u32);
32
33impl Fp {
34 #[doc(hidden)]
35 #[inline]
36 const fn is_gt_modulus(self) -> bool {
37 self.0 > MODULUS
38 }
39 const fn is_geq_modulus(self) -> bool {
40 self.0 >= MODULUS
41 }
42
43 const fn add_assign(&mut self, rhs: Self) {
44 self.0 += rhs.0;
45 self.0 = (self.0 & MODULUS) + (self.0 >> 31);
46 }
47
48 const fn sub_assign(&mut self, rhs: Self) {
49 self.0 += MODULUS - rhs.0;
50 self.0 = (self.0 & MODULUS) + (self.0 >> 31);
51 }
52
53 #[inline]
54 const fn mul(self, rhs: Self) -> Self {
55 let t = self.0 as u64 * (rhs.0 << 1) as u64;
56 #[allow(clippy::cast_possible_truncation)]
58 let t0 = t as u32 >> 1;
59 let t1 = (t >> 32) as u32;
60 let x = t0 + t1;
61 Self((x & MODULUS) + (x >> 31))
62 }
63
64 #[inline]
65 const fn sq(self) -> Self {
66 self.mul(self)
67 }
68
69 const fn sqn(mut self, n: u32) -> Self {
70 let mut i = 0;
71 while i < n {
72 self = self.sq();
73 i += 1;
74 }
75 self
76 }
77
78 const fn is_zero(self) -> bool {
79 self.0 == 0 || self.0 == MODULUS
80 }
81
82 const fn into_integer(self) -> u32 {
83 if self.is_zero() {
84 0
85 } else {
86 self.0
87 }
88 }
89}
90
91impl Field for Fp {
92 type BasePrimeField = Self;
93 type BasePrimeFieldIter = core::iter::Once<Self::BasePrimeField>;
94
95 const SQRT_PRECOMP: Option<SqrtPrecomputation<Self>> = Some(SqrtPrecomputation::Case3Mod4 {
96 modulus_plus_one_div_four: &[(MODULUS as u64 + 1) / 4],
97 });
98
99 const ZERO: Self = Self(0);
100
101 const ONE: Self = Self(1);
102
103 fn extension_degree() -> u64 {
104 1
105 }
106
107 fn from_base_prime_field(elem: Self::BasePrimeField) -> Self {
108 elem
109 }
110
111 fn to_base_prime_field_elements(&self) -> Self::BasePrimeFieldIter {
112 core::iter::once(*self)
113 }
114
115 fn from_base_prime_field_elems(elems: &[Self::BasePrimeField]) -> Option<Self> {
116 if elems.len() != usize::try_from(Self::extension_degree()).unwrap() {
117 return None;
118 }
119 Some(elems[0])
120 }
121
122 #[inline]
123 fn double(&self) -> Self {
124 let mut temp = *self;
125 temp.double_in_place();
126 temp
127 }
128
129 #[inline]
130 fn double_in_place(&mut self) -> &mut Self {
131 let x = self.0 << 1;
132 self.0 = (x & MODULUS) + (self.0 >> 30);
133 self
134 }
135
136 #[inline]
137 fn neg_in_place(&mut self) -> &mut Self {
138 self.0 = MODULUS - self.0;
139 self
140 }
141
142 #[inline]
143 fn characteristic() -> &'static [u64] {
144 const _MODULUS: &[u64] = &[MODULUS as u64];
145 _MODULUS
146 }
147
148 #[inline]
149 fn sum_of_products<const T: usize>(a: &[Self; T], b: &[Self; T]) -> Self {
150 a.iter().zip(b).map(|(&a, b)| a * b).sum()
151 }
152
153 #[inline]
154 fn from_random_bytes_with_flags<F: Flags>(_bytes: &[u8]) -> Option<(Self, F)> {
155 todo!()
156 }
157
158 #[inline]
159 fn square(&self) -> Self {
160 let mut temp = *self;
161 temp.square_in_place();
162 temp
163 }
164
165 fn square_in_place(&mut self) -> &mut Self {
166 *self = self.sq();
167 self
168 }
169
170 #[inline]
171 #[allow(clippy::just_underscores_and_digits, clippy::similar_names)]
172 fn inverse(&self) -> Option<Self> {
173 if self.is_zero() {
174 None
175 } else {
176 let t100 = Self::sqn(*self, 2);
178 let t101 = Self::mul(*self, t100);
179 let t1010 = Self::sq(t101);
180 let t1111 = Self::mul(t101, t1010);
181 let t1111000 = Self::sqn(t1111, 3);
182 let t1111101 = Self::mul(t101, t1111000);
183 let t11111010 = Self::sq(t1111101);
184 let t11111111 = Self::mul(t101, t11111010);
185 let x16 = Self::mul(Self::sqn(t11111111, 8), t11111111);
186 let x24 = Self::mul(Self::sqn(x16, 8), t11111111);
187 Some(Self::mul(Self::sqn(x24, 7), t1111101))
188 }
189 }
190
191 fn inverse_in_place(&mut self) -> Option<&mut Self> {
192 self.inverse().map(|inverse| {
193 *self = inverse;
194 self
195 })
196 }
197
198 #[inline]
200 fn frobenius_map_in_place(&mut self, _: usize) {}
201
202 #[inline]
203 fn legendre(&self) -> LegendreSymbol {
204 let s = self.pow([(u64::from(MODULUS) - 1) / 2]);
205 if s.is_zero() {
206 LegendreSymbol::Zero
207 } else if s.is_one() {
208 LegendreSymbol::QuadraticResidue
209 } else {
210 LegendreSymbol::QuadraticNonResidue
211 }
212 }
213}
214
215impl PrimeField for Fp {
216 type BigInt = BigInt<1>;
217 const MODULUS: Self::BigInt = BigInt([MODULUS as u64]);
218 const MODULUS_MINUS_ONE_DIV_TWO: Self::BigInt = Self::MODULUS.divide_by_2_round_down();
219 const MODULUS_BIT_SIZE: u32 = Self::MODULUS.const_num_bits();
220 const TRACE: Self::BigInt = Self::MODULUS.two_adic_coefficient();
221 const TRACE_MINUS_ONE_DIV_TWO: Self::BigInt = Self::TRACE.divide_by_2_round_down();
222
223 #[inline]
224 fn from_bigint(r: BigInt<1>) -> Option<Self> {
225 Some(Self::from(r.0[0]))
226 }
227
228 fn into_bigint(self) -> BigInt<1> {
229 BigInt([self.into_integer().into()])
230 }
231}
232
233impl FftField for Fp {
234 const GENERATOR: Self = Self(3);
235 const TWO_ADICITY: u32 = 1;
236 const TWO_ADIC_ROOT_OF_UNITY: Self = Self(MODULUS - 1);
237 const SMALL_SUBGROUP_BASE: Option<u32> = None;
238 const SMALL_SUBGROUP_BASE_ADICITY: Option<u32> = None;
239 const LARGE_SUBGROUP_ROOT_OF_UNITY: Option<Self> = None;
240}
241
242impl zeroize::Zeroize for Fp {
243 fn zeroize(&mut self) {
244 self.0.zeroize();
245 }
246}
247
248impl Debug for Fp {
249 fn fmt(&self, f: &mut Formatter<'_>) -> ark_std::fmt::Result {
250 ark_std::fmt::Debug::fmt(&self.into_integer(), f)
251 }
252}
253
254impl Zero for Fp {
255 #[inline]
256 fn zero() -> Self {
257 Self::ZERO
258 }
259
260 #[inline]
261 fn is_zero(&self) -> bool {
262 (*self).is_zero()
263 }
264}
265
266impl One for Fp {
267 #[inline]
268 fn one() -> Self {
269 Self::ONE
270 }
271
272 #[inline]
273 fn is_one(&self) -> bool {
274 *self == Self::ONE
275 }
276}
277
278impl PartialEq for Fp {
279 fn eq(&self, other: &Self) -> bool {
280 self.0 == other.0 || (self.is_zero() && other.is_zero())
281 }
282}
283
284impl Hash for Fp {
285 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
286 self.into_integer().hash(state);
287 }
288}
289
290impl Eq for Fp {}
291
292impl Ord for Fp {
299 #[inline]
300 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
301 self.into_integer().cmp(&other.into_integer())
302 }
303}
304
305impl PartialOrd for Fp {
312 #[inline]
313 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
314 Some(self.cmp(other))
315 }
316}
317
318impl From<num_bigint::BigUint> for Fp {
319 fn from(other: num_bigint::BigUint) -> Self {
320 (other % MODULUS)
321 .to_u32_digits()
322 .iter()
323 .copied()
324 .map(Self::from)
325 .sum()
326 }
327}
328
329impl From<Fp> for num_bigint::BigUint {
330 fn from(fp: Fp) -> Self {
331 fp.into_integer().into()
332 }
333}
334
335impl From<BigInt<1>> for Fp {
336 fn from(other: BigInt<1>) -> Self {
337 other.0[0].into()
338 }
339}
340
341impl From<Fp> for BigInt<1> {
342 fn from(fp: Fp) -> Self {
343 Self([fp.into_integer().into()])
344 }
345}
346
347impl From<u128> for Fp {
349 fn from(other: u128) -> Self {
350 #[allow(clippy::cast_possible_truncation)]
351 Self((other % u128::from(MODULUS)) as u32)
352 }
353}
354
355impl From<i128> for Fp {
356 fn from(other: i128) -> Self {
357 let abs = Self::from(other.unsigned_abs());
358 if other.is_positive() {
359 abs
360 } else {
361 -abs
362 }
363 }
364}
365
366impl From<bool> for Fp {
367 fn from(other: bool) -> Self {
368 Self(u32::from(other))
369 }
370}
371
372impl From<u64> for Fp {
373 fn from(other: u64) -> Self {
374 #[allow(clippy::cast_possible_truncation)]
375 Self((other % u64::from(MODULUS)) as u32)
376 }
377}
378
379impl From<i64> for Fp {
380 fn from(other: i64) -> Self {
381 let abs = Self::from(other.unsigned_abs());
382 if other.is_positive() {
383 abs
384 } else {
385 -abs
386 }
387 }
388}
389
390impl From<u32> for Fp {
391 fn from(other: u32) -> Self {
392 Self(other % MODULUS)
393 }
394}
395
396impl From<i32> for Fp {
397 fn from(other: i32) -> Self {
398 let abs = Self::from(other.unsigned_abs());
399 if other.is_positive() {
400 abs
401 } else {
402 -abs
403 }
404 }
405}
406
407impl From<u16> for Fp {
408 fn from(other: u16) -> Self {
409 Self(other.into())
410 }
411}
412
413impl From<i16> for Fp {
414 fn from(other: i16) -> Self {
415 let abs = Self::from(other.unsigned_abs());
416 if other.is_positive() {
417 abs
418 } else {
419 -abs
420 }
421 }
422}
423
424impl From<u8> for Fp {
425 fn from(other: u8) -> Self {
426 Self(other.into())
427 }
428}
429
430impl From<i8> for Fp {
431 fn from(other: i8) -> Self {
432 let abs = Self::from(other.unsigned_abs());
433 if other.is_positive() {
434 abs
435 } else {
436 -abs
437 }
438 }
439}
440
441impl ark_std::rand::distributions::Distribution<Fp> for ark_std::rand::distributions::Standard {
442 #[inline]
443 fn sample<R: ark_std::rand::Rng + ?Sized>(&self, rng: &mut R) -> Fp {
444 loop {
445 let mut tmp = Fp(rng.sample(Self));
446
447 let mask = u32::MAX >> (32 - MODULUS_BIT_SIZE);
449 tmp.0 &= mask;
450
451 if !tmp.is_geq_modulus() {
453 return tmp;
454 }
455 }
456 }
457}
458
459impl CanonicalSerializeWithFlags for Fp {
461 fn serialize_with_flags<W: ark_std::io::Write, F: Flags>(
462 &self,
463 mut writer: W,
464 flags: F,
465 ) -> Result<(), SerializationError> {
466 if F::BIT_SIZE > 8 {
469 return Err(SerializationError::NotEnoughSpace);
470 }
471
472 let b = self.into_integer().to_le_bytes();
473 writer.write_all(&[b[0], b[1], b[2], b[3], flags.u8_bitmask()])?;
476 Ok(())
477 }
478
479 fn serialized_size_with_flags<F: Flags>(&self) -> usize {
484 buffer_byte_size(MODULUS_BIT_SIZE as usize + F::BIT_SIZE)
485 }
486}
487
488impl CanonicalSerialize for Fp {
489 #[inline]
490 fn serialize_with_mode<W: ark_std::io::Write>(
491 &self,
492 writer: W,
493 _compress: Compress,
494 ) -> Result<(), SerializationError> {
495 self.serialize_with_flags(writer, EmptyFlags)
496 }
497
498 #[inline]
499 fn serialized_size(&self, _compress: Compress) -> usize {
500 self.serialized_size_with_flags::<EmptyFlags>()
501 }
502}
503
504impl CanonicalDeserializeWithFlags for Fp {
505 fn deserialize_with_flags<R: ark_std::io::Read, F: Flags>(
506 mut reader: R,
507 ) -> Result<(Self, F), SerializationError> {
508 if F::BIT_SIZE > 8 {
511 return Err(SerializationError::NotEnoughSpace);
512 }
513 let mut b = [0u8; 5];
516 reader.read_exact(&mut b)?;
517 let flags = F::from_u8_remove_flags(&mut b[b.len() - 1])
518 .ok_or(SerializationError::UnexpectedFlags)?;
519 let self_integer = u32::from_le_bytes(b[0..4].try_into().unwrap());
520 Ok((Self(self_integer), flags))
521 }
522}
523
524impl Valid for Fp {
525 fn check(&self) -> Result<(), SerializationError> {
526 Ok(())
527 }
528}
529
530impl CanonicalDeserialize for Fp {
531 fn deserialize_with_mode<R: ark_std::io::Read>(
532 reader: R,
533 _compress: Compress,
534 _validate: Validate,
535 ) -> Result<Self, SerializationError> {
536 Self::deserialize_with_flags::<R, EmptyFlags>(reader).map(|(r, _)| r)
537 }
538}
539
540impl FromStr for Fp {
541 type Err = ();
542
543 fn from_str(s: &str) -> Result<Self, Self::Err> {
546 if s.is_empty() {
547 return Err(());
548 }
549
550 if s == "0" {
551 return Ok(Self::zero());
552 }
553
554 let mut res = Self::zero();
555
556 let ten = Self(10);
557
558 let mut first_digit = true;
559
560 for c in s.chars() {
561 match c.to_digit(10) {
562 Some(c) => {
563 if first_digit {
564 if c == 0 {
565 return Err(());
566 }
567
568 first_digit = false;
569 }
570
571 res.mul_assign(&ten);
572 let digit = Self::from(u64::from(c));
573 res.add_assign(digit);
574 }
575 None => {
576 return Err(());
577 }
578 }
579 }
580 if res.is_gt_modulus() {
581 Err(())
582 } else {
583 Ok(res)
584 }
585 }
586}
587
588impl Display for Fp {
591 #[inline]
592 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
593 let string = self.into_integer().to_string();
594 write!(f, "{}", string.trim_start_matches('0'))
595 }
596}
597
598impl Neg for Fp {
599 type Output = Self;
600 #[inline]
601 #[must_use]
602 fn neg(mut self) -> Self {
603 Self::neg_in_place(&mut self);
604 self
605 }
606}
607
608impl<'a> Add<&'a Self> for Fp {
609 type Output = Self;
610
611 #[inline]
612 fn add(mut self, other: &Self) -> Self {
613 self.add_assign(*other);
614 self
615 }
616}
617
618impl<'a> Sub<&'a Self> for Fp {
619 type Output = Self;
620
621 #[inline]
622 fn sub(mut self, other: &Self) -> Self {
623 self.sub_assign(*other);
624 self
625 }
626}
627
628impl<'a> Mul<&'a Self> for Fp {
629 type Output = Self;
630
631 #[inline]
632 fn mul(mut self, other: &Self) -> Self {
633 self.mul_assign(other);
634 self
635 }
636}
637
638impl<'a> Div<&'a Self> for Fp {
639 type Output = Self;
640
641 #[inline]
644 fn div(mut self, other: &Self) -> Self {
645 self.mul_assign(&other.inverse().unwrap());
646 self
647 }
648}
649
650impl<'a, 'b> Add<&'b Fp> for &'a Fp {
651 type Output = Fp;
652
653 #[inline]
654 fn add(self, other: &'b Fp) -> Fp {
655 let mut result = *self;
656 result.add_assign(*other);
657 result
658 }
659}
660
661impl<'a, 'b> Sub<&'b Fp> for &'a Fp {
662 type Output = Fp;
663
664 #[inline]
665 fn sub(self, other: &Fp) -> Fp {
666 let mut result = *self;
667 result.sub_assign(*other);
668 result
669 }
670}
671
672impl<'a, 'b> Mul<&'b Fp> for &'a Fp {
673 type Output = Fp;
674
675 #[inline]
676 fn mul(self, other: &Fp) -> Fp {
677 let mut result = *self;
678 result.mul_assign(other);
679 result
680 }
681}
682
683impl<'a, 'b> Div<&'b Fp> for &'a Fp {
684 type Output = Fp;
685
686 #[inline]
687 fn div(self, other: &Fp) -> Fp {
688 let mut result = *self;
689 result.div_assign(other);
690 result
691 }
692}
693
694impl<'a> AddAssign<&'a Self> for Fp {
695 #[inline]
696 fn add_assign(&mut self, other: &Self) {
697 Self::add_assign(self, *other);
698 }
699}
700
701impl<'a> SubAssign<&'a Self> for Fp {
702 #[inline]
703 fn sub_assign(&mut self, other: &Self) {
704 Self::sub_assign(self, *other);
705 }
706}
707
708impl<'a> AddAssign<&'a mut Self> for Fp {
709 #[inline]
710 fn add_assign(&mut self, other: &mut Self) {
711 Self::add_assign(self, *other);
712 }
713}
714
715impl<'a> SubAssign<&'a mut Self> for Fp {
716 #[inline]
717 fn sub_assign(&mut self, other: &mut Self) {
718 Self::sub_assign(self, *other);
719 }
720}
721
722impl AddAssign<Self> for Fp {
723 #[inline]
724 fn add_assign(&mut self, other: Self) {
725 Self::add_assign(self, other);
726 }
727}
728
729impl SubAssign<Self> for Fp {
730 #[inline]
731 fn sub_assign(&mut self, other: Self) {
732 Self::sub_assign(self, other);
733 }
734}
735
736impl Mul<Self> for Fp {
737 type Output = Self;
738
739 #[inline]
740 fn mul(mut self, other: Self) -> Self {
741 self.mul_assign(&other);
742 self
743 }
744}
745
746impl Div<Self> for Fp {
747 type Output = Self;
748
749 #[inline]
750 fn div(mut self, other: Self) -> Self {
751 self.div_assign(&other);
752 self
753 }
754}
755
756impl Add<Self> for Fp {
757 type Output = Self;
758
759 #[inline]
760 fn add(mut self, other: Self) -> Self {
761 self.add_assign(other);
762 self
763 }
764}
765
766impl Sub<Self> for Fp {
767 type Output = Self;
768
769 #[inline]
770 fn sub(mut self, other: Self) -> Self {
771 self.sub_assign(other);
772 self
773 }
774}
775
776impl<'a> Add<&'a mut Self> for Fp {
777 type Output = Self;
778
779 #[inline]
780 fn add(self, other: &'a mut Self) -> Self {
781 let mut result = self;
782 result.add_assign(*other);
783 result
784 }
785}
786
787impl<'a> Sub<&'a mut Self> for Fp {
788 type Output = Self;
789
790 #[inline]
791 fn sub(self, other: &'a mut Self) -> Self {
792 let mut result = self;
793 result.sub_assign(*other);
794 result
795 }
796}
797
798impl<'a> Mul<&'a mut Self> for Fp {
799 type Output = Self;
800
801 #[inline]
802 fn mul(mut self, other: &'a mut Self) -> Self {
803 self.mul_assign(&*other);
804 self
805 }
806}
807
808impl<'a> Div<&'a mut Self> for Fp {
809 type Output = Self;
810
811 #[inline]
812 fn div(mut self, other: &'a mut Self) -> Self {
813 self.div_assign(&*other);
814 self
815 }
816}
817
818impl Product<Self> for Fp {
819 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
820 iter.fold(Self::one(), core::ops::Mul::mul)
821 }
822}
823
824impl<'a> Product<&'a Self> for Fp {
825 fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
826 iter.fold(Self::one(), Mul::mul)
827 }
828}
829
830impl Sum<Self> for Fp {
831 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
832 iter.fold(Self::zero(), core::ops::Add::add)
833 }
834}
835
836impl<'a> Sum<&'a Self> for Fp {
837 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
838 iter.fold(Self::zero(), core::ops::Add::add)
839 }
840}
841
842impl MulAssign<Self> for Fp {
843 #[inline]
844 fn mul_assign(&mut self, other: Self) {
845 self.mul_assign(&other);
846 }
847}
848
849impl DivAssign<Self> for Fp {
850 #[inline]
851 fn div_assign(&mut self, other: Self) {
852 self.div_assign(&other);
853 }
854}
855
856impl<'a> MulAssign<&'a Self> for Fp {
857 #[inline]
858 fn mul_assign(&mut self, other: &'a Self) {
859 *self = Self::mul(*self, *other);
860 }
861}
862
863impl<'a> MulAssign<&'a mut Self> for Fp {
864 #[inline]
865 fn mul_assign(&mut self, other: &'a mut Self) {
866 self.mul_assign(&*other);
867 }
868}
869
870impl<'a> DivAssign<&'a mut Self> for Fp {
871 #[inline]
872 fn div_assign(&mut self, other: &'a mut Self) {
873 self.div_assign(&*other);
874 }
875}
876
877impl<'a> DivAssign<&'a Self> for Fp {
880 #[inline]
881 fn div_assign(&mut self, other: &Self) {
882 self.mul_assign(&other.inverse().unwrap());
883 }
884}
885
886#[cfg(test)]
887mod tests {
888 use super::Fp as TestField;
889 use ark_algebra_test_templates::test_field;
890
891 test_field!(generated; TestField; prime);
892}