1use byteorder::{ByteOrder, LittleEndian};
2use bellman::pairing::ff::{adc, sbb, mac_with_carry};
3use bellman::pairing::ff::{BitIterator, Field, PrimeField, SqrtField, PrimeFieldRepr, PrimeFieldDecodingError, LegendreSymbol};
4use bellman::pairing::ff::LegendreSymbol::*;
5use super::ToUniform;
6
7const MODULUS: FsRepr = FsRepr([
9 0x677297dc392126f1,
10 0xab3eedb83920ee0a,
11 0x370a08b6d0302b0b,
12 0x060c89ce5c263405,
13]);
14
15const MODULUS_BITS: u32 = 251;
17
18const REPR_SHAVE_BITS: u32 = 5;
21
22const R: FsRepr = FsRepr([
24 0x073315dea08f9c76,
25 0xe7acffc6a098f24b,
26 0xf85a9201d818f015,
27 0x01f16424e1bb7724,
28]);
29
30const R2: FsRepr = FsRepr([
32 0x35e44abee7ecb21e,
33 0x74646cacf5f84ec4,
34 0xe472df203faa158f,
35 0x0445b524f1ba50a8,
36]);
37
38const INV: u64 = 0x532ce5aebc48f5ef;
40
41const GENERATOR: FsRepr = FsRepr([
43 0x6380695df1aaf958,
44 0xff3d22fdf1ecc3f8,
45 0x5c65ec9f484e3a81,
46 0x0180a96573d3d9f8,
47]);
48
49const S: u32 = 4;
51
52const ROOT_OF_UNITY: FsRepr = FsRepr([
54 0xa13885692e7afcb0,
55 0xb789766cd18573ca,
56 0xd5468c0174efc3b9,
57 0x03534b612b0b6f7a,
58]);
59
60const NEGATIVE_ONE: Fs = Fs(FsRepr([
62 0x603f81fd98918a7b,
63 0xc391edf19887fbbf,
64 0x3eaf76b4f8173af5,
65 0x041b25a97a6abce0,
66]));
67
68#[derive(Copy, Clone, PartialEq, Eq, Default, Debug, Hash)]
70pub struct FsRepr(pub [u64; 4]);
71
72impl ::rand::Rand for FsRepr {
73 #[inline(always)]
74 fn rand<R: ::rand::Rng>(rng: &mut R) -> Self {
75 FsRepr(rng.gen())
76 }
77}
78
79impl ::std::fmt::Display for FsRepr
80{
81 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
82 write!(f, "0x")?;
83 for i in self.0.iter().rev() {
84 write!(f, "{:016x}", *i)?;
85 }
86
87 Ok(())
88 }
89}
90
91impl AsRef<[u64]> for FsRepr {
92 #[inline(always)]
93 fn as_ref(&self) -> &[u64] {
94 &self.0
95 }
96}
97
98impl AsMut<[u64]> for FsRepr {
99 #[inline(always)]
100 fn as_mut(&mut self) -> &mut [u64] {
101 &mut self.0
102 }
103}
104
105impl From<u64> for FsRepr {
106 #[inline(always)]
107 fn from(val: u64) -> FsRepr {
108 let mut repr = Self::default();
109 repr.0[0] = val;
110 repr
111 }
112}
113
114impl Ord for FsRepr {
115 #[inline(always)]
116 fn cmp(&self, other: &FsRepr) -> ::std::cmp::Ordering {
117 for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) {
118 if a < b {
119 return ::std::cmp::Ordering::Less
120 } else if a > b {
121 return ::std::cmp::Ordering::Greater
122 }
123 }
124
125 ::std::cmp::Ordering::Equal
126 }
127}
128
129impl PartialOrd for FsRepr {
130 #[inline(always)]
131 fn partial_cmp(&self, other: &FsRepr) -> Option<::std::cmp::Ordering> {
132 Some(self.cmp(other))
133 }
134}
135
136impl PrimeFieldRepr for FsRepr {
137 #[inline(always)]
138 fn is_odd(&self) -> bool {
139 self.0[0] & 1 == 1
140 }
141
142 #[inline(always)]
143 fn is_even(&self) -> bool {
144 !self.is_odd()
145 }
146
147 #[inline(always)]
148 fn is_zero(&self) -> bool {
149 self.0.iter().all(|&e| e == 0)
150 }
151
152 #[inline(always)]
153 fn shr(&mut self, mut n: u32) {
154 if n >= 64 * 4 {
155 *self = Self::from(0);
156 return;
157 }
158
159 while n >= 64 {
160 let mut t = 0;
161 for i in self.0.iter_mut().rev() {
162 ::std::mem::swap(&mut t, i);
163 }
164 n -= 64;
165 }
166
167 if n > 0 {
168 let mut t = 0;
169 for i in self.0.iter_mut().rev() {
170 let t2 = *i << (64 - n);
171 *i >>= n;
172 *i |= t;
173 t = t2;
174 }
175 }
176 }
177
178 #[inline(always)]
179 fn div2(&mut self) {
180 let mut t = 0;
181 for i in self.0.iter_mut().rev() {
182 let t2 = *i << 63;
183 *i >>= 1;
184 *i |= t;
185 t = t2;
186 }
187 }
188
189 #[inline(always)]
190 fn mul2(&mut self) {
191 let mut last = 0;
192 for i in &mut self.0 {
193 let tmp = *i >> 63;
194 *i <<= 1;
195 *i |= last;
196 last = tmp;
197 }
198 }
199
200 #[inline(always)]
201 fn shl(&mut self, mut n: u32) {
202 if n >= 64 * 4 {
203 *self = Self::from(0);
204 return;
205 }
206
207 while n >= 64 {
208 let mut t = 0;
209 for i in &mut self.0 {
210 ::std::mem::swap(&mut t, i);
211 }
212 n -= 64;
213 }
214
215 if n > 0 {
216 let mut t = 0;
217 for i in &mut self.0 {
218 let t2 = *i >> (64 - n);
219 *i <<= n;
220 *i |= t;
221 t = t2;
222 }
223 }
224 }
225
226 #[inline(always)]
227 fn num_bits(&self) -> u32 {
228 let mut ret = (4 as u32) * 64;
229 for i in self.0.iter().rev() {
230 let leading = i.leading_zeros();
231 ret -= leading;
232 if leading != 64 {
233 break;
234 }
235 }
236
237 ret
238 }
239
240 #[inline(always)]
241 fn add_nocarry(&mut self, other: &FsRepr) {
242 let mut carry = 0;
243
244 for (a, b) in self.0.iter_mut().zip(other.0.iter()) {
245 *a = adc(*a, *b, &mut carry);
246 }
247 }
248
249 #[inline(always)]
250 fn sub_noborrow(&mut self, other: &FsRepr) {
251 let mut borrow = 0;
252
253 for (a, b) in self.0.iter_mut().zip(other.0.iter()) {
254 *a = sbb(*a, *b, &mut borrow);
255 }
256 }
257}
258
259#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
261pub struct Fs(FsRepr);
262
263impl ::std::fmt::Display for Fs
264{
265 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
266 write!(f, "Fs({})", self.into_repr())
267 }
268}
269
270impl ::rand::Rand for Fs {
271 fn rand<R: ::rand::Rng>(rng: &mut R) -> Self {
272 loop {
273 let mut tmp = Fs(FsRepr::rand(rng));
274
275 tmp.0.as_mut()[3] &= 0xffffffffffffffff >> REPR_SHAVE_BITS;
277
278 if tmp.is_valid() {
279 return tmp
280 }
281 }
282 }
283}
284
285impl From<Fs> for FsRepr {
286 fn from(e: Fs) -> FsRepr {
287 e.into_repr()
288 }
289}
290
291impl PrimeField for Fs {
292 type Repr = FsRepr;
293
294 fn from_repr(r: FsRepr) -> Result<Fs, PrimeFieldDecodingError> {
295 let mut r = Fs(r);
296 if r.is_valid() {
297 r.mul_assign(&Fs(R2));
298
299 Ok(r)
300 } else {
301 Err(PrimeFieldDecodingError::NotInField(format!("{}", r.0)))
302 }
303 }
304
305 fn from_raw_repr(r: FsRepr) -> Result<Fs, PrimeFieldDecodingError> {
306 let r = Fs(r);
307 if r.is_valid() {
308 Ok(r)
309 } else {
310 Err(PrimeFieldDecodingError::NotInField(format!("{}", r.0)))
311 }
312 }
313
314 fn into_repr(&self) -> FsRepr {
315 let mut r = *self;
316 r.mont_reduce((self.0).0[0], (self.0).0[1],
317 (self.0).0[2], (self.0).0[3],
318 0, 0, 0, 0);
319 r.0
320 }
321
322 fn into_raw_repr(&self) -> FsRepr {
323 let r = *self;
324 r.0
325 }
326
327 fn char() -> FsRepr {
328 MODULUS
329 }
330
331 const NUM_BITS: u32 = MODULUS_BITS;
332
333 const CAPACITY: u32 = Self::NUM_BITS - 1;
334
335 fn multiplicative_generator() -> Self {
336 Fs(GENERATOR)
337 }
338
339 const S: u32 = S;
340
341 fn root_of_unity() -> Self {
342 Fs(ROOT_OF_UNITY)
343 }
344}
345
346impl Field for Fs {
347 #[inline]
348 fn zero() -> Self {
349 Fs(FsRepr::from(0))
350 }
351
352 #[inline]
353 fn one() -> Self {
354 Fs(R)
355 }
356
357 #[inline]
358 fn is_zero(&self) -> bool {
359 self.0.is_zero()
360 }
361
362 #[inline]
363 fn add_assign(&mut self, other: &Fs) {
364 self.0.add_nocarry(&other.0);
366
367 self.reduce();
369 }
370
371 #[inline]
372 fn double(&mut self) {
373 self.0.mul2();
375
376 self.reduce();
378 }
379
380 #[inline]
381 fn sub_assign(&mut self, other: &Fs) {
382 if other.0 > self.0 {
384 self.0.add_nocarry(&MODULUS);
385 }
386
387 self.0.sub_noborrow(&other.0);
388 }
389
390 #[inline]
391 fn negate(&mut self) {
392 if !self.is_zero() {
393 let mut tmp = MODULUS;
394 tmp.sub_noborrow(&self.0);
395 self.0 = tmp;
396 }
397 }
398
399 fn inverse(&self) -> Option<Self> {
400 if self.is_zero() {
401 None
402 } else {
403 let one = FsRepr::from(1);
408
409 let mut u = self.0;
410 let mut v = MODULUS;
411 let mut b = Fs(R2); let mut c = Self::zero();
413
414 while u != one && v != one {
415 while u.is_even() {
416 u.div2();
417
418 if b.0.is_even() {
419 b.0.div2();
420 } else {
421 b.0.add_nocarry(&MODULUS);
422 b.0.div2();
423 }
424 }
425
426 while v.is_even() {
427 v.div2();
428
429 if c.0.is_even() {
430 c.0.div2();
431 } else {
432 c.0.add_nocarry(&MODULUS);
433 c.0.div2();
434 }
435 }
436
437 if v < u {
438 u.sub_noborrow(&v);
439 b.sub_assign(&c);
440 } else {
441 v.sub_noborrow(&u);
442 c.sub_assign(&b);
443 }
444 }
445
446 if u == one {
447 Some(b)
448 } else {
449 Some(c)
450 }
451 }
452 }
453
454 #[inline(always)]
455 fn frobenius_map(&mut self, _: usize) {
456 }
458
459 #[inline]
460 fn mul_assign(&mut self, other: &Fs)
461 {
462 let mut carry = 0;
463 let r0 = mac_with_carry(0, (self.0).0[0], (other.0).0[0], &mut carry);
464 let r1 = mac_with_carry(0, (self.0).0[0], (other.0).0[1], &mut carry);
465 let r2 = mac_with_carry(0, (self.0).0[0], (other.0).0[2], &mut carry);
466 let r3 = mac_with_carry(0, (self.0).0[0], (other.0).0[3], &mut carry);
467 let r4 = carry;
468 let mut carry = 0;
469 let r1 = mac_with_carry(r1, (self.0).0[1], (other.0).0[0], &mut carry);
470 let r2 = mac_with_carry(r2, (self.0).0[1], (other.0).0[1], &mut carry);
471 let r3 = mac_with_carry(r3, (self.0).0[1], (other.0).0[2], &mut carry);
472 let r4 = mac_with_carry(r4, (self.0).0[1], (other.0).0[3], &mut carry);
473 let r5 = carry;
474 let mut carry = 0;
475 let r2 = mac_with_carry(r2, (self.0).0[2], (other.0).0[0], &mut carry);
476 let r3 = mac_with_carry(r3, (self.0).0[2], (other.0).0[1], &mut carry);
477 let r4 = mac_with_carry(r4, (self.0).0[2], (other.0).0[2], &mut carry);
478 let r5 = mac_with_carry(r5, (self.0).0[2], (other.0).0[3], &mut carry);
479 let r6 = carry;
480 let mut carry = 0;
481 let r3 = mac_with_carry(r3, (self.0).0[3], (other.0).0[0], &mut carry);
482 let r4 = mac_with_carry(r4, (self.0).0[3], (other.0).0[1], &mut carry);
483 let r5 = mac_with_carry(r5, (self.0).0[3], (other.0).0[2], &mut carry);
484 let r6 = mac_with_carry(r6, (self.0).0[3], (other.0).0[3], &mut carry);
485 let r7 = carry;
486 self.mont_reduce(r0, r1, r2, r3, r4, r5, r6, r7);
487 }
488
489 #[inline]
490 fn square(&mut self)
491 {
492 let mut carry = 0;
493 let r1 = mac_with_carry(0, (self.0).0[0], (self.0).0[1], &mut carry);
494 let r2 = mac_with_carry(0, (self.0).0[0], (self.0).0[2], &mut carry);
495 let r3 = mac_with_carry(0, (self.0).0[0], (self.0).0[3], &mut carry);
496 let r4 = carry;
497 let mut carry = 0;
498 let r3 = mac_with_carry(r3, (self.0).0[1], (self.0).0[2], &mut carry);
499 let r4 = mac_with_carry(r4, (self.0).0[1], (self.0).0[3], &mut carry);
500 let r5 = carry;
501 let mut carry = 0;
502 let r5 = mac_with_carry(r5, (self.0).0[2], (self.0).0[3], &mut carry);
503 let r6 = carry;
504
505 let r7 = r6 >> 63;
506 let r6 = (r6 << 1) | (r5 >> 63);
507 let r5 = (r5 << 1) | (r4 >> 63);
508 let r4 = (r4 << 1) | (r3 >> 63);
509 let r3 = (r3 << 1) | (r2 >> 63);
510 let r2 = (r2 << 1) | (r1 >> 63);
511 let r1 = r1 << 1;
512
513 let mut carry = 0;
514 let r0 = mac_with_carry(0, (self.0).0[0], (self.0).0[0], &mut carry);
515 let r1 = adc(r1, 0, &mut carry);
516 let r2 = mac_with_carry(r2, (self.0).0[1], (self.0).0[1], &mut carry);
517 let r3 = adc(r3, 0, &mut carry);
518 let r4 = mac_with_carry(r4, (self.0).0[2], (self.0).0[2], &mut carry);
519 let r5 = adc(r5, 0, &mut carry);
520 let r6 = mac_with_carry(r6, (self.0).0[3], (self.0).0[3], &mut carry);
521 let r7 = adc(r7, 0, &mut carry);
522 self.mont_reduce(r0, r1, r2, r3, r4, r5, r6, r7);
523 }
524}
525
526impl Fs {
527 #[inline(always)]
530 fn is_valid(&self) -> bool {
531 self.0 < MODULUS
532 }
533
534 #[inline(always)]
537 fn reduce(&mut self) {
538 if !self.is_valid() {
539 self.0.sub_noborrow(&MODULUS);
540 }
541 }
542
543 #[inline(always)]
544 fn mont_reduce(
545 &mut self,
546 r0: u64,
547 mut r1: u64,
548 mut r2: u64,
549 mut r3: u64,
550 mut r4: u64,
551 mut r5: u64,
552 mut r6: u64,
553 mut r7: u64
554 )
555 {
556 let k = r0.wrapping_mul(INV);
561 let mut carry = 0;
562 mac_with_carry(r0, k, MODULUS.0[0], &mut carry);
563 r1 = mac_with_carry(r1, k, MODULUS.0[1], &mut carry);
564 r2 = mac_with_carry(r2, k, MODULUS.0[2], &mut carry);
565 r3 = mac_with_carry(r3, k, MODULUS.0[3], &mut carry);
566 r4 = adc(r4, 0, &mut carry);
567 let carry2 = carry;
568 let k = r1.wrapping_mul(INV);
569 let mut carry = 0;
570 mac_with_carry(r1, k, MODULUS.0[0], &mut carry);
571 r2 = mac_with_carry(r2, k, MODULUS.0[1], &mut carry);
572 r3 = mac_with_carry(r3, k, MODULUS.0[2], &mut carry);
573 r4 = mac_with_carry(r4, k, MODULUS.0[3], &mut carry);
574 r5 = adc(r5, carry2, &mut carry);
575 let carry2 = carry;
576 let k = r2.wrapping_mul(INV);
577 let mut carry = 0;
578 mac_with_carry(r2, k, MODULUS.0[0], &mut carry);
579 r3 = mac_with_carry(r3, k, MODULUS.0[1], &mut carry);
580 r4 = mac_with_carry(r4, k, MODULUS.0[2], &mut carry);
581 r5 = mac_with_carry(r5, k, MODULUS.0[3], &mut carry);
582 r6 = adc(r6, carry2, &mut carry);
583 let carry2 = carry;
584 let k = r3.wrapping_mul(INV);
585 let mut carry = 0;
586 mac_with_carry(r3, k, MODULUS.0[0], &mut carry);
587 r4 = mac_with_carry(r4, k, MODULUS.0[1], &mut carry);
588 r5 = mac_with_carry(r5, k, MODULUS.0[2], &mut carry);
589 r6 = mac_with_carry(r6, k, MODULUS.0[3], &mut carry);
590 r7 = adc(r7, carry2, &mut carry);
591 (self.0).0[0] = r4;
592 (self.0).0[1] = r5;
593 (self.0).0[2] = r6;
594 (self.0).0[3] = r7;
595 self.reduce();
596 }
597
598 fn mul_bits<S: AsRef<[u64]>>(&self, bits: BitIterator<S>) -> Self {
599 let mut res = Self::zero();
600 for bit in bits {
601 res.double();
602
603 if bit {
604 res.add_assign(self)
605 }
606 }
607 res
608 }
609}
610
611impl ToUniform for Fs {
612 fn to_uniform(digest: &[u8]) -> Self {
617 assert_eq!(digest.len(), 64);
618 let mut repr: [u64; 8] = [0; 8];
619 LittleEndian::read_u64_into(digest, &mut repr);
620 Self::one().mul_bits(BitIterator::new(repr))
621 }
622
623 fn to_uniform_32(digest: &[u8]) -> Self {
628 assert_eq!(digest.len(), 32);
629 let mut repr: [u64; 4] = [0; 4];
630 LittleEndian::read_u64_into(digest, &mut repr);
631 Self::one().mul_bits(BitIterator::new(repr))
632 }
633}
634
635impl SqrtField for Fs {
636
637 fn legendre(&self) -> LegendreSymbol {
638 let s = self.pow([
640 0x33b94bee1c909378,
641 0xd59f76dc1c907705,
642 0x9b85045b68181585,
643 0x030644e72e131a02,
644 ]);
645 if s == Self::zero() { Zero }
646 else if s == Self::one() { QuadraticResidue }
647 else { QuadraticNonResidue }
648 }
649
650 fn sqrt(&self) -> Option<Self> {
651 None
652
653 }
675}
676
677
678#[test]
679fn test_neg_one() {
680 let mut o = Fs::one();
681 o.negate();
682
683 assert_eq!(NEGATIVE_ONE, o);
684}
685
686#[cfg(test)]
687use rand::{SeedableRng, XorShiftRng, Rand};
688
689#[test]
690fn test_fs_repr_ordering() {
691 fn assert_equality(a: FsRepr, b: FsRepr) {
692 assert_eq!(a, b);
693 assert!(a.cmp(&b) == ::std::cmp::Ordering::Equal);
694 }
695
696 fn assert_lt(a: FsRepr, b: FsRepr) {
697 assert!(a < b);
698 assert!(b > a);
699 }
700
701 assert_equality(FsRepr([9999, 9999, 9999, 9999]), FsRepr([9999, 9999, 9999, 9999]));
702 assert_equality(FsRepr([9999, 9998, 9999, 9999]), FsRepr([9999, 9998, 9999, 9999]));
703 assert_equality(FsRepr([9999, 9999, 9999, 9997]), FsRepr([9999, 9999, 9999, 9997]));
704 assert_lt(FsRepr([9999, 9997, 9999, 9998]), FsRepr([9999, 9997, 9999, 9999]));
705 assert_lt(FsRepr([9999, 9997, 9998, 9999]), FsRepr([9999, 9997, 9999, 9999]));
706 assert_lt(FsRepr([9, 9999, 9999, 9997]), FsRepr([9999, 9999, 9999, 9997]));
707}
708
709#[test]
710fn test_fs_repr_from() {
711 assert_eq!(FsRepr::from(100), FsRepr([100, 0, 0, 0]));
712}
713
714#[test]
715fn test_fs_repr_is_odd() {
716 assert!(!FsRepr::from(0).is_odd());
717 assert!(FsRepr::from(0).is_even());
718 assert!(FsRepr::from(1).is_odd());
719 assert!(!FsRepr::from(1).is_even());
720 assert!(!FsRepr::from(324834872).is_odd());
721 assert!(FsRepr::from(324834872).is_even());
722 assert!(FsRepr::from(324834873).is_odd());
723 assert!(!FsRepr::from(324834873).is_even());
724}
725
726#[test]
727fn test_fs_repr_is_zero() {
728 assert!(FsRepr::from(0).is_zero());
729 assert!(!FsRepr::from(1).is_zero());
730 assert!(!FsRepr([0, 0, 1, 0]).is_zero());
731}
732
733#[test]
734fn test_fs_repr_div2() {
735 let mut a = FsRepr([0xbd2920b19c972321, 0x174ed0466a3be37e, 0xd468d5e3b551f0b5, 0xcb67c072733beefc]);
736 a.div2();
737 assert_eq!(a, FsRepr([0x5e949058ce4b9190, 0x8ba76823351df1bf, 0x6a346af1daa8f85a, 0x65b3e039399df77e]));
738 for _ in 0..10 {
739 a.div2();
740 }
741 assert_eq!(a, FsRepr([0x6fd7a524163392e4, 0x16a2e9da08cd477c, 0xdf9a8d1abc76aa3e, 0x196cf80e4e677d]));
742 for _ in 0..200 {
743 a.div2();
744 }
745 assert_eq!(a, FsRepr([0x196cf80e4e67, 0x0, 0x0, 0x0]));
746 for _ in 0..40 {
747 a.div2();
748 }
749 assert_eq!(a, FsRepr([0x19, 0x0, 0x0, 0x0]));
750 for _ in 0..4 {
751 a.div2();
752 }
753 assert_eq!(a, FsRepr([0x1, 0x0, 0x0, 0x0]));
754 a.div2();
755 assert!(a.is_zero());
756}
757
758#[test]
759fn test_fs_repr_shr() {
760 let mut a = FsRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1]);
761 a.shr(0);
762 assert_eq!(
763 a,
764 FsRepr([0xb33fbaec482a283f, 0x997de0d3a88cb3df, 0x9af62d2a9a0e5525, 0x36003ab08de70da1])
765 );
766 a.shr(1);
767 assert_eq!(
768 a,
769 FsRepr([0xd99fdd762415141f, 0xccbef069d44659ef, 0xcd7b16954d072a92, 0x1b001d5846f386d0])
770 );
771 a.shr(50);
772 assert_eq!(
773 a,
774 FsRepr([0xbc1a7511967bf667, 0xc5a55341caa4b32f, 0x75611bce1b4335e, 0x6c0])
775 );
776 a.shr(130);
777 assert_eq!(
778 a,
779 FsRepr([0x1d5846f386d0cd7, 0x1b0, 0x0, 0x0])
780 );
781 a.shr(64);
782 assert_eq!(
783 a,
784 FsRepr([0x1b0, 0x0, 0x0, 0x0])
785 );
786}
787
788#[test]
789fn test_fs_repr_mul2() {
790 let mut a = FsRepr::from(23712937547);
791 a.mul2();
792 assert_eq!(a, FsRepr([0xb0acd6c96, 0x0, 0x0, 0x0]));
793 for _ in 0..60 {
794 a.mul2();
795 }
796 assert_eq!(a, FsRepr([0x6000000000000000, 0xb0acd6c9, 0x0, 0x0]));
797 for _ in 0..128 {
798 a.mul2();
799 }
800 assert_eq!(a, FsRepr([0x0, 0x0, 0x6000000000000000, 0xb0acd6c9]));
801 for _ in 0..60 {
802 a.mul2();
803 }
804 assert_eq!(a, FsRepr([0x0, 0x0, 0x0, 0x9600000000000000]));
805 for _ in 0..7 {
806 a.mul2();
807 }
808 assert!(a.is_zero());
809}
810
811#[test]
812fn test_fs_repr_num_bits() {
813 let mut a = FsRepr::from(0);
814 assert_eq!(0, a.num_bits());
815 a = FsRepr::from(1);
816 for i in 1..257 {
817 assert_eq!(i, a.num_bits());
818 a.mul2();
819 }
820 assert_eq!(0, a.num_bits());
821}
822
823#[test]
824fn test_fs_repr_sub_noborrow() {
825 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
826
827 for _ in 0..1000 {
832 let mut a = FsRepr::rand(&mut rng);
833 a.0[3] >>= 30;
834 let mut b = a;
835 for _ in 0..10 {
836 b.mul2();
837 }
838 let mut c = b;
839 for _ in 0..10 {
840 c.mul2();
841 }
842
843 assert!(a < b);
844 assert!(b < c);
845
846 let mut csub_ba = c;
847 csub_ba.sub_noborrow(&b);
848 csub_ba.sub_noborrow(&a);
849
850 let mut csub_ab = c;
851 csub_ab.sub_noborrow(&a);
852 csub_ab.sub_noborrow(&b);
853
854 assert_eq!(csub_ab, csub_ba);
855 }
856}
857
858#[test]
859fn test_fs_legendre() {
860 assert_eq!(QuadraticResidue, Fs::one().legendre());
861 assert_eq!(Zero, Fs::zero().legendre());
862
863 let e = FsRepr([0x8385eec23df1f88e, 0x9a01fb412b2dba16, 0x4c928edcdd6c22f, 0x9f2df7ef69ecef9]);
864 assert_eq!(QuadraticResidue, Fs::from_repr(e).unwrap().legendre());
865 let e = FsRepr([0xe8ed9f299da78568, 0x35efdebc88b2209, 0xc82125cb1f916dbe, 0x6813d2b38c39bd0]);
866 assert_eq!(QuadraticNonResidue, Fs::from_repr(e).unwrap().legendre());
867}
868
869#[test]
870fn test_fr_repr_add_nocarry() {
871 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
872
873 for _ in 0..1000 {
879 let mut a = FsRepr::rand(&mut rng);
880 let mut b = FsRepr::rand(&mut rng);
881 let mut c = FsRepr::rand(&mut rng);
882
883 a.0[3] >>= 3;
885 b.0[3] >>= 3;
886 c.0[3] >>= 3;
887
888 let mut abc = a;
889 abc.add_nocarry(&b);
890 abc.add_nocarry(&c);
891
892 let mut acb = a;
893 acb.add_nocarry(&c);
894 acb.add_nocarry(&b);
895
896 let mut bac = b;
897 bac.add_nocarry(&a);
898 bac.add_nocarry(&c);
899
900 let mut bca = b;
901 bca.add_nocarry(&c);
902 bca.add_nocarry(&a);
903
904 let mut cab = c;
905 cab.add_nocarry(&a);
906 cab.add_nocarry(&b);
907
908 let mut cba = c;
909 cba.add_nocarry(&b);
910 cba.add_nocarry(&a);
911
912 assert_eq!(abc, acb);
913 assert_eq!(abc, bac);
914 assert_eq!(abc, bca);
915 assert_eq!(abc, cab);
916 assert_eq!(abc, cba);
917 }
918}
919
920#[test]
921fn test_fs_is_valid() {
922 let mut a = Fs(MODULUS);
923 assert!(!a.is_valid());
924 a.0.sub_noborrow(&FsRepr::from(1));
925 assert!(a.is_valid());
926 assert!(Fs(FsRepr::from(0)).is_valid());
927 assert!(!Fs(FsRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff])).is_valid());
929
930 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
931
932 for _ in 0..1000 {
933 let a = Fs::rand(&mut rng);
934 assert!(a.is_valid());
935 }
936}
937
938#[test]
939fn test_fs_add_assign() {
940 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
969
970 for _ in 0..1000 {
971 let a = Fs::rand(&mut rng);
973 let b = Fs::rand(&mut rng);
974 let c = Fs::rand(&mut rng);
975
976 let mut tmp1 = a;
977 tmp1.add_assign(&b);
978 tmp1.add_assign(&c);
979
980 let mut tmp2 = b;
981 tmp2.add_assign(&c);
982 tmp2.add_assign(&a);
983
984 assert!(tmp1.is_valid());
985 assert!(tmp2.is_valid());
986 assert_eq!(tmp1, tmp2);
987 }
988}
989
990#[test]
991fn test_fs_sub_assign() {
992 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1014
1015 for _ in 0..1000 {
1016 let a = Fs::rand(&mut rng);
1018 let b = Fs::rand(&mut rng);
1019
1020 let mut tmp1 = a;
1021 tmp1.sub_assign(&b);
1022
1023 let mut tmp2 = b;
1024 tmp2.sub_assign(&a);
1025
1026 tmp1.add_assign(&tmp2);
1027 assert!(tmp1.is_zero());
1028 }
1029}
1030
1031#[test]
1032fn test_fs_mul_assign() {
1033 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1038
1039 for _ in 0..1000000 {
1040 let a = Fs::rand(&mut rng);
1042 let b = Fs::rand(&mut rng);
1043 let c = Fs::rand(&mut rng);
1044
1045 let mut tmp1 = a;
1046 tmp1.mul_assign(&b);
1047 tmp1.mul_assign(&c);
1048
1049 let mut tmp2 = b;
1050 tmp2.mul_assign(&c);
1051 tmp2.mul_assign(&a);
1052
1053 assert_eq!(tmp1, tmp2);
1054 }
1055
1056 for _ in 0..1000000 {
1057 let r = Fs::rand(&mut rng);
1060 let mut a = Fs::rand(&mut rng);
1061 let mut b = Fs::rand(&mut rng);
1062 let mut c = Fs::rand(&mut rng);
1063
1064 let mut tmp1 = a;
1065 tmp1.add_assign(&b);
1066 tmp1.add_assign(&c);
1067 tmp1.mul_assign(&r);
1068
1069 a.mul_assign(&r);
1070 b.mul_assign(&r);
1071 c.mul_assign(&r);
1072
1073 a.add_assign(&b);
1074 a.add_assign(&c);
1075
1076 assert_eq!(tmp1, a);
1077 }
1078}
1079
1080#[test]
1081fn test_fr_squaring() {
1082 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1088
1089 for _ in 0..1000000 {
1090 let a = Fs::rand(&mut rng);
1092
1093 let mut tmp = a;
1094 tmp.square();
1095
1096 let mut tmp2 = a;
1097 tmp2.mul_assign(&a);
1098
1099 assert_eq!(tmp, tmp2);
1100 }
1101}
1102
1103#[test]
1104fn test_fs_inverse() {
1105 assert!(Fs::zero().inverse().is_none());
1106
1107 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1108
1109 let one = Fs::one();
1110
1111 for _ in 0..1000 {
1112 let mut a = Fs::rand(&mut rng);
1114 let ainv = a.inverse().unwrap();
1115 a.mul_assign(&ainv);
1116 assert_eq!(a, one);
1117 }
1118}
1119
1120#[test]
1121fn test_fs_double() {
1122 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1123
1124 for _ in 0..1000 {
1125 let mut a = Fs::rand(&mut rng);
1127 let mut b = a;
1128 b.add_assign(&a);
1129 a.double();
1130 assert_eq!(a, b);
1131 }
1132}
1133
1134#[test]
1135fn test_fs_negate() {
1136 {
1137 let mut a = Fs::zero();
1138 a.negate();
1139
1140 assert!(a.is_zero());
1141 }
1142
1143 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1144
1145 for _ in 0..1000 {
1146 let mut a = Fs::rand(&mut rng);
1148 let mut b = a;
1149 b.negate();
1150 a.add_assign(&b);
1151
1152 assert!(a.is_zero());
1153 }
1154}
1155
1156#[test]
1157fn test_fs_pow() {
1158 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1159
1160 for i in 0..1000 {
1161 let a = Fs::rand(&mut rng);
1164 let target = a.pow(&[i]);
1165 let mut c = Fs::one();
1166 for _ in 0..i {
1167 c.mul_assign(&a);
1168 }
1169 assert_eq!(c, target);
1170 }
1171
1172 for _ in 0..1000 {
1173 let a = Fs::rand(&mut rng);
1175
1176 assert_eq!(a, a.pow(Fs::char()));
1177 }
1178}
1179
1180#[test]
1181fn test_fs_sqrt() {
1182 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1183
1184 assert_eq!(Fs::zero().sqrt().unwrap(), Fs::zero());
1185
1186 for _ in 0..1000 {
1187 let a = Fs::rand(&mut rng);
1189 let mut nega = a;
1190 nega.negate();
1191 let mut b = a;
1192 b.square();
1193
1194 let b = b.sqrt().unwrap();
1195
1196 assert!(a == b || nega == b);
1197 }
1198
1199 for _ in 0..1000 {
1200 let a = Fs::rand(&mut rng);
1202
1203 if let Some(mut tmp) = a.sqrt() {
1204 tmp.square();
1205
1206 assert_eq!(a, tmp);
1207 }
1208 }
1209}
1210
1211#[test]
1212fn test_fs_from_into_repr() {
1213 assert!(Fs::from_repr(FsRepr([0xd0970e5ed6f72cb8, 0xa6682093ccc81082, 0x6673b0101343b00, 0xe7db4ea6533afa9])).is_err());
1215
1216 assert!(Fs::from_repr(Fs::char()).is_err());
1218
1219 let a = FsRepr([0x5f2d0c05d0337b71, 0xa1df2b0f8a20479, 0xad73785e71bb863, 0x504a00480c9acec]);
1221 let mut a_fs = Fs::from_repr(a).unwrap();
1222 let b = FsRepr([0x66356ff51e477562, 0x60a92ab55cf7603, 0x8e4273c7364dd192, 0x36df8844a344dc5]);
1223 let b_fs = Fs::from_repr(b).unwrap();
1224 let c = FsRepr([0x7eef61708f4f2868, 0x747a7e6cf52946fb, 0x83dd75d7c9120017, 0x762f5177f0f3df7]);
1225 a_fs.mul_assign(&b_fs);
1226 assert_eq!(a_fs.into_repr(), c);
1227
1228 assert!(Fs::from_repr(FsRepr::from(0)).unwrap().is_zero());
1230
1231 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
1232
1233 for _ in 0..1000 {
1234 let a = Fs::rand(&mut rng);
1236 let a_repr = a.into_repr();
1237 let b_repr = FsRepr::from(a);
1238 assert_eq!(a_repr, b_repr);
1239 let a_again = Fs::from_repr(a_repr).unwrap();
1240
1241 assert_eq!(a, a_again);
1242 }
1243}
1244
1245#[test]
1246fn test_fs_repr_display() {
1247 assert_eq!(
1248 format!("{}", FsRepr([0xa296db59787359df, 0x8d3e33077430d318, 0xd1abf5c606102eb7, 0xcbc33ee28108f0])),
1249 "0x00cbc33ee28108f0d1abf5c606102eb78d3e33077430d318a296db59787359df".to_string()
1250 );
1251 assert_eq!(
1252 format!("{}", FsRepr([0x14cb03535054a620, 0x312aa2bf2d1dff52, 0x970fe98746ab9361, 0xc1e18acf82711e6])),
1253 "0x0c1e18acf82711e6970fe98746ab9361312aa2bf2d1dff5214cb03535054a620".to_string()
1254 );
1255 assert_eq!(
1256 format!("{}", FsRepr([0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff])),
1257 "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff".to_string()
1258 );
1259 assert_eq!(
1260 format!("{}", FsRepr([0, 0, 0, 0])),
1261 "0x0000000000000000000000000000000000000000000000000000000000000000".to_string()
1262 );
1263}
1264
1265#[test]
1266fn test_fs_display() {
1267 assert_eq!(
1268 format!("{}", Fs::from_repr(FsRepr([0x5528efb9998a01a3, 0x5bd2add5cb357089, 0xc061fa6adb491f98, 0x70db9d143db03d9])).unwrap()),
1269 "Fs(0x070db9d143db03d9c061fa6adb491f985bd2add5cb3570895528efb9998a01a3)".to_string()
1270 );
1271 assert_eq!(
1272 format!("{}", Fs::from_repr(FsRepr([0xd674745e2717999e, 0xbeb1f52d3e96f338, 0x9c7ae147549482b9, 0x999706024530d22])).unwrap()),
1273 "Fs(0x0999706024530d229c7ae147549482b9beb1f52d3e96f338d674745e2717999e)".to_string()
1274 );
1275}
1276
1277#[test]
1278fn test_fs_num_bits() {
1279 assert_eq!(Fs::NUM_BITS, 251);
1280 assert_eq!(Fs::CAPACITY, 250);
1281}
1282
1283#[test]
1284fn test_fs_root_of_unity() {
1285 assert_eq!(Fs::multiplicative_generator(), Fs::from_repr(FsRepr::from(7)).unwrap());
1287 assert_eq!(
1288 Fs::multiplicative_generator().pow([
1289 0xa677297dc392126f,
1290 0xbab3eedb83920ee0,
1291 0x5370a08b6d0302b0,
1292 0x0060c89ce5c26340,
1293 ]),
1294 Fs::root_of_unity()
1295 );
1296 assert_eq!(
1297 Fs::root_of_unity().pow([1 << Fs::S]),
1298 Fs::one()
1299 );
1300 assert!(Fs::multiplicative_generator().sqrt().is_none());
1301}