Skip to main content

primefield/
macros.rs

1//! Macros for defining field element types.
2
3mod fiat;
4
5/// Creates a ZST representing the Montgomery parameters for a given field modulus.
6///
7/// Accepts the following parameters:
8///
9/// - name of the ZST representing the field modulus
10/// - hex serialization of the modulus
11/// - `crypto-bigint` unsigned integer type (e.g. U256)
12/// - number of bytes in an encoded field element
13/// - byte order to use when encoding/decoding field elements
14/// - documentation string for the field modulus type
15///
16/// ```
17/// use primefield::{ByteOrder, bigint::U256, consts::U32};
18///
19/// primefield::monty_field_params!(
20///     name: FieldParams,
21///     modulus: "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
22///     uint: U256,
23///     byte_order: ByteOrder::BigEndian,
24///     multiplicative_generator: 6,
25///     doc: "P-256 field modulus"
26/// );
27/// ```
28#[macro_export]
29macro_rules! monty_field_params {
30    (
31        name: $name:ident,
32        modulus: $modulus_hex:expr,
33        uint: $uint:ty,
34        byte_order: $byte_order:expr,
35        multiplicative_generator: $multiplicative_generator:expr,
36        doc: $doc:expr
37    ) => {
38        use $crate::bigint::modular::ConstMontyParams;
39
40        $crate::bigint::const_prime_monty_params!(
41            $name,
42            $uint,
43            $modulus_hex,
44            $multiplicative_generator,
45            $doc
46        );
47
48        impl $crate::MontyFieldParams<{ <$uint>::LIMBS }> for $name {
49            type ByteSize = $crate::bigint::hybrid_array::typenum::U<
50                { $name::PARAMS.modulus().as_ref().bits().div_ceil(8) as usize },
51            >;
52            const BYTE_ORDER: $crate::ByteOrder = $byte_order;
53            const MODULUS_HEX: &'static str = $modulus_hex;
54            const T: $uint = $crate::compute_t($name::PARAMS.modulus().as_ref());
55        }
56    };
57}
58
59/// Implements a field element type whose internal representation is in
60/// Montgomery form, providing a combination of trait impls and inherent impls
61/// which are `const fn` where possible.
62///
63/// Accepts a set of `const fn` arithmetic operation functions as arguments.
64///
65/// # Inherent impls
66/// - `const ZERO: Self`
67/// - `const ONE: Self` (multiplicative identity)
68/// - `pub fn from_bytes`
69/// - `pub fn from_slice`
70/// - `pub fn from_uint`
71/// - `fn from_uint_unchecked`
72/// - `pub fn to_bytes`
73/// - `pub fn to_canonical`
74/// - `pub fn is_odd`
75/// - `pub fn is_zero`
76/// - `pub fn double`
77///
78/// # Trait impls
79/// - `ConditionallySelectable`
80/// - `ConstantTimeEq`
81/// - `ConstantTimeGreater`
82/// - `ConstantTimeLess`
83/// - `CtEq`
84/// - `CtSelect`
85/// - `Default`
86/// - `DefaultIsZeroes`
87/// - `Eq`
88/// - `Field`
89/// - `PartialEq`
90/// - `Retrieve`
91///
92/// ## Ops
93/// - `Add`
94/// - `AddAssign`
95/// - `Sub`
96/// - `SubAssign`
97/// - `Mul`
98/// - `MulAssign`
99/// - `Neg`
100/// - `Invert`
101#[macro_export]
102macro_rules! monty_field_element {
103    (
104        name: $fe:tt,
105        params: $params:ty,
106        uint: $uint:path,
107        doc: $doc:expr
108    ) => {
109        #[doc = $crate::monty_field_element_doc!($doc)]
110        #[derive(Clone, Copy, PartialOrd, Ord)]
111        pub struct $fe(
112            pub(super) $crate::MontyFieldElement<$params, { <$params>::LIMBS }>,
113        );
114
115        impl $fe {
116            /// Zero element.
117            pub const ZERO: Self =
118                Self($crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::ZERO);
119
120            /// Multiplicative identity.
121            pub const ONE: Self =
122                Self($crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::ONE);
123
124            /// Create a [`
125            #[doc = stringify!($fe)]
126            /// `] from a canonical byte representation using the field's configured byte order.
127            pub fn from_bytes(
128                repr: &$crate::MontyFieldBytes<$params, { <$params>::LIMBS }>,
129            ) -> $crate::subtle::CtOption<Self> {
130                $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::from_bytes(repr).map(Self)
131            }
132
133            /// Decode [`
134            #[doc = stringify!($fe)]
135            /// `] from a byte slice using the field's configured byte order.
136            pub fn from_slice(slice: &[u8]) -> Option<Self> {
137                $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::from_slice(slice)
138                    .map(Self)
139            }
140
141            /// Decode a [`
142            #[doc = stringify!($fe)]
143            /// `] from hex-encoded bytes using the field's configured byte order.
144            ///
145            /// This is primarily intended for defining constants using hex literals.
146            ///
147            /// # Panics
148            ///
149            /// - When hex is malformed
150            /// - When input is the wrong length
151            /// - If input overflows the modulus
152            pub const fn from_hex_vartime(hex: &str) -> Self {
153                use $crate::array::typenum::Unsigned;
154
155                assert!(
156                    hex.len() == <$params as $crate::MontyFieldParams<{ <$params>::LIMBS }>>::ByteSize::USIZE * 2,
157                    "hex is the wrong length"
158                );
159
160                // Build a hex string of the expected size, regardless of the size of `Uint`
161                let mut hex_bytes = [b'0'; { <$uint>::BITS as usize / 4 }];
162
163                let offset = match <$params as $crate::MontyFieldParams<{ <$params>::LIMBS }>>::BYTE_ORDER {
164                    $crate::ByteOrder::BigEndian => hex_bytes.len() - hex.len(),
165                    $crate::ByteOrder::LittleEndian => 0
166                };
167
168                let mut i = 0;
169                while i < hex.len() {
170                    hex_bytes[i + offset] = hex.as_bytes()[i];
171                    i += 1;
172                }
173
174                match core::str::from_utf8(&hex_bytes) {
175                    Ok(padded_hex) => Self(
176                        $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::from_hex_vartime(padded_hex),
177                    ),
178                    Err(_) => panic!("invalid hex string"),
179                }
180
181
182            }
183
184            /// Decode [`
185            #[doc = stringify!($fe)]
186            /// `]
187            /// from [`
188            #[doc = stringify!($uint)]
189            /// `] converting it into Montgomery form:
190            ///
191            /// ```text
192            /// w * R^2 * R^-1 mod p = wR mod p
193            /// ```
194            pub fn from_uint(uint: &$uint) -> $crate::subtle::CtOption<Self> {
195                $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::from_uint(uint).map(Self)
196            }
197
198            /// Convert a `u64` into a [`
199            #[doc = stringify!($fe)]
200            /// `].
201            pub const fn from_u64(w: u64) -> Self {
202                Self($crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::from_u64(w))
203            }
204
205            /// Returns the big-endian encoding of this [`
206            #[doc = stringify!($fe)]
207            /// `].
208            pub fn to_bytes(self) -> $crate::MontyFieldBytes<$params, { <$params>::LIMBS }> {
209                self.0.to_bytes()
210            }
211
212            /// Determine if this [`
213            #[doc = stringify!($fe)]
214            /// `] is odd in the SEC1 sense: `self mod 2 == 1`.
215            ///
216            /// # Returns
217            ///
218            /// If odd, return `Choice(1)`.  Otherwise, return `Choice(0)`.
219            pub fn is_odd(&self) -> $crate::subtle::Choice {
220                self.0.is_odd()
221            }
222
223            /// Determine if this [`
224            #[doc = stringify!($fe)]
225            /// `] is even in the SEC1 sense: `self mod 2 == 0`.
226            ///
227            /// # Returns
228            ///
229            /// If even, return `Choice(1)`.  Otherwise, return `Choice(0)`.
230            pub fn is_even(&self) -> $crate::subtle::Choice {
231                !self.is_odd()
232            }
233
234            /// Determine if this [`
235            #[doc = stringify!($fe)]
236            /// `] is zero.
237            ///
238            /// # Returns
239            ///
240            /// If zero, return `Choice(1)`.  Otherwise, return `Choice(0)`.
241            pub fn is_zero(&self) -> $crate::subtle::Choice {
242                self.0.is_zero()
243            }
244
245            /// Returns `self^exp`, where `exp` is a little-endian integer exponent.
246            ///
247            /// **This operation is variable time with respect to the exponent `exp`.**
248            ///
249            /// If the exponent is fixed, this operation is constant time.
250            pub const fn pow_vartime<const RHS_LIMBS: usize>(
251                &self,
252                exp: &$crate::bigint::Uint<RHS_LIMBS>
253            ) -> Self {
254                Self(self.0.pow_vartime(exp))
255            }
256
257            /// Returns `self^(2^n) mod p`.
258            ///
259            /// **This operation is variable time with respect to the exponent `n`.**
260            ///
261            /// If the exponent is fixed, this operation is constant time.
262            pub const fn sqn_vartime(&self, n: usize) -> Self {
263                Self(self.0.sqn_vartime(n))
264            }
265        }
266
267        impl $crate::bigint::modular::ConstMontyParams<{ <$params>::LIMBS }> for $fe {
268            const LIMBS: usize = <$params>::LIMBS;
269            const PARAMS: $crate::bigint::modular::FixedMontyParams<{ <$uint>::LIMBS }> =
270                <$params>::PARAMS;
271        }
272
273        impl $crate::common::Generate for $fe {
274            fn try_generate_from_rng<R: $crate::rand_core::TryCryptoRng + ?Sized>(
275                rng: &mut R,
276            ) -> ::core::result::Result<Self, R::Error> {
277                <Self as $crate::ff::Field>::try_random(rng)
278            }
279        }
280
281        impl $crate::ff::Field for $fe {
282            const ZERO: Self = Self::ZERO;
283            const ONE: Self = Self::ONE;
284
285            fn try_random<R: $crate::rand_core::TryRng + ?Sized>(
286                rng: &mut R,
287            ) -> ::core::result::Result<Self, R::Error> {
288                $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::try_random(rng)
289                    .map(Self)
290            }
291
292            fn is_zero(&self) -> Choice {
293                self.0.is_zero()
294            }
295
296            fn square(&self) -> Self {
297                self.square()
298            }
299
300            fn double(&self) -> Self {
301                self.double()
302            }
303
304            fn invert(&self) -> CtOption<Self> {
305                self.invert()
306            }
307
308            fn sqrt(&self) -> CtOption<Self> {
309                self.0.sqrt().map(Self)
310            }
311
312            fn sqrt_ratio(num: &Self, div: &Self) -> (Choice, Self) {
313                $crate::ff::helpers::sqrt_ratio_generic(num, div)
314            }
315        }
316
317        impl $crate::ff::PrimeField for $fe {
318            type Repr = $crate::MontyFieldBytes<$params, { <$params>::LIMBS }>;
319
320            const MODULUS: &'static str =
321                <$params as $crate::MontyFieldParams<{ <$uint>::LIMBS }>>::MODULUS_HEX;
322            const NUM_BITS: u32 =
323                $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::NUM_BITS;
324            const CAPACITY: u32 =
325                $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::CAPACITY;
326            const TWO_INV: Self =
327                Self($crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::TWO_INV);
328            const MULTIPLICATIVE_GENERATOR: Self = Self(
329                $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::MULTIPLICATIVE_GENERATOR,
330            );
331            const S: u32 = $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::S;
332            const ROOT_OF_UNITY: Self =
333                Self($crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::ROOT_OF_UNITY);
334            const ROOT_OF_UNITY_INV: Self =
335                Self($crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::ROOT_OF_UNITY_INV);
336            const DELTA: Self =
337                Self($crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::DELTA);
338
339            #[inline]
340            fn from_repr(bytes: Self::Repr) -> $crate::subtle::CtOption<Self> {
341                $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::from_repr(bytes).map(Self)
342            }
343
344            #[inline]
345            fn to_repr(&self) -> Self::Repr {
346                self.0.to_repr()
347            }
348
349            #[inline]
350            fn is_odd(&self) -> $crate::subtle::Choice {
351                self.0.is_odd()
352            }
353        }
354
355        impl $crate::FieldExt for $fe {}
356
357        impl $crate::PrimeFieldExt for $fe {
358            const REPR_ENDIANNESS: $crate::ByteOrder =
359                <$params as $crate::MontyFieldParams<{ <$params>::LIMBS }>>::BYTE_ORDER;
360        }
361
362        $crate::field_op!($fe, Add, add, add);
363        $crate::field_op!($fe, Sub, sub, sub);
364        $crate::field_op!($fe, Mul, mul, multiply);
365
366        impl ::core::ops::AddAssign<$fe> for $fe {
367            #[inline]
368            fn add_assign(&mut self, other: $fe) {
369                *self = *self + other;
370            }
371        }
372
373        impl ::core::ops::AddAssign<&$fe> for $fe {
374            #[inline]
375            fn add_assign(&mut self, other: &$fe) {
376                *self = *self + other;
377            }
378        }
379
380        impl ::core::ops::SubAssign<$fe> for $fe {
381            #[inline]
382            fn sub_assign(&mut self, other: $fe) {
383                *self = *self - other;
384            }
385        }
386
387        impl ::core::ops::SubAssign<&$fe> for $fe {
388            #[inline]
389            fn sub_assign(&mut self, other: &$fe) {
390                *self = *self - other;
391            }
392        }
393
394        impl ::core::ops::MulAssign<&$fe> for $fe {
395            #[inline]
396            fn mul_assign(&mut self, other: &$fe) {
397                *self = *self * other;
398            }
399        }
400
401        impl ::core::ops::MulAssign for $fe {
402            #[inline]
403            fn mul_assign(&mut self, other: $fe) {
404                *self = *self * other;
405            }
406        }
407
408        impl ::core::ops::Neg for $fe {
409            type Output = $fe;
410
411            #[inline]
412            fn neg(self) -> $fe {
413                <$fe>::neg(&self)
414            }
415        }
416
417        impl ::core::ops::Neg for &$fe {
418            type Output = $fe;
419
420            #[inline]
421            fn neg(self) -> $fe {
422                <$fe>::neg(self)
423            }
424        }
425
426        impl ::core::fmt::Debug for $fe {
427            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
428                write!(f, "{}(0x{:X})", stringify!($fe), &self.0)
429            }
430        }
431
432        impl Default for $fe {
433            fn default() -> Self {
434                Self::ZERO
435            }
436        }
437
438        impl Eq for $fe {}
439        impl PartialEq for $fe {
440            fn eq(&self, rhs: &Self) -> bool {
441                self.0.ct_eq(&(rhs.0)).into()
442            }
443        }
444
445        impl From<u32> for $fe {
446            fn from(n: u32) -> $fe {
447                Self::from_uint_unchecked(<$uint>::from(n))
448            }
449        }
450
451        impl From<u64> for $fe {
452            fn from(n: u64) -> $fe {
453                Self::from_uint_unchecked(<$uint>::from(n))
454            }
455        }
456
457        impl From<u128> for $fe {
458            fn from(n: u128) -> $fe {
459                Self::from_uint_unchecked(<$uint>::from(n))
460            }
461        }
462
463        impl From<$fe> for $crate::MontyFieldBytes<$params, { <$params>::LIMBS }> {
464            fn from(fe: $fe) -> Self {
465                $crate::MontyFieldBytes::<$params, { <$params>::LIMBS }>::from(&fe)
466            }
467        }
468
469        impl From<&$fe> for $crate::MontyFieldBytes<$params, { <$params>::LIMBS }> {
470            fn from(fe: &$fe) -> Self {
471                fe.to_repr()
472            }
473        }
474
475        impl From<$crate::MontyFieldElement::<$params, { <$params>::LIMBS }>> for $fe {
476            fn from(fe: $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>) -> $fe {
477                $fe(fe)
478            }
479        }
480
481        impl From<$fe> for $crate::MontyFieldElement<$params, { <$params>::LIMBS }> {
482            fn from(fe: $fe) -> $crate::MontyFieldElement<$params, { <$params>::LIMBS }> {
483                fe.0
484            }
485        }
486
487        impl From<$fe> for $uint {
488            fn from(fe: $fe) -> $uint {
489                <$uint>::from(&fe)
490            }
491        }
492
493        impl From<&$fe> for $uint {
494            fn from(fe: &$fe) -> $uint {
495                fe.to_canonical()
496            }
497        }
498
499        impl TryFrom<$uint> for $fe {
500            type Error = $crate::Error;
501
502            fn try_from(w: $uint) -> $crate::Result<Self> {
503                Self::try_from(&w)
504            }
505        }
506
507        impl TryFrom<&$uint> for $fe {
508            type Error = $crate::Error;
509
510            fn try_from(w: &$uint) -> $crate::Result<Self> {
511                Self::from_uint(w).into_option().ok_or($crate::Error)
512            }
513        }
514
515        impl ::core::iter::Sum for $fe {
516            #[allow(unused_qualifications)]
517            fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
518                iter.reduce(core::ops::Add::add).unwrap_or(Self::ZERO)
519            }
520        }
521
522        impl<'a> ::core::iter::Sum<&'a $fe> for $fe {
523            fn sum<I: Iterator<Item = &'a $fe>>(iter: I) -> Self {
524                iter.copied().sum()
525            }
526        }
527
528        impl ::core::iter::Product for $fe {
529            #[allow(unused_qualifications)]
530            fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
531                iter.reduce(core::ops::Mul::mul).unwrap_or(Self::ONE)
532            }
533        }
534
535        impl<'a> ::core::iter::Product<&'a $fe> for $fe {
536            fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
537                iter.copied().product()
538            }
539        }
540
541        impl $crate::bigint::Invert for $fe {
542            type Output = CtOption<Self>;
543
544            fn invert(&self) -> CtOption<Self> {
545                self.invert()
546            }
547
548            fn invert_vartime(&self) -> CtOption<Self> {
549                self.0.invert_vartime().map(Self)
550            }
551        }
552
553        impl $crate::bigint::modular::Retrieve for $fe {
554            type Output = $uint;
555
556            fn retrieve(&self) -> $uint {
557                $crate::bigint::modular::Retrieve::retrieve(&self.0)
558            }
559        }
560
561        impl $crate::subtle::ConditionallySelectable for $fe {
562            fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
563                Self(
564                    $crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::conditional_select(
565                        &a.0, &b.0, choice,
566                    ),
567                )
568            }
569        }
570
571        impl $crate::subtle::ConstantTimeEq for $fe {
572            fn ct_eq(&self, other: &Self) -> $crate::subtle::Choice {
573                self.0.ct_eq(&other.0)
574            }
575        }
576
577        impl $crate::subtle::ConstantTimeGreater for $fe {
578            fn ct_gt(&self, other: &Self) -> $crate::subtle::Choice {
579                self.0.ct_gt(&other.0)
580            }
581        }
582
583        impl $crate::subtle::ConstantTimeLess for $fe {
584            fn ct_lt(&self, other: &Self) -> $crate::subtle::Choice {
585                self.0.ct_lt(&other.0)
586            }
587        }
588
589        impl $crate::bigint::ctutils::CtSelect for $fe {
590            fn ct_select(&self, other: &Self, choice: $crate::bigint::ctutils::Choice) -> Self {
591                Self(
592                    $crate::bigint::ctutils::CtSelect::ct_select(
593                        &self.0, &other.0, choice,
594                    ),
595                )
596            }
597        }
598
599        impl $crate::bigint::ctutils::CtEq for $fe {
600            fn ct_eq(&self, other: &Self) -> $crate::bigint::ctutils::Choice {
601                $crate::bigint::ctutils::CtEq::ct_eq(&self.0, &other.0)
602            }
603        }
604
605        impl $crate::bigint::ctutils::CtGt for $fe {
606            fn ct_gt(&self, other: &Self) -> $crate::bigint::ctutils::Choice {
607                $crate::bigint::ctutils::CtGt::ct_gt(&self.0, &other.0)
608            }
609        }
610
611        impl $crate::bigint::ctutils::CtLt for $fe {
612            fn ct_lt(&self, other: &Self) -> $crate::bigint::ctutils::Choice {
613                $crate::bigint::ctutils::CtLt::ct_lt(&self.0, &other.0)
614            }
615        }
616
617        impl $crate::zeroize::DefaultIsZeroes for $fe {}
618    };
619}
620
621/// Add `const fn` methods to the given field element for performing field arithmetic operations,
622/// e.g. `add`, `double`, `sub`, `multiply`, `neg`.
623///
624/// This macro wraps a generic field implementation provided by the `crypto-bigint` crate, which is
625/// exposed as the [`primefield::MontyFieldElement`][`crate::MontyFieldElement`] type.
626#[macro_export]
627macro_rules! monty_field_arithmetic {
628    (
629        name: $fe:tt,
630        params: $params:ty,
631        uint: $uint:ty
632    ) => {
633        impl $fe {
634            /// Decode [`
635            #[doc = stringify!($fe)]
636            /// `] from [`
637            #[doc = stringify!($uint)]
638            /// `] converting it into Montgomery form.
639            ///
640            /// Does *not* perform a check that the field element does not overflow the order.
641            ///
642            /// Used incorrectly this can lead to invalid results!
643            #[inline]
644            pub(crate) const fn from_uint_unchecked(w: $uint) -> Self {
645                // TODO(tarcieri): this reduces every time, maybe we can find a way to skip that?
646                Self($crate::MontyFieldElement::from_uint_reduced(&w))
647            }
648
649            /// Translate [`
650            #[doc = stringify!($fe)]
651            /// `] out of the Montgomery domain, returning a [`
652            #[doc = stringify!($uint)]
653            /// `] in canonical form.
654            #[inline]
655            pub const fn to_canonical(self) -> $uint {
656                self.0.to_canonical()
657            }
658
659            /// Add elements.
660            #[inline]
661            pub const fn add(&self, rhs: &Self) -> Self {
662                Self(self.0.add(&rhs.0))
663            }
664
665            /// Double element (add it to itself).
666            #[inline]
667            #[must_use]
668            pub const fn double(&self) -> Self {
669                Self(self.0.double())
670            }
671
672            /// Subtract elements.
673            #[inline]
674            pub const fn sub(&self, rhs: &Self) -> Self {
675                Self(self.0.sub(&rhs.0))
676            }
677
678            /// Multiply elements.
679            #[inline]
680            pub const fn multiply(&self, rhs: &Self) -> Self {
681                Self(self.0.multiply(&rhs.0))
682            }
683
684            /// Negate element.
685            #[inline]
686            pub const fn neg(&self) -> Self {
687                Self(self.0.neg())
688            }
689
690            /// Compute modular square.
691            #[inline]
692            #[must_use]
693            pub const fn square(&self) -> Self {
694                Self(self.0.square())
695            }
696
697            /// Compute
698            #[doc = stringify!($fe)]
699            /// inversion: `1 / self`.
700            #[inline]
701            pub fn invert(&self) -> $crate::subtle::CtOption<Self> {
702                self.0.invert().map(Self)
703            }
704
705            /// Compute
706            #[doc = stringify!($fe)]
707            /// inversion: `1 / self` in variable-time.
708            #[inline]
709            pub fn invert_vartime(&self) -> $crate::subtle::CtOption<Self> {
710                self.0.invert_vartime().map(Self)
711            }
712
713            /// Compute field inversion as a `const fn`. Panics if `self` is zero.
714            ///
715            /// This is mainly intended for inverting constants at compile time.
716            pub const fn const_invert(&self) -> Self {
717                Self(self.0.const_invert())
718            }
719        }
720    };
721}
722
723/// Write `Reduce` impls for a particular field implementation which delegate to
724/// `MontyFieldElement`.
725#[macro_export]
726macro_rules! monty_field_reduce {
727    (
728        name: $fe:tt,
729        params: $params:ty,
730        uint: $uint:path,
731    ) => {
732        impl $crate::bigint::Reduce<$uint> for $fe {
733            fn reduce(w: &$uint) -> Self {
734                Self($crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::reduce(w))
735            }
736        }
737
738        impl $crate::bigint::Reduce<$crate::MontyFieldBytes<$params, { <$params>::LIMBS }>>
739            for $fe
740        {
741            #[inline]
742            fn reduce(bytes: &$crate::MontyFieldBytes<$params, { <$params>::LIMBS }>) -> Self {
743                Self($crate::MontyFieldElement::<$params, { <$params>::LIMBS }>::reduce(bytes))
744            }
745        }
746    };
747}
748
749/// Emit a `core::ops` trait wrapper for an inherent method which is expected to be provided by a
750/// backend arithmetic implementation (e.g. `fiat-crypto`)
751#[macro_export]
752macro_rules! field_op {
753    ($fe:path, $op:tt, $func:ident, $inner_func:ident) => {
754        impl ::core::ops::$op for $fe {
755            type Output = $fe;
756
757            #[inline]
758            fn $func(self, rhs: $fe) -> $fe {
759                <$fe>::$inner_func(&self, &rhs)
760            }
761        }
762
763        impl ::core::ops::$op<&$fe> for $fe {
764            type Output = $fe;
765
766            #[inline]
767            fn $func(self, rhs: &$fe) -> $fe {
768                <$fe>::$inner_func(&self, rhs)
769            }
770        }
771
772        impl ::core::ops::$op<&$fe> for &$fe {
773            type Output = $fe;
774
775            #[inline]
776            fn $func(self, rhs: &$fe) -> $fe {
777                <$fe>::$inner_func(self, rhs)
778            }
779        }
780    };
781}
782
783/// Write documentation for a field element type.
784#[doc(hidden)]
785#[macro_export]
786#[rustfmt::skip]
787macro_rules! monty_field_element_doc {
788    ($about:expr) => {
789        concat!(
790            $about,
791            "\n\n",
792            "# Trait impls\n",
793            "\n",
794            "Much of the important functionality is provided by traits from the [`ff`] crate:\n",
795            "\n",
796            "- [`Field`] represents elements of finite fields and provides:\n",
797            "  - [`Field::random`] generate a random field element\n",
798            "  - `double`, `square`, and `invert` operations\n",
799            "  - Bounds for [`Add`], [`Sub`], [`Mul`], and [`Neg`] (and `*Assign` equivalents)\n",
800            "  - Bounds for [`ConditionallySelectable`] from the `subtle` crate\n",
801            "- [`PrimeField`] represents elements of prime fields and provides:\n",
802            "  - `from_repr`/`to_repr` for converting field elements from/to big integers.\n",
803            "  - `MULTIPLICATIVE_GENERATOR` and `ROOT_OF_UNITY` constants.\n",
804            "\n",
805            "Please see the documentation for the relevant traits for more information.\n"
806        )
807    };
808}