1#![recursion_limit = "1024"]
2
3extern crate proc_macro;
4#[macro_use]
5extern crate quote;
6
7use num_bigint::BigUint;
8use num_integer::Integer;
9use num_traits::{One, ToPrimitive, Zero};
10use quote::TokenStreamExt;
11use std::str::FromStr;
12
13#[proc_macro_derive(PrimeField, attributes(PrimeFieldModulus, PrimeFieldGenerator))]
14pub fn prime_field(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
15 let ast: syn::DeriveInput = syn::parse(input).unwrap();
17
18 let repr_ident =
20 fetch_wrapped_ident(&ast.data).expect("PrimeField derive only operates over tuple structs of a single item");
21
22 let modulus: BigUint = fetch_attr("PrimeFieldModulus", &ast.attrs)
24 .expect("Please supply a PrimeFieldModulus attribute")
25 .parse()
26 .expect("PrimeFieldModulus should be a number");
27
28 let generator: BigUint = fetch_attr("PrimeFieldGenerator", &ast.attrs)
31 .expect("Please supply a PrimeFieldGenerator attribute")
32 .parse()
33 .expect("PrimeFieldGenerator should be a number");
34
35 let mut limbs = 1;
38 {
39 let mod2 = (&modulus) << 1; let mut cur = BigUint::one() << 64; while cur < mod2 {
42 limbs += 1;
43 cur = cur << 64;
44 }
45 }
46
47 let mut gen = proc_macro2::TokenStream::new();
48
49 let (constants_impl, sqrt_impl) =
50 prime_field_constants_and_sqrt(&ast.ident, &repr_ident, modulus, limbs, generator);
51
52 gen.extend(constants_impl);
53 gen.extend(prime_field_repr_impl(&repr_ident, limbs));
54 gen.extend(prime_field_impl(&ast.ident, &repr_ident, limbs));
55 gen.extend(sqrt_impl);
56
57 gen.into()
59}
60
61fn fetch_wrapped_ident(body: &syn::Data) -> Option<syn::Ident> {
63 match body {
64 &syn::Data::Struct(ref variant_data) => match variant_data.fields {
65 syn::Fields::Unnamed(ref fields) => {
66 if fields.unnamed.len() == 1 {
67 match fields.unnamed[0].ty {
68 syn::Type::Path(ref path) => {
69 if path.path.segments.len() == 1 {
70 return Some(path.path.segments[0].ident.clone());
71 }
72 }
73 _ => {}
74 }
75 }
76 }
77 _ => {}
78 },
79 _ => {}
80 };
81
82 None
83}
84
85fn fetch_attr(name: &str, attrs: &[syn::Attribute]) -> Option<String> {
87 for attr in attrs {
88 if let Some(meta) = attr.interpret_meta() {
89 match meta {
90 syn::Meta::NameValue(nv) => {
91 if nv.ident.to_string() == name {
92 match nv.lit {
93 syn::Lit::Str(ref s) => return Some(s.value()),
94 _ => {
95 panic!("attribute {} should be a string", name);
96 }
97 }
98 }
99 }
100 _ => {
101 panic!("attribute {} should be a string", name);
102 }
103 }
104 }
105 }
106
107 None
108}
109
110fn prime_field_repr_impl(repr: &syn::Ident, limbs: usize) -> proc_macro2::TokenStream {
112 quote! {
113 #[derive(Copy, Clone, PartialEq, Eq, Default)]
114 pub struct #repr(pub [u64; #limbs]);
115
116 impl ::std::fmt::Debug for #repr
117 {
118 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
119 write!(f, "0x")?;
120 for i in self.0.iter().rev() {
121 write!(f, "{:016x}", *i)?;
122 }
123
124 Ok(())
125 }
126 }
127
128 impl ::std::fmt::Display for #repr {
129 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
130 write!(f, "0x")?;
131 for i in self.0.iter().rev() {
132 write!(f, "{:016x}", *i)?;
133 }
134
135 Ok(())
136 }
137 }
138
139 impl AsRef<[u64]> for #repr {
140 #[inline(always)]
141 fn as_ref(&self) -> &[u64] {
142 &self.0
143 }
144 }
145
146 impl AsMut<[u64]> for #repr {
147 #[inline(always)]
148 fn as_mut(&mut self) -> &mut [u64] {
149 &mut self.0
150 }
151 }
152
153 impl From<u64> for #repr {
154 #[inline(always)]
155 fn from(val: u64) -> #repr {
156 use std::default::Default;
157
158 let mut repr = Self::default();
159 repr.0[0] = val;
160 repr
161 }
162 }
163
164 impl Ord for #repr {
165 #[inline(always)]
166 fn cmp(&self, other: &#repr) -> ::std::cmp::Ordering {
167 for (a, b) in self.0.iter().rev().zip(other.0.iter().rev()) {
168 if a < b {
169 return ::std::cmp::Ordering::Less
170 } else if a > b {
171 return ::std::cmp::Ordering::Greater
172 }
173 }
174
175 ::std::cmp::Ordering::Equal
176 }
177 }
178
179 impl PartialOrd for #repr {
180 #[inline(always)]
181 fn partial_cmp(&self, other: &#repr) -> Option<::std::cmp::Ordering> {
182 Some(self.cmp(other))
183 }
184 }
185
186 impl crate::librustzcash::algebra::field::PrimeFieldRepr for #repr {
187 #[inline(always)]
188 fn is_odd(&self) -> bool {
189 self.0[0] & 1 == 1
190 }
191
192 #[inline(always)]
193 fn is_even(&self) -> bool {
194 !self.is_odd()
195 }
196
197 #[inline(always)]
198 fn is_zero(&self) -> bool {
199 self.0.iter().all(|&e| e == 0)
200 }
201
202 #[inline(always)]
203 fn shr(&mut self, mut n: u32) {
204 if n as usize >= 64 * #limbs {
205 *self = Self::from(0);
206 return;
207 }
208
209 while n >= 64 {
210 let mut t = 0;
211 for i in self.0.iter_mut().rev() {
212 ::std::mem::swap(&mut t, i);
213 }
214 n -= 64;
215 }
216
217 if n > 0 {
218 let mut t = 0;
219 for i in self.0.iter_mut().rev() {
220 let t2 = *i << (64 - n);
221 *i >>= n;
222 *i |= t;
223 t = t2;
224 }
225 }
226 }
227
228 #[inline(always)]
229 fn div2(&mut self) {
230 let mut t = 0;
231 for i in self.0.iter_mut().rev() {
232 let t2 = *i << 63;
233 *i >>= 1;
234 *i |= t;
235 t = t2;
236 }
237 }
238
239 #[inline(always)]
240 fn mul2(&mut self) {
241 let mut last = 0;
242 for i in &mut self.0 {
243 let tmp = *i >> 63;
244 *i <<= 1;
245 *i |= last;
246 last = tmp;
247 }
248 }
249
250 #[inline(always)]
251 fn shl(&mut self, mut n: u32) {
252 if n as usize >= 64 * #limbs {
253 *self = Self::from(0);
254 return;
255 }
256
257 while n >= 64 {
258 let mut t = 0;
259 for i in &mut self.0 {
260 ::std::mem::swap(&mut t, i);
261 }
262 n -= 64;
263 }
264
265 if n > 0 {
266 let mut t = 0;
267 for i in &mut self.0 {
268 let t2 = *i >> (64 - n);
269 *i <<= n;
270 *i |= t;
271 t = t2;
272 }
273 }
274 }
275
276 #[inline(always)]
277 fn num_bits(&self) -> u32 {
278 let mut ret = (#limbs as u32) * 64;
279 for i in self.0.iter().rev() {
280 let leading = i.leading_zeros();
281 ret -= leading;
282 if leading != 64 {
283 break;
284 }
285 }
286
287 ret
288 }
289
290 #[inline(always)]
291 fn add_nocarry(&mut self, other: &#repr) {
292 let mut carry = 0;
293
294 for (a, b) in self.0.iter_mut().zip(other.0.iter()) {
295 *a = crate::librustzcash::algebra::field::adc(*a, *b, &mut carry);
296 }
297 }
298
299 #[inline(always)]
300 fn sub_noborrow(&mut self, other: &#repr) {
301 let mut borrow = 0;
302
303 for (a, b) in self.0.iter_mut().zip(other.0.iter()) {
304 *a = crate::librustzcash::algebra::field::sbb(*a, *b, &mut borrow);
305 }
306 }
307 }
308 }
309}
310
311fn biguint_to_real_u64_vec(mut v: BigUint, limbs: usize) -> Vec<u64> {
313 let m = BigUint::one() << 64;
314 let mut ret = vec![];
315
316 while v > BigUint::zero() {
317 ret.push((&v % &m).to_u64().unwrap());
318 v = v >> 64;
319 }
320
321 while ret.len() < limbs {
322 ret.push(0);
323 }
324
325 assert!(ret.len() == limbs);
326
327 ret
328}
329
330fn biguint_to_u64_vec(v: BigUint, limbs: usize) -> proc_macro2::TokenStream {
332 let ret = biguint_to_real_u64_vec(v, limbs);
333 quote!([#(#ret,)*])
334}
335
336fn biguint_num_bits(mut v: BigUint) -> u32 {
337 let mut bits = 0;
338
339 while v != BigUint::zero() {
340 v = v >> 1;
341 bits += 1;
342 }
343
344 bits
345}
346
347fn exp(base: BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint {
349 let mut ret = BigUint::one();
350
351 for i in exp
352 .to_bytes_be()
353 .into_iter()
354 .flat_map(|x| (0..8).rev().map(move |i| (x >> i).is_odd()))
355 {
356 ret = (&ret * &ret) % modulus;
357 if i {
358 ret = (ret * &base) % modulus;
359 }
360 }
361
362 ret
363}
364
365#[test]
366fn test_exp() {
367 assert_eq!(
368 exp(
369 BigUint::from_str("4398572349857239485729348572983472345").unwrap(),
370 &BigUint::from_str("5489673498567349856734895").unwrap(),
371 &BigUint::from_str("52435875175126190479447740508185965837690552500527637822603658699938581184513")
372 .unwrap()
373 ),
374 BigUint::from_str("4371221214068404307866768905142520595925044802278091865033317963560480051536").unwrap()
375 );
376}
377
378fn prime_field_constants_and_sqrt(
379 name: &syn::Ident,
380 repr: &syn::Ident,
381 modulus: BigUint,
382 limbs: usize,
383 generator: BigUint,
384) -> (proc_macro2::TokenStream, proc_macro2::TokenStream) {
385 let modulus_num_bits = biguint_num_bits(modulus.clone());
386
387 let repr_shave_bits = (64 * limbs as u32) - biguint_num_bits(modulus.clone());
392
393 let r = (BigUint::one() << (limbs * 64)) % &modulus;
395
396 let mut s: u32 = 0;
398 let mut t = &modulus - BigUint::from_str("1").unwrap();
399 while t.is_even() {
400 t = t >> 1;
401 s += 1;
402 }
403
404 let root_of_unity = biguint_to_u64_vec((exp(generator.clone(), &t, &modulus) * &r) % &modulus, limbs);
406 let generator = biguint_to_u64_vec((generator.clone() * &r) % &modulus, limbs);
407
408 let mod_minus_1_over_2 = biguint_to_u64_vec((&modulus - BigUint::from_str("1").unwrap()) >> 1, limbs);
409 let legendre_impl = quote! {
410 fn legendre(&self) -> crate::librustzcash::algebra::field::LegendreSymbol {
411 let s = self.pow(#mod_minus_1_over_2);
413 if s == Self::zero() {
414 crate::librustzcash::algebra::field::LegendreSymbol::Zero
415 } else if s == Self::one() {
416 crate::librustzcash::algebra::field::LegendreSymbol::QuadraticResidue
417 } else {
418 crate::librustzcash::algebra::field::LegendreSymbol::QuadraticNonResidue
419 }
420 }
421 };
422
423 let sqrt_impl = if (&modulus % BigUint::from_str("4").unwrap()) == BigUint::from_str("3").unwrap() {
424 let mod_minus_3_over_4 = biguint_to_u64_vec((&modulus - BigUint::from_str("3").unwrap()) >> 2, limbs);
425
426 let rneg = biguint_to_u64_vec(&modulus - &r, limbs);
428
429 quote! {
430 impl crate::librustzcash::algebra::field::SqrtField for #name {
431 #legendre_impl
432
433 fn sqrt(&self) -> Option<Self> {
434 let mut a1 = self.pow(#mod_minus_3_over_4);
438
439 let mut a0 = a1;
440 a0.square();
441 a0.mul_assign(self);
442
443 if a0.0 == #repr(#rneg) {
444 None
445 } else {
446 a1.mul_assign(self);
447 Some(a1)
448 }
449 }
450 }
451 }
452 } else if (&modulus % BigUint::from_str("16").unwrap()) == BigUint::from_str("1").unwrap() {
453 let t_plus_1_over_2 = biguint_to_u64_vec((&t + BigUint::one()) >> 1, limbs);
454 let t = biguint_to_u64_vec(t.clone(), limbs);
455
456 quote! {
457 impl crate::librustzcash::algebra::field::SqrtField for #name {
458 #legendre_impl
459
460 fn sqrt(&self) -> Option<Self> {
461 match self.legendre() {
465 crate::librustzcash::algebra::field::LegendreSymbol::Zero => Some(*self),
466 crate::librustzcash::algebra::field::LegendreSymbol::QuadraticNonResidue => None,
467 crate::librustzcash::algebra::field::LegendreSymbol::QuadraticResidue => {
468 let mut c = #name(ROOT_OF_UNITY);
469 let mut r = self.pow(#t_plus_1_over_2);
470 let mut t = self.pow(#t);
471 let mut m = S;
472
473 while t != Self::one() {
474 let mut i = 1;
475 {
476 let mut t2i = t;
477 t2i.square();
478 loop {
479 if t2i == Self::one() {
480 break;
481 }
482 t2i.square();
483 i += 1;
484 }
485 }
486
487 for _ in 0..(m - i - 1) {
488 c.square();
489 }
490 r.mul_assign(&c);
491 c.square();
492 t.mul_assign(&c);
493 m = i;
494 }
495
496 Some(r)
497 }
498 }
499 }
500 }
501 }
502 } else {
503 quote! {}
504 };
505
506 let r2 = biguint_to_u64_vec((&r * &r) % &modulus, limbs);
508
509 let r = biguint_to_u64_vec(r, limbs);
510 let modulus = biguint_to_real_u64_vec(modulus, limbs);
511
512 let mut inv = 1u64;
514 for _ in 0..63 {
515 inv = inv.wrapping_mul(inv);
516 inv = inv.wrapping_mul(modulus[0]);
517 }
518 inv = inv.wrapping_neg();
519
520 (
521 quote! {
522 const MODULUS: #repr = #repr([#(#modulus,)*]);
524
525 const MODULUS_BITS: u32 = #modulus_num_bits;
527
528 const REPR_SHAVE_BITS: u32 = #repr_shave_bits;
531
532 const R: #repr = #repr(#r);
534
535 const R2: #repr = #repr(#r2);
537
538 const INV: u64 = #inv;
540
541 const GENERATOR: #repr = #repr(#generator);
544
545 const S: u32 = #s;
547
548 const ROOT_OF_UNITY: #repr = #repr(#root_of_unity);
550 },
551 sqrt_impl,
552 )
553}
554
555fn prime_field_impl(name: &syn::Ident, repr: &syn::Ident, limbs: usize) -> proc_macro2::TokenStream {
557 fn get_temp(n: usize) -> syn::Ident {
559 syn::Ident::new(&format!("r{}", n), proc_macro2::Span::call_site())
560 }
561
562 let mut mont_paramlist = proc_macro2::TokenStream::new();
565 mont_paramlist.append_separated(
566 (0..(limbs * 2)).map(|i| (i, get_temp(i))).map(|(i, x)| {
567 if i != 0 {
568 quote! {mut #x: u64}
569 } else {
570 quote! {#x: u64}
571 }
572 }),
573 proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone),
574 );
575
576 fn mont_impl(limbs: usize) -> proc_macro2::TokenStream {
578 let mut gen = proc_macro2::TokenStream::new();
579
580 for i in 0..limbs {
581 {
582 let temp = get_temp(i);
583 gen.extend(quote! {
584 let k = #temp.wrapping_mul(INV);
585 let mut carry = 0;
586 crate::librustzcash::algebra::field::mac_with_carry(#temp, k, MODULUS.0[0], &mut carry);
587 });
588 }
589
590 for j in 1..limbs {
591 let temp = get_temp(i + j);
592 gen.extend(quote! {
593 #temp = crate::librustzcash::algebra::field::mac_with_carry(#temp, k, MODULUS.0[#j], &mut carry);
594 });
595 }
596
597 let temp = get_temp(i + limbs);
598
599 if i == 0 {
600 gen.extend(quote! {
601 #temp = crate::librustzcash::algebra::field::adc(#temp, 0, &mut carry);
602 });
603 } else {
604 gen.extend(quote! {
605 #temp = crate::librustzcash::algebra::field::adc(#temp, carry2, &mut carry);
606 });
607 }
608
609 if i != (limbs - 1) {
610 gen.extend(quote! {
611 let carry2 = carry;
612 });
613 }
614 }
615
616 for i in 0..limbs {
617 let temp = get_temp(limbs + i);
618
619 gen.extend(quote! {
620 (self.0).0[#i] = #temp;
621 });
622 }
623
624 gen
625 }
626
627 fn sqr_impl(a: proc_macro2::TokenStream, limbs: usize) -> proc_macro2::TokenStream {
628 let mut gen = proc_macro2::TokenStream::new();
629
630 for i in 0..(limbs - 1) {
631 gen.extend(quote! {
632 let mut carry = 0;
633 });
634
635 for j in (i + 1)..limbs {
636 let temp = get_temp(i + j);
637 if i == 0 {
638 gen.extend(quote!{
639 let #temp = crate::librustzcash::algebra::field::mac_with_carry(0, (#a.0).0[#i], (#a.0).0[#j], &mut carry);
640 });
641 } else {
642 gen.extend(quote!{
643 let #temp = crate::librustzcash::algebra::field::mac_with_carry(#temp, (#a.0).0[#i], (#a.0).0[#j], &mut carry);
644 });
645 }
646 }
647
648 let temp = get_temp(i + limbs);
649
650 gen.extend(quote! {
651 let #temp = carry;
652 });
653 }
654
655 for i in 1..(limbs * 2) {
656 let temp0 = get_temp(limbs * 2 - i);
657 let temp1 = get_temp(limbs * 2 - i - 1);
658
659 if i == 1 {
660 gen.extend(quote! {
661 let #temp0 = #temp1 >> 63;
662 });
663 } else if i == (limbs * 2 - 1) {
664 gen.extend(quote! {
665 let #temp0 = #temp0 << 1;
666 });
667 } else {
668 gen.extend(quote! {
669 let #temp0 = (#temp0 << 1) | (#temp1 >> 63);
670 });
671 }
672 }
673
674 gen.extend(quote! {
675 let mut carry = 0;
676 });
677
678 for i in 0..limbs {
679 let temp0 = get_temp(i * 2);
680 let temp1 = get_temp(i * 2 + 1);
681 if i == 0 {
682 gen.extend(quote!{
683 let #temp0 = crate::librustzcash::algebra::field::mac_with_carry(0, (#a.0).0[#i], (#a.0).0[#i], &mut carry);
684 });
685 } else {
686 gen.extend(quote!{
687 let #temp0 = crate::librustzcash::algebra::field::mac_with_carry(#temp0, (#a.0).0[#i], (#a.0).0[#i], &mut carry);
688 });
689 }
690
691 gen.extend(quote! {
692 let #temp1 = crate::librustzcash::algebra::field::adc(#temp1, 0, &mut carry);
693 });
694 }
695
696 let mut mont_calling = proc_macro2::TokenStream::new();
697 mont_calling.append_separated(
698 (0..(limbs * 2)).map(|i| get_temp(i)),
699 proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone),
700 );
701
702 gen.extend(quote! {
703 self.mont_reduce(#mont_calling);
704 });
705
706 gen
707 }
708
709 fn mul_impl(a: proc_macro2::TokenStream, b: proc_macro2::TokenStream, limbs: usize) -> proc_macro2::TokenStream {
710 let mut gen = proc_macro2::TokenStream::new();
711
712 for i in 0..limbs {
713 gen.extend(quote! {
714 let mut carry = 0;
715 });
716
717 for j in 0..limbs {
718 let temp = get_temp(i + j);
719
720 if i == 0 {
721 gen.extend(quote!{
722 let #temp = crate::librustzcash::algebra::field::mac_with_carry(0, (#a.0).0[#i], (#b.0).0[#j], &mut carry);
723 });
724 } else {
725 gen.extend(quote!{
726 let #temp = crate::librustzcash::algebra::field::mac_with_carry(#temp, (#a.0).0[#i], (#b.0).0[#j], &mut carry);
727 });
728 }
729 }
730
731 let temp = get_temp(i + limbs);
732
733 gen.extend(quote! {
734 let #temp = carry;
735 });
736 }
737
738 let mut mont_calling = proc_macro2::TokenStream::new();
739 mont_calling.append_separated(
740 (0..(limbs * 2)).map(|i| get_temp(i)),
741 proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone),
742 );
743
744 gen.extend(quote! {
745 self.mont_reduce(#mont_calling);
746 });
747
748 gen
749 }
750
751 let squaring_impl = sqr_impl(quote! {self}, limbs);
752 let multiply_impl = mul_impl(quote! {self}, quote! {other}, limbs);
753 let montgomery_impl = mont_impl(limbs);
754
755 let mut into_repr_params = proc_macro2::TokenStream::new();
757 into_repr_params.append_separated(
758 (0..limbs)
759 .map(|i| quote! { (self.0).0[#i] })
760 .chain((0..limbs).map(|_| quote! {0})),
761 proc_macro2::Punct::new(',', proc_macro2::Spacing::Alone),
762 );
763
764 let top_limb_index = limbs - 1;
765
766 quote! {
767 impl ::std::marker::Copy for #name { }
768
769 impl ::std::clone::Clone for #name {
770 fn clone(&self) -> #name {
771 *self
772 }
773 }
774
775 impl ::std::cmp::PartialEq for #name {
776 fn eq(&self, other: &#name) -> bool {
777 self.0 == other.0
778 }
779 }
780
781 impl ::std::cmp::Eq for #name { }
782
783 impl ::std::fmt::Debug for #name
784 {
785 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
786 write!(f, "{}({:?})", stringify!(#name), self.into_repr())
787 }
788 }
789
790 impl Ord for #name {
792 #[inline(always)]
793 fn cmp(&self, other: &#name) -> ::std::cmp::Ordering {
794 self.into_repr().cmp(&other.into_repr())
795 }
796 }
797
798 impl PartialOrd for #name {
799 #[inline(always)]
800 fn partial_cmp(&self, other: &#name) -> Option<::std::cmp::Ordering> {
801 Some(self.cmp(other))
802 }
803 }
804
805 impl ::std::fmt::Display for #name {
806 fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
807 write!(f, "{}({})", stringify!(#name), self.into_repr())
808 }
809 }
810
811 impl From<#name> for #repr {
812 fn from(e: #name) -> #repr {
813 e.into_repr()
814 }
815 }
816
817 impl crate::librustzcash::algebra::field::PrimeField for #name {
818 type Repr = #repr;
819
820 fn from_repr(r: #repr) -> Result<#name, PrimeFieldDecodingError> {
821 let mut r = #name(r);
822 if r.is_valid() {
823 r.mul_assign(&#name(R2));
824
825 Ok(r)
826 } else {
827 Err(PrimeFieldDecodingError::NotInField(format!("{}", r.0)))
828 }
829 }
830
831 fn into_repr(&self) -> #repr {
832 let mut r = *self;
833 r.mont_reduce(
834 #into_repr_params
835 );
836
837 r.0
838 }
839
840 fn char() -> #repr {
841 MODULUS
842 }
843
844 const NUM_BITS: u32 = MODULUS_BITS;
845
846 const CAPACITY: u32 = Self::NUM_BITS - 1;
847
848 fn multiplicative_generator() -> Self {
849 #name(GENERATOR)
850 }
851
852 const S: u32 = S;
853
854 fn root_of_unity() -> Self {
855 #name(ROOT_OF_UNITY)
856 }
857 }
858
859 impl crate::librustzcash::algebra::field::Field for #name {
860 fn random<R: ::rand_core::RngCore>(rng: &mut R) -> Self {
862 loop {
863 let mut tmp = {
864 let mut repr = [0u64; #limbs];
865 for i in 0..#limbs {
866 repr[i] = rng.next_u64();
867 }
868 #name(#repr(repr))
869 };
870
871 tmp.0.as_mut()[#top_limb_index] &= 0xffffffffffffffff >> REPR_SHAVE_BITS;
873
874 if tmp.is_valid() {
875 return tmp
876 }
877 }
878 }
879
880 #[inline]
881 fn zero() -> Self {
882 #name(#repr::from(0))
883 }
884
885 #[inline]
886 fn one() -> Self {
887 #name(R)
888 }
889
890 #[inline]
891 fn is_zero(&self) -> bool {
892 self.0.is_zero()
893 }
894
895 #[inline]
896 fn add_assign(&mut self, other: &#name) {
897 self.0.add_nocarry(&other.0);
899
900 self.reduce();
902 }
903
904 #[inline]
905 fn double(&mut self) {
906 self.0.mul2();
908
909 self.reduce();
911 }
912
913 #[inline]
914 fn sub_assign(&mut self, other: &#name) {
915 if other.0 > self.0 {
917 self.0.add_nocarry(&MODULUS);
918 }
919
920 self.0.sub_noborrow(&other.0);
921 }
922
923 #[inline]
924 fn negate(&mut self) {
925 if !self.is_zero() {
926 let mut tmp = MODULUS;
927 tmp.sub_noborrow(&self.0);
928 self.0 = tmp;
929 }
930 }
931
932 fn inverse(&self) -> Option<Self> {
933 if self.is_zero() {
934 None
935 } else {
936 let one = #repr::from(1);
941
942 let mut u = self.0;
943 let mut v = MODULUS;
944 let mut b = #name(R2); let mut c = Self::zero();
946
947 while u != one && v != one {
948 while u.is_even() {
949 u.div2();
950
951 if b.0.is_even() {
952 b.0.div2();
953 } else {
954 b.0.add_nocarry(&MODULUS);
955 b.0.div2();
956 }
957 }
958
959 while v.is_even() {
960 v.div2();
961
962 if c.0.is_even() {
963 c.0.div2();
964 } else {
965 c.0.add_nocarry(&MODULUS);
966 c.0.div2();
967 }
968 }
969
970 if v < u {
971 u.sub_noborrow(&v);
972 b.sub_assign(&c);
973 } else {
974 v.sub_noborrow(&u);
975 c.sub_assign(&b);
976 }
977 }
978
979 if u == one {
980 Some(b)
981 } else {
982 Some(c)
983 }
984 }
985 }
986
987 #[inline(always)]
988 fn frobenius_map(&mut self, _: usize) {
989 }
991
992 #[inline]
993 fn mul_assign(&mut self, other: &#name)
994 {
995 #multiply_impl
996 }
997
998 #[inline]
999 fn square(&mut self)
1000 {
1001 #squaring_impl
1002 }
1003 }
1004
1005 impl #name {
1006 #[inline(always)]
1009 fn is_valid(&self) -> bool {
1010 self.0 < MODULUS
1011 }
1012
1013 #[inline(always)]
1016 fn reduce(&mut self) {
1017 if !self.is_valid() {
1018 self.0.sub_noborrow(&MODULUS);
1019 }
1020 }
1021
1022 #[inline(always)]
1023 fn mont_reduce(
1024 &mut self,
1025 #mont_paramlist
1026 )
1027 {
1028 #montgomery_impl
1033
1034 self.reduce();
1035 }
1036 }
1037 }
1038}