diff --git a/Cargo.toml b/Cargo.toml index 8ee6b32..b78bde6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" authors = ["awick"] [dependencies] -quickcheck = "0.7.1" \ No newline at end of file +quickcheck = "^0.7.2" \ No newline at end of file diff --git a/generate.hs b/generate.hs index a973125..fe53152 100644 --- a/generate.hs +++ b/generate.hs @@ -135,7 +135,7 @@ needs = [ Need RSA (\ size -> [Req (size `div` 2) Sub, Req (size + 64) SignedAdd, Req (size + 64) SignedSub, Req (size + 64) SignedCmp - ]) + ]) , Need ModInv (\ size -> [Req size BaseOps, Req (size + 64) SignedBase, Req (size + 64) BaseOps, @@ -143,7 +143,7 @@ needs = [ Need RSA (\ size -> [Req (size `div` 2) Sub, Req size EGCD, Req (size + 64) SignedAdd, Req size Barretts - ]) + ]) ] -- needs = [ Need ModExp (\ size -> [Req size ModMul -- ,Req size ModSq @@ -219,6 +219,9 @@ rsaSizes = [512,1024,2048,3072,4096,8192,15360] baseRequirements :: [Requirement] baseRequirements = concatMap (\ x -> [Req x RSA]) rsaSizes + ++ [Req 192 Add, Req 256 Add, Req 384 Add] -- used for testing + ++ [Req 192 Mul, Req 384 Mul] -- used for testing + ++ [Req 448 (Convert 512)] -- used for testing requirements :: [Requirement] requirements = go baseRequirements diff --git a/src/lib.rs b/src/lib.rs index 6c685a6..b0db1ce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,3 @@ -#![recursion_limit="1024"] - #[cfg(test)] #[macro_use] extern crate quickcheck; @@ -7,4 +5,46 @@ extern crate quickcheck; pub mod signed; pub mod unsigned; #[cfg(test)] -pub mod testing; \ No newline at end of file +pub mod testing; + +#[cfg(test)] +mod arithmetic { + use super::signed::*; + use super::unsigned::*; + + quickcheck! { + fn commutivity_signed_add(x: I576, y: I576) -> bool { + (&x + &y) == (&y + &x) + } + fn commutivity_unsigned_add(x: U576, y: U576) -> bool { + (&x + &y) == (&y + &x) + } + fn commutivity_unsigned_mul(x: U192, y: U192) -> bool { + (&x * &y) == (&y * &x) + } + + fn associativity_unsigned_add(x: U192, y: U192, z: U192) -> bool { + (U256::from(&x) + (&y + &z)) == ((&x + &y) + U256::from(&z)) + } + fn associativity_unsigned_mul(x: U192, y: U192, z: U192) -> bool { + (U384::from(&x) * (&y * &z)) == ((&x * &y) * U384::from(&z)) + } + + fn identity_signed_add(x: I576) -> bool { + (&x + I576::zero()) == I640::from(&x) + } + fn identity_unsigned_add(x: U576) -> bool { + (&x + U576::zero()) == U640::from(&x) + } + fn identity_unsigned_mul(x: U192) -> bool { + (&x * U192::from(1u64)) == U384::from(&x) + } + + fn additive_inverse(x: I576) -> bool { + (&x + x.negate()) == I640::zero() + } + fn distribution(x: U192, y: U192, z: U192) -> bool { + (U256::from(&x) * (&y + &z)) == U512::from((&x * &y) + (&x * &z)) + } + } +} \ No newline at end of file diff --git a/src/signed/add.rs b/src/signed/add.rs index a9f8cfc..17d3687 100644 --- a/src/signed/add.rs +++ b/src/signed/add.rs @@ -60,16 +60,19 @@ macro_rules! add_impls value: &self.value + &rhs.value } } else { - if self.value > rhs.value { - $bigger { - negative: self.negative, - value: $ubigger::from(&self.value - &rhs.value) - } - } else { - $bigger { - negative: rhs.negative, - value: $ubigger::from(&rhs.value - &self.value) - } + match self.value.cmp(&rhs.value) { + Ordering::Greater => + $bigger { + negative: self.negative, + value: $ubigger::from(&self.value - &rhs.value) + }, + Ordering::Less => + $bigger { + negative: rhs.negative, + value: $ubigger::from(&rhs.value - &self.value) + }, + Ordering::Equal => + $bigger::zero() } } } diff --git a/src/signed/base.rs b/src/signed/base.rs index f3a1d3b..f8116f3 100644 --- a/src/signed/base.rs +++ b/src/signed/base.rs @@ -85,16 +85,18 @@ macro_rules! signed_impls { } } -// #[cfg(test)] -// impl Arbitrary for $sname { -// fn arbitrary(g: &mut G) -> $name { -// let neg = g.gen::(); -// let val = g.gen::<$name>(); -// $sname{ negative: neg, value: val } -// } -// } - #[cfg(test)] + impl Arbitrary for $sname { + fn arbitrary(g: &mut G) -> $sname + where G: Gen + { + let neg = bool::arbitrary(g); + let val = $name::arbitrary(g); + let neg2 = if val.is_zero() { false } else { neg }; + $sname{ negative: neg2, value: val } + } + } + impl fmt::Debug for $sname { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if self.negative { diff --git a/src/signed/mod.rs b/src/signed/mod.rs index 37cf770..14b90e8 100644 --- a/src/signed/mod.rs +++ b/src/signed/mod.rs @@ -26,6 +26,8 @@ mod shift; #[macro_use] mod subtraction; +#[cfg(test)] +use quickcheck::{Arbitrary,Gen}; use std::cmp::{Ord,Ordering,PartialOrd}; use std::fmt; use std::ops::{Add,AddAssign};