1use alloc::vec;
4use alloc::vec::Vec;
5use core::fmt::{self, Debug, Display, Formatter};
6use core::hash::Hash;
7use core::iter::{Product, Sum};
8use core::marker::PhantomData;
9use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
10use core::{array, iter};
11
12use num_bigint::BigUint;
13use p3_field::integers::QuotientMap;
14use p3_field::op_assign_macros::{
15 impl_add_assign, impl_div_methods, impl_mul_methods, impl_sub_assign,
16};
17use p3_field::{
18 Field, InjectiveMonomial, Packable, PermutationMonomial, PrimeCharacteristicRing, PrimeField,
19 PrimeField32, PrimeField64, RawDataSerializable, TwoAdicField,
20 impl_raw_serializable_primefield32, quotient_map_small_int,
21};
22use p3_util::{flatten_to_base, gcd_inversion_prime_field_32};
23use rand::Rng;
24use rand::distr::{Distribution, StandardUniform};
25use serde::de::Error;
26use serde::{Deserialize, Deserializer, Serialize};
27
28use crate::utils::{
29 add, from_monty, halve_u32, large_monty_reduce, monty_reduce, monty_reduce_u128, sub, to_monty,
30 to_monty_64, to_monty_64_signed, to_monty_signed,
31};
32use crate::{FieldParameters, MontyParameters, RelativelyPrimePower, TwoAdicData};
33
34#[derive(Clone, Copy, Default, Eq, Hash, PartialEq)]
35#[repr(transparent)] #[must_use]
37pub struct MontyField31<MP: MontyParameters> {
38 pub(crate) value: u32,
43 _phantom: PhantomData<MP>,
44}
45
46impl<MP: MontyParameters> MontyField31<MP> {
47 #[inline(always)]
51 pub const fn new(value: u32) -> Self {
52 const {
53 assert!(MP::PRIME % 2 == 1, "PRIME must be odd");
54 assert!(MP::PRIME < (1 << 31), "PRIME must be a 31-bit prime");
55 assert!(MP::MONTY_BITS == 32);
56 assert!(
57 MP::PRIME.wrapping_mul(MP::MONTY_MU) == 1,
58 "MONTY_MU must satisfy PRIME * MONTY_MU ≡ 1 (mod 2^32)"
59 );
60 }
61 Self {
62 value: to_monty::<MP>(value),
63 _phantom: PhantomData,
64 }
65 }
66
67 #[inline(always)]
71 pub(crate) const fn new_monty(value: u32) -> Self {
72 Self {
73 value,
74 _phantom: PhantomData,
75 }
76 }
77
78 #[inline(always)]
80 pub(crate) const fn to_u32(elem: &Self) -> u32 {
81 from_monty::<MP>(elem.value)
82 }
83
84 #[inline]
88 pub const fn new_array<const N: usize>(input: [u32; N]) -> [Self; N] {
89 let mut output = [Self::new_monty(0); N];
90 let mut i = 0;
91 while i < N {
92 output[i] = Self::new(input[i]);
93 i += 1;
94 }
95 output
96 }
97
98 #[inline]
101 pub const fn new_2d_array<const N: usize, const M: usize>(
102 input: [[u32; N]; M],
103 ) -> [[Self; N]; M] {
104 let mut output = [[Self::new_monty(0); N]; M];
105 let mut i = 0;
106 while i < M {
107 output[i] = Self::new_array(input[i]);
108 i += 1;
109 }
110 output
111 }
112}
113
114impl<FP: FieldParameters> MontyField31<FP> {
115 const MONTY_POWERS_OF_TWO: [Self; 64] = {
116 let mut powers_of_two = [FP::MONTY_ONE; 64];
117 let mut i = 1;
118 while i < 64 {
119 powers_of_two[i] = Self::new_monty(to_monty_64::<FP>(1 << i));
120 i += 1;
121 }
122 powers_of_two
123 };
124
125 const HALF: Self = Self::new(FP::HALF_P_PLUS_1);
126}
127
128impl<FP: MontyParameters> Ord for MontyField31<FP> {
129 #[inline]
130 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
131 Self::to_u32(self).cmp(&Self::to_u32(other))
132 }
133}
134
135impl<FP: MontyParameters> PartialOrd for MontyField31<FP> {
136 #[inline]
137 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
138 Some(self.cmp(other))
139 }
140}
141
142impl<FP: MontyParameters> Display for MontyField31<FP> {
143 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
144 Display::fmt(&Self::to_u32(self), f)
145 }
146}
147
148impl<FP: MontyParameters> Debug for MontyField31<FP> {
149 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
150 Debug::fmt(&Self::to_u32(self), f)
151 }
152}
153
154impl<FP: MontyParameters> Distribution<MontyField31<FP>> for StandardUniform {
155 #[inline]
156 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MontyField31<FP> {
157 loop {
158 let next_u31 = rng.next_u32() >> 1;
159 let is_canonical = next_u31 < FP::PRIME;
160 if is_canonical {
161 return MontyField31::new_monty(next_u31);
162 }
163 }
164 }
165}
166
167impl<FP: FieldParameters> Serialize for MontyField31<FP> {
168 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
169 serializer.serialize_u32(self.value)
171 }
172}
173
174impl<'de, FP: FieldParameters> Deserialize<'de> for MontyField31<FP> {
175 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
176 let val = u32::deserialize(d)?;
178 if val < FP::PRIME {
179 Ok(Self::new_monty(val))
180 } else {
181 Err(D::Error::custom("Value is out of range"))
182 }
183 }
184}
185
186impl<MP: MontyParameters> Packable for MontyField31<MP> {}
187
188impl<FP: FieldParameters> PrimeCharacteristicRing for MontyField31<FP> {
189 type PrimeSubfield = Self;
190
191 const ZERO: Self = FP::MONTY_ZERO;
192 const ONE: Self = FP::MONTY_ONE;
193 const TWO: Self = FP::MONTY_TWO;
194 const NEG_ONE: Self = FP::MONTY_NEG_ONE;
195
196 #[inline(always)]
197 fn from_prime_subfield(f: Self) -> Self {
198 f
199 }
200
201 #[inline]
202 fn halve(&self) -> Self {
203 Self::new_monty(halve_u32::<FP>(self.value))
204 }
205
206 #[inline]
207 fn mul_2exp_u64(&self, exp: u64) -> Self {
208 match exp {
212 0 => *self,
213 1 => *self + *self,
214 _ => {
215 if exp < 64 {
216 *self * Self::MONTY_POWERS_OF_TWO[exp as usize]
217 } else {
218 *self * Self::TWO.exp_u64(exp)
220 }
221 }
222 }
223 }
224
225 #[inline]
226 fn div_2exp_u64(&self, exp: u64) -> Self {
227 if exp <= 32 {
228 let long_prod = (self.value as u64) << (32 - exp);
232 Self::new_monty(monty_reduce::<FP>(long_prod))
233 } else {
234 *self * Self::HALF.exp_u64(exp)
237 }
238 }
239
240 #[inline]
241 fn zero_vec(len: usize) -> Vec<Self> {
242 unsafe { flatten_to_base(vec![0u32; len]) }
248 }
249
250 #[inline]
251 fn sum_array<const N: usize>(input: &[Self]) -> Self {
252 assert_eq!(N, input.len());
253 match N {
257 0 => Self::ZERO,
258 1 => input[0],
259 2 => input[0] + input[1],
260 3 => input[0] + input[1] + input[2],
261 4 => (input[0] + input[1]) + (input[2] + input[3]),
262 5 => Self::sum_array::<4>(&input[..4]) + Self::sum_array::<1>(&input[4..]),
263 6 => Self::sum_array::<4>(&input[..4]) + Self::sum_array::<2>(&input[4..]),
264 7 => Self::sum_array::<4>(&input[..4]) + Self::sum_array::<3>(&input[4..]),
265 _ => input.iter().copied().sum(),
266 }
267 }
268
269 #[inline]
270 fn dot_product<const N: usize>(lhs: &[Self; N], rhs: &[Self; N]) -> Self {
271 const {
272 assert!(N as u64 <= (1 << 34));
273
274 debug_assert!(FP::MONTY_BITS == 32);
277 debug_assert!((FP::PRIME as u64) < (1 << 31));
278 }
279 match N {
280 0 => Self::ZERO,
281 1 => lhs[0] * rhs[0],
282 2 => {
283 let u64_prod_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
287 + (lhs[1].value as u64) * (rhs[1].value as u64);
288 Self::new_monty(monty_reduce::<FP>(u64_prod_sum))
289 }
290 3 => {
291 let u64_prod_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
294 + (lhs[1].value as u64) * (rhs[1].value as u64)
295 + (lhs[2].value as u64) * (rhs[2].value as u64);
296 Self::new_monty(large_monty_reduce::<FP>(u64_prod_sum))
297 }
298 4 => {
299 let u64_prod_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
302 + (lhs[1].value as u64) * (rhs[1].value as u64)
303 + (lhs[2].value as u64) * (rhs[2].value as u64)
304 + (lhs[3].value as u64) * (rhs[3].value as u64);
305 Self::new_monty(large_monty_reduce::<FP>(u64_prod_sum))
306 }
307 5 => {
308 let head_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
309 + (lhs[1].value as u64) * (rhs[1].value as u64)
310 + (lhs[2].value as u64) * (rhs[2].value as u64)
311 + (lhs[3].value as u64) * (rhs[3].value as u64);
312 let tail_sum = (lhs[4].value as u64) * (rhs[4].value as u64);
313 let head_sum_corr = head_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
315 let sum = head_sum.min(head_sum_corr) + tail_sum;
318 Self::new_monty(large_monty_reduce::<FP>(sum))
319 }
320 6 => {
321 let head_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
322 + (lhs[1].value as u64) * (rhs[1].value as u64)
323 + (lhs[2].value as u64) * (rhs[2].value as u64)
324 + (lhs[3].value as u64) * (rhs[3].value as u64);
325 let tail_sum = (lhs[4].value as u64) * (rhs[4].value as u64)
326 + (lhs[5].value as u64) * (rhs[5].value as u64);
327 let head_sum_corr = head_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
329 let sum = head_sum.min(head_sum_corr) + tail_sum;
332 Self::new_monty(large_monty_reduce::<FP>(sum))
333 }
334 7 => {
335 let head_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
336 + (lhs[1].value as u64) * (rhs[1].value as u64)
337 + (lhs[2].value as u64) * (rhs[2].value as u64)
338 + (lhs[3].value as u64) * (rhs[3].value as u64);
339 let tail_sum = (lhs[4].value as u64) * (rhs[4].value as u64)
340 + lhs[5].value as u64 * (rhs[5].value as u64)
341 + lhs[6].value as u64 * (rhs[6].value as u64);
342 let head_sum_corr = head_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
344 let tail_sum_corr = tail_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
345 let sum = head_sum.min(head_sum_corr) + tail_sum.min(tail_sum_corr);
348 Self::new_monty(large_monty_reduce::<FP>(sum))
349 }
350 8 => {
351 let head_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
352 + (lhs[1].value as u64) * (rhs[1].value as u64)
353 + (lhs[2].value as u64) * (rhs[2].value as u64)
354 + (lhs[3].value as u64) * (rhs[3].value as u64);
355 let tail_sum = (lhs[4].value as u64) * (rhs[4].value as u64)
356 + lhs[5].value as u64 * (rhs[5].value as u64)
357 + lhs[6].value as u64 * (rhs[6].value as u64)
358 + lhs[7].value as u64 * (rhs[7].value as u64);
359 let head_sum_corr = head_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
361 let tail_sum_corr = tail_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
362 let sum = head_sum.min(head_sum_corr) + tail_sum.min(tail_sum_corr);
365 Self::new_monty(large_monty_reduce::<FP>(sum))
366 }
367 _ => {
368 let acc_u128 = lhs
371 .chunks(4)
372 .zip(rhs.chunks(4))
373 .map(|(l, r)| {
374 let u64_prod_sum = l
378 .iter()
379 .zip(r)
380 .map(|(l, r)| (l.value as u64) * (r.value as u64))
381 .sum::<u64>();
382 u64_prod_sum as u128
383 })
384 .sum();
385 Self::new_monty(monty_reduce_u128::<FP>(acc_u128))
387 }
388 }
389 }
390}
391
392impl<FP: FieldParameters + RelativelyPrimePower<D>, const D: u64> InjectiveMonomial<D>
393 for MontyField31<FP>
394{
395}
396
397impl<FP: FieldParameters + RelativelyPrimePower<D>, const D: u64> PermutationMonomial<D>
398 for MontyField31<FP>
399{
400 fn injective_exp_root_n(&self) -> Self {
401 FP::exp_root_d(*self)
402 }
403}
404
405impl<FP: FieldParameters> RawDataSerializable for MontyField31<FP> {
406 impl_raw_serializable_primefield32!();
407}
408
409impl<FP: FieldParameters> Field for MontyField31<FP> {
410 #[cfg(all(target_arch = "aarch64", target_feature = "neon"))]
411 type Packing = crate::PackedMontyField31Neon<FP>;
412 #[cfg(all(
413 target_arch = "x86_64",
414 target_feature = "avx2",
415 not(target_feature = "avx512f")
416 ))]
417 type Packing = crate::PackedMontyField31AVX2<FP>;
418 #[cfg(all(target_arch = "x86_64", target_feature = "avx512f"))]
419 type Packing = crate::PackedMontyField31AVX512<FP>;
420 #[cfg(not(any(
421 all(target_arch = "aarch64", target_feature = "neon"),
422 all(
423 target_arch = "x86_64",
424 target_feature = "avx2",
425 not(target_feature = "avx512f")
426 ),
427 all(target_arch = "x86_64", target_feature = "avx512f"),
428 )))]
429 type Packing = Self;
430
431 const GENERATOR: Self = FP::MONTY_GEN;
432
433 fn try_inverse(&self) -> Option<Self> {
434 if self.is_zero() {
435 return None;
436 }
437
438 const NUM_PRIME_BITS: u32 = 31;
440
441 let gcd_inverse = gcd_inversion_prime_field_32::<NUM_PRIME_BITS>(self.value, FP::PRIME);
446
447 let pos_inverse = (((FP::PRIME as i64) << 30) + gcd_inverse) as u64;
450
451 let uncorrected_value = Self::new_monty(monty_reduce::<FP>(pos_inverse));
455
456 Some(uncorrected_value.mul_2exp_u64((3 * FP::MONTY_BITS - (2 * NUM_PRIME_BITS - 2)) as u64))
464 }
465
466 #[inline]
467 fn order() -> BigUint {
468 FP::PRIME.into()
469 }
470}
471
472quotient_map_small_int!(MontyField31, u32, FieldParameters, [u8, u16]);
473quotient_map_small_int!(MontyField31, i32, FieldParameters, [i8, i16]);
474
475impl<FP: FieldParameters> QuotientMap<u32> for MontyField31<FP> {
476 #[inline]
478 fn from_int(int: u32) -> Self {
479 Self::new(int)
480 }
481
482 #[inline]
486 fn from_canonical_checked(int: u32) -> Option<Self> {
487 (int < FP::PRIME).then(|| Self::new(int))
488 }
489
490 #[inline(always)]
495 unsafe fn from_canonical_unchecked(int: u32) -> Self {
496 Self::new(int)
497 }
498}
499
500impl<FP: FieldParameters> QuotientMap<i32> for MontyField31<FP> {
501 #[inline]
503 fn from_int(int: i32) -> Self {
504 Self::new_monty(to_monty_signed::<FP>(int))
505 }
506
507 #[inline]
511 fn from_canonical_checked(int: i32) -> Option<Self> {
512 let bound = (FP::PRIME >> 1) as i32;
513 if int <= bound {
514 (int >= (-bound)).then(|| Self::new_monty(to_monty_signed::<FP>(int)))
515 } else {
516 None
517 }
518 }
519
520 #[inline(always)]
525 unsafe fn from_canonical_unchecked(int: i32) -> Self {
526 Self::new_monty(to_monty_signed::<FP>(int))
527 }
528}
529
530impl<FP: FieldParameters> QuotientMap<u64> for MontyField31<FP> {
531 fn from_int(int: u64) -> Self {
533 Self::new_monty(to_monty_64::<FP>(int))
534 }
535
536 fn from_canonical_checked(int: u64) -> Option<Self> {
540 (int < FP::PRIME as u64).then(|| Self::new(int as u32))
541 }
542
543 unsafe fn from_canonical_unchecked(int: u64) -> Self {
548 Self::new_monty(to_monty_64::<FP>(int))
549 }
550}
551
552impl<FP: FieldParameters> QuotientMap<i64> for MontyField31<FP> {
553 fn from_int(int: i64) -> Self {
555 Self::new_monty(to_monty_64_signed::<FP>(int))
556 }
557
558 fn from_canonical_checked(int: i64) -> Option<Self> {
562 let bound = (FP::PRIME >> 1) as i64;
563 if int <= bound {
564 (int >= (-bound)).then(|| Self::new_monty(to_monty_signed::<FP>(int as i32)))
565 } else {
566 None
567 }
568 }
569
570 unsafe fn from_canonical_unchecked(int: i64) -> Self {
575 Self::new_monty(to_monty_64_signed::<FP>(int))
576 }
577}
578
579impl<FP: FieldParameters> QuotientMap<u128> for MontyField31<FP> {
580 fn from_int(int: u128) -> Self {
582 Self::new_monty(to_monty::<FP>((int % (FP::PRIME as u128)) as u32))
583 }
584
585 fn from_canonical_checked(int: u128) -> Option<Self> {
589 (int < FP::PRIME as u128).then(|| Self::new(int as u32))
590 }
591
592 unsafe fn from_canonical_unchecked(int: u128) -> Self {
597 Self::new_monty(to_monty_64::<FP>(int as u64))
598 }
599}
600
601impl<FP: FieldParameters> QuotientMap<i128> for MontyField31<FP> {
602 fn from_int(int: i128) -> Self {
604 Self::new_monty(to_monty_signed::<FP>((int % (FP::PRIME as i128)) as i32))
605 }
606
607 fn from_canonical_checked(int: i128) -> Option<Self> {
611 let bound = (FP::PRIME >> 1) as i128;
612 if int <= bound {
613 (int >= (-bound)).then(|| Self::new_monty(to_monty_signed::<FP>(int as i32)))
614 } else {
615 None
616 }
617 }
618
619 unsafe fn from_canonical_unchecked(int: i128) -> Self {
624 Self::new_monty(to_monty_64_signed::<FP>(int as i64))
625 }
626}
627
628impl<FP: FieldParameters> PrimeField for MontyField31<FP> {
629 fn as_canonical_biguint(&self) -> BigUint {
630 self.as_canonical_u32().into()
631 }
632}
633
634impl<FP: FieldParameters> PrimeField64 for MontyField31<FP> {
635 const ORDER_U64: u64 = FP::PRIME as u64;
636
637 #[inline]
638 fn as_canonical_u64(&self) -> u64 {
639 self.as_canonical_u32().into()
640 }
641
642 #[inline]
643 fn to_unique_u64(&self) -> u64 {
644 self.value as u64
647 }
648}
649
650impl<FP: FieldParameters> PrimeField32 for MontyField31<FP> {
651 const ORDER_U32: u32 = FP::PRIME;
652
653 #[inline]
654 fn as_canonical_u32(&self) -> u32 {
655 Self::to_u32(self)
656 }
657
658 #[inline]
659 fn to_unique_u32(&self) -> u32 {
660 self.value
663 }
664}
665
666impl<FP: FieldParameters + TwoAdicData> TwoAdicField for MontyField31<FP> {
667 const TWO_ADICITY: usize = FP::TWO_ADICITY;
668 fn two_adic_generator(bits: usize) -> Self {
669 const {
670 assert!(
672 (FP::PRIME as u64 - 1).is_multiple_of(1u64 << FP::TWO_ADICITY),
673 "2^TWO_ADICITY must divide PRIME - 1"
674 );
675 assert!(
677 ((FP::PRIME as u64 - 1) >> FP::TWO_ADICITY) % 2 == 1,
678 "TWO_ADICITY must be maximal"
679 );
680 }
681 assert!(bits <= Self::TWO_ADICITY);
682 FP::TWO_ADIC_GENERATORS.as_ref()[bits]
683 }
684}
685
686impl<FP: MontyParameters> Add for MontyField31<FP> {
687 type Output = Self;
688
689 #[inline]
690 fn add(self, rhs: Self) -> Self {
691 Self::new_monty(add::<FP>(self.value, rhs.value))
692 }
693}
694
695impl<FP: MontyParameters> Sub for MontyField31<FP> {
696 type Output = Self;
697
698 #[inline]
699 fn sub(self, rhs: Self) -> Self {
700 Self::new_monty(sub::<FP>(self.value, rhs.value))
701 }
702}
703
704impl<FP: FieldParameters> Neg for MontyField31<FP> {
705 type Output = Self;
706
707 #[inline]
708 fn neg(self) -> Self::Output {
709 Self::ZERO - self
710 }
711}
712
713impl<FP: MontyParameters> Mul for MontyField31<FP> {
714 type Output = Self;
715
716 #[inline]
717 fn mul(self, rhs: Self) -> Self {
718 let long_prod = self.value as u64 * rhs.value as u64;
719 Self::new_monty(monty_reduce::<FP>(long_prod))
720 }
721}
722
723impl_add_assign!(MontyField31, (MontyParameters, MP));
724impl_sub_assign!(MontyField31, (MontyParameters, MP));
725impl_mul_methods!(MontyField31, (FieldParameters, FP));
726impl_div_methods!(MontyField31, MontyField31, (FieldParameters, FP));
727
728impl<FP: MontyParameters> Sum for MontyField31<FP> {
729 #[inline]
730 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
731 let sum = iter.map(|x| x.value as u64).sum::<u64>();
736 Self::new_monty((sum % FP::PRIME as u64) as u32)
737 }
738}