pub struct Residue32<'a> { /* private fields */ }Expand description
A residue with an odd modulus not exceeding 2_654_435_769.
§Fast modular multiplication
Residue32 provides fast modular multiplication using Plantard multiplication.
This method eliminates one multiplication when one of the operands is reused multiple times.
As a result, Residue32::pow and other operations are typically
faster than implementations based on Montgomery multiplication.
§Usage
use lib_modulo::Modulus32;
// set modulus
let modulus = Modulus32::new(3);
// performs modular arithmetic
let one = modulus.residue(1);
let two = modulus.residue(2);
let five = modulus.residue(5);
assert_eq!(two * five, one)Two residues with different modulus can interact, but the result will be meaningless.
It is highly recommended to use a block to ensure that Modulus32, therefore Residue32s, are dropped.
Implementations§
Source§impl<'a> Residue32<'a>
impl<'a> Residue32<'a>
Sourcepub const fn into_raw(self) -> Raw32
pub const fn into_raw(self) -> Raw32
Extract the internal representation of self.
use lib_modulo::{Modulus32, Raw32};
let modulus = Modulus32::new(1001);
// save memory
let residues: Vec<Raw32> = (1..=1000).map(|x| modulus.residue(x).into_raw()).collect();Sourcepub const fn is_zero(self) -> bool
pub const fn is_zero(self) -> bool
Checks whether self is 0.
§Example
use lib_modulo::Modulus32;
let modulus = Modulus32::new(5);
assert!(modulus.residue(10).is_zero())Sourcepub const fn get(self) -> u64
pub const fn get(self) -> u64
Returns the residue.
§Example
use lib_modulo::Modulus32;
let modulus = Modulus32::new(7);
assert_eq!(modulus.residue(10).get(), 3)Sourcepub const fn modulus(&self) -> u64
pub const fn modulus(&self) -> u64
Returns the modulus.
§Example
use lib_modulo::Modulus32;
let modulus = Modulus32::new(11);
assert_eq!(modulus.residue(2).modulus(), 11);Sourcepub const fn inv(self) -> Result<Self, u64>
pub const fn inv(self) -> Result<Self, u64>
Calculates the modular inverse of self, using extended binary GCD algorithm.
Modular inverse can be defined if and only if self and the modulus is coprime.
Ok(x):xis the modular inverse.Err(x):xis the GCD ofselfand themodulus, wheregcd(0, a)is defined to bea.
§Time complexity
O(log self)
§Example
use lib_modulo::Modulus32;
let modulus = Modulus32::new(3 * 5);
let residue = modulus.residue(2);
assert!(residue.inv().is_ok_and(|inv| (inv * residue).get() == 1));
let residue = modulus.residue(6);
assert!(residue.inv().is_err_and(|gcd| gcd == 3));Trait Implementations§
Source§impl<'a> AddAssign for Residue32<'a>
impl<'a> AddAssign for Residue32<'a>
Source§fn add_assign(&mut self, rhs: Self)
fn add_assign(&mut self, rhs: Self)
+= operation. Read moreSource§impl<'a> MulAssign for Residue32<'a>
impl<'a> MulAssign for Residue32<'a>
Source§fn mul_assign(&mut self, rhs: Self)
fn mul_assign(&mut self, rhs: Self)
*= operation. Read moreSource§impl<'a> SubAssign for Residue32<'a>
impl<'a> SubAssign for Residue32<'a>
Source§fn sub_assign(&mut self, rhs: Self)
fn sub_assign(&mut self, rhs: Self)
-= operation. Read more