Cleaner (?) implementation of signed numbers.
This commit is contained in:
@@ -1,3 +1,293 @@
|
|||||||
|
macro_rules! construct_signed {
|
||||||
|
($type: ident, $base: ident, $modname: ident) => {
|
||||||
|
pub struct $type {
|
||||||
|
negative: bool,
|
||||||
|
value: $base
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for $type {
|
||||||
|
fn clone(&self) -> $type {
|
||||||
|
$type{ negative: self.negative, value: self.value.clone() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> PartialEq<&'a $type> for $type {
|
||||||
|
fn eq(&self, other: &&$type) -> bool {
|
||||||
|
(self.negative == other.negative) &&
|
||||||
|
(self.value == other.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for $type {
|
||||||
|
fn eq(&self, other: &$type) -> bool {
|
||||||
|
(self.negative == other.negative) &&
|
||||||
|
(self.value == other.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for $type {}
|
||||||
|
|
||||||
|
impl Debug for $type {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> Result<(),Error> {
|
||||||
|
if self.negative {
|
||||||
|
f.write_str("-")?;
|
||||||
|
} else {
|
||||||
|
f.write_str("+")?;
|
||||||
|
}
|
||||||
|
self.value.fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for $type {
|
||||||
|
fn partial_cmp(&self, other: &$type) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for $type {
|
||||||
|
fn cmp(&self, other: &$type) -> Ordering {
|
||||||
|
match (self.negative, other.negative) {
|
||||||
|
(true, true) =>
|
||||||
|
self.value.cmp(&other.value).reverse(),
|
||||||
|
(true, false) => Ordering::Greater,
|
||||||
|
(false, true) => Ordering::Less,
|
||||||
|
(false, false) =>
|
||||||
|
self.value.cmp(&other.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CryptoNumBase for $type {
|
||||||
|
fn zero() -> $type {
|
||||||
|
$type{ negative: false, value: $base::zero() }
|
||||||
|
}
|
||||||
|
fn max_value() -> $type {
|
||||||
|
$type{ negative: false, value: $base::max_value() }
|
||||||
|
}
|
||||||
|
fn is_zero(&self) -> bool {
|
||||||
|
self.value.is_zero()
|
||||||
|
}
|
||||||
|
fn is_odd(&self) -> bool {
|
||||||
|
self.value.is_odd()
|
||||||
|
}
|
||||||
|
fn is_even(&self) -> bool {
|
||||||
|
self.value.is_even()
|
||||||
|
}
|
||||||
|
fn from_u8(x: u8) -> $type {
|
||||||
|
$type{ negative: false, value: $base::from_u8(x) }
|
||||||
|
}
|
||||||
|
fn to_u8(&self) -> u8 {
|
||||||
|
self.value.to_u8()
|
||||||
|
}
|
||||||
|
fn from_u16(x: u16) -> $type {
|
||||||
|
$type{ negative: false, value: $base::from_u16(x) }
|
||||||
|
}
|
||||||
|
fn to_u16(&self) -> u16 {
|
||||||
|
self.value.to_u16()
|
||||||
|
}
|
||||||
|
fn from_u32(x: u32) -> $type {
|
||||||
|
$type{ negative: false, value: $base::from_u32(x) }
|
||||||
|
}
|
||||||
|
fn to_u32(&self) -> u32 {
|
||||||
|
self.value.to_u32()
|
||||||
|
}
|
||||||
|
fn from_u64(x: u64) -> $type {
|
||||||
|
$type{ negative: false, value: $base::from_u64(x) }
|
||||||
|
}
|
||||||
|
fn to_u64(&self) -> u64 {
|
||||||
|
self.value.to_u64()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CryptoNumFastMod for $type {
|
||||||
|
type BarrettMu = <$base as CryptoNumFastMod>::BarrettMu;
|
||||||
|
|
||||||
|
fn barrett_mu(&self) -> Option<Self::BarrettMu> {
|
||||||
|
if self.negative {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
self.value.barrett_mu()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fastmod(&self, mu: &Self::BarrettMu) -> $type {
|
||||||
|
let res = self.value.fastmod(mu);
|
||||||
|
$type{ negative: self.negative, value: res }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CryptoNumSigned for $type {
|
||||||
|
type Unsigned = $base;
|
||||||
|
|
||||||
|
fn new(v: $base) -> $type {
|
||||||
|
$type{ negative: false, value: v.clone() }
|
||||||
|
}
|
||||||
|
fn abs(&self) -> $base {
|
||||||
|
self.value.clone()
|
||||||
|
}
|
||||||
|
fn is_positive(&self) -> bool {
|
||||||
|
!self.negative
|
||||||
|
}
|
||||||
|
fn is_negative(&self) -> bool {
|
||||||
|
self.negative
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Neg for $type {
|
||||||
|
type Output = $type;
|
||||||
|
|
||||||
|
fn neg(self) -> $type {
|
||||||
|
(&self).neg()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Neg for &'a $type {
|
||||||
|
type Output = $type;
|
||||||
|
|
||||||
|
fn neg(self) -> $type {
|
||||||
|
if self.value.is_zero() {
|
||||||
|
$type{ negative: false, value: self.value.clone() }
|
||||||
|
} else {
|
||||||
|
$type{ negative: !self.negative, value: self.value.clone() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> AddAssign<&'a $type> for $type {
|
||||||
|
fn add_assign(&mut self, other: &$type) {
|
||||||
|
let signs_match = self.negative == other.negative;
|
||||||
|
let ordering = self.value.cmp(&other.value);
|
||||||
|
|
||||||
|
match (signs_match, ordering) {
|
||||||
|
(true, _) =>
|
||||||
|
// if the signs are the same, we maintain the sign and
|
||||||
|
// just increase the magnitude
|
||||||
|
self.value.add_assign(&other.value),
|
||||||
|
(false, Ordering::Equal) => {
|
||||||
|
// if the signs are different and the numbers are equal,
|
||||||
|
// we just set this to zero. However, we actually do the
|
||||||
|
// subtraction to make the timing roughly similar.
|
||||||
|
self.negative = false;
|
||||||
|
self.value.sub_assign(&other.value)
|
||||||
|
}
|
||||||
|
(false, Ordering::Less) => {
|
||||||
|
// if the signs are different and the first one is less
|
||||||
|
// than the second, then we flip the sign and subtract.
|
||||||
|
self.negative = !self.negative;
|
||||||
|
let mut other_copy = other.value.clone();
|
||||||
|
other_copy.sub_assign(&self.value);
|
||||||
|
self.value = other_copy;
|
||||||
|
}
|
||||||
|
(false, Ordering::Greater) => {
|
||||||
|
// if the signs are different and the first one is
|
||||||
|
// greater than the second, then we leave the sign and
|
||||||
|
// subtract.
|
||||||
|
self.value.sub_assign(&other.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> SubAssign<&'a $type> for $type {
|
||||||
|
fn sub_assign(&mut self, other: &$type) {
|
||||||
|
// this is a bit inefficient, but a heck of a lot easier.
|
||||||
|
let mut other2 = other.clone();
|
||||||
|
other2.negative = !other2.negative;
|
||||||
|
self.add_assign(&other2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> MulAssign<&'a $type> for $type {
|
||||||
|
fn mul_assign(&mut self, other: &$type) {
|
||||||
|
self.negative = self.negative ^ other.negative;
|
||||||
|
self.value.mul_assign(&other.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DivAssign<&'a $type> for $type {
|
||||||
|
fn div_assign(&mut self, other: &$type) {
|
||||||
|
self.negative = self.negative ^ other.negative;
|
||||||
|
self.value.div_assign(&other.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> RemAssign<&'a $type> for $type {
|
||||||
|
fn rem_assign(&mut self, other: &$type) {
|
||||||
|
self.value.rem_assign(&other.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
derive_operators!($type,Add,add,AddAssign,add_assign);
|
||||||
|
derive_operators!($type,Sub,sub,SubAssign,sub_assign);
|
||||||
|
derive_operators!($type,Mul,mul,MulAssign,mul_assign);
|
||||||
|
derive_operators!($type,Div,div,DivAssign,div_assign);
|
||||||
|
derive_operators!($type,Rem,rem,RemAssign,rem_assign);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod $modname {
|
||||||
|
use quickcheck::{Arbitrary,Gen};
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl Arbitrary for $type {
|
||||||
|
fn arbitrary<G: Gen>(g: &mut G) -> $type {
|
||||||
|
let value = $base::arbitrary(g);
|
||||||
|
if value.is_zero() {
|
||||||
|
$type{ negative: false, value: value }
|
||||||
|
} else {
|
||||||
|
$type{ negative: g.gen_weighted_bool(2), value: value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quickcheck! {
|
||||||
|
fn double_negation(x: $type) -> bool {
|
||||||
|
(- (- &x)) == &x
|
||||||
|
}
|
||||||
|
fn add_identity(x: $type) -> bool {
|
||||||
|
(&x + $type::zero()) == &x
|
||||||
|
}
|
||||||
|
fn add_commutivity(x: $type, y: $type) -> bool {
|
||||||
|
(&x + &y) == (&y + &x)
|
||||||
|
}
|
||||||
|
fn add_associativity(a: $type, b: $type, c: $type) -> bool {
|
||||||
|
// we shift these to get away from rollover
|
||||||
|
let x = $type{ negative: a.negative, value: a.value >> 2 };
|
||||||
|
let y = $type{ negative: b.negative, value: b.value >> 2 };
|
||||||
|
let z = $type{ negative: c.negative, value: c.value >> 2 };
|
||||||
|
(&x + (&y + &z)) == ((&x + &y) + &z)
|
||||||
|
}
|
||||||
|
fn sub_is_add_negation(x: $type, y: $type) -> bool {
|
||||||
|
(&x - &y) == (&x + (- &y))
|
||||||
|
}
|
||||||
|
fn sub_destroys(x: $type) -> bool {
|
||||||
|
(&x - &x) == $type::zero()
|
||||||
|
}
|
||||||
|
fn mul_identity(x: $type) -> bool {
|
||||||
|
(&x * $type::from_u8(1)) == &x
|
||||||
|
}
|
||||||
|
fn mul_commutivity(x: $type, y: $type) -> bool {
|
||||||
|
(&x * &y) == (&y * &x)
|
||||||
|
}
|
||||||
|
fn mul_associativity(a: $type, b: $type, c: $type) -> bool {
|
||||||
|
// we shift these to get away from rollover
|
||||||
|
let s = (a.value.bit_size() / 2) - 2;
|
||||||
|
let x = $type{ negative: a.negative, value: a.value >> s };
|
||||||
|
let y = $type{ negative: b.negative, value: b.value >> s };
|
||||||
|
let z = $type{ negative: c.negative, value: c.value >> s };
|
||||||
|
(&x * (&y * &z)) == ((&x * &y) * &z)
|
||||||
|
}
|
||||||
|
#[ignore]
|
||||||
|
fn div_identity(a: $type) -> bool {
|
||||||
|
&a / $type::from_u64(1) == a
|
||||||
|
}
|
||||||
|
fn div_self_is_one(a: $type) -> bool {
|
||||||
|
(&a / &a) == $type::from_u64(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! construct_unsigned {
|
macro_rules! construct_unsigned {
|
||||||
($type: ident, $barrett: ident, $modname: ident, $count: expr) => {
|
($type: ident, $barrett: ident, $modname: ident, $count: expr) => {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -75,9 +365,12 @@ macro_rules! construct_unsigned {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opers2!($type,BitOrAssign,bitor_assign,BitOr,bitor,generic_bitor);
|
generic_2arg!($type, BitOrAssign, bitor_assign, generic_bitor);
|
||||||
opers2!($type,BitAndAssign,bitand_assign,BitAnd,bitand,generic_bitand);
|
generic_2arg!($type, BitAndAssign, bitand_assign, generic_bitand);
|
||||||
opers2!($type,BitXorAssign,bitxor_assign,BitXor,bitxor,generic_bitxor);
|
generic_2arg!($type, BitXorAssign, bitxor_assign, generic_bitxor);
|
||||||
|
generic_2arg!($type, AddAssign, add_assign, generic_add);
|
||||||
|
generic_2arg!($type, SubAssign, sub_assign, generic_sub);
|
||||||
|
generic_3arg!($type, MulAssign, mul_assign, generic_mul);
|
||||||
|
|
||||||
shifts!($type, usize);
|
shifts!($type, usize);
|
||||||
shifts!($type, u64);
|
shifts!($type, u64);
|
||||||
@@ -89,19 +382,6 @@ macro_rules! construct_unsigned {
|
|||||||
shifts!($type, u8);
|
shifts!($type, u8);
|
||||||
shifts!($type, i8);
|
shifts!($type, i8);
|
||||||
|
|
||||||
opers2!($type,AddAssign,add_assign,Add,add,generic_add);
|
|
||||||
opers2!($type,SubAssign,sub_assign,Sub,sub,generic_sub);
|
|
||||||
opers3!($type,MulAssign,mul_assign,Mul,mul,generic_mul);
|
|
||||||
|
|
||||||
impl DivAssign<$type> for $type {
|
|
||||||
fn div_assign(&mut self, rhs: $type) {
|
|
||||||
let mut dead = [0; $count];
|
|
||||||
let copy = self.contents.clone();
|
|
||||||
generic_div(©, &rhs.contents,
|
|
||||||
&mut self.contents, &mut dead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> DivAssign<&'a $type> for $type {
|
impl<'a> DivAssign<&'a $type> for $type {
|
||||||
fn div_assign(&mut self, rhs: &$type) {
|
fn div_assign(&mut self, rhs: &$type) {
|
||||||
let mut dead = [0; $count];
|
let mut dead = [0; $count];
|
||||||
@@ -111,63 +391,6 @@ macro_rules! construct_unsigned {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Div<$type> for $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn div(self, rhs: $type) -> $type {
|
|
||||||
let mut res = $type::zero();
|
|
||||||
let mut dead = [0; $count];
|
|
||||||
generic_div(&self.contents, &rhs.contents,
|
|
||||||
&mut res.contents, &mut dead);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Div<$type> for &'a $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn div(self, rhs: $type) -> $type {
|
|
||||||
let mut res = $type::zero();
|
|
||||||
let mut dead = [0; $count];
|
|
||||||
generic_div(&self.contents, &rhs.contents,
|
|
||||||
&mut res.contents, &mut dead);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Div<&'a $type> for $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn div(self, rhs: &$type) -> $type {
|
|
||||||
let mut res = $type::zero();
|
|
||||||
let mut dead = [0; $count];
|
|
||||||
generic_div(&self.contents, &rhs.contents,
|
|
||||||
&mut res.contents, &mut dead);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a,'b> Div<&'a $type> for &'b $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn div(self, rhs: &$type) -> $type {
|
|
||||||
let mut res = $type::zero();
|
|
||||||
let mut dead = [0; $count];
|
|
||||||
generic_div(&self.contents, &rhs.contents,
|
|
||||||
&mut res.contents, &mut dead);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RemAssign<$type> for $type {
|
|
||||||
fn rem_assign(&mut self, rhs: $type) {
|
|
||||||
let mut dead = [0; $count];
|
|
||||||
let copy = self.contents.clone();
|
|
||||||
generic_div(©, &rhs.contents,
|
|
||||||
&mut dead, &mut self.contents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> RemAssign<&'a $type> for $type {
|
impl<'a> RemAssign<&'a $type> for $type {
|
||||||
fn rem_assign(&mut self, rhs: &$type) {
|
fn rem_assign(&mut self, rhs: &$type) {
|
||||||
let mut dead = [0; $count];
|
let mut dead = [0; $count];
|
||||||
@@ -177,53 +400,14 @@ macro_rules! construct_unsigned {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Rem<$type> for $type {
|
derive_operators!($type, BitOr, bitor, BitOrAssign, bitor_assign);
|
||||||
type Output = $type;
|
derive_operators!($type, BitAnd, bitand, BitAndAssign, bitand_assign);
|
||||||
|
derive_operators!($type, BitXor, bitxor, BitXorAssign, bitxor_assign);
|
||||||
fn rem(self, rhs: $type) -> $type {
|
derive_operators!($type, Add, add, AddAssign, add_assign);
|
||||||
let mut res = $type::zero();
|
derive_operators!($type, Sub, sub, SubAssign, sub_assign);
|
||||||
let mut dead = [0; $count];
|
derive_operators!($type, Mul, mul, MulAssign, mul_assign);
|
||||||
generic_div(&self.contents, &rhs.contents,
|
derive_operators!($type, Div, div, DivAssign, div_assign);
|
||||||
&mut dead, &mut res.contents);
|
derive_operators!($type, Rem, rem, RemAssign, rem_assign);
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Rem<$type> for &'a $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn rem(self, rhs: $type) -> $type {
|
|
||||||
let mut res = $type::zero();
|
|
||||||
let mut dead = [0; $count];
|
|
||||||
generic_div(&self.contents, &rhs.contents,
|
|
||||||
&mut dead, &mut res.contents);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Rem<&'a $type> for $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn rem(self, rhs: &$type) -> $type {
|
|
||||||
let mut res = $type::zero();
|
|
||||||
let mut dead = [0; $count];
|
|
||||||
generic_div(&self.contents, &rhs.contents,
|
|
||||||
&mut dead, &mut res.contents);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a,'b> Rem<&'a $type> for &'b $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn rem(self, rhs: &$type) -> $type {
|
|
||||||
let mut res = $type::zero();
|
|
||||||
let mut dead = [0; $count];
|
|
||||||
generic_div(&self.contents, &rhs.contents,
|
|
||||||
&mut dead, &mut res.contents);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CryptoNumBase for $type {
|
impl CryptoNumBase for $type {
|
||||||
fn zero() -> $type {
|
fn zero() -> $type {
|
||||||
@@ -879,188 +1063,74 @@ macro_rules! shifts {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! opers2 {
|
macro_rules! generic_2arg {
|
||||||
($type:ident,$asncl:ident,$asnfn:ident,$cl:ident,$fn:ident,$impl:ident) => {
|
($type: ident, $asncl: ident, $asnfn: ident, $impl: ident) => {
|
||||||
impl $asncl for $type {
|
|
||||||
fn $asnfn(&mut self, other: $type) {
|
|
||||||
$impl(&mut self.contents, &other.contents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> $asncl<&'a $type> for $type {
|
impl<'a> $asncl<&'a $type> for $type {
|
||||||
fn $asnfn(&mut self, other: &$type) {
|
fn $asnfn(&mut self, other: &$type) {
|
||||||
$impl(&mut self.contents, &other.contents);
|
$impl(&mut self.contents, &other.contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $cl for $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn $fn(self, rhs: $type) -> $type {
|
|
||||||
let mut copy = self.clone();
|
|
||||||
$impl(&mut copy.contents, &rhs.contents);
|
|
||||||
copy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> $cl<&'a $type> for $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn $fn(self, rhs: &$type) -> $type {
|
|
||||||
let mut copy = self.clone();
|
|
||||||
$impl(&mut copy.contents, &rhs.contents);
|
|
||||||
copy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> $cl<$type> for &'a $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn $fn(self, rhs: $type) -> $type {
|
|
||||||
let mut copy = self.clone();
|
|
||||||
$impl(&mut copy.contents, &rhs.contents);
|
|
||||||
copy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a,'b> $cl<&'a $type> for &'b $type {
|
|
||||||
type Output = $type;
|
|
||||||
|
|
||||||
fn $fn(self, rhs: &$type) -> $type {
|
|
||||||
let mut copy = self.clone();
|
|
||||||
$impl(&mut copy.contents, &rhs.contents);
|
|
||||||
copy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! opers3 {
|
macro_rules! generic_3arg {
|
||||||
($type:ident,$asncl:ident,$asnfn:ident,$cl:ident,$fn:ident,$impl:ident) => {
|
($type: ident, $asncl: ident, $asnfn: ident, $impl: ident) => {
|
||||||
impl $asncl for $type {
|
|
||||||
fn $asnfn(&mut self, other: $type) {
|
|
||||||
let copy = self.contents.clone();
|
|
||||||
$impl(&mut self.contents, ©, &other.contents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> $asncl<&'a $type> for $type {
|
impl<'a> $asncl<&'a $type> for $type {
|
||||||
fn $asnfn(&mut self, other: &$type) {
|
fn $asnfn(&mut self, other: &$type) {
|
||||||
let copy = self.contents.clone();
|
let copy = self.contents.clone();
|
||||||
$impl(&mut self.contents, ©, &other.contents);
|
$impl(&mut self.contents, ©, &other.contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! derive_operators
|
||||||
|
{
|
||||||
|
($type: ident, $cl: ident, $fn: ident, $asncl: ident, $asnfn: ident) => {
|
||||||
|
impl $asncl for $type {
|
||||||
|
fn $asnfn(&mut self, other: $type) {
|
||||||
|
self.$asnfn(&other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl $cl for $type {
|
impl $cl for $type {
|
||||||
type Output = $type;
|
type Output = $type;
|
||||||
|
|
||||||
fn $fn(self, rhs: $type) -> $type {
|
fn $fn(self, other: $type) -> $type {
|
||||||
let mut copy = self.clone();
|
let mut res = self.clone();
|
||||||
$impl(&mut copy.contents, &self.contents, &rhs.contents);
|
res.$asnfn(&other);
|
||||||
copy
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> $cl<&'a $type> for $type {
|
impl<'a> $cl<&'a $type> for $type {
|
||||||
type Output = $type;
|
type Output = $type;
|
||||||
|
|
||||||
fn $fn(self, rhs: &$type) -> $type {
|
fn $fn(self, other: &$type) -> $type {
|
||||||
let mut copy = self.clone();
|
let mut res = self.clone();
|
||||||
$impl(&mut copy.contents, &self.contents, &rhs.contents);
|
res.$asnfn(other);
|
||||||
copy
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> $cl<$type> for &'a $type {
|
impl<'a> $cl<$type> for &'a $type {
|
||||||
type Output = $type;
|
type Output = $type;
|
||||||
|
|
||||||
fn $fn(self, rhs: $type) -> $type {
|
fn $fn(self, other: $type) -> $type {
|
||||||
let mut copy = self.clone();
|
let mut res = self.clone();
|
||||||
$impl(&mut copy.contents, &self.contents, &rhs.contents);
|
res.$asnfn(&other);
|
||||||
copy
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a,'b> $cl<&'a $type> for &'b $type {
|
impl<'a,'b> $cl<&'a $type> for &'b $type {
|
||||||
type Output = $type;
|
type Output = $type;
|
||||||
|
|
||||||
fn $fn(self, rhs: &$type) -> $type {
|
fn $fn(self, other: &$type) -> $type {
|
||||||
let mut copy = self.clone();
|
|
||||||
$impl(&mut copy.contents, &self.contents, &rhs.contents);
|
|
||||||
copy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! math_operator {
|
|
||||||
($cl: ident, $fn: ident, $asn: ident) => {
|
|
||||||
impl<T> $cl for Signed<T>
|
|
||||||
where
|
|
||||||
T: Clone + Ord,
|
|
||||||
T: AddAssign + SubAssign + MulAssign + DivAssign,
|
|
||||||
{
|
|
||||||
type Output = Signed<T>;
|
|
||||||
|
|
||||||
fn $fn(self, rhs: Signed<T>) -> Signed<T>
|
|
||||||
{
|
|
||||||
let mut res = self.clone();
|
let mut res = self.clone();
|
||||||
res.$asn(rhs);
|
res.$asnfn(other);
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a,T> $cl<&'a Signed<T>> for Signed<T>
|
|
||||||
where
|
|
||||||
T: Clone + Ord,
|
|
||||||
T: AddAssign + SubAssign + MulAssign + DivAssign,
|
|
||||||
T: AddAssign<&'a T> + SubAssign<&'a T>,
|
|
||||||
T: MulAssign<&'a T> + DivAssign<&'a T>
|
|
||||||
{
|
|
||||||
type Output = Signed<T>;
|
|
||||||
|
|
||||||
fn $fn(self, rhs: &'a Signed<T>) -> Signed<T>
|
|
||||||
{
|
|
||||||
let mut res = self.clone();
|
|
||||||
res.$asn(rhs);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a,T> $cl for &'a Signed<T>
|
|
||||||
where
|
|
||||||
T: Clone + Ord,
|
|
||||||
T: AddAssign + SubAssign + MulAssign + DivAssign,
|
|
||||||
T: AddAssign<&'a T> + SubAssign<&'a T>,
|
|
||||||
T: MulAssign<&'a T> + DivAssign<&'a T>
|
|
||||||
{
|
|
||||||
type Output = Signed<T>;
|
|
||||||
|
|
||||||
fn $fn(self, rhs: &'a Signed<T>) -> Signed<T>
|
|
||||||
{
|
|
||||||
let mut res = self.clone();
|
|
||||||
res.$asn(rhs);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a,T> $cl<Signed<T>> for &'a Signed<T>
|
|
||||||
where
|
|
||||||
T: Clone + Ord,
|
|
||||||
T: AddAssign + SubAssign + MulAssign + DivAssign,
|
|
||||||
T: AddAssign<&'a T> + SubAssign<&'a T>,
|
|
||||||
T: MulAssign<&'a T> + DivAssign<&'a T>
|
|
||||||
{
|
|
||||||
type Output = Signed<T>;
|
|
||||||
|
|
||||||
fn $fn(self, rhs: Signed<T>) -> Signed<T>
|
|
||||||
{
|
|
||||||
let mut res = self.clone();
|
|
||||||
res.$asn(rhs);
|
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,443 +1,15 @@
|
|||||||
|
use cryptonum::core::*;
|
||||||
use cryptonum::traits::*;
|
use cryptonum::traits::*;
|
||||||
use cryptonum::unsigned::*;
|
use cryptonum::unsigned::*;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::fmt::{Debug,Error,Formatter};
|
||||||
|
use std::ops::*;
|
||||||
|
|
||||||
pub struct I512 {
|
construct_signed!(I512, U512, i512);
|
||||||
negative: bool,
|
construct_signed!(I1024, U1024, i1024);
|
||||||
value: U512
|
construct_signed!(I2048, U2048, i2048);
|
||||||
}
|
construct_signed!(I3072, U3072, i3072);
|
||||||
|
construct_signed!(I4096, U4096, i4096);
|
||||||
|
construct_signed!(I7680, U7680, i7680);
|
||||||
//use cryptonum::traits::*;
|
construct_signed!(I8192, U8192, i8192);
|
||||||
//use std::cmp::Ordering;
|
construct_signed!(I15360, U15360, i15360);
|
||||||
//use std::fmt::{Debug,Error,Formatter};
|
|
||||||
//use std::ops::*;
|
|
||||||
//
|
|
||||||
//pub struct Signed<T: Sized>
|
|
||||||
// where T: Clone + CryptoNumBase + Sized
|
|
||||||
//{
|
|
||||||
// positive: bool,
|
|
||||||
// value: T
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<T> Signed<T>
|
|
||||||
// where T: Clone + CryptoNumBase + Sized
|
|
||||||
//{
|
|
||||||
// pub fn new(v: T) -> Signed<T> {
|
|
||||||
// Signed{ positive: true, value: v }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// pub fn abs(&self) -> T
|
|
||||||
// {
|
|
||||||
// self.value.clone()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// pub fn is_positive(&self) -> bool
|
|
||||||
// {
|
|
||||||
// self.positive && !self.value.is_zero()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// pub fn is_negative(&self) -> bool
|
|
||||||
// {
|
|
||||||
// !self.positive && !self.value.is_zero()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// pub fn negate(&mut self)
|
|
||||||
// {
|
|
||||||
// self.positive = !self.positive;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<T> CryptoNumBase for Signed<T>
|
|
||||||
// where T: Clone + CryptoNumBase + Sized
|
|
||||||
//{
|
|
||||||
// fn zero() -> Signed<T> {
|
|
||||||
// Signed{ positive: true, value: T::zero() }
|
|
||||||
// }
|
|
||||||
// fn max_value() -> Signed<T> {
|
|
||||||
// Signed{ positive: true, value: T::max_value() }
|
|
||||||
// }
|
|
||||||
// fn is_zero(&self) -> bool {
|
|
||||||
// self.value.is_zero()
|
|
||||||
// }
|
|
||||||
// fn is_odd(&self) -> bool {
|
|
||||||
// self.value.is_odd()
|
|
||||||
// }
|
|
||||||
// fn is_even(&self) -> bool {
|
|
||||||
// self.value.is_even()
|
|
||||||
// }
|
|
||||||
// fn from_u8(x: u8) -> Signed<T> {
|
|
||||||
// Signed{ positive: true, value: T::from_u8(x) }
|
|
||||||
// }
|
|
||||||
// fn to_u8(&self) -> u8 {
|
|
||||||
// self.value.to_u8()
|
|
||||||
// }
|
|
||||||
// fn from_u16(x: u16) -> Signed<T> {
|
|
||||||
// Signed{ positive: true, value: T::from_u16(x) }
|
|
||||||
// }
|
|
||||||
// fn to_u16(&self) -> u16 {
|
|
||||||
// self.value.to_u16()
|
|
||||||
// }
|
|
||||||
// fn from_u32(x: u32) -> Signed<T> {
|
|
||||||
// Signed{ positive: true, value: T::from_u32(x) }
|
|
||||||
// }
|
|
||||||
// fn to_u32(&self) -> u32 {
|
|
||||||
// self.value.to_u32()
|
|
||||||
// }
|
|
||||||
// fn from_u64(x: u64) -> Signed<T> {
|
|
||||||
// Signed{ positive: true, value: T::from_u64(x) }
|
|
||||||
// }
|
|
||||||
// fn to_u64(&self) -> u64 {
|
|
||||||
// self.value.to_u64()
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<T: CryptoNumFastMod> CryptoNumFastMod for Signed<T> {
|
|
||||||
// type BarrettMu = T::BarrettMu;
|
|
||||||
//
|
|
||||||
// fn barrett_mu(&self) -> Option<T::BarrettMu> {
|
|
||||||
// if self.positive {
|
|
||||||
// self.value.barrett_mu()
|
|
||||||
// } else {
|
|
||||||
// None
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// fn fastmod(&self, mu: &T::BarrettMu) -> Signed<T> {
|
|
||||||
// Signed{ positive: self.positive, value: self.value.fastmod(&mu) }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<T: Clone> Clone for Signed<T> {
|
|
||||||
// fn clone(&self) -> Signed<T> {
|
|
||||||
// Signed{ positive: self.positive, value: self.value.clone() }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
//impl<'a,T: PartialEq> PartialEq<&'a Signed<T>> for Signed<T> {
|
|
||||||
// fn eq(&self, other: &&Signed<T>) -> bool {
|
|
||||||
// (self.positive == other.positive) && (self.value == other.value)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<'a,T: PartialEq> PartialEq<Signed<T>> for &'a Signed<T> {
|
|
||||||
// fn eq(&self, other: &Signed<T>) -> bool {
|
|
||||||
// (self.positive == other.positive) && (self.value == other.value)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<T: PartialEq> PartialEq for Signed<T> {
|
|
||||||
// fn eq(&self, other: &Signed<T>) -> bool {
|
|
||||||
// (self.positive == other.positive) && (self.value == other.value)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<T: Eq> Eq for Signed<T> {}
|
|
||||||
//
|
|
||||||
//impl<T: Debug> Debug for Signed<T> {
|
|
||||||
// fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
|
||||||
// if self.positive {
|
|
||||||
// f.write_str("+")?;
|
|
||||||
// } else {
|
|
||||||
// f.write_str("-")?;
|
|
||||||
// }
|
|
||||||
// self.value.fmt(f)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<T: Ord> Ord for Signed<T> {
|
|
||||||
// fn cmp(&self, other: &Signed<T>) -> Ordering {
|
|
||||||
// match (self.positive, other.positive) {
|
|
||||||
// (true, true) => self.value.cmp(&other.value),
|
|
||||||
// (true, false) => Ordering::Greater,
|
|
||||||
// (false, true) => Ordering::Less,
|
|
||||||
// (false, false) =>
|
|
||||||
// self.value.cmp(&other.value).reverse()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<T: Ord> PartialOrd for Signed<T> {
|
|
||||||
// fn partial_cmp(&self, other: &Signed<T>) -> Option<Ordering>{
|
|
||||||
// Some(self.cmp(other))
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//impl<T: Clone> Neg for Signed<T> {
|
|
||||||
// type Output = Signed<T>;
|
|
||||||
//
|
|
||||||
// fn neg(self) -> Signed<T> {
|
|
||||||
// Signed {
|
|
||||||
// positive: !self.positive,
|
|
||||||
// value: self.value.clone()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<'a,T: Clone> Neg for &'a Signed<T> {
|
|
||||||
// type Output = Signed<T>;
|
|
||||||
//
|
|
||||||
// fn neg(self) -> Signed<T> {
|
|
||||||
// Signed {
|
|
||||||
// positive: !self.positive,
|
|
||||||
// value: self.value.clone()
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//impl<T> AddAssign for Signed<T>
|
|
||||||
// where
|
|
||||||
// T: Clone + Ord,
|
|
||||||
// T: AddAssign + SubAssign,
|
|
||||||
//{
|
|
||||||
// fn add_assign(&mut self, other: Signed<T>) {
|
|
||||||
// match (self.positive, other.positive, self.value.cmp(&other.value)) {
|
|
||||||
// // if the signs are the same, we maintain the sign and just increase
|
|
||||||
// // the magnitude
|
|
||||||
// (x, y, _) if x == y =>
|
|
||||||
// self.value.add_assign(other.value),
|
|
||||||
// // if the signs are different and the numbers are equal, we just set
|
|
||||||
// // this to zero. However, we actually do the subtraction to make the
|
|
||||||
// // timing roughly similar.
|
|
||||||
// (_, _, Ordering::Equal) => {
|
|
||||||
// self.positive = true;
|
|
||||||
// self.value.sub_assign(other.value);
|
|
||||||
// }
|
|
||||||
// // if the signs are different and the first one is less than the
|
|
||||||
// // second, then we flip the sign and subtract.
|
|
||||||
// (_, _, Ordering::Less) => {
|
|
||||||
// self.positive = !self.positive;
|
|
||||||
// let temp = self.value.clone();
|
|
||||||
// self.value = other.value.clone();
|
|
||||||
// self.value.sub_assign(temp);
|
|
||||||
// }
|
|
||||||
// // if the signs are different and the first one is greater than the
|
|
||||||
// // second, then we leave the sign and subtract.
|
|
||||||
// (_, _, Ordering::Greater) => {
|
|
||||||
// self.value.sub_assign(other.value);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<'a,T> AddAssign<&'a Signed<T>> for Signed<T>
|
|
||||||
// where
|
|
||||||
// T: Clone + Ord,
|
|
||||||
// T: AddAssign + SubAssign,
|
|
||||||
// T: AddAssign<&'a T> + SubAssign<&'a T>
|
|
||||||
//{
|
|
||||||
// fn add_assign(&mut self, other: &'a Signed<T>) {
|
|
||||||
// match (self.positive, other.positive, self.value.cmp(&other.value)) {
|
|
||||||
// // if the signs are the same, we maintain the sign and just increase
|
|
||||||
// // the magnitude
|
|
||||||
// (x, y, _) if x == y =>
|
|
||||||
// self.value.add_assign(&other.value),
|
|
||||||
// // if the signs are different and the numbers are equal, we just set
|
|
||||||
// // this to zero. However, we actually do the subtraction to make the
|
|
||||||
// // timing roughly similar.
|
|
||||||
// (_, _, Ordering::Equal) => {
|
|
||||||
// self.positive = true;
|
|
||||||
// self.value.sub_assign(&other.value);
|
|
||||||
// }
|
|
||||||
// // if the signs are different and the first one is less than the
|
|
||||||
// // second, then we flip the sign and subtract.
|
|
||||||
// (_, _, Ordering::Less) => {
|
|
||||||
// self.positive = !self.positive;
|
|
||||||
// let temp = self.value.clone();
|
|
||||||
// self.value = other.value.clone();
|
|
||||||
// self.value.sub_assign(temp);
|
|
||||||
// }
|
|
||||||
// // if the signs are different and the first one is greater than the
|
|
||||||
// // second, then we leave the sign and subtract.
|
|
||||||
// (_, _, Ordering::Greater) => {
|
|
||||||
// self.value.sub_assign(&other.value);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//math_operator!(Add,add,add_assign);
|
|
||||||
//
|
|
||||||
////------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//impl<T> SubAssign for Signed<T>
|
|
||||||
// where
|
|
||||||
// T: Clone + Ord,
|
|
||||||
// T: AddAssign + SubAssign,
|
|
||||||
//{
|
|
||||||
// fn sub_assign(&mut self, other: Signed<T>) {
|
|
||||||
// let mut other2 = other.clone();
|
|
||||||
// other2.positive = !other.positive;
|
|
||||||
// self.add_assign(other2);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<'a,T> SubAssign<&'a Signed<T>> for Signed<T>
|
|
||||||
// where
|
|
||||||
// T: Clone + Ord,
|
|
||||||
// T: AddAssign + SubAssign,
|
|
||||||
// T: AddAssign<&'a T> + SubAssign<&'a T>
|
|
||||||
//{
|
|
||||||
// fn sub_assign(&mut self, other: &'a Signed<T>) {
|
|
||||||
// let mut other2 = other.clone();
|
|
||||||
// other2.positive = !other.positive;
|
|
||||||
// self.add_assign(other2);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//math_operator!(Sub,sub,sub_assign);
|
|
||||||
//
|
|
||||||
////------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//impl<T> MulAssign for Signed<T>
|
|
||||||
// where
|
|
||||||
// T: MulAssign
|
|
||||||
//{
|
|
||||||
// fn mul_assign(&mut self, other: Signed<T>) {
|
|
||||||
// self.positive = !(self.positive ^ other.positive);
|
|
||||||
// self.value *= other.value;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<'a,T> MulAssign<&'a Signed<T>> for Signed<T>
|
|
||||||
// where
|
|
||||||
// T: MulAssign + MulAssign<&'a T>
|
|
||||||
//{
|
|
||||||
// fn mul_assign(&mut self, other: &'a Signed<T>) {
|
|
||||||
// self.positive = !(self.positive ^ other.positive);
|
|
||||||
// self.value *= &other.value;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//math_operator!(Mul,mul,mul_assign);
|
|
||||||
//
|
|
||||||
////------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//impl<T> DivAssign for Signed<T>
|
|
||||||
// where
|
|
||||||
// T: DivAssign
|
|
||||||
//{
|
|
||||||
// fn div_assign(&mut self, other: Signed<T>) {
|
|
||||||
// self.positive = !(self.positive ^ other.positive);
|
|
||||||
// self.value /= other.value;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//impl<'a,T> DivAssign<&'a Signed<T>> for Signed<T>
|
|
||||||
// where
|
|
||||||
// T: DivAssign + DivAssign<&'a T>
|
|
||||||
//{
|
|
||||||
// fn div_assign(&mut self, other: &'a Signed<T>) {
|
|
||||||
// self.positive = !(self.positive ^ other.positive);
|
|
||||||
// self.value /= &other.value;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//math_operator!(Div,div,div_assign);
|
|
||||||
//
|
|
||||||
////------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
//#[cfg(test)]
|
|
||||||
//mod tests {
|
|
||||||
// use cryptonum::unsigned::U512;
|
|
||||||
// use quickcheck::{Arbitrary,Gen};
|
|
||||||
// use std::cmp::{max,min};
|
|
||||||
// use super::*;
|
|
||||||
//
|
|
||||||
// impl<T: Arbitrary + CryptoNumBase> Arbitrary for Signed<T> {
|
|
||||||
// fn arbitrary<G: Gen>(g: &mut G) -> Signed<T> {
|
|
||||||
// let value = T::arbitrary(g);
|
|
||||||
// if value.is_zero() {
|
|
||||||
// Signed {
|
|
||||||
// positive: true,
|
|
||||||
// value: value
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// Signed {
|
|
||||||
// positive: g.gen_weighted_bool(2),
|
|
||||||
// value: value
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// quickcheck! {
|
|
||||||
// fn double_negation(x: Signed<U512>) -> bool {
|
|
||||||
// &x == (- (- &x))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// quickcheck! {
|
|
||||||
// fn add_associates(x: Signed<U512>, y: Signed<U512>, z: Signed<U512>)
|
|
||||||
// -> bool
|
|
||||||
// {
|
|
||||||
// let mut a = x.clone();
|
|
||||||
// let mut b = y.clone();
|
|
||||||
// let mut c = z.clone();
|
|
||||||
//
|
|
||||||
// // we shift these right because rollover makes for weird behavior
|
|
||||||
// a.value >>= 2;
|
|
||||||
// b.value >>= 2;
|
|
||||||
// c.value >>= 2;
|
|
||||||
//
|
|
||||||
// (&a + (&b + &c)) == ((&a + &b) + &c)
|
|
||||||
// }
|
|
||||||
// fn add_commutes(x: Signed<U512>, y: Signed<U512>) -> bool {
|
|
||||||
// (&x + &y) == (&y + &x)
|
|
||||||
// }
|
|
||||||
// fn add_identity(x: Signed<U512>) -> bool {
|
|
||||||
// let zero = Signed{ positive: true, value: U512::zero() };
|
|
||||||
// (&x + &zero) == &x
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// quickcheck! {
|
|
||||||
// fn sub_is_add_negation(x: Signed<U512>, y: Signed<U512>) -> bool {
|
|
||||||
// (&x - &y) == (&x + (- &y))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// quickcheck! {
|
|
||||||
// fn mul_associates(x: Signed<U512>, y: Signed<U512>, z: Signed<U512>)
|
|
||||||
// -> bool
|
|
||||||
// {
|
|
||||||
// let mut a = x.clone();
|
|
||||||
// let mut b = y.clone();
|
|
||||||
// let mut c = z.clone();
|
|
||||||
//
|
|
||||||
// // we shift these right because rollover makes for weird behavior
|
|
||||||
// a.value >>= 258;
|
|
||||||
// b.value >>= 258;
|
|
||||||
// c.value >>= 258;
|
|
||||||
//
|
|
||||||
// (&a * (&b * &c)) == ((&a * &b) * &c)
|
|
||||||
// }
|
|
||||||
// fn mul_commutes(x: Signed<U512>, y: Signed<U512>) -> bool {
|
|
||||||
// (&x * &y) == (&y * &x)
|
|
||||||
// }
|
|
||||||
// fn mul_identity(x: Signed<U512>) -> bool {
|
|
||||||
// let one = Signed{ positive: true, value: U512::from_u8(1) };
|
|
||||||
// (&x * &one) == &x
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// quickcheck! {
|
|
||||||
// fn add_mul_distribution(x:Signed<U512>,y:Signed<U512>,z:Signed<U512>)
|
|
||||||
// -> bool
|
|
||||||
// {
|
|
||||||
// let mut a = x.clone();
|
|
||||||
// let mut b = y.clone();
|
|
||||||
// let mut c = z.clone();
|
|
||||||
//
|
|
||||||
// // we shift these right because rollover makes for weird behavior
|
|
||||||
// a.value >>= 258;
|
|
||||||
// b.value >>= 258;
|
|
||||||
// c.value >>= 258;
|
|
||||||
//
|
|
||||||
// (&a * (&b + &c)) == ((&a * &b) + (&a * &c))
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user