/// Computations of the modular inverse. pub trait ModDiv: Sized { /// Compute the modular division of the number by the given number and /// modulus. The divisor *must* have a modular inverse for this function /// to succeed. fn moddiv(&self, divisor: &Self, phi: &Self) -> Self; } macro_rules! moddiv_impls { ($sname: ident, $dbl: ident) => { impl ModDiv for $sname { fn moddiv(&self, divisor: &Self, phi: &Self) -> Self { let safe_divisor = divisor % phi; let i = safe_divisor.modinv(&phi).expect("no modular inverse of moddiv divisor"); let selfi = i * self; $sname::from( selfi % $dbl::from(phi) ) } } }; } #[cfg(test)] macro_rules! generate_moddiv_tests { ($sname: ident, $tname: ident, $mname: ident) => { #[test] fn $mname() { generate_moddiv_tests!(body $sname, $tname, $mname); } }; (ignore $sname: ident, $tname: ident, $mname: ident) => { #[test] #[ignore] fn $mname() { generate_moddiv_tests!(body $sname, $tname, $mname); } }; (body $sname: ident, $tname: ident, $mname: ident) => { let fname = build_test_path("moddiv", stringify!($sname)); run_test(fname.to_string(), 4, |case| { let (nega, abytes) = case.get("a").unwrap(); let (negb, bbytes) = case.get("b").unwrap(); let (negm, mbytes) = case.get("m").unwrap(); let (negc, cbytes) = case.get("c").unwrap(); let a = $sname::new(*nega, $tname::from_bytes(abytes)); let b = $sname::new(*negb, $tname::from_bytes(bbytes)); let m = $sname::new(*negm, $tname::from_bytes(mbytes)); let c = $sname::new(*negc, $tname::from_bytes(cbytes)); let res = a.moddiv(&b, &m); assert_eq!(c, res); }); }; }