1use ff::{Field, PrimeField, PrimeFieldRepr};
2
3#[derive(PrimeField)]
4#[PrimeFieldModulus = "52435875175126190479447740508185965837690552500527637822603658699938581184513"]
5#[PrimeFieldGenerator = "7"]
6pub struct Fr(FrRepr);
7
8#[cfg(test)]
9use rand::{Rand, SeedableRng, XorShiftRng};
10
11#[test]
12fn test_fr_repr_ordering() {
13 fn assert_equality(a: FrRepr, b: FrRepr) {
14 assert_eq!(a, b);
15 assert!(a.cmp(&b) == ::std::cmp::Ordering::Equal);
16 }
17
18 fn assert_lt(a: FrRepr, b: FrRepr) {
19 assert!(a < b);
20 assert!(b > a);
21 }
22
23 assert_equality(
24 FrRepr([9999, 9999, 9999, 9999]),
25 FrRepr([9999, 9999, 9999, 9999]),
26 );
27 assert_equality(
28 FrRepr([9999, 9998, 9999, 9999]),
29 FrRepr([9999, 9998, 9999, 9999]),
30 );
31 assert_equality(
32 FrRepr([9999, 9999, 9999, 9997]),
33 FrRepr([9999, 9999, 9999, 9997]),
34 );
35 assert_lt(
36 FrRepr([9999, 9997, 9999, 9998]),
37 FrRepr([9999, 9997, 9999, 9999]),
38 );
39 assert_lt(
40 FrRepr([9999, 9997, 9998, 9999]),
41 FrRepr([9999, 9997, 9999, 9999]),
42 );
43 assert_lt(
44 FrRepr([9, 9999, 9999, 9997]),
45 FrRepr([9999, 9999, 9999, 9997]),
46 );
47}
48
49#[test]
50fn test_fr_repr_from() {
51 assert_eq!(FrRepr::from(100), FrRepr([100, 0, 0, 0]));
52}
53
54#[test]
55fn test_fr_repr_is_odd() {
56 assert!(!FrRepr::from(0).is_odd());
57 assert!(FrRepr::from(0).is_even());
58 assert!(FrRepr::from(1).is_odd());
59 assert!(!FrRepr::from(1).is_even());
60 assert!(!FrRepr::from(324834872).is_odd());
61 assert!(FrRepr::from(324834872).is_even());
62 assert!(FrRepr::from(324834873).is_odd());
63 assert!(!FrRepr::from(324834873).is_even());
64}
65
66#[test]
67fn test_fr_repr_is_zero() {
68 assert!(FrRepr::from(0).is_zero());
69 assert!(!FrRepr::from(1).is_zero());
70 assert!(!FrRepr([0, 0, 1, 0]).is_zero());
71}
72
73#[test]
74fn test_fr_repr_div2() {
75 let mut a = FrRepr([
76 0xbd2920b19c972321,
77 0x174ed0466a3be37e,
78 0xd468d5e3b551f0b5,
79 0xcb67c072733beefc,
80 ]);
81 a.div2();
82 assert_eq!(
83 a,
84 FrRepr([
85 0x5e949058ce4b9190,
86 0x8ba76823351df1bf,
87 0x6a346af1daa8f85a,
88 0x65b3e039399df77e
89 ])
90 );
91 for _ in 0..10 {
92 a.div2();
93 }
94 assert_eq!(
95 a,
96 FrRepr([
97 0x6fd7a524163392e4,
98 0x16a2e9da08cd477c,
99 0xdf9a8d1abc76aa3e,
100 0x196cf80e4e677d
101 ])
102 );
103 for _ in 0..200 {
104 a.div2();
105 }
106 assert_eq!(a, FrRepr([0x196cf80e4e67, 0x0, 0x0, 0x0]));
107 for _ in 0..40 {
108 a.div2();
109 }
110 assert_eq!(a, FrRepr([0x19, 0x0, 0x0, 0x0]));
111 for _ in 0..4 {
112 a.div2();
113 }
114 assert_eq!(a, FrRepr([0x1, 0x0, 0x0, 0x0]));
115 a.div2();
116 assert!(a.is_zero());
117}
118
119#[test]
120fn test_fr_repr_shr() {
121 let mut a = FrRepr([
122 0xb33fbaec482a283f,
123 0x997de0d3a88cb3df,
124 0x9af62d2a9a0e5525,
125 0x36003ab08de70da1,
126 ]);
127 a.shr(0);
128 assert_eq!(
129 a,
130 FrRepr([
131 0xb33fbaec482a283f,
132 0x997de0d3a88cb3df,
133 0x9af62d2a9a0e5525,
134 0x36003ab08de70da1
135 ])
136 );
137 a.shr(1);
138 assert_eq!(
139 a,
140 FrRepr([
141 0xd99fdd762415141f,
142 0xccbef069d44659ef,
143 0xcd7b16954d072a92,
144 0x1b001d5846f386d0
145 ])
146 );
147 a.shr(50);
148 assert_eq!(
149 a,
150 FrRepr([
151 0xbc1a7511967bf667,
152 0xc5a55341caa4b32f,
153 0x75611bce1b4335e,
154 0x6c0
155 ])
156 );
157 a.shr(130);
158 assert_eq!(a, FrRepr([0x1d5846f386d0cd7, 0x1b0, 0x0, 0x0]));
159 a.shr(64);
160 assert_eq!(a, FrRepr([0x1b0, 0x0, 0x0, 0x0]));
161}
162
163#[test]
164fn test_fr_repr_mul2() {
165 let mut a = FrRepr::from(23712937547);
166 a.mul2();
167 assert_eq!(a, FrRepr([0xb0acd6c96, 0x0, 0x0, 0x0]));
168 for _ in 0..60 {
169 a.mul2();
170 }
171 assert_eq!(a, FrRepr([0x6000000000000000, 0xb0acd6c9, 0x0, 0x0]));
172 for _ in 0..128 {
173 a.mul2();
174 }
175 assert_eq!(a, FrRepr([0x0, 0x0, 0x6000000000000000, 0xb0acd6c9]));
176 for _ in 0..60 {
177 a.mul2();
178 }
179 assert_eq!(a, FrRepr([0x0, 0x0, 0x0, 0x9600000000000000]));
180 for _ in 0..7 {
181 a.mul2();
182 }
183 assert!(a.is_zero());
184}
185
186#[test]
187fn test_fr_repr_num_bits() {
188 let mut a = FrRepr::from(0);
189 assert_eq!(0, a.num_bits());
190 a = FrRepr::from(1);
191 for i in 1..257 {
192 assert_eq!(i, a.num_bits());
193 a.mul2();
194 }
195 assert_eq!(0, a.num_bits());
196}
197
198#[test]
199fn test_fr_repr_sub_noborrow() {
200 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
201
202 let mut t = FrRepr([
203 0x8e62a7e85264e2c3,
204 0xb23d34c1941d3ca,
205 0x5976930b7502dd15,
206 0x600f3fb517bf5495,
207 ]);
208 t.sub_noborrow(&FrRepr([
209 0xd64f669809cbc6a4,
210 0xfa76cb9d90cf7637,
211 0xfefb0df9038d43b3,
212 0x298a30c744b31acf,
213 ]));
214 assert!(
215 t == FrRepr([
216 0xb813415048991c1f,
217 0x10ad07ae88725d92,
218 0x5a7b851271759961,
219 0x36850eedd30c39c5
220 ])
221 );
222
223 for _ in 0..1000 {
224 let mut a = FrRepr::rand(&mut rng);
225 a.0[3] >>= 30;
226 let mut b = a;
227 for _ in 0..10 {
228 b.mul2();
229 }
230 let mut c = b;
231 for _ in 0..10 {
232 c.mul2();
233 }
234
235 assert!(a < b);
236 assert!(b < c);
237
238 let mut csub_ba = c;
239 csub_ba.sub_noborrow(&b);
240 csub_ba.sub_noborrow(&a);
241
242 let mut csub_ab = c;
243 csub_ab.sub_noborrow(&a);
244 csub_ab.sub_noborrow(&b);
245
246 assert_eq!(csub_ab, csub_ba);
247 }
248
249 let mut qplusone = FrRepr([
251 0xffffffff00000001,
252 0x53bda402fffe5bfe,
253 0x3339d80809a1d805,
254 0x73eda753299d7d48,
255 ]);
256 qplusone.sub_noborrow(&FrRepr([
257 0xffffffff00000002,
258 0x53bda402fffe5bfe,
259 0x3339d80809a1d805,
260 0x73eda753299d7d48,
261 ]));
262 assert_eq!(
263 qplusone,
264 FrRepr([
265 0xffffffffffffffff,
266 0xffffffffffffffff,
267 0xffffffffffffffff,
268 0xffffffffffffffff
269 ])
270 );
271}
272
273#[test]
274fn test_fr_legendre() {
275 use ff::LegendreSymbol::*;
276 use ff::SqrtField;
277
278 assert_eq!(QuadraticResidue, Fr::one().legendre());
279 assert_eq!(Zero, Fr::zero().legendre());
280
281 let e = FrRepr([
282 0x0dbc5349cd5664da,
283 0x8ac5b6296e3ae29d,
284 0x127cb819feceaa3b,
285 0x3a6b21fb03867191,
286 ]);
287 assert_eq!(QuadraticResidue, Fr::from_repr(e).unwrap().legendre());
288 let e = FrRepr([
289 0x96341aefd047c045,
290 0x9b5f4254500a4d65,
291 0x1ee08223b68ac240,
292 0x31d9cd545c0ec7c6,
293 ]);
294 assert_eq!(QuadraticNonResidue, Fr::from_repr(e).unwrap().legendre());
295}
296
297#[test]
298fn test_fr_repr_add_nocarry() {
299 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
300
301 let mut t = FrRepr([
302 0xd64f669809cbc6a4,
303 0xfa76cb9d90cf7637,
304 0xfefb0df9038d43b3,
305 0x298a30c744b31acf,
306 ]);
307 t.add_nocarry(&FrRepr([
308 0x8e62a7e85264e2c3,
309 0xb23d34c1941d3ca,
310 0x5976930b7502dd15,
311 0x600f3fb517bf5495,
312 ]));
313 assert_eq!(
314 t,
315 FrRepr([
316 0x64b20e805c30a967,
317 0x59a9ee9aa114a02,
318 0x5871a104789020c9,
319 0x8999707c5c726f65
320 ])
321 );
322
323 for _ in 0..1000 {
325 let mut a = FrRepr::rand(&mut rng);
326 let mut b = FrRepr::rand(&mut rng);
327 let mut c = FrRepr::rand(&mut rng);
328
329 a.0[3] >>= 3;
331 b.0[3] >>= 3;
332 c.0[3] >>= 3;
333
334 let mut abc = a;
335 abc.add_nocarry(&b);
336 abc.add_nocarry(&c);
337
338 let mut acb = a;
339 acb.add_nocarry(&c);
340 acb.add_nocarry(&b);
341
342 let mut bac = b;
343 bac.add_nocarry(&a);
344 bac.add_nocarry(&c);
345
346 let mut bca = b;
347 bca.add_nocarry(&c);
348 bca.add_nocarry(&a);
349
350 let mut cab = c;
351 cab.add_nocarry(&a);
352 cab.add_nocarry(&b);
353
354 let mut cba = c;
355 cba.add_nocarry(&b);
356 cba.add_nocarry(&a);
357
358 assert_eq!(abc, acb);
359 assert_eq!(abc, bac);
360 assert_eq!(abc, bca);
361 assert_eq!(abc, cab);
362 assert_eq!(abc, cba);
363 }
364
365 let mut x = FrRepr([
367 0xffffffffffffffff,
368 0xffffffffffffffff,
369 0xffffffffffffffff,
370 0xffffffffffffffff,
371 ]);
372 x.add_nocarry(&FrRepr::from(1));
373 assert!(x.is_zero());
374}
375
376#[test]
377fn test_fr_is_valid() {
378 let mut a = Fr(MODULUS);
379 assert!(!a.is_valid());
380 a.0.sub_noborrow(&FrRepr::from(1));
381 assert!(a.is_valid());
382 assert!(Fr(FrRepr::from(0)).is_valid());
383 assert!(
384 Fr(FrRepr([
385 0xffffffff00000000,
386 0x53bda402fffe5bfe,
387 0x3339d80809a1d805,
388 0x73eda753299d7d48
389 ])).is_valid()
390 );
391 assert!(
392 !Fr(FrRepr([
393 0xffffffffffffffff,
394 0xffffffffffffffff,
395 0xffffffffffffffff,
396 0xffffffffffffffff
397 ])).is_valid()
398 );
399
400 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
401
402 for _ in 0..1000 {
403 let a = Fr::rand(&mut rng);
404 assert!(a.is_valid());
405 }
406}
407
408#[test]
409fn test_fr_add_assign() {
410 {
411 let mut tmp = Fr(FrRepr([
413 0x437ce7616d580765,
414 0xd42d1ccb29d1235b,
415 0xed8f753821bd1423,
416 0x4eede1c9c89528ca,
417 ]));
418 assert!(tmp.is_valid());
419 tmp.add_assign(&Fr(FrRepr::from(0)));
421 assert_eq!(
422 tmp,
423 Fr(FrRepr([
424 0x437ce7616d580765,
425 0xd42d1ccb29d1235b,
426 0xed8f753821bd1423,
427 0x4eede1c9c89528ca
428 ]))
429 );
430 tmp.add_assign(&Fr(FrRepr::from(1)));
432 assert_eq!(
433 tmp,
434 Fr(FrRepr([
435 0x437ce7616d580766,
436 0xd42d1ccb29d1235b,
437 0xed8f753821bd1423,
438 0x4eede1c9c89528ca
439 ]))
440 );
441 tmp.add_assign(&Fr(FrRepr([
443 0x946f435944f7dc79,
444 0xb55e7ee6533a9b9b,
445 0x1e43b84c2f6194ca,
446 0x58717ab525463496,
447 ])));
448 assert_eq!(
449 tmp,
450 Fr(FrRepr([
451 0xd7ec2abbb24fe3de,
452 0x35cdf7ae7d0d62f7,
453 0xd899557c477cd0e9,
454 0x3371b52bc43de018
455 ]))
456 );
457 tmp = Fr(FrRepr([
459 0xffffffff00000000,
460 0x53bda402fffe5bfe,
461 0x3339d80809a1d805,
462 0x73eda753299d7d48,
463 ]));
464 tmp.add_assign(&Fr(FrRepr::from(1)));
465 assert!(tmp.0.is_zero());
466 tmp = Fr(FrRepr([
468 0xade5adacdccb6190,
469 0xaa21ee0f27db3ccd,
470 0x2550f4704ae39086,
471 0x591d1902e7c5ba27,
472 ]));
473 tmp.add_assign(&Fr(FrRepr([
474 0x521a525223349e70,
475 0xa99bb5f3d8231f31,
476 0xde8e397bebe477e,
477 0x1ad08e5041d7c321,
478 ])));
479 assert_eq!(
480 tmp,
481 Fr(FrRepr([
482 0xffffffff00000000,
483 0x53bda402fffe5bfe,
484 0x3339d80809a1d805,
485 0x73eda753299d7d48
486 ]))
487 );
488 tmp.add_assign(&Fr(FrRepr::from(1)));
490 assert!(tmp.0.is_zero());
491 }
492
493 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
496
497 for _ in 0..1000 {
498 let a = Fr::rand(&mut rng);
500 let b = Fr::rand(&mut rng);
501 let c = Fr::rand(&mut rng);
502
503 let mut tmp1 = a;
504 tmp1.add_assign(&b);
505 tmp1.add_assign(&c);
506
507 let mut tmp2 = b;
508 tmp2.add_assign(&c);
509 tmp2.add_assign(&a);
510
511 assert!(tmp1.is_valid());
512 assert!(tmp2.is_valid());
513 assert_eq!(tmp1, tmp2);
514 }
515}
516
517#[test]
518fn test_fr_sub_assign() {
519 {
520 let mut tmp = Fr(FrRepr([
522 0x6a68c64b6f735a2b,
523 0xd5f4d143fe0a1972,
524 0x37c17f3829267c62,
525 0xa2f37391f30915c,
526 ]));
527 tmp.sub_assign(&Fr(FrRepr([
528 0xade5adacdccb6190,
529 0xaa21ee0f27db3ccd,
530 0x2550f4704ae39086,
531 0x591d1902e7c5ba27,
532 ])));
533 assert_eq!(
534 tmp,
535 Fr(FrRepr([
536 0xbc83189d92a7f89c,
537 0x7f908737d62d38a3,
538 0x45aa62cfe7e4c3e1,
539 0x24ffc5896108547d
540 ]))
541 );
542
543 tmp = Fr(FrRepr([
545 0xade5adacdccb6190,
546 0xaa21ee0f27db3ccd,
547 0x2550f4704ae39086,
548 0x591d1902e7c5ba27,
549 ]));
550 tmp.sub_assign(&Fr(FrRepr([
551 0x6a68c64b6f735a2b,
552 0xd5f4d143fe0a1972,
553 0x37c17f3829267c62,
554 0xa2f37391f30915c,
555 ])));
556 assert_eq!(
557 tmp,
558 Fr(FrRepr([
559 0x437ce7616d580765,
560 0xd42d1ccb29d1235b,
561 0xed8f753821bd1423,
562 0x4eede1c9c89528ca
563 ]))
564 );
565
566 tmp = Fr(FrRepr::from(0));
568 tmp.sub_assign(&Fr(FrRepr::from(0)));
569 assert!(tmp.is_zero());
570
571 tmp = Fr(FrRepr([
572 0x437ce7616d580765,
573 0xd42d1ccb29d1235b,
574 0xed8f753821bd1423,
575 0x4eede1c9c89528ca,
576 ]));
577 tmp.sub_assign(&Fr(FrRepr::from(0)));
578 assert_eq!(
579 tmp,
580 Fr(FrRepr([
581 0x437ce7616d580765,
582 0xd42d1ccb29d1235b,
583 0xed8f753821bd1423,
584 0x4eede1c9c89528ca
585 ]))
586 );
587 }
588
589 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
590
591 for _ in 0..1000 {
592 let a = Fr::rand(&mut rng);
594 let b = Fr::rand(&mut rng);
595
596 let mut tmp1 = a;
597 tmp1.sub_assign(&b);
598
599 let mut tmp2 = b;
600 tmp2.sub_assign(&a);
601
602 tmp1.add_assign(&tmp2);
603 assert!(tmp1.is_zero());
604 }
605}
606
607#[test]
608fn test_fr_mul_assign() {
609 let mut tmp = Fr(FrRepr([
610 0x6b7e9b8faeefc81a,
611 0xe30a8463f348ba42,
612 0xeff3cb67a8279c9c,
613 0x3d303651bd7c774d,
614 ]));
615 tmp.mul_assign(&Fr(FrRepr([
616 0x13ae28e3bc35ebeb,
617 0xa10f4488075cae2c,
618 0x8160e95a853c3b5d,
619 0x5ae3f03b561a841d,
620 ])));
621 assert!(
622 tmp == Fr(FrRepr([
623 0x23717213ce710f71,
624 0xdbee1fe53a16e1af,
625 0xf565d3e1c2a48000,
626 0x4426507ee75df9d7
627 ]))
628 );
629
630 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
631
632 for _ in 0..1000000 {
633 let a = Fr::rand(&mut rng);
635 let b = Fr::rand(&mut rng);
636 let c = Fr::rand(&mut rng);
637
638 let mut tmp1 = a;
639 tmp1.mul_assign(&b);
640 tmp1.mul_assign(&c);
641
642 let mut tmp2 = b;
643 tmp2.mul_assign(&c);
644 tmp2.mul_assign(&a);
645
646 assert_eq!(tmp1, tmp2);
647 }
648
649 for _ in 0..1000000 {
650 let r = Fr::rand(&mut rng);
653 let mut a = Fr::rand(&mut rng);
654 let mut b = Fr::rand(&mut rng);
655 let mut c = Fr::rand(&mut rng);
656
657 let mut tmp1 = a;
658 tmp1.add_assign(&b);
659 tmp1.add_assign(&c);
660 tmp1.mul_assign(&r);
661
662 a.mul_assign(&r);
663 b.mul_assign(&r);
664 c.mul_assign(&r);
665
666 a.add_assign(&b);
667 a.add_assign(&c);
668
669 assert_eq!(tmp1, a);
670 }
671}
672
673#[test]
674fn test_fr_squaring() {
675 let mut a = Fr(FrRepr([
676 0xffffffffffffffff,
677 0xffffffffffffffff,
678 0xffffffffffffffff,
679 0x73eda753299d7d47,
680 ]));
681 assert!(a.is_valid());
682 a.square();
683 assert_eq!(
684 a,
685 Fr::from_repr(FrRepr([
686 0xc0d698e7bde077b8,
687 0xb79a310579e76ec2,
688 0xac1da8d0a9af4e5f,
689 0x13f629c49bf23e97
690 ])).unwrap()
691 );
692
693 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
694
695 for _ in 0..1000000 {
696 let a = Fr::rand(&mut rng);
698
699 let mut tmp = a;
700 tmp.square();
701
702 let mut tmp2 = a;
703 tmp2.mul_assign(&a);
704
705 assert_eq!(tmp, tmp2);
706 }
707}
708
709#[test]
710fn test_fr_inverse() {
711 assert!(Fr::zero().inverse().is_none());
712
713 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
714
715 let one = Fr::one();
716
717 for _ in 0..1000 {
718 let mut a = Fr::rand(&mut rng);
720 let ainv = a.inverse().unwrap();
721 a.mul_assign(&ainv);
722 assert_eq!(a, one);
723 }
724}
725
726#[test]
727fn test_fr_double() {
728 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
729
730 for _ in 0..1000 {
731 let mut a = Fr::rand(&mut rng);
733 let mut b = a;
734 b.add_assign(&a);
735 a.double();
736 assert_eq!(a, b);
737 }
738}
739
740#[test]
741fn test_fr_negate() {
742 {
743 let mut a = Fr::zero();
744 a.negate();
745
746 assert!(a.is_zero());
747 }
748
749 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
750
751 for _ in 0..1000 {
752 let mut a = Fr::rand(&mut rng);
754 let mut b = a;
755 b.negate();
756 a.add_assign(&b);
757
758 assert!(a.is_zero());
759 }
760}
761
762#[test]
763fn test_fr_pow() {
764 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
765
766 for i in 0..1000 {
767 let a = Fr::rand(&mut rng);
770 let target = a.pow(&[i]);
771 let mut c = Fr::one();
772 for _ in 0..i {
773 c.mul_assign(&a);
774 }
775 assert_eq!(c, target);
776 }
777
778 for _ in 0..1000 {
779 let a = Fr::rand(&mut rng);
781
782 assert_eq!(a, a.pow(Fr::char()));
783 }
784}
785
786#[test]
787fn test_fr_sqrt() {
788 use ff::SqrtField;
789
790 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
791
792 assert_eq!(Fr::zero().sqrt().unwrap(), Fr::zero());
793
794 for _ in 0..1000 {
795 let a = Fr::rand(&mut rng);
797 let mut nega = a;
798 nega.negate();
799 let mut b = a;
800 b.square();
801
802 let b = b.sqrt().unwrap();
803
804 assert!(a == b || nega == b);
805 }
806
807 for _ in 0..1000 {
808 let a = Fr::rand(&mut rng);
810
811 if let Some(mut tmp) = a.sqrt() {
812 tmp.square();
813
814 assert_eq!(a, tmp);
815 }
816 }
817}
818
819#[test]
820fn test_fr_from_into_repr() {
821 assert!(
823 Fr::from_repr(FrRepr([
824 0xffffffff00000002,
825 0x53bda402fffe5bfe,
826 0x3339d80809a1d805,
827 0x73eda753299d7d48
828 ])).is_err()
829 );
830
831 assert!(Fr::from_repr(Fr::char()).is_err());
833
834 let a = FrRepr([
836 0x25ebe3a3ad3c0c6a,
837 0x6990e39d092e817c,
838 0x941f900d42f5658e,
839 0x44f8a103b38a71e0,
840 ]);
841 let mut a_fr = Fr::from_repr(a).unwrap();
842 let b = FrRepr([
843 0x264e9454885e2475,
844 0x46f7746bb0308370,
845 0x4683ef5347411f9,
846 0x58838d7f208d4492,
847 ]);
848 let b_fr = Fr::from_repr(b).unwrap();
849 let c = FrRepr([
850 0x48a09ab93cfc740d,
851 0x3a6600fbfc7a671,
852 0x838567017501d767,
853 0x7161d6da77745512,
854 ]);
855 a_fr.mul_assign(&b_fr);
856 assert_eq!(a_fr.into_repr(), c);
857
858 assert!(Fr::from_repr(FrRepr::from(0)).unwrap().is_zero());
860
861 let mut rng = XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]);
862
863 for _ in 0..1000 {
864 let a = Fr::rand(&mut rng);
866 let a_repr = a.into_repr();
867 let b_repr = FrRepr::from(a);
868 assert_eq!(a_repr, b_repr);
869 let a_again = Fr::from_repr(a_repr).unwrap();
870
871 assert_eq!(a, a_again);
872 }
873}
874
875#[test]
876fn test_fr_repr_display() {
877 assert_eq!(
878 format!(
879 "{}",
880 FrRepr([
881 0x2829c242fa826143,
882 0x1f32cf4dd4330917,
883 0x932e4e479d168cd9,
884 0x513c77587f563f64
885 ])
886 ),
887 "0x513c77587f563f64932e4e479d168cd91f32cf4dd43309172829c242fa826143".to_string()
888 );
889 assert_eq!(
890 format!(
891 "{}",
892 FrRepr([
893 0x25ebe3a3ad3c0c6a,
894 0x6990e39d092e817c,
895 0x941f900d42f5658e,
896 0x44f8a103b38a71e0
897 ])
898 ),
899 "0x44f8a103b38a71e0941f900d42f5658e6990e39d092e817c25ebe3a3ad3c0c6a".to_string()
900 );
901 assert_eq!(
902 format!(
903 "{}",
904 FrRepr([
905 0xffffffffffffffff,
906 0xffffffffffffffff,
907 0xffffffffffffffff,
908 0xffffffffffffffff
909 ])
910 ),
911 "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff".to_string()
912 );
913 assert_eq!(
914 format!("{}", FrRepr([0, 0, 0, 0])),
915 "0x0000000000000000000000000000000000000000000000000000000000000000".to_string()
916 );
917}
918
919#[test]
920fn test_fr_display() {
921 assert_eq!(
922 format!(
923 "{}",
924 Fr::from_repr(FrRepr([
925 0xc3cae746a3b5ecc7,
926 0x185ec8eb3f5b5aee,
927 0x684499ffe4b9dd99,
928 0x7c9bba7afb68faa
929 ])).unwrap()
930 ),
931 "Fr(0x07c9bba7afb68faa684499ffe4b9dd99185ec8eb3f5b5aeec3cae746a3b5ecc7)".to_string()
932 );
933 assert_eq!(
934 format!(
935 "{}",
936 Fr::from_repr(FrRepr([
937 0x44c71298ff198106,
938 0xb0ad10817df79b6a,
939 0xd034a80a2b74132b,
940 0x41cf9a1336f50719
941 ])).unwrap()
942 ),
943 "Fr(0x41cf9a1336f50719d034a80a2b74132bb0ad10817df79b6a44c71298ff198106)".to_string()
944 );
945}
946
947#[test]
948fn test_fr_num_bits() {
949 assert_eq!(Fr::NUM_BITS, 255);
950 assert_eq!(Fr::CAPACITY, 254);
951}
952
953#[test]
954fn test_fr_root_of_unity() {
955 use ff::SqrtField;
956
957 assert_eq!(Fr::S, 32);
958 assert_eq!(
959 Fr::multiplicative_generator(),
960 Fr::from_repr(FrRepr::from(7)).unwrap()
961 );
962 assert_eq!(
963 Fr::multiplicative_generator().pow([
964 0xfffe5bfeffffffff,
965 0x9a1d80553bda402,
966 0x299d7d483339d808,
967 0x73eda753
968 ]),
969 Fr::root_of_unity()
970 );
971 assert_eq!(Fr::root_of_unity().pow([1 << Fr::S]), Fr::one());
972 assert!(Fr::multiplicative_generator().sqrt().is_none());
973}
974
975#[test]
976fn fr_field_tests() {
977 crate::tests::field::random_field_tests::<Fr>();
978 crate::tests::field::random_sqrt_tests::<Fr>();
979 crate::tests::field::random_frobenius_tests::<Fr, _>(Fr::char(), 13);
980 crate::tests::field::from_str_tests::<Fr>();
981}
982
983#[test]
984fn fr_repr_tests() {
985 crate::tests::repr::random_repr_tests::<FrRepr>();
986}