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