diff --git a/src/algorithms.rs b/src/algorithms.rs index fc94584c..b9e61381 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -517,11 +517,12 @@ fn mac3(acc: &mut [BigDigit], b: &[BigDigit], c: &[BigDigit]) { // Recomposition. The coefficients of the polynomial are now known. // // Evaluate at w(t) where t is our given base to get the result. + let bits = big_digit::BITS * i; let result = r0 - + (comp1 << (32 * i)) - + (comp2 << (2 * 32 * i)) - + (comp3 << (3 * 32 * i)) - + (r4 << (4 * 32 * i)); + + (comp1 << bits) + + (comp2 << (2 * bits)) + + (comp3 << (3 * bits)) + + (r4 << (4 * bits)); let result_pos = result.to_biguint().unwrap(); add2(&mut acc[..], &result_pos.data); } diff --git a/tests/torture.rs b/tests/torture.rs index 4f073d31..3c72db8a 100644 --- a/tests/torture.rs +++ b/tests/torture.rs @@ -8,10 +8,14 @@ use num_bigint::RandBigInt; use num_traits::Zero; use rand::prelude::*; +fn get_rng() -> SmallRng { + let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + SmallRng::from_seed(seed) +} + fn test_mul_divide_torture_count(count: usize) { let bits_max = 1 << 12; - let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; - let mut rng = SmallRng::from_seed(seed); + let mut rng = get_rng(); for _ in 0..count { // Test with numbers of random sizes: @@ -33,11 +37,40 @@ fn test_mul_divide_torture_count(count: usize) { #[test] fn test_mul_divide_torture() { - test_mul_divide_torture_count(1000); + test_mul_divide_torture_count(1_000); } #[test] #[ignore] fn test_mul_divide_torture_long() { - test_mul_divide_torture_count(1000000); + test_mul_divide_torture_count(1_000_000); +} + +fn test_factored_mul_torture_count(count: usize) { + let bits = 1 << 16; + let mut rng = get_rng(); + + for _ in 0..count { + let w = rng.gen_biguint(bits); + let x = rng.gen_biguint(bits); + let y = rng.gen_biguint(bits); + let z = rng.gen_biguint(bits); + + let prod1 = (&w * &x) * (&y * &z); + let prod2 = (&w * &y) * (&x * &z); + let prod3 = (&w * &z) * (&x * &y); + assert_eq!(prod1, prod2); + assert_eq!(prod2, prod3); + } +} + +#[test] +fn test_factored_mul_torture() { + test_factored_mul_torture_count(50); +} + +#[test] +#[ignore] +fn test_factored_mul_torture_long() { + test_factored_mul_torture_count(1_000); }