Add support for modular division with negative divisors.
This commit is contained in:
@@ -11,10 +11,9 @@ macro_rules! moddiv_impls {
|
||||
impl ModDiv for $sname {
|
||||
fn moddiv(&self, divisor: &Self, phi: &Self) -> Self
|
||||
{
|
||||
assert!(!divisor.is_negative());
|
||||
let safe_divisor = divisor % phi;
|
||||
let unsigned_i = safe_divisor.value.modinv(&phi.value).expect("no modular inverse of moddiv divisor");
|
||||
let i = $sname::new(false, unsigned_i);
|
||||
let i = $sname::new(divisor.negative, unsigned_i);
|
||||
let selfi = i * self;
|
||||
$sname::from( selfi % $dbl::from(phi) )
|
||||
}
|
||||
@@ -50,12 +49,6 @@ macro_rules! generate_moddiv_tests {
|
||||
let m = $sname::new(*negm, $tname::from_bytes(mbytes));
|
||||
let c = $sname::new(*negc, $tname::from_bytes(cbytes));
|
||||
let res = a.moddiv(&b, &m);
|
||||
println!("-------------");
|
||||
println!("a: {:x}", a);
|
||||
println!("b: {:x}", b);
|
||||
println!("m: {:x}", m);
|
||||
println!("c: {:x}", c);
|
||||
println!("r: {:x}", res);
|
||||
assert_eq!(c, res);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -38,6 +38,7 @@ testDatabase = [
|
||||
(SignedCmp, "sigcmp", "signed compare", sigcmpTest),
|
||||
(SignedMul, "sigmul", "signed multiply", sigmulTest),
|
||||
(SignedDiv, "sigdiv", "signed division", sigdivTest),
|
||||
(SignedModInv,"smodinv", "signed modular inversion",smodinvTest),
|
||||
(SignedShift, "sigshiftr", "signed shift right", sigshiftrTest),
|
||||
(SignedShift, "sigshiftl", "signed shift left", sigshiftlTest),
|
||||
(SignedSub, "sigsub", "signed subtraction", sigsubTest),
|
||||
@@ -287,7 +288,7 @@ moddivTest :: Test
|
||||
moddivTest size memoryIn =
|
||||
let attempt memory0 =
|
||||
let (a, memory1) = genSign (generateNum memory0 "a" size)
|
||||
(b, memory2) = generateNum memory1 "b" size
|
||||
(b, memory2) = genSign (generateNum memory1 "b" size)
|
||||
(m, memory3) = generateNum memory2 "m" size
|
||||
maybe_res = divmod a b m
|
||||
in case maybe_res of
|
||||
|
||||
Reference in New Issue
Block a user