quotient_map_large_uint

Macro quotient_map_large_uint 

Source
macro_rules! quotient_map_large_uint {
    ($field:ty, $field_size:ty, $field_order:expr, $checked_bounds:literal, $unchecked_bounds:literal, [$($large_int:ty),*] ) => { ... };
}
Expand description

If the unsigned integer type is large enough, there is often no method better for from_int than just doing a modular reduction to a smaller type.

This macro accepts 6 inputs.

  • The name of the prime field P
  • The smallest natural integer type large enough to contain the field characteristic.
  • The characteristic of the field.
  • A string giving the range for which from_canonical_checked produces the correct result.
  • A string giving the range for which from_canonical_unchecked produces the correct result.
  • A list of large integer types to auto implement QuotientMap<LargeInt>.

For a concrete example, quotient_map_large_uint!(Mersenne31, u32, Mersenne31::ORDER_U32, "[0, 2^31 - 2]", "[0, 2^31 - 1]", [u128]) would produce the following code:

impl QuotientMap<u128> for Mersenne31 {
    /// Convert a given `u128` integer into an element of the `Mersenne31` field.
    ///
    /// Uses a modular reduction to reduce to canonical form.
    /// This should be avoided in performance critical locations.
    #[inline]
    fn from_int(int: u128) -> Mersenne31 {
        // Check at compile time.
        const { assert!(size_of::<u128>() > size_of::<u32>()); }
        let red = (int % (Mersenne31::ORDER_U32 as u128)) as u32;
           unsafe {
               // This is safe as red is less than the field order by assumption.
               Self::from_canonical_unchecked(red)
           }
    }

    /// Convert a given `u128` integer into an element of the `Mersenne31` field.
    ///
    /// Returns `None` if the input does not lie in the range: [0, 2^31 - 2].
    #[inline]
    fn from_canonical_checked(int: u128) -> Option<Mersenne31> {
        if int < Mersenne31::ORDER_U32 as u128 {
            unsafe {
                // This is safe as we just checked that int is less than the field order.
                Some(Self::from_canonical_unchecked(int as u32))
            }
        } else {
            None
        }
    }

    /// Convert a given `u128` integer into an element of the `Mersenne31` field.
    ///
    /// # Safety
    /// The input must lie in the range:", [0, 2^31 - 1].
    #[inline]
    unsafe fn from_canonical_unchecked(int: u128) -> Mersenne31 {
        unsafe {
            Self::from_canonical_unchecked(int as u32)
        }
    }
}