primitives/algebra/field/mersenne/
m107.rs1use std::{
2 iter::{Product, Sum},
3 ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign},
4};
5
6use crypto_bigint::rand_core::RngCore;
7use ff::{Field, PrimeField};
8use hybrid_array::Array;
9use rand::Rng;
10use serde::{Deserialize, Serialize};
11use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
12use typenum::{U1, U14, U16};
13use wincode::{SchemaRead, SchemaWrite};
14
15use crate::{
16 algebra::{
17 field::{
18 exponentiation::{pow2_minus_1, pow2_pow},
19 FieldExtension,
20 },
21 ops::{AccReduce, ReduceWide},
22 uniform_bytes::FromUniformBytes,
23 },
24 random::{CryptoRngCore, Random},
25 types::{HeapArray, Positive},
26};
27
28mod ff_impl {
29 use ff::PrimeField;
30 use serde::{Deserialize, Serialize};
31
32 #[derive(PrimeField, Serialize, Deserialize)]
33 #[PrimeFieldModulus = "162259276829213363391578010288127"]
34 #[PrimeFieldGenerator = "3"]
35 #[PrimeFieldReprEndianness = "little"]
36 pub struct Mersenne107FF([u64; 2]);
37}
38
39#[derive(
40 Copy, Clone, Default, Debug, SchemaRead, SchemaWrite, PartialEq, Eq, Hash, Ord, PartialOrd,
41)]
42#[repr(C)]
43pub struct Mersenne107(pub(super) u128);
44
45impl Serialize for Mersenne107 {
46 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
47 where
48 S: serde::Serializer,
49 {
50 self.as_le_array().serialize(serializer)
51 }
52}
53
54impl<'de> Deserialize<'de> for Mersenne107 {
55 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
56 where
57 D: serde::Deserializer<'de>,
58 {
59 let arr = <[u8; 14]>::deserialize(deserializer)?;
60 Self::from_canonical_bytes(&arr).ok_or_else(|| {
61 serde::de::Error::custom("Invalid Mersenne107 canonical byte representation")
62 })
63 }
64}
65
66impl Mersenne107 {
67 pub const NUM_BITS: usize = 107;
68 pub const MODULUS: u128 = (1u128 << Self::NUM_BITS) - 1;
69 pub const MAX: u128 = Self::MODULUS - 1;
70
71 fn as_le_array(&self) -> [u8; 14] {
72 let mut arr = [0u8; 14];
73 arr[..14].copy_from_slice(&self.0.to_le_bytes()[..14]);
74 arr
75 }
76
77 fn from_canonical_bytes(arr: &[u8; 14]) -> Option<Self> {
78 let mut tmp = [0u8; 16];
79 tmp[..14].copy_from_slice(arr);
80 let val = u128::from_le_bytes(tmp);
81 (val < Self::MODULUS).then_some(Self(val))
82 }
83}
84
85#[macros::op_variants(owned)]
90impl<'a> MulAssign<&'a Mersenne107> for Mersenne107 {
91 #[inline]
92 fn mul_assign(&mut self, rhs: &'a Mersenne107) {
93 self.0 = super::m107_ops::mul(self.0, rhs.0);
94 }
95}
96
97#[macros::op_variants(owned)]
98impl<'a> Mul<&'a Mersenne107> for Mersenne107 {
99 type Output = Self;
100 #[inline]
101 fn mul(self, rhs: &'a Mersenne107) -> Self::Output {
102 let mut res = self;
103 res.mul_assign(rhs);
104 res
105 }
106}
107
108#[macros::op_variants(owned)]
113impl<'a> AddAssign<&'a Mersenne107> for Mersenne107 {
114 #[inline]
115 fn add_assign(&mut self, rhs: &'a Mersenne107) {
116 self.0 += rhs.0;
117 super::m107_ops::reduce_mod_1bit_inplace(&mut self.0);
118 }
119}
120#[macros::op_variants(owned)]
121impl<'a> Add<&'a Mersenne107> for Mersenne107 {
122 type Output = Self;
123
124 #[inline]
125 fn add(self, rhs: &'a Mersenne107) -> Self::Output {
126 let mut res = self;
127 res.add_assign(rhs);
128 res
129 }
130}
131
132#[macros::op_variants(owned)]
137impl<'a> SubAssign<&'a Mersenne107> for Mersenne107 {
138 #[inline]
139 fn sub_assign(&mut self, rhs: &'a Mersenne107) {
140 self.0 += Self::MODULUS - rhs.0;
141 super::m107_ops::reduce_mod_1bit_inplace(&mut self.0);
142 }
143}
144
145#[macros::op_variants(owned)]
146impl<'a> Sub<&'a Mersenne107> for Mersenne107 {
147 type Output = Self;
148
149 #[inline]
150 fn sub(mut self, rhs: &'a Mersenne107) -> Self::Output {
151 self.sub_assign(rhs);
152 self
153 }
154}
155
156#[macros::op_variants(borrowed)]
161impl Neg for Mersenne107 {
162 type Output = Mersenne107;
163
164 fn neg(self) -> Self::Output {
165 Self(super::m107_ops::reduce_mod_1bit(Self::MODULUS - self.0))
166 }
167}
168
169impl ConditionallySelectable for Mersenne107 {
174 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
175 Self(u128::conditional_select(&a.0, &b.0, choice))
176 }
177}
178
179impl ConstantTimeEq for Mersenne107 {
180 fn ct_eq(&self, other: &Self) -> Choice {
181 self.0.ct_eq(&other.0)
182 }
183}
184
185impl Sum for Mersenne107 {
190 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
191 let t = iter.fold(<Self as AccReduce>::zero_wide(), |mut acc, x| {
192 Self::acc(&mut acc, &x);
193 acc
194 });
195 Self::reduce_mod_order(t)
196 }
197}
198
199impl<'a> Sum<&'a Self> for Mersenne107 {
200 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
201 let t = iter.fold(<Self as AccReduce>::zero_wide(), |mut acc, x| {
202 Self::acc(&mut acc, x);
203 acc
204 });
205 Self::reduce_mod_order(t)
206 }
207}
208
209impl<'a> Product<&'a Self> for Mersenne107 {
210 fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
211 iter.fold(Self::ONE, |acc, x| acc * x)
212 }
213}
214
215impl Product for Mersenne107 {
216 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
217 iter.fold(Self::ONE, |acc, x| acc * x)
218 }
219}
220
221impl Field for Mersenne107 {
226 const ZERO: Self = Mersenne107(0);
227 const ONE: Self = Mersenne107(1);
228
229 fn random(mut rng: impl RngCore) -> Self {
230 let tmp = rng.gen::<u128>();
231 Self(super::m107_ops::reduce_mod(tmp)) }
235
236 fn square(&self) -> Self {
237 *self * self }
239
240 fn double(&self) -> Self {
241 Self(super::m107_ops::reduce_mod_1bit(self.0 << 1))
242 }
243
244 fn invert(&self) -> CtOption<Self> {
245 let val: ff_impl::Mersenne107FF = self.into();
248 let inv = val.invert();
249 inv.map(|v| v.into())
250 }
251
252 fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
253 let uv = *num * div;
259 let uv3 = div.square() * uv;
260 let y = uv * pow2_minus_1(uv3, 105);
261 let is_qr = (y.square() * div).ct_eq(num);
262 (is_qr, y)
263 }
264
265 fn sqrt(&self) -> CtOption<Self> {
266 let root = pow2_pow(*self, 105);
270 CtOption::new(root, root.square().ct_eq(self))
271 }
272}
273
274impl FieldExtension for Mersenne107 {
279 type Subfield = Self;
280 type Degree = U1;
281 type FieldBitSize = typenum::U<{ Mersenne107::NUM_BITS }>;
282 type FieldBytesSize = U14;
283
284 fn to_subfield_elements(&self) -> Array<Self::Subfield, Self::Degree> {
285 Array([*self])
286 }
287
288 fn from_subfield_elements(elems: Array<Self::Subfield, Self::Degree>) -> Self {
289 elems[0]
290 }
291
292 fn to_le_bytes(&self) -> Array<u8, Self::FieldBytesSize> {
293 self.as_le_array().into()
294 }
295
296 fn from_le_bytes(bytes: &[u8]) -> Option<Self> {
297 if bytes.len() == 14 {
298 let arr: &[u8; 14] = bytes.try_into().expect("This should never fail");
299 Self::from_canonical_bytes(arr)
300 } else {
301 None
302 }
303 }
304
305 fn mul_by_subfield(&self, other: &Self::Subfield) -> Self {
306 *self * other
307 }
308
309 fn generator() -> Self {
310 Self(3u128) }
312}
313
314impl Random for Mersenne107 {
315 fn random(mut rng: impl CryptoRngCore) -> Self {
316 let tmp = rng.gen::<u128>();
317 Self(super::m107_ops::reduce_mod(tmp))
318 }
319
320 fn random_array<M: Positive>(mut rng: impl CryptoRngCore) -> HeapArray<Self, M> {
321 let mut buf = HeapArray::<Self, M>::default().into_box_bytes();
322 rng.fill_bytes(&mut buf);
323 let mut tmp = HeapArray::from_box_bytes(buf);
324 tmp.iter_mut()
325 .for_each(|v: &mut Self| super::m107_ops::reduce_mod_inplace(&mut v.0));
326 tmp
327 }
328}
329
330unsafe impl bytemuck::Zeroable for Mersenne107 {}
331unsafe impl bytemuck::Pod for Mersenne107 {}
332
333impl FromUniformBytes for Mersenne107 {
334 type UniformBytes = U16;
335 fn from_uniform_bytes(bytes: &hybrid_array::Array<u8, Self::UniformBytes>) -> Self {
336 let mut val = u128::from_le_bytes(bytes.0);
337 super::m107_ops::reduce_mod_inplace(&mut val);
338 Self(val)
339 }
340}
341
342impl From<u64> for Mersenne107 {
343 fn from(val: u64) -> Self {
344 Self(val as u128)
345 }
346}
347
348impl From<u128> for Mersenne107 {
349 fn from(val: u128) -> Self {
350 Self(super::m107_ops::reduce_mod(val))
351 }
352}
353
354impl From<ff_impl::Mersenne107FF> for Mersenne107 {
355 fn from(val: ff_impl::Mersenne107FF) -> Self {
356 Self::from_le_bytes(&val.to_repr().as_ref()[..14]).unwrap()
357 }
358}
359
360impl<'a> From<&'a Mersenne107> for ff_impl::Mersenne107FF {
361 fn from(val: &'a Mersenne107) -> Self {
362 Self::from_repr(ff_impl::Mersenne107FFRepr(val.0.to_le_bytes())).unwrap()
363 }
364}
365
366#[cfg(test)]
367mod test {
368 use ff::Field;
369 use num_bigint::BigInt;
370 use typenum::Unsigned;
371
372 use crate::{
373 algebra::field::{
374 mersenne::{m107::Mersenne107, test::bigint_to_m107},
375 FieldExtension,
376 },
377 random::test_rng,
378 };
379
380 type M = typenum::U1000;
381
382 #[test]
383 fn test_neg() {
384 fn test_internal(a: Mersenne107) {
385 let exp = bigint_to_m107(-BigInt::from(a.0));
386 let act = -a;
387 assert_eq!(exp, act, "a = {a:?}");
388 }
389
390 let mut rng = test_rng();
391 for _ in 0..M::to_usize() {
392 let a = Mersenne107::random(&mut rng);
393 test_internal(a);
394 }
395
396 test_internal(Mersenne107::ZERO);
398 test_internal(Mersenne107::ONE);
399 test_internal(Mersenne107(Mersenne107::MAX));
400 }
401
402 #[test]
403 fn test_invert() {
404 fn test_internal(a: Mersenne107) {
405 let a_inv = a.invert().unwrap();
406 let act = a * a_inv;
407 assert_eq!(Mersenne107::ONE, act, "a = {a:?}");
408 }
409
410 let mut rng = test_rng();
411 for _ in 0..M::to_usize() {
412 let a = Mersenne107::random(&mut rng);
413 if a == Mersenne107::ZERO {
414 continue;
415 }
416 test_internal(a);
417 }
418
419 test_internal(Mersenne107::ONE);
421 test_internal(Mersenne107(Mersenne107::MAX));
422 }
423
424 #[test]
425 fn test_sqrt() {
426 fn test_internal(a: Mersenne107) {
427 let a_sqrt = a.sqrt();
428 if a_sqrt.into_option().is_none() {
429 return;
430 }
431
432 let a_sqrt = a_sqrt.unwrap();
433 let act = a_sqrt * a_sqrt;
434 assert_eq!(a, act, "a = {a:?}");
435 }
436
437 let mut rng = test_rng();
438 for _ in 0..M::to_usize() {
439 let a = Mersenne107::random(&mut rng);
440 test_internal(a);
441 }
442
443 test_internal(Mersenne107::ZERO);
445 test_internal(Mersenne107::ONE);
446 test_internal(Mersenne107(Mersenne107::MAX));
447 }
448
449 #[test]
450 fn test_sqrt_ratio() {
451 fn test_internal(num: Mersenne107, div: Mersenne107) {
452 let (is_qr, y) = Mersenne107::sqrt_ratio(&num, &div);
453
454 let num_ff: super::ff_impl::Mersenne107FF = (&num).into();
456 let div_ff: super::ff_impl::Mersenne107FF = (&div).into();
457 let (is_qr_ref, _) = super::ff_impl::Mersenne107FF::sqrt_ratio(&num_ff, &div_ff);
458 assert_eq!(
459 bool::from(is_qr),
460 bool::from(is_qr_ref),
461 "QR mismatch for num={num:?} div={div:?}"
462 );
463
464 if bool::from(is_qr) {
466 assert_eq!(
467 y.square() * div,
468 num,
469 "wrong root for num={num:?} div={div:?}"
470 );
471 }
472 }
473
474 let mut rng = test_rng();
475 for _ in 0..M::to_usize() {
476 let num = Mersenne107::random(&mut rng);
477 let div = Mersenne107::random(&mut rng);
478 if div == Mersenne107::ZERO {
479 continue;
480 }
481 test_internal(num, div);
482 test_internal(Mersenne107::ONE, div);
484 }
485
486 test_internal(Mersenne107::ONE, Mersenne107::ONE);
488 test_internal(Mersenne107::ZERO, Mersenne107::ONE);
489 test_internal(Mersenne107(Mersenne107::MAX), Mersenne107::ONE);
490 }
491
492 #[test]
493 fn test_canonical_bytes_decoding() {
494 let value = Mersenne107::from(123456789u64);
495 let bytes = value.to_le_bytes();
496 assert_eq!(Mersenne107::from_le_bytes(&bytes), Some(value));
497
498 let modulus_bytes = [
500 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x07,
501 ];
502 assert_eq!(Mersenne107::from_le_bytes(&modulus_bytes), None);
503 }
504
505 macro_rules! test_op {
506 ($op:tt) => {
507 fn test_internal(a: Mersenne107, b: Mersenne107) {
508 let exp = bigint_to_m107(BigInt::from(a.0) $op BigInt::from(b.0));
509 let act = a $op b;
510 assert_eq!(exp, act, "a = {a:?}, b = {b:?}");
511 }
512
513 let mut rng = test_rng();
514 for _ in 0..M::to_usize() {
515 let a = Mersenne107::random(&mut rng);
516 let b = Mersenne107::random(&mut rng);
517 test_internal(a, b);
518 }
519
520 test_internal(Mersenne107::ZERO, Mersenne107::ZERO);
522 test_internal(Mersenne107::ZERO, Mersenne107::ONE);
523 test_internal(Mersenne107::ONE, Mersenne107::ZERO);
524 test_internal(Mersenne107::ONE, Mersenne107::ONE);
525 test_internal(Mersenne107::ZERO, Mersenne107(Mersenne107::MAX));
526 test_internal(Mersenne107::ONE, Mersenne107(Mersenne107::MAX));
527 test_internal(Mersenne107(Mersenne107::MAX), Mersenne107::ZERO);
528 test_internal(Mersenne107(Mersenne107::MAX), Mersenne107::ONE);
529 test_internal(Mersenne107(Mersenne107::MAX), Mersenne107(Mersenne107::MAX));
530 }
531 }
532
533 #[test]
534 fn test_mul() {
535 test_op!(*);
536 }
537 #[test]
538 fn test_add() {
539 test_op!(+);
540 }
541 #[test]
542 fn test_sub() {
543 test_op!(-);
544 }
545}