Add support for scaling numbers by primitive types.

This commit is contained in:
2019-01-01 20:50:09 -08:00
parent 69312c6a42
commit 4114db21be
68 changed files with 184563 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ subtraction_impls!(I192, I256, U256);
mul_impls!(I192, I384);
div_impls!(I192, U192);
smodinv_impls!(I192, I256);
scale_impls!(I192, I256);
conversion_impls!(I192, U192, I256, U256);
conversion_impls!(I192, U192, I384, U384);
conversion_impls!(I192, U192, I512, U512);
@@ -18,6 +19,7 @@ subtraction_impls!(I256, I320, U320);
mul_impls!(I256, I512);
div_impls!(I256, U256);
smodinv_impls!(I256, I320);
scale_impls!(I256, I320);
conversion_impls!(I256, U256, I320, U320);
conversion_impls!(I256, U256, I512, U512);
conversion_impls!(I256, U256, I576, U576);
@@ -31,6 +33,7 @@ shift_impls!(I320, U320);
subtraction_impls!(I320, I384, U384);
mul_impls!(I320, I640);
div_impls!(I320, U320);
scale_impls!(I320, I384);
conversion_impls!(I320, U320, I384, U384);
conversion_impls!(I320, U320, I640, U640);
conversion_impls!(I320, U320, I704, U704);
@@ -40,6 +43,7 @@ subtraction_impls!(I384, I448, U448);
mul_impls!(I384, I768);
div_impls!(I384, U384);
smodinv_impls!(I384, I448);
scale_impls!(I384, I448);
conversion_impls!(I384, U384, I448, U448);
conversion_impls!(I384, U384, I768, U768);
conversion_impls!(I384, U384, I896, U896);
@@ -52,6 +56,7 @@ shift_impls!(I448, U448);
subtraction_impls!(I448, I512, U512);
mul_impls!(I448, I896);
div_impls!(I448, U448);
scale_impls!(I448, I512);
conversion_impls!(I448, U448, I512, U512);
conversion_impls!(I448, U448, I896, U896);
conversion_impls!(I448, U448, I960, U960);
@@ -59,6 +64,7 @@ signed_impls!(I512, U512);
subtraction_impls!(I512, I576, U576);
mul_impls!(I512, I1024);
div_impls!(I512, U512);
scale_impls!(I512, I576);
conversion_impls!(I512, U512, I576, U576);
conversion_impls!(I512, U512, I1024, U1024);
egcd_impls!(I576, U512, I512, I1152);
@@ -72,6 +78,7 @@ subtraction_impls!(I576, I640, U640);
mul_impls!(I576, I1152);
div_impls!(I576, U576);
smodinv_impls!(I576, I640);
scale_impls!(I576, I640);
conversion_impls!(I576, U576, I640, U640);
conversion_impls!(I576, U576, I1152, U1152);
conversion_impls!(I576, U576, I1216, U1216);
@@ -85,6 +92,7 @@ shift_impls!(I640, U640);
subtraction_impls!(I640, I704, U704);
mul_impls!(I640, I1280);
div_impls!(I640, U640);
scale_impls!(I640, I704);
conversion_impls!(I640, U640, I704, U704);
conversion_impls!(I640, U640, I1280, U1280);
conversion_impls!(I640, U640, I1344, U1344);
@@ -95,6 +103,7 @@ signed_impls!(I896, U896);
subtraction_impls!(I896, I960, U960);
mul_impls!(I896, I1792);
div_impls!(I896, U896);
scale_impls!(I896, I960);
conversion_impls!(I896, U896, I960, U960);
conversion_impls!(I896, U896, I1792, U1792);
signed_impls!(I960, U960);
@@ -109,6 +118,7 @@ shift_impls!(I1088, U1088);
subtraction_impls!(I1088, I1152, U1152);
mul_impls!(I1088, I2176);
div_impls!(I1088, U1088);
scale_impls!(I1088, I1152);
conversion_impls!(I1088, U1088, I1152, U1152);
conversion_impls!(I1088, U1088, I2176, U2176);
conversion_impls!(I1088, U1088, I2240, U2240);
@@ -121,6 +131,7 @@ signed_impls!(I1280, U1280);
subtraction_impls!(I1280, I1344, U1344);
mul_impls!(I1280, I2560);
div_impls!(I1280, U1280);
scale_impls!(I1280, I1344);
conversion_impls!(I1280, U1280, I1344, U1344);
conversion_impls!(I1280, U1280, I2560, U2560);
signed_impls!(I1344, U1344);
@@ -134,6 +145,7 @@ shift_impls!(I1600, U1600);
subtraction_impls!(I1600, I1664, U1664);
mul_impls!(I1600, I3200);
div_impls!(I1600, U1600);
scale_impls!(I1600, I1664);
conversion_impls!(I1600, U1600, I1664, U1664);
conversion_impls!(I1600, U1600, I3200, U3200);
conversion_impls!(I1600, U1600, I3264, U3264);
@@ -150,6 +162,7 @@ shift_impls!(I2112, U2112);
subtraction_impls!(I2112, I2176, U2176);
mul_impls!(I2112, I4224);
div_impls!(I2112, U2112);
scale_impls!(I2112, I2176);
conversion_impls!(I2112, U2112, I2176, U2176);
conversion_impls!(I2112, U2112, I4224, U4224);
conversion_impls!(I2112, U2112, I4288, U4288);
@@ -169,6 +182,7 @@ shift_impls!(I3136, U3136);
subtraction_impls!(I3136, I3200, U3200);
mul_impls!(I3136, I6272);
div_impls!(I3136, U3136);
scale_impls!(I3136, I3200);
conversion_impls!(I3136, U3136, I3200, U3200);
conversion_impls!(I3136, U3136, I6272, U6272);
conversion_impls!(I3136, U3136, I6336, U6336);
@@ -187,6 +201,7 @@ shift_impls!(I4160, U4160);
subtraction_impls!(I4160, I4224, U4224);
mul_impls!(I4160, I8320);
div_impls!(I4160, U4160);
scale_impls!(I4160, I4224);
conversion_impls!(I4160, U4160, I4224, U4224);
conversion_impls!(I4160, U4160, I8320, U8320);
conversion_impls!(I4160, U4160, I8384, U8384);
@@ -208,6 +223,7 @@ shift_impls!(I7744, U7744);
subtraction_impls!(I7744, I7808, U7808);
mul_impls!(I7744, I15488);
div_impls!(I7744, U7744);
scale_impls!(I7744, I7808);
conversion_impls!(I7744, U7744, I7808, U7808);
conversion_impls!(I7744, U7744, I15488, U15488);
conversion_impls!(I7744, U7744, I15552, U15552);
@@ -223,6 +239,7 @@ shift_impls!(I8256, U8256);
subtraction_impls!(I8256, I8320, U8320);
mul_impls!(I8256, I16512);
div_impls!(I8256, U8256);
scale_impls!(I8256, I8320);
conversion_impls!(I8256, U8256, I8320, U8320);
conversion_impls!(I8256, U8256, I16512, U16512);
conversion_impls!(I8256, U8256, I16576, U16576);
@@ -241,6 +258,7 @@ shift_impls!(I15424, U15424);
subtraction_impls!(I15424, I15488, U15488);
mul_impls!(I15424, I30848);
div_impls!(I15424, U15424);
scale_impls!(I15424, I15488);
conversion_impls!(I15424, U15424, I15488, U15488);
conversion_impls!(I15424, U15424, I30848, U30848);
conversion_impls!(I15424, U15424, I30912, U30912);
@@ -523,6 +541,29 @@ mod tests {
generate_sigshiftr_tests!(I8256, U8256, i8256);
generate_sigshiftr_tests!(I15424, U15424, i15424);
}
mod sigscale {
use super::super::*;
use testing::{build_test_path,run_test};
generate_sigscale_tests!(I192, U192, i192, I256, U256);
generate_sigscale_tests!(I256, U256, i256, I320, U320);
generate_sigscale_tests!(I320, U320, i320, I384, U384);
generate_sigscale_tests!(I384, U384, i384, I448, U448);
generate_sigscale_tests!(I448, U448, i448, I512, U512);
generate_sigscale_tests!(I512, U512, i512, I576, U576);
generate_sigscale_tests!(I576, U576, i576, I640, U640);
generate_sigscale_tests!(I640, U640, i640, I704, U704);
generate_sigscale_tests!(I896, U896, i896, I960, U960);
generate_sigscale_tests!(I1088, U1088, i1088, I1152, U1152);
generate_sigscale_tests!(I1280, U1280, i1280, I1344, U1344);
generate_sigscale_tests!(I1600, U1600, i1600, I1664, U1664);
generate_sigscale_tests!(I2112, U2112, i2112, I2176, U2176);
generate_sigscale_tests!(I3136, U3136, i3136, I3200, U3200);
generate_sigscale_tests!(I4160, U4160, i4160, I4224, U4224);
generate_sigscale_tests!(I7744, U7744, i7744, I7808, U7808);
generate_sigscale_tests!(I8256, U8256, i8256, I8320, U8320);
generate_sigscale_tests!(I15424, U15424, i15424, I15488, U15488);
}
mod egcd {
use super::super::*;
use testing::{build_test_path,run_test};

View File

@@ -28,6 +28,8 @@ mod modinv;
#[macro_use]
mod mul;
#[macro_use]
mod scale;
#[macro_use]
mod shift;
#[macro_use]
mod subtraction;

121
src/signed/scale.rs Normal file
View File

@@ -0,0 +1,121 @@
macro_rules! scale_impls
{
($base: ident, $big: ident) => {
scale_impls!($base, $big, u8);
scale_impls!($base, $big, u16);
scale_impls!($base, $big, u32);
scale_impls!($base, $big, u64);
scale_impls!($base, $big, usize);
scale_impls!($base, $big, scaled i8);
scale_impls!($base, $big, scaled i16);
scale_impls!($base, $big, scaled i32);
scale_impls!($base, $big, scaled i64);
scale_impls!($base, $big, scaled isize);
};
($base: ident, $big: ident, $prim: ident) => {
impl Mul<$prim> for $base {
type Output = $big;
fn mul(self, factor: $prim) -> $big {
&self * factor
}
}
impl<'a> Mul<$prim> for &'a $base {
type Output = $big;
fn mul(self, factor: $prim) -> $big {
let mut res = $big::zero();
scale(&mut res.value.value, &self.value.value, factor as u64);
res.negative = self.negative && !res.value.is_zero();
res
}
}
impl Mul<$base> for $prim {
type Output = $big;
fn mul(self, rhs: $base) -> $big {
rhs.mul(self)
}
}
impl<'a> Mul<&'a $base> for $prim {
type Output = $big;
fn mul(self, rhs: &$base) -> $big {
rhs.mul(self)
}
}
};
($base: ident, $big: ident, scaled $prim: ident) => {
impl Mul<$prim> for $base {
type Output = $big;
fn mul(self, factor: $prim) -> $big {
&self * factor
}
}
impl<'a> Mul<$prim> for &'a $base {
type Output = $big;
fn mul(self, factor: $prim) -> $big {
let mut res = $big::zero();
scale(&mut res.value.value, &self.value.value, factor.abs() as u64);
res.negative = (self.negative ^ (factor < 0)) && !res.value.is_zero();
res
}
}
impl Mul<$base> for $prim {
type Output = $big;
fn mul(self, rhs: $base) -> $big {
rhs.mul(self)
}
}
impl<'a> Mul<&'a $base> for $prim {
type Output = $big;
fn mul(self, rhs: &$base) -> $big {
rhs.mul(self)
}
}
};
}
#[cfg(test)]
macro_rules! generate_sigscale_tests
{
($name: ident, $uname: ident, $lname: ident, $big: ident, $ubig: ident) => {
#[test]
fn $lname() {
generate_sigscale_tests!(body $name, $uname, $lname, $big, $ubig);
}
};
(ignore $name: ident, $uname:ident, $lname: ident, $big: ident, $ubig: ident) => {
#[test]
#[ignore]
fn $lname() {
generate_sigscale_tests!(body $name, $uname, $lname, $big, $ubig);
}
};
(body $name: ident, $uname: ident, $lname: ident, $big: ident, $ubig: ident) => {
let fname = build_test_path("sigscale", stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (nega, abytes) = case.get("a").unwrap();
let (negb, bbytes) = case.get("b").unwrap();
let (negc, cbytes) = case.get("c").unwrap();
let a = $name::new(*nega, $uname::from_bytes(abytes));
let bbig = $name::new(*negb, $uname::from_bytes(bbytes));
let c = $big::new(*negc, $ubig::from_bytes(cbytes));
let b = i64::from(&bbig);
let res = &a * b;
assert_eq!(c, res);
});
};
}

