ff_derive_zeroize/
lib.rs

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