From a595eb349df64b7807d73c5b20f796f8beb19555 Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Sat, 24 Mar 2018 16:00:02 -0700 Subject: [PATCH] Negation. --- src/cryptonum/mod.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/cryptonum/mod.rs b/src/cryptonum/mod.rs index 4dff616..c7bf5b0 100644 --- a/src/cryptonum/mod.rs +++ b/src/cryptonum/mod.rs @@ -3,6 +3,7 @@ mod conversions; use num::{BigUint,ToPrimitive,Zero}; use std::cmp::Ordering; +use std::ops::*; /// In case you were wondering, it stands for "Unsigned Crypto Num". #[derive(Clone,Debug,PartialEq,Eq)] @@ -109,6 +110,27 @@ impl Ord for UCN { } } +//------------------------------------------------------------------------------ +// +// Bit Operations +// +//------------------------------------------------------------------------------ + +impl Not for UCN { + type Output = UCN; + + fn not(self) -> UCN { + let mut contents = self.contents; + + for x in contents.iter_mut() { + *x = !*x; + } + + let mut res = UCN{ contents: contents }; + res.clean(); + res + } +} //------------------------------------------------------------------------------ // @@ -207,4 +229,35 @@ mod test { (&val == ©) && (val.cmp(©) == Ordering::Equal) } } + + impl Arbitrary for UCN { + fn arbitrary(g: &mut G) -> UCN { + let lenopts = [4,8,16,32,48,64,112,128,240]; + let mut len = *g.choose(&lenopts).unwrap(); + let mut contents = Vec::with_capacity(len); + + while len > 0 { + contents.push(g.gen()); + len -= 1; + } + UCN{ contents: contents } + } + } + + fn expand_to_match(a: &mut UCN, b: &UCN) { + assert!(a.contents.len() <= b.contents.len()); + while a.contents.len() < b.contents.len() { + a.contents.push(0); + } + } + + quickcheck! { + fn double_negation(x: UCN) -> bool { + let mut x2 = x.clone().not(); + expand_to_match(&mut x2, &x); + let mut x3 = x2.not(); + expand_to_match(&mut x3, &x); + x3 == x + } + } }