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

@@ -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]);
});
};
}