ff_uint_derive/
lib.rs

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