1use core::convert::TryInto;
5use core::fmt;
6use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8use ff::{Field, PrimeField};
9use rand_core::RngCore;
10use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
11
12#[cfg(feature = "bits")]
13use ff::{FieldBits, PrimeFieldBits};
14
15use crate::util::{adc, mac, sbb};
16
17#[derive(Clone, Copy, Eq)]
23pub struct Fr(pub(crate) [u64; 4]);
24
25impl fmt::Debug for Fr {
26 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27 let tmp = self.to_bytes();
28 write!(f, "0x")?;
29 for &b in tmp.iter().rev() {
30 write!(f, "{:02x}", b)?;
31 }
32 Ok(())
33 }
34}
35
36impl fmt::Display for Fr {
37 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38 write!(f, "{:?}", self)
39 }
40}
41
42impl From<u64> for Fr {
43 fn from(val: u64) -> Fr {
44 Fr([val, 0, 0, 0]) * R2
45 }
46}
47
48impl ConstantTimeEq for Fr {
49 fn ct_eq(&self, other: &Self) -> Choice {
50 self.0[0].ct_eq(&other.0[0])
51 & self.0[1].ct_eq(&other.0[1])
52 & self.0[2].ct_eq(&other.0[2])
53 & self.0[3].ct_eq(&other.0[3])
54 }
55}
56
57impl PartialEq for Fr {
58 #[inline]
59 fn eq(&self, other: &Self) -> bool {
60 bool::from(self.ct_eq(other))
61 }
62}
63
64impl ConditionallySelectable for Fr {
65 fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
66 Fr([
67 u64::conditional_select(&a.0[0], &b.0[0], choice),
68 u64::conditional_select(&a.0[1], &b.0[1], choice),
69 u64::conditional_select(&a.0[2], &b.0[2], choice),
70 u64::conditional_select(&a.0[3], &b.0[3], choice),
71 ])
72 }
73}
74
75pub const MODULUS: Fr = Fr([
78 0xd097_0e5e_d6f7_2cb7,
79 0xa668_2093_ccc8_1082,
80 0x0667_3b01_0134_3b00,
81 0x0e7d_b4ea_6533_afa9,
82]);
83
84#[cfg(not(target_pointer_width = "64"))]
86const MODULUS_LIMBS_32: [u32; 8] = [
87 0xd6f7_2cb7,
88 0xd097_0e5e,
89 0xccc8_1082,
90 0xa668_2093,
91 0x0134_3b00,
92 0x0667_3b01,
93 0x6533_afa9,
94 0x0e7d_b4ea,
95];
96
97const MODULUS_BITS: u32 = 252;
99
100const GENERATOR: Fr = Fr([
102 0x720b_1b19_d49e_a8f1,
103 0xbf4a_a361_01f1_3a58,
104 0x5fa8_cc96_8193_ccbb,
105 0x0e70_cbdc_7dcc_f3ac,
106]);
107
108const S: u32 = 1;
110
111const ROOT_OF_UNITY: Fr = Fr([
113 0xaa9f_02ab_1d61_24de,
114 0xb352_4a64_6611_2932,
115 0x7342_2612_15ac_260b,
116 0x04d6_b87b_1da2_59e2,
117]);
118
119impl<'a> Neg for &'a Fr {
120 type Output = Fr;
121
122 #[inline]
123 fn neg(self) -> Fr {
124 self.neg()
125 }
126}
127
128impl Neg for Fr {
129 type Output = Fr;
130
131 #[inline]
132 fn neg(self) -> Fr {
133 -&self
134 }
135}
136
137impl<'a, 'b> Sub<&'b Fr> for &'a Fr {
138 type Output = Fr;
139
140 #[inline]
141 fn sub(self, rhs: &'b Fr) -> Fr {
142 self.sub(rhs)
143 }
144}
145
146impl<'a, 'b> Add<&'b Fr> for &'a Fr {
147 type Output = Fr;
148
149 #[inline]
150 fn add(self, rhs: &'b Fr) -> Fr {
151 self.add(rhs)
152 }
153}
154
155impl<'a, 'b> Mul<&'b Fr> for &'a Fr {
156 type Output = Fr;
157
158 #[inline]
159 fn mul(self, rhs: &'b Fr) -> Fr {
160 self.mul(rhs)
163 }
164}
165
166impl_binops_additive!(Fr, Fr);
167impl_binops_multiplicative!(Fr, Fr);
168
169const INV: u64 = 0x1ba3_a358_ef78_8ef9;
171
172const R: Fr = Fr([
174 0x25f8_0bb3_b996_07d9,
175 0xf315_d62f_66b6_e750,
176 0x9325_14ee_eb88_14f4,
177 0x09a6_fc6f_4791_55c6,
178]);
179
180const R2: Fr = Fr([
182 0x6771_9aa4_95e5_7731,
183 0x51b0_cef0_9ce3_fc26,
184 0x69da_b7fa_c026_e9a5,
185 0x04f6_547b_8d12_7688,
186]);
187
188const R3: Fr = Fr([
190 0xe0d6_c656_3d83_0544,
191 0x323e_3883_598d_0f85,
192 0xf0fe_a300_4c2e_2ba8,
193 0x0587_4f84_9467_37ec,
194]);
195
196impl Default for Fr {
197 fn default() -> Self {
198 Self::zero()
199 }
200}
201
202impl Fr {
203 #[inline]
205 pub const fn zero() -> Fr {
206 Fr([0, 0, 0, 0])
207 }
208
209 #[inline]
211 pub const fn one() -> Fr {
212 R
213 }
214
215 #[inline]
217 pub const fn double(&self) -> Fr {
218 self.add(self)
219 }
220
221 pub fn from_bytes(bytes: &[u8; 32]) -> CtOption<Fr> {
225 let mut tmp = Fr([0, 0, 0, 0]);
226
227 tmp.0[0] = u64::from_le_bytes(bytes[0..8].try_into().unwrap());
228 tmp.0[1] = u64::from_le_bytes(bytes[8..16].try_into().unwrap());
229 tmp.0[2] = u64::from_le_bytes(bytes[16..24].try_into().unwrap());
230 tmp.0[3] = u64::from_le_bytes(bytes[24..32].try_into().unwrap());
231
232 let (_, borrow) = sbb(tmp.0[0], MODULUS.0[0], 0);
234 let (_, borrow) = sbb(tmp.0[1], MODULUS.0[1], borrow);
235 let (_, borrow) = sbb(tmp.0[2], MODULUS.0[2], borrow);
236 let (_, borrow) = sbb(tmp.0[3], MODULUS.0[3], borrow);
237
238 let is_some = (borrow as u8) & 1;
242
243 tmp *= &R2;
246
247 CtOption::new(tmp, Choice::from(is_some))
248 }
249
250 pub fn to_bytes(&self) -> [u8; 32] {
253 let tmp = Fr::montgomery_reduce(self.0[0], self.0[1], self.0[2], self.0[3], 0, 0, 0, 0);
256
257 let mut res = [0; 32];
258 res[0..8].copy_from_slice(&tmp.0[0].to_le_bytes());
259 res[8..16].copy_from_slice(&tmp.0[1].to_le_bytes());
260 res[16..24].copy_from_slice(&tmp.0[2].to_le_bytes());
261 res[24..32].copy_from_slice(&tmp.0[3].to_le_bytes());
262
263 res
264 }
265
266 pub fn from_bytes_wide(bytes: &[u8; 64]) -> Fr {
269 Fr::from_u512([
270 u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
271 u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
272 u64::from_le_bytes(bytes[16..24].try_into().unwrap()),
273 u64::from_le_bytes(bytes[24..32].try_into().unwrap()),
274 u64::from_le_bytes(bytes[32..40].try_into().unwrap()),
275 u64::from_le_bytes(bytes[40..48].try_into().unwrap()),
276 u64::from_le_bytes(bytes[48..56].try_into().unwrap()),
277 u64::from_le_bytes(bytes[56..64].try_into().unwrap()),
278 ])
279 }
280
281 fn from_u512(limbs: [u64; 8]) -> Fr {
282 let d0 = Fr([limbs[0], limbs[1], limbs[2], limbs[3]]);
296 let d1 = Fr([limbs[4], limbs[5], limbs[6], limbs[7]]);
297 d0 * R2 + d1 * R3
299 }
300
301 pub const fn from_raw(val: [u64; 4]) -> Self {
304 (&Fr(val)).mul(&R2)
305 }
306
307 #[inline]
309 pub const fn square(&self) -> Fr {
310 let (r1, carry) = mac(0, self.0[0], self.0[1], 0);
311 let (r2, carry) = mac(0, self.0[0], self.0[2], carry);
312 let (r3, r4) = mac(0, self.0[0], self.0[3], carry);
313
314 let (r3, carry) = mac(r3, self.0[1], self.0[2], 0);
315 let (r4, r5) = mac(r4, self.0[1], self.0[3], carry);
316
317 let (r5, r6) = mac(r5, self.0[2], self.0[3], 0);
318
319 let r7 = r6 >> 63;
320 let r6 = (r6 << 1) | (r5 >> 63);
321 let r5 = (r5 << 1) | (r4 >> 63);
322 let r4 = (r4 << 1) | (r3 >> 63);
323 let r3 = (r3 << 1) | (r2 >> 63);
324 let r2 = (r2 << 1) | (r1 >> 63);
325 let r1 = r1 << 1;
326
327 let (r0, carry) = mac(0, self.0[0], self.0[0], 0);
328 let (r1, carry) = adc(0, r1, carry);
329 let (r2, carry) = mac(r2, self.0[1], self.0[1], carry);
330 let (r3, carry) = adc(0, r3, carry);
331 let (r4, carry) = mac(r4, self.0[2], self.0[2], carry);
332 let (r5, carry) = adc(0, r5, carry);
333 let (r6, carry) = mac(r6, self.0[3], self.0[3], carry);
334 let (r7, _) = adc(0, r7, carry);
335
336 Fr::montgomery_reduce(r0, r1, r2, r3, r4, r5, r6, r7)
337 }
338
339 pub fn sqrt(&self) -> CtOption<Self> {
341 let sqrt = self.pow_vartime(&[
345 0xb425_c397_b5bd_cb2e,
346 0x299a_0824_f332_0420,
347 0x4199_cec0_404d_0ec0,
348 0x039f_6d3a_994c_ebea,
349 ]);
350
351 CtOption::new(
352 sqrt,
353 (sqrt * sqrt).ct_eq(self), )
355 }
356
357 pub fn pow(&self, by: &[u64; 4]) -> Self {
360 let mut res = Self::one();
361 for e in by.iter().rev() {
362 for i in (0..64).rev() {
363 res = res.square();
364 let mut tmp = res;
365 tmp.mul_assign(self);
366 res.conditional_assign(&tmp, (((*e >> i) & 0x1) as u8).into());
367 }
368 }
369 res
370 }
371
372 pub fn pow_vartime(&self, by: &[u64; 4]) -> Self {
379 let mut res = Self::one();
380 for e in by.iter().rev() {
381 for i in (0..64).rev() {
382 res = res.square();
383
384 if ((*e >> i) & 1) == 1 {
385 res.mul_assign(self);
386 }
387 }
388 }
389 res
390 }
391
392 pub fn invert(&self) -> CtOption<Self> {
395 #[inline(always)]
396 fn square_assign_multi(n: &mut Fr, num_times: usize) {
397 for _ in 0..num_times {
398 *n = n.square();
399 }
400 }
401 let mut t1 = self.square();
403 let mut t0 = t1.square();
404 let mut t3 = t0 * t1;
405 let t6 = t3 * self;
406 let t7 = t6 * t1;
407 let t12 = t7 * t3;
408 let t13 = t12 * t0;
409 let t16 = t12 * t3;
410 let t2 = t13 * t3;
411 let t15 = t16 * t3;
412 let t19 = t2 * t0;
413 let t9 = t15 * t3;
414 let t18 = t9 * t3;
415 let t14 = t18 * t1;
416 let t4 = t18 * t0;
417 let t8 = t18 * t3;
418 let t17 = t14 * t3;
419 let t11 = t8 * t3;
420 t1 = t17 * t3;
421 let t5 = t11 * t3;
422 t3 = t5 * t0;
423 t0 = t5.square();
424 square_assign_multi(&mut t0, 5);
425 t0.mul_assign(&t3);
426 square_assign_multi(&mut t0, 6);
427 t0.mul_assign(&t8);
428 square_assign_multi(&mut t0, 7);
429 t0.mul_assign(&t19);
430 square_assign_multi(&mut t0, 6);
431 t0.mul_assign(&t13);
432 square_assign_multi(&mut t0, 8);
433 t0.mul_assign(&t14);
434 square_assign_multi(&mut t0, 6);
435 t0.mul_assign(&t18);
436 square_assign_multi(&mut t0, 7);
437 t0.mul_assign(&t17);
438 square_assign_multi(&mut t0, 5);
439 t0.mul_assign(&t16);
440 square_assign_multi(&mut t0, 3);
441 t0.mul_assign(self);
442 square_assign_multi(&mut t0, 11);
443 t0.mul_assign(&t11);
444 square_assign_multi(&mut t0, 8);
445 t0.mul_assign(&t5);
446 square_assign_multi(&mut t0, 5);
447 t0.mul_assign(&t15);
448 square_assign_multi(&mut t0, 8);
449 t0.mul_assign(self);
450 square_assign_multi(&mut t0, 12);
451 t0.mul_assign(&t13);
452 square_assign_multi(&mut t0, 7);
453 t0.mul_assign(&t9);
454 square_assign_multi(&mut t0, 5);
455 t0.mul_assign(&t15);
456 square_assign_multi(&mut t0, 14);
457 t0.mul_assign(&t14);
458 square_assign_multi(&mut t0, 5);
459 t0.mul_assign(&t13);
460 square_assign_multi(&mut t0, 2);
461 t0.mul_assign(self);
462 square_assign_multi(&mut t0, 6);
463 t0.mul_assign(self);
464 square_assign_multi(&mut t0, 9);
465 t0.mul_assign(&t7);
466 square_assign_multi(&mut t0, 6);
467 t0.mul_assign(&t12);
468 square_assign_multi(&mut t0, 8);
469 t0.mul_assign(&t11);
470 square_assign_multi(&mut t0, 3);
471 t0.mul_assign(self);
472 square_assign_multi(&mut t0, 12);
473 t0.mul_assign(&t9);
474 square_assign_multi(&mut t0, 11);
475 t0.mul_assign(&t8);
476 square_assign_multi(&mut t0, 8);
477 t0.mul_assign(&t7);
478 square_assign_multi(&mut t0, 4);
479 t0.mul_assign(&t6);
480 square_assign_multi(&mut t0, 10);
481 t0.mul_assign(&t5);
482 square_assign_multi(&mut t0, 7);
483 t0.mul_assign(&t3);
484 square_assign_multi(&mut t0, 6);
485 t0.mul_assign(&t4);
486 square_assign_multi(&mut t0, 7);
487 t0.mul_assign(&t3);
488 square_assign_multi(&mut t0, 5);
489 t0.mul_assign(&t2);
490 square_assign_multi(&mut t0, 6);
491 t0.mul_assign(&t2);
492 square_assign_multi(&mut t0, 7);
493 t0.mul_assign(&t1);
494
495 CtOption::new(t0, !self.ct_eq(&Self::zero()))
496 }
497
498 #[inline]
499 #[allow(clippy::too_many_arguments)]
500 const fn montgomery_reduce(
501 r0: u64,
502 r1: u64,
503 r2: u64,
504 r3: u64,
505 r4: u64,
506 r5: u64,
507 r6: u64,
508 r7: u64,
509 ) -> Self {
510 let k = r0.wrapping_mul(INV);
515 let (_, carry) = mac(r0, k, MODULUS.0[0], 0);
516 let (r1, carry) = mac(r1, k, MODULUS.0[1], carry);
517 let (r2, carry) = mac(r2, k, MODULUS.0[2], carry);
518 let (r3, carry) = mac(r3, k, MODULUS.0[3], carry);
519 let (r4, carry2) = adc(r4, 0, carry);
520
521 let k = r1.wrapping_mul(INV);
522 let (_, carry) = mac(r1, k, MODULUS.0[0], 0);
523 let (r2, carry) = mac(r2, k, MODULUS.0[1], carry);
524 let (r3, carry) = mac(r3, k, MODULUS.0[2], carry);
525 let (r4, carry) = mac(r4, k, MODULUS.0[3], carry);
526 let (r5, carry2) = adc(r5, carry2, carry);
527
528 let k = r2.wrapping_mul(INV);
529 let (_, carry) = mac(r2, k, MODULUS.0[0], 0);
530 let (r3, carry) = mac(r3, k, MODULUS.0[1], carry);
531 let (r4, carry) = mac(r4, k, MODULUS.0[2], carry);
532 let (r5, carry) = mac(r5, k, MODULUS.0[3], carry);
533 let (r6, carry2) = adc(r6, carry2, carry);
534
535 let k = r3.wrapping_mul(INV);
536 let (_, carry) = mac(r3, k, MODULUS.0[0], 0);
537 let (r4, carry) = mac(r4, k, MODULUS.0[1], carry);
538 let (r5, carry) = mac(r5, k, MODULUS.0[2], carry);
539 let (r6, carry) = mac(r6, k, MODULUS.0[3], carry);
540 let (r7, _) = adc(r7, carry2, carry);
541
542 (&Fr([r4, r5, r6, r7])).sub(&MODULUS)
544 }
545
546 #[inline]
548 pub const fn mul(&self, rhs: &Self) -> Self {
549 let (r0, carry) = mac(0, self.0[0], rhs.0[0], 0);
552 let (r1, carry) = mac(0, self.0[0], rhs.0[1], carry);
553 let (r2, carry) = mac(0, self.0[0], rhs.0[2], carry);
554 let (r3, r4) = mac(0, self.0[0], rhs.0[3], carry);
555
556 let (r1, carry) = mac(r1, self.0[1], rhs.0[0], 0);
557 let (r2, carry) = mac(r2, self.0[1], rhs.0[1], carry);
558 let (r3, carry) = mac(r3, self.0[1], rhs.0[2], carry);
559 let (r4, r5) = mac(r4, self.0[1], rhs.0[3], carry);
560
561 let (r2, carry) = mac(r2, self.0[2], rhs.0[0], 0);
562 let (r3, carry) = mac(r3, self.0[2], rhs.0[1], carry);
563 let (r4, carry) = mac(r4, self.0[2], rhs.0[2], carry);
564 let (r5, r6) = mac(r5, self.0[2], rhs.0[3], carry);
565
566 let (r3, carry) = mac(r3, self.0[3], rhs.0[0], 0);
567 let (r4, carry) = mac(r4, self.0[3], rhs.0[1], carry);
568 let (r5, carry) = mac(r5, self.0[3], rhs.0[2], carry);
569 let (r6, r7) = mac(r6, self.0[3], rhs.0[3], carry);
570
571 Fr::montgomery_reduce(r0, r1, r2, r3, r4, r5, r6, r7)
572 }
573
574 #[inline]
576 pub const fn sub(&self, rhs: &Self) -> Self {
577 let (d0, borrow) = sbb(self.0[0], rhs.0[0], 0);
578 let (d1, borrow) = sbb(self.0[1], rhs.0[1], borrow);
579 let (d2, borrow) = sbb(self.0[2], rhs.0[2], borrow);
580 let (d3, borrow) = sbb(self.0[3], rhs.0[3], borrow);
581
582 let (d0, carry) = adc(d0, MODULUS.0[0] & borrow, 0);
585 let (d1, carry) = adc(d1, MODULUS.0[1] & borrow, carry);
586 let (d2, carry) = adc(d2, MODULUS.0[2] & borrow, carry);
587 let (d3, _) = adc(d3, MODULUS.0[3] & borrow, carry);
588
589 Fr([d0, d1, d2, d3])
590 }
591
592 #[inline]
594 pub const fn add(&self, rhs: &Self) -> Self {
595 let (d0, carry) = adc(self.0[0], rhs.0[0], 0);
596 let (d1, carry) = adc(self.0[1], rhs.0[1], carry);
597 let (d2, carry) = adc(self.0[2], rhs.0[2], carry);
598 let (d3, _) = adc(self.0[3], rhs.0[3], carry);
599
600 (&Fr([d0, d1, d2, d3])).sub(&MODULUS)
603 }
604
605 #[inline]
607 pub const fn neg(&self) -> Self {
608 let (d0, borrow) = sbb(MODULUS.0[0], self.0[0], 0);
612 let (d1, borrow) = sbb(MODULUS.0[1], self.0[1], borrow);
613 let (d2, borrow) = sbb(MODULUS.0[2], self.0[2], borrow);
614 let (d3, _) = sbb(MODULUS.0[3], self.0[3], borrow);
615
616 let mask = (((self.0[0] | self.0[1] | self.0[2] | self.0[3]) == 0) as u64).wrapping_sub(1);
619
620 Fr([d0 & mask, d1 & mask, d2 & mask, d3 & mask])
621 }
622}
623
624impl From<Fr> for [u8; 32] {
625 fn from(value: Fr) -> [u8; 32] {
626 value.to_bytes()
627 }
628}
629
630impl<'a> From<&'a Fr> for [u8; 32] {
631 fn from(value: &'a Fr) -> [u8; 32] {
632 value.to_bytes()
633 }
634}
635
636impl Field for Fr {
637 fn random(mut rng: impl RngCore) -> Self {
638 let mut buf = [0; 64];
639 rng.fill_bytes(&mut buf);
640 Self::from_bytes_wide(&buf)
641 }
642
643 fn zero() -> Self {
644 Self::zero()
645 }
646
647 fn one() -> Self {
648 Self::one()
649 }
650
651 #[must_use]
652 fn square(&self) -> Self {
653 self.square()
654 }
655
656 #[must_use]
657 fn double(&self) -> Self {
658 self.double()
659 }
660
661 fn invert(&self) -> CtOption<Self> {
662 self.invert()
663 }
664
665 fn sqrt(&self) -> CtOption<Self> {
666 self.sqrt()
667 }
668}
669
670impl PrimeField for Fr {
671 type Repr = [u8; 32];
672
673 fn from_repr(r: Self::Repr) -> CtOption<Self> {
674 Self::from_bytes(&r)
675 }
676
677 fn to_repr(&self) -> Self::Repr {
678 self.to_bytes()
679 }
680
681 fn is_odd(&self) -> Choice {
682 Choice::from(self.to_bytes()[0] & 1)
683 }
684
685 const NUM_BITS: u32 = MODULUS_BITS;
686 const CAPACITY: u32 = Self::NUM_BITS - 1;
687
688 fn multiplicative_generator() -> Self {
689 GENERATOR
690 }
691
692 const S: u32 = S;
693
694 fn root_of_unity() -> Self {
695 ROOT_OF_UNITY
696 }
697}
698
699#[cfg(all(feature = "bits", not(target_pointer_width = "64")))]
700type ReprBits = [u32; 8];
701
702#[cfg(all(feature = "bits", target_pointer_width = "64"))]
703type ReprBits = [u64; 4];
704
705#[cfg(feature = "bits")]
706impl PrimeFieldBits for Fr {
707 type ReprBits = ReprBits;
708
709 fn to_le_bits(&self) -> FieldBits<Self::ReprBits> {
710 let bytes = self.to_bytes();
711
712 #[cfg(not(target_pointer_width = "64"))]
713 let limbs = [
714 u32::from_le_bytes(bytes[0..4].try_into().unwrap()),
715 u32::from_le_bytes(bytes[4..8].try_into().unwrap()),
716 u32::from_le_bytes(bytes[8..12].try_into().unwrap()),
717 u32::from_le_bytes(bytes[12..16].try_into().unwrap()),
718 u32::from_le_bytes(bytes[16..20].try_into().unwrap()),
719 u32::from_le_bytes(bytes[20..24].try_into().unwrap()),
720 u32::from_le_bytes(bytes[24..28].try_into().unwrap()),
721 u32::from_le_bytes(bytes[28..32].try_into().unwrap()),
722 ];
723
724 #[cfg(target_pointer_width = "64")]
725 let limbs = [
726 u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
727 u64::from_le_bytes(bytes[8..16].try_into().unwrap()),
728 u64::from_le_bytes(bytes[16..24].try_into().unwrap()),
729 u64::from_le_bytes(bytes[24..32].try_into().unwrap()),
730 ];
731
732 FieldBits::new(limbs)
733 }
734
735 fn char_le_bits() -> FieldBits<Self::ReprBits> {
736 #[cfg(not(target_pointer_width = "64"))]
737 {
738 FieldBits::new(MODULUS_LIMBS_32)
739 }
740
741 #[cfg(target_pointer_width = "64")]
742 FieldBits::new(MODULUS.0)
743 }
744}
745
746#[test]
747fn test_inv() {
748 let mut inv = 1u64;
752 for _ in 0..63 {
753 inv = inv.wrapping_mul(inv);
754 inv = inv.wrapping_mul(MODULUS.0[0]);
755 }
756 inv = inv.wrapping_neg();
757
758 assert_eq!(inv, INV);
759}
760
761#[test]
762fn test_debug() {
763 assert_eq!(
764 format!("{:?}", Fr::zero()),
765 "0x0000000000000000000000000000000000000000000000000000000000000000"
766 );
767 assert_eq!(
768 format!("{:?}", Fr::one()),
769 "0x0000000000000000000000000000000000000000000000000000000000000001"
770 );
771 assert_eq!(
772 format!("{:?}", R2),
773 "0x09a6fc6f479155c6932514eeeb8814f4f315d62f66b6e75025f80bb3b99607d9"
774 );
775}
776
777#[test]
778fn test_equality() {
779 assert_eq!(Fr::zero(), Fr::zero());
780 assert_eq!(Fr::one(), Fr::one());
781 assert_eq!(R2, R2);
782
783 assert!(Fr::zero() != Fr::one());
784 assert!(Fr::one() != R2);
785}
786
787#[test]
788fn test_to_bytes() {
789 assert_eq!(
790 Fr::zero().to_bytes(),
791 [
792 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
793 0, 0, 0
794 ]
795 );
796
797 assert_eq!(
798 Fr::one().to_bytes(),
799 [
800 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
801 0, 0, 0
802 ]
803 );
804
805 assert_eq!(
806 R2.to_bytes(),
807 [
808 217, 7, 150, 185, 179, 11, 248, 37, 80, 231, 182, 102, 47, 214, 21, 243, 244, 20, 136,
809 235, 238, 20, 37, 147, 198, 85, 145, 71, 111, 252, 166, 9
810 ]
811 );
812
813 assert_eq!(
814 (-&Fr::one()).to_bytes(),
815 [
816 182, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
817 1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 14
818 ]
819 );
820}
821
822#[test]
823fn test_from_bytes() {
824 assert_eq!(
825 Fr::from_bytes(&[
826 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
827 0, 0, 0
828 ])
829 .unwrap(),
830 Fr::zero()
831 );
832
833 assert_eq!(
834 Fr::from_bytes(&[
835 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
836 0, 0, 0
837 ])
838 .unwrap(),
839 Fr::one()
840 );
841
842 assert_eq!(
843 Fr::from_bytes(&[
844 217, 7, 150, 185, 179, 11, 248, 37, 80, 231, 182, 102, 47, 214, 21, 243, 244, 20, 136,
845 235, 238, 20, 37, 147, 198, 85, 145, 71, 111, 252, 166, 9
846 ])
847 .unwrap(),
848 R2
849 );
850
851 assert!(bool::from(
853 Fr::from_bytes(&[
854 182, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
855 1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 14
856 ])
857 .is_some()
858 ));
859
860 assert!(bool::from(
862 Fr::from_bytes(&[
863 183, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
864 1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 14
865 ])
866 .is_none()
867 ));
868
869 assert!(bool::from(
871 Fr::from_bytes(&[
872 184, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
873 1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 14
874 ])
875 .is_none()
876 ));
877
878 assert!(bool::from(
879 Fr::from_bytes(&[
880 183, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
881 1, 1, 59, 104, 6, 169, 175, 51, 101, 234, 180, 125, 14
882 ])
883 .is_none()
884 ));
885
886 assert!(bool::from(
887 Fr::from_bytes(&[
888 183, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
889 1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 15
890 ])
891 .is_none()
892 ));
893}
894
895#[test]
896fn test_from_u512_zero() {
897 assert_eq!(
898 Fr::zero(),
899 Fr::from_u512([
900 MODULUS.0[0],
901 MODULUS.0[1],
902 MODULUS.0[2],
903 MODULUS.0[3],
904 0,
905 0,
906 0,
907 0
908 ])
909 );
910}
911
912#[test]
913fn test_from_u512_r() {
914 assert_eq!(R, Fr::from_u512([1, 0, 0, 0, 0, 0, 0, 0]));
915}
916
917#[test]
918fn test_from_u512_r2() {
919 assert_eq!(R2, Fr::from_u512([0, 0, 0, 0, 1, 0, 0, 0]));
920}
921
922#[test]
923fn test_from_u512_max() {
924 let max_u64 = 0xffff_ffff_ffff_ffff;
925 assert_eq!(
926 R3 - R,
927 Fr::from_u512([max_u64, max_u64, max_u64, max_u64, max_u64, max_u64, max_u64, max_u64])
928 );
929}
930
931#[test]
932fn test_from_bytes_wide_r2() {
933 assert_eq!(
934 R2,
935 Fr::from_bytes_wide(&[
936 217, 7, 150, 185, 179, 11, 248, 37, 80, 231, 182, 102, 47, 214, 21, 243, 244, 20, 136,
937 235, 238, 20, 37, 147, 198, 85, 145, 71, 111, 252, 166, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
938 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
939 ])
940 );
941}
942
943#[test]
944fn test_from_bytes_wide_negative_one() {
945 assert_eq!(
946 -&Fr::one(),
947 Fr::from_bytes_wide(&[
948 182, 44, 247, 214, 94, 14, 151, 208, 130, 16, 200, 204, 147, 32, 104, 166, 0, 59, 52,
949 1, 1, 59, 103, 6, 169, 175, 51, 101, 234, 180, 125, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
950 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
951 ])
952 );
953}
954
955#[test]
956fn test_from_bytes_wide_maximum() {
957 assert_eq!(
958 Fr([
959 0x8b75_c901_5ae4_2a22,
960 0xe590_82e7_bf9e_38b8,
961 0x6440_c912_61da_51b3,
962 0x0a5e_07ff_b209_91cf,
963 ]),
964 Fr::from_bytes_wide(&[0xff; 64])
965 );
966}
967
968#[test]
969fn test_zero() {
970 assert_eq!(Fr::zero(), -&Fr::zero());
971 assert_eq!(Fr::zero(), Fr::zero() + Fr::zero());
972 assert_eq!(Fr::zero(), Fr::zero() - Fr::zero());
973 assert_eq!(Fr::zero(), Fr::zero() * Fr::zero());
974}
975
976#[cfg(test)]
977const LARGEST: Fr = Fr([
978 0xd097_0e5e_d6f7_2cb6,
979 0xa668_2093_ccc8_1082,
980 0x0667_3b01_0134_3b00,
981 0x0e7d_b4ea_6533_afa9,
982]);
983
984#[test]
985fn test_addition() {
986 let mut tmp = LARGEST;
987 tmp += &LARGEST;
988
989 assert_eq!(
990 tmp,
991 Fr([
992 0xd097_0e5e_d6f7_2cb5,
993 0xa668_2093_ccc8_1082,
994 0x0667_3b01_0134_3b00,
995 0x0e7d_b4ea_6533_afa9
996 ])
997 );
998
999 let mut tmp = LARGEST;
1000 tmp += &Fr([1, 0, 0, 0]);
1001
1002 assert_eq!(tmp, Fr::zero());
1003}
1004
1005#[test]
1006fn test_negation() {
1007 let tmp = -&LARGEST;
1008
1009 assert_eq!(tmp, Fr([1, 0, 0, 0]));
1010
1011 let tmp = -&Fr::zero();
1012 assert_eq!(tmp, Fr::zero());
1013 let tmp = -&Fr([1, 0, 0, 0]);
1014 assert_eq!(tmp, LARGEST);
1015}
1016
1017#[test]
1018fn test_subtraction() {
1019 let mut tmp = LARGEST;
1020 tmp -= &LARGEST;
1021
1022 assert_eq!(tmp, Fr::zero());
1023
1024 let mut tmp = Fr::zero();
1025 tmp -= &LARGEST;
1026
1027 let mut tmp2 = MODULUS;
1028 tmp2 -= &LARGEST;
1029
1030 assert_eq!(tmp, tmp2);
1031}
1032
1033#[test]
1034fn test_multiplication() {
1035 let mut cur = LARGEST;
1036
1037 for _ in 0..100 {
1038 let mut tmp = cur;
1039 tmp *= &cur;
1040
1041 let mut tmp2 = Fr::zero();
1042 for b in cur
1043 .to_bytes()
1044 .iter()
1045 .rev()
1046 .flat_map(|byte| (0..8).rev().map(move |i| ((byte >> i) & 1u8) == 1u8))
1047 {
1048 let tmp3 = tmp2;
1049 tmp2.add_assign(&tmp3);
1050
1051 if b {
1052 tmp2.add_assign(&cur);
1053 }
1054 }
1055
1056 assert_eq!(tmp, tmp2);
1057
1058 cur.add_assign(&LARGEST);
1059 }
1060}
1061
1062#[test]
1063fn test_squaring() {
1064 let mut cur = LARGEST;
1065
1066 for _ in 0..100 {
1067 let mut tmp = cur;
1068 tmp = tmp.square();
1069
1070 let mut tmp2 = Fr::zero();
1071 for b in cur
1072 .to_bytes()
1073 .iter()
1074 .rev()
1075 .flat_map(|byte| (0..8).rev().map(move |i| ((byte >> i) & 1u8) == 1u8))
1076 {
1077 let tmp3 = tmp2;
1078 tmp2.add_assign(&tmp3);
1079
1080 if b {
1081 tmp2.add_assign(&cur);
1082 }
1083 }
1084
1085 assert_eq!(tmp, tmp2);
1086
1087 cur.add_assign(&LARGEST);
1088 }
1089}
1090
1091#[test]
1092fn test_inversion() {
1093 assert!(bool::from(Fr::zero().invert().is_none()));
1094 assert_eq!(Fr::one().invert().unwrap(), Fr::one());
1095 assert_eq!((-&Fr::one()).invert().unwrap(), -&Fr::one());
1096
1097 let mut tmp = R2;
1098
1099 for _ in 0..100 {
1100 let mut tmp2 = tmp.invert().unwrap();
1101 tmp2.mul_assign(&tmp);
1102
1103 assert_eq!(tmp2, Fr::one());
1104
1105 tmp.add_assign(&R2);
1106 }
1107}
1108
1109#[test]
1110fn test_invert_is_pow() {
1111 let r_minus_2 = [
1112 0xd097_0e5e_d6f7_2cb5,
1113 0xa668_2093_ccc8_1082,
1114 0x0667_3b01_0134_3b00,
1115 0x0e7d_b4ea_6533_afa9,
1116 ];
1117
1118 let mut r1 = R;
1119 let mut r2 = R;
1120 let mut r3 = R;
1121
1122 for _ in 0..100 {
1123 r1 = r1.invert().unwrap();
1124 r2 = r2.pow_vartime(&r_minus_2);
1125 r3 = r3.pow(&r_minus_2);
1126
1127 assert_eq!(r1, r2);
1128 assert_eq!(r2, r3);
1129 r1.add_assign(&R);
1131 r2 = r1;
1132 r3 = r1;
1133 }
1134}
1135
1136#[test]
1137fn test_sqrt() {
1138 let mut square = Fr([
1139 0xd097_0e5e_d6f7_2cb5,
1141 0xa668_2093_ccc8_1082,
1142 0x0667_3b01_0134_3b00,
1143 0x0e7d_b4ea_6533_afa9,
1144 ]);
1145
1146 let mut none_count = 0;
1147
1148 for _ in 0..100 {
1149 let square_root = square.sqrt();
1150 if bool::from(square_root.is_none()) {
1151 none_count += 1;
1152 } else {
1153 assert_eq!(square_root.unwrap() * square_root.unwrap(), square);
1154 }
1155 square -= Fr::one();
1156 }
1157
1158 assert_eq!(47, none_count);
1159}
1160
1161#[test]
1162fn test_from_raw() {
1163 assert_eq!(
1164 Fr::from_raw([
1165 0x25f8_0bb3_b996_07d8,
1166 0xf315_d62f_66b6_e750,
1167 0x9325_14ee_eb88_14f4,
1168 0x09a6_fc6f_4791_55c6,
1169 ]),
1170 Fr::from_raw([0xffff_ffff_ffff_ffff; 4])
1171 );
1172
1173 assert_eq!(Fr::from_raw(MODULUS.0), Fr::zero());
1174
1175 assert_eq!(Fr::from_raw([1, 0, 0, 0]), R);
1176}