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)
}
}
}