View File

@@ -8,6 +8,7 @@ modexp_impls!(U192, BarrettU192);
modmul_impls!(U192, U384, BarrettU192);
modsq_impls!(U192, U384, BarrettU192);
multiply_impls!(U192, U384);
scale_impls!(U192, U256);
shift_impls!(U192, 3);
square_impls!(U192, U384, 192);
subtraction_impls!(U192, 3);
@@ -30,6 +31,7 @@ modexp_impls!(U256, BarrettU256);
modmul_impls!(U256, U512, BarrettU256);
modsq_impls!(U256, U512, BarrettU256);
multiply_impls!(U256, U512);
scale_impls!(U256, U320);
shift_impls!(U256, 4);
square_impls!(U256, U512, 256);
subtraction_impls!(U256, 4);
@@ -49,6 +51,7 @@ base_impls!(U320, 5);
random_impls!(U320, UniformU320);
div_impls!(U320, U640);
multiply_impls!(U320, U640);
scale_impls!(U320, U384);
shift_impls!(U320, 5);
subtraction_impls!(U320, 5);
conversion_impls!(U320, U384);
@@ -62,6 +65,7 @@ random_impls!(U384, UniformU384);
barrett_impl!(BarrettU384, U384, U448, U768, U832);
div_impls!(U384, U768);
multiply_impls!(U384, U768);
scale_impls!(U384, U448);
shift_impls!(U384, 6);
subtraction_impls!(U384, 6);
conversion_impls!(U384, U448);
@@ -74,6 +78,7 @@ base_impls!(U448, 7);
random_impls!(U448, UniformU448);
div_impls!(U448, U896);
multiply_impls!(U448, U896);
scale_impls!(U448, U512);
shift_impls!(U448, 7);
subtraction_impls!(U448, 7);
conversion_impls!(U448, U512);
@@ -91,6 +96,7 @@ modexp_impls!(U512, BarrettU512);
modmul_impls!(U512, U1024, BarrettU512);
modsq_impls!(U512, U1024, BarrettU512);
multiply_impls!(U512, U1024);
scale_impls!(U512, U576);
shift_impls!(U512, 8);
square_impls!(U512, U1024, 512);
subtraction_impls!(U512, 8);
@@ -106,6 +112,7 @@ random_impls!(U576, UniformU576);
barrett_impl!(BarrettU576, U576, U640, U1152, U1216);
div_impls!(U576, U1152);
multiply_impls!(U576, U1152);
scale_impls!(U576, U640);
shift_impls!(U576, 9);
subtraction_impls!(U576, 9);
conversion_impls!(U576, U640);
@@ -119,6 +126,7 @@ base_impls!(U640, 10);
random_impls!(U640, UniformU640);
div_impls!(U640, U1280);
multiply_impls!(U640, U1280);
scale_impls!(U640, U704);
shift_impls!(U640, 10);
subtraction_impls!(U640, 10);
conversion_impls!(U640, U704);
@@ -134,6 +142,7 @@ base_impls!(U768, 12);
random_impls!(U768, UniformU768);
div_impls!(U768, U1536);
multiply_impls!(U768, U1536);
scale_impls!(U768, U832);
shift_impls!(U768, 12);
subtraction_impls!(U768, 12);
conversion_impls!(U768, U832);
@@ -143,6 +152,7 @@ base_impls!(U832, 13);
random_impls!(U832, UniformU832);
div_impls!(U832, U1664);
multiply_impls!(U832, U1664);
scale_impls!(U832, U896);
subtraction_impls!(U832, 13);
conversion_impls!(U832, U896);
conversion_impls!(U832, U1664);
@@ -151,6 +161,7 @@ base_impls!(U896, 14);
random_impls!(U896, UniformU896);
div_impls!(U896, U1792);
multiply_impls!(U896, U1792);
scale_impls!(U896, U960);
shift_impls!(U896, 14);
subtraction_impls!(U896, 14);
conversion_impls!(U896, U960);
@@ -168,6 +179,7 @@ modexp_impls!(U1024, BarrettU1024);
modmul_impls!(U1024, U2048, BarrettU1024);
modsq_impls!(U1024, U2048, BarrettU1024);
multiply_impls!(U1024, U2048);
scale_impls!(U1024, U1088);
shift_impls!(U1024, 16);
square_impls!(U1024, U2048, 1024);
subtraction_impls!(U1024, 16);
@@ -183,6 +195,7 @@ base_impls!(U1088, 17);
random_impls!(U1088, UniformU1088);
div_impls!(U1088, U2176);
multiply_impls!(U1088, U2176);
scale_impls!(U1088, U1152);
shift_impls!(U1088, 17);
subtraction_impls!(U1088, 17);
conversion_impls!(U1088, U1152);
@@ -195,6 +208,7 @@ base_impls!(U1152, 18);
random_impls!(U1152, UniformU1152);
div_impls!(U1152, U2304);
multiply_impls!(U1152, U2304);
scale_impls!(U1152, U1216);
shift_impls!(U1152, 18);
subtraction_impls!(U1152, 18);
conversion_impls!(U1152, U1216);
@@ -204,6 +218,7 @@ base_impls!(U1216, 19);
random_impls!(U1216, UniformU1216);
div_impls!(U1216, U2432);
multiply_impls!(U1216, U2432);
scale_impls!(U1216, U1280);
subtraction_impls!(U1216, 19);
conversion_impls!(U1216, U1280);
conversion_impls!(U1216, U2432);
@@ -212,6 +227,7 @@ base_impls!(U1280, 20);
random_impls!(U1280, UniformU1280);
div_impls!(U1280, U2560);
multiply_impls!(U1280, U2560);
scale_impls!(U1280, U1344);
shift_impls!(U1280, 20);
subtraction_impls!(U1280, 20);
conversion_impls!(U1280, U1344);
@@ -228,6 +244,7 @@ modexp_impls!(U1536, BarrettU1536);
modmul_impls!(U1536, U3072, BarrettU1536);
modsq_impls!(U1536, U3072, BarrettU1536);
multiply_impls!(U1536, U3072);
scale_impls!(U1536, U1600);
shift_impls!(U1536, 24);
square_impls!(U1536, U3072, 1536);
subtraction_impls!(U1536, 24);
@@ -240,6 +257,7 @@ base_impls!(U1600, 25);
random_impls!(U1600, UniformU1600);
div_impls!(U1600, U3200);
multiply_impls!(U1600, U3200);
scale_impls!(U1600, U1664);
shift_impls!(U1600, 25);
subtraction_impls!(U1600, 25);
conversion_impls!(U1600, U1664);
@@ -263,6 +281,7 @@ modexp_impls!(U2048, BarrettU2048);
modmul_impls!(U2048, U4096, BarrettU2048);
modsq_impls!(U2048, U4096, BarrettU2048);
multiply_impls!(U2048, U4096);
scale_impls!(U2048, U2112);
shift_impls!(U2048, 32);
square_impls!(U2048, U4096, 2048);
subtraction_impls!(U2048, 32);
@@ -278,6 +297,7 @@ base_impls!(U2112, 33);
random_impls!(U2112, UniformU2112);
div_impls!(U2112, U4224);
multiply_impls!(U2112, U4224);
scale_impls!(U2112, U2176);
shift_impls!(U2112, 33);
subtraction_impls!(U2112, 33);
conversion_impls!(U2112, U2176);
@@ -313,6 +333,7 @@ modexp_impls!(U3072, BarrettU3072);
modmul_impls!(U3072, U6144, BarrettU3072);
modsq_impls!(U3072, U6144, BarrettU3072);
multiply_impls!(U3072, U6144);
scale_impls!(U3072, U3136);
shift_impls!(U3072, 48);
square_impls!(U3072, U6144, 3072);
subtraction_impls!(U3072, 48);
@@ -328,6 +349,7 @@ base_impls!(U3136, 49);
random_impls!(U3136, UniformU3136);
div_impls!(U3136, U6272);
multiply_impls!(U3136, U6272);
scale_impls!(U3136, U3200);
shift_impls!(U3136, 49);
subtraction_impls!(U3136, 49);
conversion_impls!(U3136, U3200);
@@ -354,6 +376,7 @@ modexp_impls!(U4096, BarrettU4096);
modmul_impls!(U4096, U8192, BarrettU4096);
modsq_impls!(U4096, U8192, BarrettU4096);
multiply_impls!(U4096, U8192);
scale_impls!(U4096, U4160);
shift_impls!(U4096, 64);
square_impls!(U4096, U8192, 4096);
subtraction_impls!(U4096, 64);
@@ -366,6 +389,7 @@ base_impls!(U4160, 65);
random_impls!(U4160, UniformU4160);
div_impls!(U4160, U8320);
multiply_impls!(U4160, U8320);
scale_impls!(U4160, U4224);
shift_impls!(U4160, 65);
subtraction_impls!(U4160, 65);
conversion_impls!(U4160, U4224);
@@ -378,6 +402,7 @@ base_impls!(U4224, 66);
random_impls!(U4224, UniformU4224);
div_impls!(U4224, U8448);
multiply_impls!(U4224, U8448);
scale_impls!(U4224, U4288);
shift_impls!(U4224, 66);
subtraction_impls!(U4224, 66);
conversion_impls!(U4224, U4288);
@@ -390,6 +415,7 @@ base_impls!(U6144, 96);
random_impls!(U6144, UniformU6144);
div_impls!(U6144, U12288);
multiply_impls!(U6144, U12288);
scale_impls!(U6144, U6208);
shift_impls!(U6144, 96);
subtraction_impls!(U6144, 96);
conversion_impls!(U6144, U6208);
@@ -399,6 +425,7 @@ base_impls!(U6208, 97);
random_impls!(U6208, UniformU6208);
div_impls!(U6208, U12416);
multiply_impls!(U6208, U12416);
scale_impls!(U6208, U6272);
subtraction_impls!(U6208, 97);
conversion_impls!(U6208, U6272);
conversion_impls!(U6208, U12416);
@@ -420,6 +447,7 @@ modexp_impls!(U7680, BarrettU7680);
modmul_impls!(U7680, U15360, BarrettU7680);
modsq_impls!(U7680, U15360, BarrettU7680);
multiply_impls!(U7680, U15360);
scale_impls!(U7680, U7744);
shift_impls!(U7680, 120);
square_impls!(U7680, U15360, 7680);
subtraction_impls!(U7680, 120);
@@ -432,6 +460,7 @@ base_impls!(U7744, 121);
random_impls!(U7744, UniformU7744);
div_impls!(U7744, U15488);
multiply_impls!(U7744, U15488);
scale_impls!(U7744, U7808);
shift_impls!(U7744, 121);
subtraction_impls!(U7744, 121);
conversion_impls!(U7744, U7808);
@@ -451,6 +480,7 @@ modexp_impls!(U8192, BarrettU8192);
modmul_impls!(U8192, U16384, BarrettU8192);
modsq_impls!(U8192, U16384, BarrettU8192);
multiply_impls!(U8192, U16384);
scale_impls!(U8192, U8256);
shift_impls!(U8192, 128);
square_impls!(U8192, U16384, 8192);
subtraction_impls!(U8192, 128);
@@ -462,6 +492,7 @@ base_impls!(U8256, 129);
random_impls!(U8256, UniformU8256);
div_impls!(U8256, U16512);
multiply_impls!(U8256, U16512);
scale_impls!(U8256, U8320);
shift_impls!(U8256, 129);
subtraction_impls!(U8256, 129);
conversion_impls!(U8256, U8320);
@@ -474,6 +505,7 @@ base_impls!(U8320, 130);
random_impls!(U8320, UniformU8320);
div_impls!(U8320, U16640);
multiply_impls!(U8320, U16640);
scale_impls!(U8320, U8384);
shift_impls!(U8320, 130);
subtraction_impls!(U8320, 130);
conversion_impls!(U8320, U8384);
@@ -491,8 +523,11 @@ base_impls!(U12416, 194);
random_impls!(U12416, UniformU12416);
div_impls!(U12416, U24832);
multiply_impls!(U12416, U24832);
scale_impls!(U12416, U12480);
subtraction_impls!(U12416, 194);
conversion_impls!(U12416, U24832);
base_impls!(U12480, 195);
random_impls!(U12480, UniformU12480);
base_impls!(U15360, 240);
random_impls!(U15360, UniformU15360);
barrett_impl!(BarrettU15360, U15360, U15424, U30720, U30784);
@@ -502,6 +537,7 @@ modexp_impls!(U15360, BarrettU15360);
modmul_impls!(U15360, U30720, BarrettU15360);
modsq_impls!(U15360, U30720, BarrettU15360);
multiply_impls!(U15360, U30720);
scale_impls!(U15360, U15424);
shift_impls!(U15360, 240);
square_impls!(U15360, U30720, 15360);
subtraction_impls!(U15360, 240);
@@ -513,6 +549,7 @@ base_impls!(U15424, 241);
random_impls!(U15424, UniformU15424);
div_impls!(U15424, U30848);
multiply_impls!(U15424, U30848);
scale_impls!(U15424, U15488);
shift_impls!(U15424, 241);
subtraction_impls!(U15424, 241);
conversion_impls!(U15424, U15488);
@@ -533,6 +570,7 @@ base_impls!(U16384, 256);
random_impls!(U16384, UniformU16384);
div_impls!(U16384, U32768);
multiply_impls!(U16384, U32768);
scale_impls!(U16384, U16448);
shift_impls!(U16384, 256);
subtraction_impls!(U16384, 256);
conversion_impls!(U16384, U16448);
@@ -542,6 +580,7 @@ base_impls!(U16448, 257);
random_impls!(U16448, UniformU16448);
div_impls!(U16448, U32896);
multiply_impls!(U16448, U32896);
scale_impls!(U16448, U16512);
subtraction_impls!(U16448, 257);
conversion_impls!(U16448, U16512);
conversion_impls!(U16448, U32896);
@@ -564,6 +603,7 @@ base_impls!(U30720, 480);
random_impls!(U30720, UniformU30720);
div_impls!(U30720, U61440);
multiply_impls!(U30720, U61440);
scale_impls!(U30720, U30784);
shift_impls!(U30720, 480);
subtraction_impls!(U30720, 480);
conversion_impls!(U30720, U30784);
@@ -573,6 +613,7 @@ base_impls!(U30784, 481);
random_impls!(U30784, UniformU30784);
div_impls!(U30784, U61568);
multiply_impls!(U30784, U61568);
scale_impls!(U30784, U30848);
subtraction_impls!(U30784, 481);
conversion_impls!(U30784, U30848);
conversion_impls!(U30784, U61568);
@@ -657,6 +698,7 @@ mod tests {
generate_base_tests!(U8448, u8448);
generate_base_tests!(U12288, u12288);
generate_base_tests!(U12416, u12416);
generate_base_tests!(U12480, u12480);
generate_base_tests!(U15360, u15360);
generate_base_tests!(U15424, u15424);
generate_base_tests!(U15488, u15488);
@@ -729,6 +771,7 @@ mod tests {
generate_conversion_tests!(U8448, u8448);
generate_conversion_tests!(U12288, u12288);
generate_conversion_tests!(U12416, u12416);
generate_conversion_tests!(U12480, u12480);
generate_conversion_tests!(U15360, u15360);
generate_conversion_tests!(U15424, u15424);
generate_conversion_tests!(U15488, u15488);
@@ -801,6 +844,7 @@ mod tests {
generate_codec_tests!(U8448, u8448);
generate_codec_tests!(U12288, u12288);
generate_codec_tests!(U12416, u12416);
generate_codec_tests!(U12480, u12480);
generate_codec_tests!(U15360, u15360);
generate_codec_tests!(U15424, u15424);
generate_codec_tests!(U15488, u15488);
@@ -876,6 +920,7 @@ mod tests {
generate_cmp_tests!(U8448, u8448);
generate_cmp_tests!(U12288, u12288);
generate_cmp_tests!(U12416, u12416);
generate_cmp_tests!(U12480, u12480);
generate_cmp_tests!(U15360, u15360);
generate_cmp_tests!(U15424, u15424);
generate_cmp_tests!(U15488, u15488);
@@ -1145,6 +1190,50 @@ mod tests {
generate_mul_tests!(ignore U30720, u30720, U61440);
generate_mul_tests!(ignore U30784, u30784, U61568);
}
mod scale {
use super::super::*;
use testing::{build_test_path,run_test};
generate_scale_tests!(U192, u192, U256);
generate_scale_tests!(U256, u256, U320);
generate_scale_tests!(U320, u320, U384);
generate_scale_tests!(U384, u384, U448);
generate_scale_tests!(U448, u448, U512);
generate_scale_tests!(U512, u512, U576);
generate_scale_tests!(U576, u576, U640);
generate_scale_tests!(U640, u640, U704);
generate_scale_tests!(U768, u768, U832);
generate_scale_tests!(U832, u832, U896);
generate_scale_tests!(U896, u896, U960);
generate_scale_tests!(U1024, u1024, U1088);
generate_scale_tests!(U1088, u1088, U1152);
generate_scale_tests!(U1152, u1152, U1216);
generate_scale_tests!(U1216, u1216, U1280);
generate_scale_tests!(U1280, u1280, U1344);
generate_scale_tests!(U1536, u1536, U1600);
generate_scale_tests!(U1600, u1600, U1664);
generate_scale_tests!(U2048, u2048, U2112);
generate_scale_tests!(U2112, u2112, U2176);
generate_scale_tests!(U3072, u3072, U3136);
generate_scale_tests!(U3136, u3136, U3200);
generate_scale_tests!(U4096, u4096, U4160);
generate_scale_tests!(U4160, u4160, U4224);
generate_scale_tests!(U4224, u4224, U4288);
generate_scale_tests!(U6144, u6144, U6208);
generate_scale_tests!(U6208, u6208, U6272);
generate_scale_tests!(U7680, u7680, U7744);
generate_scale_tests!(U7744, u7744, U7808);
generate_scale_tests!(U8192, u8192, U8256);
generate_scale_tests!(U8256, u8256, U8320);
generate_scale_tests!(U8320, u8320, U8384);
generate_scale_tests!(ignore U12416, u12416, U12480);
generate_scale_tests!(ignore U15360, u15360, U15424);
generate_scale_tests!(ignore U15424, u15424, U15488);
generate_scale_tests!(ignore U16384, u16384, U16448);
generate_scale_tests!(ignore U16448, u16448, U16512);
generate_scale_tests!(ignore U30720, u30720, U30784);
generate_scale_tests!(ignore U30784, u30784, U30848);
}
mod div {
use super::super::*;
use testing::{build_test_path,run_test};

View File

@@ -42,6 +42,8 @@ mod primes;
#[macro_use]
mod rand;
#[macro_use]
mod scale;
#[macro_use]
mod shifts;
#[macro_use]
mod sqrt;
@@ -61,6 +63,7 @@ pub use self::square::Square;
pub use self::sqrt::SquareRoot;
pub(crate) use self::add::unsafe_addition;
pub(crate) use self::scale::scale;
use rand::{Rng,RngCore};
use rand::distributions::{Distribution,Standard};

93
src/unsigned/scale.rs Normal file
View File

@@ -0,0 +1,93 @@
pub fn scale(dest: &mut [u64], bignum: &[u64], factor: u64)
{
let len = bignum.len();
let factor128 = factor as u128;
let mut carry = 0;
assert_eq!(dest.len(), len+1, "Bad destination size in scale");
for i in 0..len {
let digit128 = bignum[i] as u128;
let res128 = carry + (digit128 * factor128);
dest[i] = res128 as u64;
carry = res128 >> 64;
}
dest[len] = carry as u64;
}
macro_rules! scale_impls
{
($base: ident, $big: ident) => {
scale_impls!($base, $big, u8);
scale_impls!($base, $big, u16);
scale_impls!($base, $big, u32);
scale_impls!($base, $big, u64);
scale_impls!($base, $big, usize);
};
($base: ident, $big: ident, $prim: ident) => {
impl Mul<$prim> for $base {
type Output = $big;
fn mul(self, factor: $prim) -> $big {
&self * factor
}
}
impl<'a> Mul<$prim> for &'a $base {
type Output = $big;
fn mul(self, factor: $prim) -> $big {
let mut res = $big::zero();
scale(&mut res.value, &self.value, factor as u64);
res
}
}
impl Mul<$base> for $prim {
type Output = $big;
fn mul(self, rhs: $base) -> $big {
rhs.mul(self)
}
}
impl<'a> Mul<&'a $base> for $prim {
type Output = $big;
fn mul(self, rhs: &$base) -> $big {
rhs.mul(self)
}
}
}
}
#[cfg(test)]
macro_rules! generate_scale_tests
{
($name: ident, $lname: ident, $big: ident) => {
#[test]
fn $lname() {
generate_scale_tests!(body $name, $lname, $big);
}
};
(ignore $name: ident, $lname: ident, $big: ident) => {
#[test]
#[ignore]
fn $lname() {
generate_scale_tests!(body $name, $lname, $big);
}
};
(body $name: ident, $lname: ident, $big: ident) => {
let fname = build_test_path("scale", stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, cbytes) = case.get("c").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let c = $big::from_bytes(cbytes);
assert_eq!(c, &a * b.value[0]);
});
};
}

View File

@@ -60,6 +60,7 @@ main = do
ModMul -> hPutStrLn hndl ("modmul_impls!(U" ++ show size ++ ", U" ++ show (size * 2) ++ ", BarrettU" ++ show size ++ ");")
ModSq -> hPutStrLn hndl ("modsq_impls!(U" ++ show size ++ ", U" ++ show (size * 2) ++ ", BarrettU" ++ show size ++ ");")
Mul -> hPutStrLn hndl ("multiply_impls!(U" ++ show size ++ ", U" ++ show (size * 2) ++ ");")
Scale -> hPutStrLn hndl ("scale_impls!(U" ++ show size ++ ", U" ++ show (size + 64) ++ ");")
Shifts -> hPutStrLn hndl ("shift_impls!(U" ++ show size ++ ", " ++ show (size `div` 64) ++ ");")
Square -> hPutStrLn hndl ("square_impls!(U" ++ show size ++ ", U" ++ show (size * 2) ++ ", " ++ show size ++ ");")
SquareRoot -> hPutStrLn hndl ("sqrt_impls!(U" ++ show size ++ ");")
@@ -79,6 +80,7 @@ main = do
generateTestBlock hndl "shiftr" Shifts True 9000 []
generateTestBlock hndl "add" Add True 9000 [(+ 64)]
generateTestBlock hndl "mul" Mul True 9000 [(* 2)]
generateTestBlock hndl "scale" Scale True 9000 [(+ 64)]
generateTestBlock hndl "div" Div True 2049 []
generateTestBlock hndl "barrett_gen" Barretts True 2000 [(+ 64)]
generateTestBlock hndl "barrett_red" Barretts True 4000 [(+ 64), (* 2)]
@@ -102,6 +104,7 @@ main = do
SignedMul -> hPutStrLn hndl ("mul_impls!(I" ++ show size ++ ", I" ++ show (size * 2) ++ ");")
SignedDiv -> hPutStrLn hndl ("div_impls!(I" ++ show size ++ ", U" ++ show size ++ ");")
SignedModInv -> hPutStrLn hndl ("smodinv_impls!(I" ++ show size ++ ", I" ++ show (size + 64) ++ ");")
SignedScale -> hPutStrLn hndl ("scale_impls!(I" ++ show size ++ ", I" ++ show (size + 64) ++ ");")
EGCD -> hPutStrLn hndl ("egcd_impls!(I" ++ show (size + 64) ++ ", U" ++ show size ++ ", I" ++ show size ++ ", I" ++ show ((size + 64) * 2) ++ ");")
ModDiv -> hPutStrLn hndl ("moddiv_impls!(I" ++ show size ++ ", I" ++ show (size * 2) ++ ");")
ModInv -> hPutStrLn hndl ("modinv_impls!(U" ++ show size ++ ", I" ++ show (size + 64) ++ ", U" ++ show (size + 64) ++ ");")
@@ -119,6 +122,7 @@ main = do
generateSigTestBlock hndl "sigdiv" SignedDiv True 2049 [] []
generateSigTestBlock hndl "sigshiftl" SignedShift True 16384 [] []
generateSigTestBlock hndl "sigshiftr" SignedShift True 16384 [] []
generateSigTestBlock hndl "sigscale" SignedScale True 16384 [(+ 64)] [(+ 64)]
generateSigTestBlock hndl "egcd" EGCD True 1024 [(+ 64)] [(+ 64)]
generateSigTestBlock hndl "moddiv" ModDiv True 2048 [] []
generateSigTestBlock hndl "modinv" ModInv True 2048 [] []

View File

@@ -16,6 +16,7 @@ data Operation = Add
| ModMul
| ModSq
| Mul
| Scale
| Shifts
| Square
| Sub
@@ -28,6 +29,7 @@ data Operation = Add
| SignedMul
| SignedDiv
| SignedModInv
| SignedScale
| SigConvert Int
| SquareRoot
| EGCD
@@ -136,9 +138,11 @@ needs = [ Need RSA (\ size -> [Req (size `div` 2) Sub,
Req size (Convert (size + 64))
])
, Need Mul (\ size -> [Req size BaseOps,
Req size Scale,
Req (size * 2) BaseOps,
Req size (Convert (size * 2))
])
, Need Scale (\ size -> [Req (size + 64) BaseOps])
, Need Shifts (\ size -> [Req size BaseOps
])
, Need Square (\ size -> [Req size BaseOps,
@@ -167,6 +171,7 @@ needs = [ Need RSA (\ size -> [Req (size `div` 2) Sub,
Req size (SigConvert (size + 64))
])
, Need SignedMul (\ size -> [Req size Mul,
Req size SignedScale,
Req (size * 2) SignedBase,
Req size (SigConvert (size * 2))
])

View File

@@ -29,6 +29,7 @@ testDatabase = [
(ModMul, "modmul", "modular multiplication", modmulTest),
(ModSq, "modsq", "modular square", modsqTest),
(Mul, "mul", "unsigned multiplication", mulTest),
(Scale, "scale", "unsigned scaling", scaleTest),
(Shifts, "shiftl", "unsigned shift left", shiftlTest),
(Shifts, "shiftr", "unsigned shift right", shiftrTest),
(Square, "square", "unsigned squaring", squareTest),
@@ -37,6 +38,7 @@ testDatabase = [
(SignedBase, "signed", "signed base", signedTest),
(SignedCmp, "sigcmp", "signed compare", sigcmpTest),
(SignedMul, "sigmul", "signed multiply", sigmulTest),
(SignedScale, "sigscale", "signed scaling", sigscaleTest),
(SignedDiv, "sigdiv", "signed division", sigdivTest),
(SignedModInv,"smodinv", "signed modular inversion",smodinvTest),
(SignedShift, "sigshiftr", "signed shift right", sigshiftrTest),
@@ -329,3 +331,22 @@ smodinvTest size memoryIn =
assert ((a * c) `mod` b == 1) $
(res, c, memory2)
in attempt memoryIn
scaleTest :: Test
scaleTest size memory0 =
let (a, memory1) = generateNum memory0 "a" size
(b, memory2) = generateNum memory1 "b" 64
c = a * b
res = Map.fromList [("a", showX a), ("b", showX b),
("c", showX c)]
in (res, c, memory2)
sigscaleTest :: Test
sigscaleTest size memory0 =
let (a, memory1) = genSign (generateNum memory0 "a" size)
(b, memory2) = genSign (generateNum memory1 "b" 63)
c = a * b
res = Map.fromList [("a", showX a), ("b", showX b),
("c", showX c)]
in (res, c, memory2)

8008
testdata/base/12480.test vendored Normal file

File diff suppressed because it is too large Load Diff

5005
testdata/cmp/12480.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00192.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00256.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00320.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00384.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00448.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00512.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00576.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00640.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00768.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00832.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/00896.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/01024.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/01088.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/01152.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/01216.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/01280.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/01536.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/01600.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/02048.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/02112.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/03072.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/03136.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/04096.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/04160.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/04224.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/06144.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/06208.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/07680.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/07744.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/08192.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/08256.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/08320.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/12416.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/15360.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/15424.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/16384.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/16448.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/scale/30720.test vendored Normal file

File diff suppressed because one or more lines are too long

3003
testdata/scale/30784.test vendored Normal file

File diff suppressed because one or more lines are too long

3003
testdata/sigscale/00192.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/00256.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/00320.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/00384.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/00448.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/00512.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/00576.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/00640.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/00896.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/01088.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/01280.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/01600.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/02112.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/03136.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/04160.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/07744.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/08256.test vendored Normal file

File diff suppressed because it is too large Load Diff

3003
testdata/sigscale/15424.test vendored Normal file

File diff suppressed because it is too large Load Diff