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 Self {
53 value: to_monty::<MP>(value),
54 _phantom: PhantomData,
55 }
56 }
57
58 #[inline(always)]
62 pub(crate) const fn new_monty(value: u32) -> Self {
63 Self {
64 value,
65 _phantom: PhantomData,
66 }
67 }
68
69 #[inline(always)]
71 pub(crate) const fn to_u32(elem: &Self) -> u32 {
72 from_monty::<MP>(elem.value)
73 }
74
75 #[inline]
79 pub const fn new_array<const N: usize>(input: [u32; N]) -> [Self; N] {
80 let mut output = [Self::new_monty(0); N];
81 let mut i = 0;
82 while i < N {
83 output[i] = Self::new(input[i]);
84 i += 1;
85 }
86 output
87 }
88
89 #[inline]
92 pub const fn new_2d_array<const N: usize, const M: usize>(
93 input: [[u32; N]; M],
94 ) -> [[Self; N]; M] {
95 let mut output = [[Self::new_monty(0); N]; M];
96 let mut i = 0;
97 while i < M {
98 output[i] = Self::new_array(input[i]);
99 i += 1;
100 }
101 output
102 }
103}
104
105impl<FP: FieldParameters> MontyField31<FP> {
106 const MONTY_POWERS_OF_TWO: [Self; 64] = {
107 let mut powers_of_two = [FP::MONTY_ONE; 64];
108 let mut i = 1;
109 while i < 64 {
110 powers_of_two[i] = Self::new_monty(to_monty_64::<FP>(1 << i));
111 i += 1;
112 }
113 powers_of_two
114 };
115
116 const HALF: Self = Self::new(FP::HALF_P_PLUS_1);
117}
118
119impl<FP: MontyParameters> Ord for MontyField31<FP> {
120 #[inline]
121 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
122 Self::to_u32(self).cmp(&Self::to_u32(other))
123 }
124}
125
126impl<FP: MontyParameters> PartialOrd for MontyField31<FP> {
127 #[inline]
128 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
129 Some(self.cmp(other))
130 }
131}
132
133impl<FP: MontyParameters> Display for MontyField31<FP> {
134 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
135 Display::fmt(&Self::to_u32(self), f)
136 }
137}
138
139impl<FP: MontyParameters> Debug for MontyField31<FP> {
140 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
141 Debug::fmt(&Self::to_u32(self), f)
142 }
143}
144
145impl<FP: MontyParameters> Distribution<MontyField31<FP>> for StandardUniform {
146 #[inline]
147 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MontyField31<FP> {
148 loop {
149 let next_u31 = rng.next_u32() >> 1;
150 let is_canonical = next_u31 < FP::PRIME;
151 if is_canonical {
152 return MontyField31::new_monty(next_u31);
153 }
154 }
155 }
156}
157
158impl<FP: FieldParameters> Serialize for MontyField31<FP> {
159 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
160 serializer.serialize_u32(self.value)
162 }
163}
164
165impl<'de, FP: FieldParameters> Deserialize<'de> for MontyField31<FP> {
166 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
167 let val = u32::deserialize(d)?;
169 if val < FP::PRIME {
170 Ok(Self::new_monty(val))
171 } else {
172 Err(D::Error::custom("Value is out of range"))
173 }
174 }
175}
176
177impl<MP: MontyParameters> Packable for MontyField31<MP> {}
178
179impl<FP: FieldParameters> PrimeCharacteristicRing for MontyField31<FP> {
180 type PrimeSubfield = Self;
181
182 const ZERO: Self = FP::MONTY_ZERO;
183 const ONE: Self = FP::MONTY_ONE;
184 const TWO: Self = FP::MONTY_TWO;
185 const NEG_ONE: Self = FP::MONTY_NEG_ONE;
186
187 #[inline(always)]
188 fn from_prime_subfield(f: Self) -> Self {
189 f
190 }
191
192 #[inline]
193 fn halve(&self) -> Self {
194 Self::new_monty(halve_u32::<FP>(self.value))
195 }
196
197 #[inline]
198 fn mul_2exp_u64(&self, exp: u64) -> Self {
199 if exp < 64 {
203 *self * Self::MONTY_POWERS_OF_TWO[exp as usize]
204 } else {
205 *self * Self::TWO.exp_u64(exp)
207 }
208 }
209
210 #[inline]
211 fn div_2exp_u64(&self, exp: u64) -> Self {
212 if exp <= 32 {
213 let long_prod = (self.value as u64) << (32 - exp);
217 Self::new_monty(monty_reduce::<FP>(long_prod))
218 } else {
219 *self * Self::HALF.exp_u64(exp)
222 }
223 }
224
225 #[inline]
226 fn zero_vec(len: usize) -> Vec<Self> {
227 unsafe { flatten_to_base(vec![0u32; len]) }
233 }
234
235 #[inline]
236 fn sum_array<const N: usize>(input: &[Self]) -> Self {
237 assert_eq!(N, input.len());
238 match N {
242 0 => Self::ZERO,
243 1 => input[0],
244 2 => input[0] + input[1],
245 3 => input[0] + input[1] + input[2],
246 4 => (input[0] + input[1]) + (input[2] + input[3]),
247 5 => Self::sum_array::<4>(&input[..4]) + Self::sum_array::<1>(&input[4..]),
248 6 => Self::sum_array::<4>(&input[..4]) + Self::sum_array::<2>(&input[4..]),
249 7 => Self::sum_array::<4>(&input[..4]) + Self::sum_array::<3>(&input[4..]),
250 _ => input.iter().copied().sum(),
251 }
252 }
253
254 #[inline]
255 fn dot_product<const N: usize>(lhs: &[Self; N], rhs: &[Self; N]) -> Self {
256 const {
257 assert!(N as u64 <= (1 << 34));
258
259 debug_assert!(FP::MONTY_BITS == 32);
262 debug_assert!((FP::PRIME as u64) < (1 << 31));
263 }
264 match N {
265 0 => Self::ZERO,
266 1 => lhs[0] * rhs[0],
267 2 => {
268 let u64_prod_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
272 + (lhs[1].value as u64) * (rhs[1].value as u64);
273 Self::new_monty(monty_reduce::<FP>(u64_prod_sum))
274 }
275 3 => {
276 let u64_prod_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
279 + (lhs[1].value as u64) * (rhs[1].value as u64)
280 + (lhs[2].value as u64) * (rhs[2].value as u64);
281 Self::new_monty(large_monty_reduce::<FP>(u64_prod_sum))
282 }
283 4 => {
284 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 + (lhs[2].value as u64) * (rhs[2].value as u64)
289 + (lhs[3].value as u64) * (rhs[3].value as u64);
290 Self::new_monty(large_monty_reduce::<FP>(u64_prod_sum))
291 }
292 5 => {
293 let head_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 + (lhs[3].value as u64) * (rhs[3].value as u64);
297 let tail_sum = (lhs[4].value as u64) * (rhs[4].value as u64);
298 let head_sum_corr = head_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
300 let sum = head_sum.min(head_sum_corr) + tail_sum;
303 Self::new_monty(large_monty_reduce::<FP>(sum))
304 }
305 6 => {
306 let head_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
307 + (lhs[1].value as u64) * (rhs[1].value as u64)
308 + (lhs[2].value as u64) * (rhs[2].value as u64)
309 + (lhs[3].value as u64) * (rhs[3].value as u64);
310 let tail_sum = (lhs[4].value as u64) * (rhs[4].value as u64)
311 + (lhs[5].value as u64) * (rhs[5].value as u64);
312 let head_sum_corr = head_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
314 let sum = head_sum.min(head_sum_corr) + tail_sum;
317 Self::new_monty(large_monty_reduce::<FP>(sum))
318 }
319 7 => {
320 let head_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
321 + (lhs[1].value as u64) * (rhs[1].value as u64)
322 + (lhs[2].value as u64) * (rhs[2].value as u64)
323 + (lhs[3].value as u64) * (rhs[3].value as u64);
324 let tail_sum = (lhs[4].value as u64) * (rhs[4].value as u64)
325 + lhs[5].value as u64 * (rhs[5].value as u64)
326 + lhs[6].value as u64 * (rhs[6].value as u64);
327 let head_sum_corr = head_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
329 let tail_sum_corr = tail_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
330 let sum = head_sum.min(head_sum_corr) + tail_sum.min(tail_sum_corr);
333 Self::new_monty(large_monty_reduce::<FP>(sum))
334 }
335 8 => {
336 let head_sum = (lhs[0].value as u64) * (rhs[0].value as u64)
337 + (lhs[1].value as u64) * (rhs[1].value as u64)
338 + (lhs[2].value as u64) * (rhs[2].value as u64)
339 + (lhs[3].value as u64) * (rhs[3].value as u64);
340 let tail_sum = (lhs[4].value as u64) * (rhs[4].value as u64)
341 + lhs[5].value as u64 * (rhs[5].value as u64)
342 + lhs[6].value as u64 * (rhs[6].value as u64)
343 + lhs[7].value as u64 * (rhs[7].value as u64);
344 let head_sum_corr = head_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
346 let tail_sum_corr = tail_sum.wrapping_sub((FP::PRIME as u64) << FP::MONTY_BITS);
347 let sum = head_sum.min(head_sum_corr) + tail_sum.min(tail_sum_corr);
350 Self::new_monty(large_monty_reduce::<FP>(sum))
351 }
352 _ => {
353 let acc_u128 = lhs
356 .chunks(4)
357 .zip(rhs.chunks(4))
358 .map(|(l, r)| {
359 let u64_prod_sum = l
363 .iter()
364 .zip(r)
365 .map(|(l, r)| (l.value as u64) * (r.value as u64))
366 .sum::<u64>();
367 u64_prod_sum as u128
368 })
369 .sum();
370 Self::new_monty(monty_reduce_u128::<FP>(acc_u128))
372 }
373 }
374 }
375}
376
377impl<FP: FieldParameters + RelativelyPrimePower<D>, const D: u64> InjectiveMonomial<D>
378 for MontyField31<FP>
379{
380}
381
382impl<FP: FieldParameters + RelativelyPrimePower<D>, const D: u64> PermutationMonomial<D>
383 for MontyField31<FP>
384{
385 fn injective_exp_root_n(&self) -> Self {
386 FP::exp_root_d(*self)
387 }
388}
389
390impl<FP: FieldParameters> RawDataSerializable for MontyField31<FP> {
391 impl_raw_serializable_primefield32!();
392}
393
394impl<FP: FieldParameters> Field for MontyField31<FP> {
395 #[cfg(all(target_arch = "aarch64", target_feature = "neon"))]
396 type Packing = crate::PackedMontyField31Neon<FP>;
397 #[cfg(all(
398 target_arch = "x86_64",
399 target_feature = "avx2",
400 not(target_feature = "avx512f")
401 ))]
402 type Packing = crate::PackedMontyField31AVX2<FP>;
403 #[cfg(all(target_arch = "x86_64", target_feature = "avx512f"))]
404 type Packing = crate::PackedMontyField31AVX512<FP>;
405 #[cfg(not(any(
406 all(target_arch = "aarch64", target_feature = "neon"),
407 all(
408 target_arch = "x86_64",
409 target_feature = "avx2",
410 not(target_feature = "avx512f")
411 ),
412 all(target_arch = "x86_64", target_feature = "avx512f"),
413 )))]
414 type Packing = Self;
415
416 const GENERATOR: Self = FP::MONTY_GEN;
417
418 fn try_inverse(&self) -> Option<Self> {
419 if self.is_zero() {
420 return None;
421 }
422
423 const NUM_PRIME_BITS: u32 = 31;
425
426 let gcd_inverse = gcd_inversion_prime_field_32::<NUM_PRIME_BITS>(self.value, FP::PRIME);
431
432 let pos_inverse = (((FP::PRIME as i64) << 30) + gcd_inverse) as u64;
435
436 let uncorrected_value = Self::new_monty(monty_reduce::<FP>(pos_inverse));
440
441 Some(uncorrected_value.mul_2exp_u64((3 * FP::MONTY_BITS - (2 * NUM_PRIME_BITS - 2)) as u64))
449 }
450
451 #[inline]
452 fn order() -> BigUint {
453 FP::PRIME.into()
454 }
455}
456
457quotient_map_small_int!(MontyField31, u32, FieldParameters, [u8, u16]);
458quotient_map_small_int!(MontyField31, i32, FieldParameters, [i8, i16]);
459
460impl<FP: FieldParameters> QuotientMap<u32> for MontyField31<FP> {
461 #[inline]
463 fn from_int(int: u32) -> Self {
464 Self::new(int)
465 }
466
467 #[inline]
471 fn from_canonical_checked(int: u32) -> Option<Self> {
472 (int < FP::PRIME).then(|| Self::new(int))
473 }
474
475 #[inline(always)]
480 unsafe fn from_canonical_unchecked(int: u32) -> Self {
481 Self::new(int)
482 }
483}
484
485impl<FP: FieldParameters> QuotientMap<i32> for MontyField31<FP> {
486 #[inline]
488 fn from_int(int: i32) -> Self {
489 Self::new_monty(to_monty_signed::<FP>(int))
490 }
491
492 #[inline]
496 fn from_canonical_checked(int: i32) -> Option<Self> {
497 let bound = (FP::PRIME >> 1) as i32;
498 if int <= bound {
499 (int >= (-bound)).then(|| Self::new_monty(to_monty_signed::<FP>(int)))
500 } else {
501 None
502 }
503 }
504
505 #[inline(always)]
510 unsafe fn from_canonical_unchecked(int: i32) -> Self {
511 Self::new_monty(to_monty_signed::<FP>(int))
512 }
513}
514
515impl<FP: FieldParameters> QuotientMap<u64> for MontyField31<FP> {
516 fn from_int(int: u64) -> Self {
518 Self::new_monty(to_monty_64::<FP>(int))
519 }
520
521 fn from_canonical_checked(int: u64) -> Option<Self> {
525 (int < FP::PRIME as u64).then(|| Self::new(int as u32))
526 }
527
528 unsafe fn from_canonical_unchecked(int: u64) -> Self {
533 Self::new_monty(to_monty_64::<FP>(int))
534 }
535}
536
537impl<FP: FieldParameters> QuotientMap<i64> for MontyField31<FP> {
538 fn from_int(int: i64) -> Self {
540 Self::new_monty(to_monty_64_signed::<FP>(int))
541 }
542
543 fn from_canonical_checked(int: i64) -> Option<Self> {
547 let bound = (FP::PRIME >> 1) as i64;
548 if int <= bound {
549 (int >= (-bound)).then(|| Self::new_monty(to_monty_signed::<FP>(int as i32)))
550 } else {
551 None
552 }
553 }
554
555 unsafe fn from_canonical_unchecked(int: i64) -> Self {
560 Self::new_monty(to_monty_64_signed::<FP>(int))
561 }
562}
563
564impl<FP: FieldParameters> QuotientMap<u128> for MontyField31<FP> {
565 fn from_int(int: u128) -> Self {
567 Self::new_monty(to_monty::<FP>((int % (FP::PRIME as u128)) as u32))
568 }
569
570 fn from_canonical_checked(int: u128) -> Option<Self> {
574 (int < FP::PRIME as u128).then(|| Self::new(int as u32))
575 }
576
577 unsafe fn from_canonical_unchecked(int: u128) -> Self {
582 Self::new_monty(to_monty_64::<FP>(int as u64))
583 }
584}
585
586impl<FP: FieldParameters> QuotientMap<i128> for MontyField31<FP> {
587 fn from_int(int: i128) -> Self {
589 Self::new_monty(to_monty_signed::<FP>((int % (FP::PRIME as i128)) as i32))
590 }
591
592 fn from_canonical_checked(int: i128) -> Option<Self> {
596 let bound = (FP::PRIME >> 1) as i128;
597 if int <= bound {
598 (int >= (-bound)).then(|| Self::new_monty(to_monty_signed::<FP>(int as i32)))
599 } else {
600 None
601 }
602 }
603
604 unsafe fn from_canonical_unchecked(int: i128) -> Self {
609 Self::new_monty(to_monty_64_signed::<FP>(int as i64))
610 }
611}
612
613impl<FP: FieldParameters> PrimeField for MontyField31<FP> {
614 fn as_canonical_biguint(&self) -> BigUint {
615 self.as_canonical_u32().into()
616 }
617}
618
619impl<FP: FieldParameters> PrimeField64 for MontyField31<FP> {
620 const ORDER_U64: u64 = FP::PRIME as u64;
621
622 #[inline]
623 fn as_canonical_u64(&self) -> u64 {
624 self.as_canonical_u32().into()
625 }
626
627 #[inline]
628 fn to_unique_u64(&self) -> u64 {
629 self.value as u64
632 }
633}
634
635impl<FP: FieldParameters> PrimeField32 for MontyField31<FP> {
636 const ORDER_U32: u32 = FP::PRIME;
637
638 #[inline]
639 fn as_canonical_u32(&self) -> u32 {
640 Self::to_u32(self)
641 }
642
643 #[inline]
644 fn to_unique_u32(&self) -> u32 {
645 self.value
648 }
649}
650
651impl<FP: FieldParameters + TwoAdicData> TwoAdicField for MontyField31<FP> {
652 const TWO_ADICITY: usize = FP::TWO_ADICITY;
653 fn two_adic_generator(bits: usize) -> Self {
654 assert!(bits <= Self::TWO_ADICITY);
655 FP::TWO_ADIC_GENERATORS.as_ref()[bits]
656 }
657}
658
659impl<FP: MontyParameters> Add for MontyField31<FP> {
660 type Output = Self;
661
662 #[inline]
663 fn add(self, rhs: Self) -> Self {
664 Self::new_monty(add::<FP>(self.value, rhs.value))
665 }
666}
667
668impl<FP: MontyParameters> Sub for MontyField31<FP> {
669 type Output = Self;
670
671 #[inline]
672 fn sub(self, rhs: Self) -> Self {
673 Self::new_monty(sub::<FP>(self.value, rhs.value))
674 }
675}
676
677impl<FP: FieldParameters> Neg for MontyField31<FP> {
678 type Output = Self;
679
680 #[inline]
681 fn neg(self) -> Self::Output {
682 Self::ZERO - self
683 }
684}
685
686impl<FP: MontyParameters> Mul for MontyField31<FP> {
687 type Output = Self;
688
689 #[inline]
690 fn mul(self, rhs: Self) -> Self {
691 let long_prod = self.value as u64 * rhs.value as u64;
692 Self::new_monty(monty_reduce::<FP>(long_prod))
693 }
694}
695
696impl_add_assign!(MontyField31, (MontyParameters, MP));
697impl_sub_assign!(MontyField31, (MontyParameters, MP));
698impl_mul_methods!(MontyField31, (FieldParameters, FP));
699impl_div_methods!(MontyField31, MontyField31, (FieldParameters, FP));
700
701impl<FP: MontyParameters> Sum for MontyField31<FP> {
702 #[inline]
703 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
704 let sum = iter.map(|x| x.value as u64).sum::<u64>();
709 Self::new_monty((sum % FP::PRIME as u64) as u32)
710 }
711}