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 let mut limbs = 1;
82 {
83 let mod2 = (&modulus) << 1; let mut cur = BigUint::one() << 64; 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 gen.into()
118}
119
120fn 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
148fn 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
168fn 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
185fn 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 let inner_shave_bits = (64 * limbs as u32) - biguint_num_bits(modulus.clone());
236
237 let r = (BigUint::one() << (limbs * 64)) % &modulus;
239
240 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 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 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 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 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 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 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 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 const MODULUS: #inner = #inner::new([#(#modulus,)*]);
375
376 const MODULUS_BITS: u32 = #modulus_num_bits;
378
379 const REPR_SHAVE_BITS: u32 = #inner_shave_bits;
382
383 const R: #inner = #inner::new(#r);
385
386 const R2: #inner = #inner::new(#r2);
388
389 const INV: u64 = #inv;
391
392 const GENERATOR: #inner = #inner::new(#generator);
395
396 const S: u32 = #s;
398
399 const ROOT_OF_UNITY: #inner = #inner::new(#root_of_unity);
401 }
402 },
403 sqrt_impl,
404 )
405}
406
407fn prime_field_impl(
409 cratename: &Ident,
410 name: &syn::Type,
411 inner: &syn::Type,
412 limbs: usize,
413) -> proc_macro2::TokenStream {
414 fn get_temp(n: usize) -> syn::Ident {
416 syn::Ident::new(&format!("r{}", n), proc_macro2::Span::call_site())
417 }
418
419 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 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 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 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 #[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 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 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); 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 #[inline(always)]
941 fn is_valid(&self) -> bool {
942 self.0 < Self::MODULUS
943 }
944
945 #[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 #montgomery_impl.reduced()
966 }
967 }
968 }
969}