Nevermind, let's try doing this in a less type-filled way.
This commit is contained in:
@@ -14,5 +14,5 @@ mod unsigned;
|
|||||||
|
|
||||||
// pub use self::extended_math::{modexp,modinv,extended_euclidean,egcd};
|
// pub use self::extended_math::{modexp,modinv,extended_euclidean,egcd};
|
||||||
// pub use self::primes::{probably_prime};
|
// pub use self::primes::{probably_prime};
|
||||||
pub use self::signed::{Signed};
|
pub use self::signed::{I512};
|
||||||
pub use self::unsigned::{U512,U1024,U2048,U3072,U4096,U7680,U8192,U15360};
|
pub use self::unsigned::{U512,U1024,U2048,U3072,U4096,U7680,U8192,U15360};
|
||||||
|
|||||||
@@ -1,431 +1,443 @@
|
|||||||
use cryptonum::traits::*;
|
use cryptonum::traits::*;
|
||||||
use std::cmp::Ordering;
|
use cryptonum::unsigned::*;
|
||||||
use std::fmt::{Debug,Error,Formatter};
|
|
||||||
use std::ops::*;
|
|
||||||
|
|
||||||
pub struct Signed<T: Sized> {
|
pub struct I512 {
|
||||||
positive: bool,
|
negative: bool,
|
||||||
value: T
|
value: U512
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Signed<T> {
|
|
||||||
pub fn new(v: T) -> Signed<T> {
|
|
||||||
Signed{ positive: true, value: v }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn abs(&self) -> T
|
//use cryptonum::traits::*;
|
||||||
where T: Clone
|
//use std::cmp::Ordering;
|
||||||
{
|
//use std::fmt::{Debug,Error,Formatter};
|
||||||
self.value.clone()
|
//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() }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
pub fn is_positive(&self) -> bool
|
//impl<'a,T: PartialEq> PartialEq<&'a Signed<T>> for Signed<T> {
|
||||||
where T: CryptoNumBase
|
// fn eq(&self, other: &&Signed<T>) -> bool {
|
||||||
{
|
// (self.positive == other.positive) && (self.value == other.value)
|
||||||
self.positive && !self.value.is_zero()
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
pub fn is_negative(&self) -> bool
|
//impl<'a,T: PartialEq> PartialEq<Signed<T>> for &'a Signed<T> {
|
||||||
where T: CryptoNumBase
|
// fn eq(&self, other: &Signed<T>) -> bool {
|
||||||
{
|
// (self.positive == other.positive) && (self.value == other.value)
|
||||||
!self.positive && !self.value.is_zero()
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
pub fn negate(&mut self)
|
//impl<T: PartialEq> PartialEq for Signed<T> {
|
||||||
{
|
// fn eq(&self, other: &Signed<T>) -> bool {
|
||||||
self.positive = !self.positive;
|
// (self.positive == other.positive) && (self.value == other.value)
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
impl<T: CryptoNumBase> CryptoNumBase for Signed<T> {
|
//impl<T: Eq> Eq for Signed<T> {}
|
||||||
fn zero() -> Signed<T> {
|
//
|
||||||
Signed{ positive: true, value: T::zero() }
|
//impl<T: Debug> Debug for Signed<T> {
|
||||||
}
|
// fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
||||||
fn max_value() -> Signed<T> {
|
// if self.positive {
|
||||||
Signed{ positive: true, value: T::max_value() }
|
// f.write_str("+")?;
|
||||||
}
|
// } else {
|
||||||
fn is_zero(&self) -> bool {
|
// f.write_str("-")?;
|
||||||
self.value.is_zero()
|
// }
|
||||||
}
|
// self.value.fmt(f)
|
||||||
fn is_odd(&self) -> bool {
|
// }
|
||||||
self.value.is_odd()
|
//}
|
||||||
}
|
//
|
||||||
fn is_even(&self) -> bool {
|
//impl<T: Ord> Ord for Signed<T> {
|
||||||
self.value.is_even()
|
// fn cmp(&self, other: &Signed<T>) -> Ordering {
|
||||||
}
|
// match (self.positive, other.positive) {
|
||||||
fn from_u8(x: u8) -> Signed<T> {
|
// (true, true) => self.value.cmp(&other.value),
|
||||||
Signed{ positive: true, value: T::from_u8(x) }
|
// (true, false) => Ordering::Greater,
|
||||||
}
|
// (false, true) => Ordering::Less,
|
||||||
fn to_u8(&self) -> u8 {
|
// (false, false) =>
|
||||||
self.value.to_u8()
|
// self.value.cmp(&other.value).reverse()
|
||||||
}
|
// }
|
||||||
fn from_u16(x: u16) -> Signed<T> {
|
// }
|
||||||
Signed{ positive: true, value: T::from_u16(x) }
|
//}
|
||||||
}
|
//
|
||||||
fn to_u16(&self) -> u16 {
|
//impl<T: Ord> PartialOrd for Signed<T> {
|
||||||
self.value.to_u16()
|
// fn partial_cmp(&self, other: &Signed<T>) -> Option<Ordering>{
|
||||||
}
|
// Some(self.cmp(other))
|
||||||
fn from_u32(x: u32) -> Signed<T> {
|
// }
|
||||||
Signed{ positive: true, value: T::from_u32(x) }
|
//}
|
||||||
}
|
//
|
||||||
fn to_u32(&self) -> u32 {
|
////------------------------------------------------------------------------------
|
||||||
self.value.to_u32()
|
//
|
||||||
}
|
//impl<T: Clone> Neg for Signed<T> {
|
||||||
fn from_u64(x: u64) -> Signed<T> {
|
// type Output = Signed<T>;
|
||||||
Signed{ positive: true, value: T::from_u64(x) }
|
//
|
||||||
}
|
// fn neg(self) -> Signed<T> {
|
||||||
fn to_u64(&self) -> u64 {
|
// Signed {
|
||||||
self.value.to_u64()
|
// positive: !self.positive,
|
||||||
}
|
// value: self.value.clone()
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
impl<T: CryptoNumFastMod> CryptoNumFastMod for Signed<T> {
|
//}
|
||||||
type BarrettMu = T::BarrettMu;
|
//
|
||||||
|
//impl<'a,T: Clone> Neg for &'a Signed<T> {
|
||||||
fn barrett_mu(&self) -> Option<T::BarrettMu> {
|
// type Output = Signed<T>;
|
||||||
if self.positive {
|
//
|
||||||
self.value.barrett_mu()
|
// fn neg(self) -> Signed<T> {
|
||||||
} else {
|
// Signed {
|
||||||
None
|
// positive: !self.positive,
|
||||||
}
|
// value: self.value.clone()
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
fn fastmod(&self, mu: &T::BarrettMu) -> Signed<T> {
|
//}
|
||||||
Signed{ positive: self.positive, value: self.value.fastmod(&mu) }
|
//
|
||||||
}
|
////------------------------------------------------------------------------------
|
||||||
}
|
//
|
||||||
|
//impl<T> AddAssign for Signed<T>
|
||||||
impl<T: Clone> Clone for Signed<T> {
|
// where
|
||||||
fn clone(&self) -> Signed<T> {
|
// T: Clone + Ord,
|
||||||
Signed{ positive: self.positive, value: self.value.clone() }
|
// T: AddAssign + SubAssign,
|
||||||
}
|
//{
|
||||||
}
|
// fn add_assign(&mut self, other: Signed<T>) {
|
||||||
|
// match (self.positive, other.positive, self.value.cmp(&other.value)) {
|
||||||
impl<'a,T: PartialEq> PartialEq<&'a Signed<T>> for Signed<T> {
|
// // if the signs are the same, we maintain the sign and just increase
|
||||||
fn eq(&self, other: &&Signed<T>) -> bool {
|
// // the magnitude
|
||||||
(self.positive == other.positive) && (self.value == other.value)
|
// (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
|
||||||
impl<'a,T: PartialEq> PartialEq<Signed<T>> for &'a Signed<T> {
|
// // timing roughly similar.
|
||||||
fn eq(&self, other: &Signed<T>) -> bool {
|
// (_, _, Ordering::Equal) => {
|
||||||
(self.positive == other.positive) && (self.value == other.value)
|
// self.positive = true;
|
||||||
}
|
// self.value.sub_assign(other.value);
|
||||||
}
|
// }
|
||||||
|
// // if the signs are different and the first one is less than the
|
||||||
impl<T: PartialEq> PartialEq for Signed<T> {
|
// // second, then we flip the sign and subtract.
|
||||||
fn eq(&self, other: &Signed<T>) -> bool {
|
// (_, _, Ordering::Less) => {
|
||||||
(self.positive == other.positive) && (self.value == other.value)
|
// self.positive = !self.positive;
|
||||||
}
|
// let temp = self.value.clone();
|
||||||
}
|
// self.value = other.value.clone();
|
||||||
|
// self.value.sub_assign(temp);
|
||||||
impl<T: Eq> Eq for Signed<T> {}
|
// }
|
||||||
|
// // if the signs are different and the first one is greater than the
|
||||||
impl<T: Debug> Debug for Signed<T> {
|
// // second, then we leave the sign and subtract.
|
||||||
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
|
// (_, _, Ordering::Greater) => {
|
||||||
if self.positive {
|
// self.value.sub_assign(other.value);
|
||||||
f.write_str("+")?;
|
// }
|
||||||
} else {
|
// }
|
||||||
f.write_str("-")?;
|
// }
|
||||||
}
|
//}
|
||||||
self.value.fmt(f)
|
//
|
||||||
}
|
//impl<'a,T> AddAssign<&'a Signed<T>> for Signed<T>
|
||||||
}
|
// where
|
||||||
|
// T: Clone + Ord,
|
||||||
impl<T: Ord> Ord for Signed<T> {
|
// T: AddAssign + SubAssign,
|
||||||
fn cmp(&self, other: &Signed<T>) -> Ordering {
|
// T: AddAssign<&'a T> + SubAssign<&'a T>
|
||||||
match (self.positive, other.positive) {
|
//{
|
||||||
(true, true) => self.value.cmp(&other.value),
|
// fn add_assign(&mut self, other: &'a Signed<T>) {
|
||||||
(true, false) => Ordering::Greater,
|
// match (self.positive, other.positive, self.value.cmp(&other.value)) {
|
||||||
(false, true) => Ordering::Less,
|
// // if the signs are the same, we maintain the sign and just increase
|
||||||
(false, false) =>
|
// // the magnitude
|
||||||
self.value.cmp(&other.value).reverse()
|
// (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.
|
||||||
impl<T: Ord> PartialOrd for Signed<T> {
|
// (_, _, Ordering::Equal) => {
|
||||||
fn partial_cmp(&self, other: &Signed<T>) -> Option<Ordering>{
|
// self.positive = true;
|
||||||
Some(self.cmp(other))
|
// 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;
|
||||||
impl<T: Clone> Neg for Signed<T> {
|
// let temp = self.value.clone();
|
||||||
type Output = Signed<T>;
|
// self.value = other.value.clone();
|
||||||
|
// self.value.sub_assign(temp);
|
||||||
fn neg(self) -> Signed<T> {
|
// }
|
||||||
Signed {
|
// // if the signs are different and the first one is greater than the
|
||||||
positive: !self.positive,
|
// // second, then we leave the sign and subtract.
|
||||||
value: self.value.clone()
|
// (_, _, Ordering::Greater) => {
|
||||||
}
|
// self.value.sub_assign(&other.value);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
impl<'a,T: Clone> Neg for &'a Signed<T> {
|
//}
|
||||||
type Output = Signed<T>;
|
//
|
||||||
|
//math_operator!(Add,add,add_assign);
|
||||||
fn neg(self) -> Signed<T> {
|
//
|
||||||
Signed {
|
////------------------------------------------------------------------------------
|
||||||
positive: !self.positive,
|
//
|
||||||
value: self.value.clone()
|
//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();
|
||||||
impl<T> AddAssign for Signed<T>
|
// other2.positive = !other.positive;
|
||||||
where
|
// self.add_assign(other2);
|
||||||
T: Clone + Ord,
|
// }
|
||||||
T: AddAssign + SubAssign,
|
//}
|
||||||
{
|
//
|
||||||
fn add_assign(&mut self, other: Signed<T>) {
|
//impl<'a,T> SubAssign<&'a Signed<T>> for Signed<T>
|
||||||
match (self.positive, other.positive, self.value.cmp(&other.value)) {
|
// where
|
||||||
// if the signs are the same, we maintain the sign and just increase
|
// T: Clone + Ord,
|
||||||
// the magnitude
|
// T: AddAssign + SubAssign,
|
||||||
(x, y, _) if x == y =>
|
// T: AddAssign<&'a T> + SubAssign<&'a T>
|
||||||
self.value.add_assign(other.value),
|
//{
|
||||||
// if the signs are different and the numbers are equal, we just set
|
// fn sub_assign(&mut self, other: &'a Signed<T>) {
|
||||||
// this to zero. However, we actually do the subtraction to make the
|
// let mut other2 = other.clone();
|
||||||
// timing roughly similar.
|
// other2.positive = !other.positive;
|
||||||
(_, _, Ordering::Equal) => {
|
// self.add_assign(other2);
|
||||||
self.positive = true;
|
// }
|
||||||
self.value.sub_assign(other.value);
|
//}
|
||||||
}
|
//
|
||||||
// if the signs are different and the first one is less than the
|
//math_operator!(Sub,sub,sub_assign);
|
||||||
// second, then we flip the sign and subtract.
|
//
|
||||||
(_, _, Ordering::Less) => {
|
////------------------------------------------------------------------------------
|
||||||
self.positive = !self.positive;
|
//
|
||||||
let temp = self.value.clone();
|
//impl<T> MulAssign for Signed<T>
|
||||||
self.value = other.value.clone();
|
// where
|
||||||
self.value.sub_assign(temp);
|
// T: MulAssign
|
||||||
}
|
//{
|
||||||
// if the signs are different and the first one is greater than the
|
// fn mul_assign(&mut self, other: Signed<T>) {
|
||||||
// second, then we leave the sign and subtract.
|
// self.positive = !(self.positive ^ other.positive);
|
||||||
(_, _, Ordering::Greater) => {
|
// self.value *= other.value;
|
||||||
self.value.sub_assign(other.value);
|
// }
|
||||||
}
|
//}
|
||||||
}
|
//
|
||||||
}
|
//impl<'a,T> MulAssign<&'a Signed<T>> for Signed<T>
|
||||||
}
|
// where
|
||||||
|
// T: MulAssign + MulAssign<&'a T>
|
||||||
impl<'a,T> AddAssign<&'a Signed<T>> for Signed<T>
|
//{
|
||||||
where
|
// fn mul_assign(&mut self, other: &'a Signed<T>) {
|
||||||
T: Clone + Ord,
|
// self.positive = !(self.positive ^ other.positive);
|
||||||
T: AddAssign + SubAssign,
|
// self.value *= &other.value;
|
||||||
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)) {
|
//math_operator!(Mul,mul,mul_assign);
|
||||||
// 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),
|
//impl<T> DivAssign for Signed<T>
|
||||||
// if the signs are different and the numbers are equal, we just set
|
// where
|
||||||
// this to zero. However, we actually do the subtraction to make the
|
// T: DivAssign
|
||||||
// timing roughly similar.
|
//{
|
||||||
(_, _, Ordering::Equal) => {
|
// fn div_assign(&mut self, other: Signed<T>) {
|
||||||
self.positive = true;
|
// self.positive = !(self.positive ^ other.positive);
|
||||||
self.value.sub_assign(&other.value);
|
// self.value /= 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) => {
|
//impl<'a,T> DivAssign<&'a Signed<T>> for Signed<T>
|
||||||
self.positive = !self.positive;
|
// where
|
||||||
let temp = self.value.clone();
|
// T: DivAssign + DivAssign<&'a T>
|
||||||
self.value = other.value.clone();
|
//{
|
||||||
self.value.sub_assign(temp);
|
// fn div_assign(&mut self, other: &'a Signed<T>) {
|
||||||
}
|
// self.positive = !(self.positive ^ other.positive);
|
||||||
// if the signs are different and the first one is greater than the
|
// self.value /= &other.value;
|
||||||
// second, then we leave the sign and subtract.
|
// }
|
||||||
(_, _, Ordering::Greater) => {
|
//}
|
||||||
self.value.sub_assign(&other.value);
|
//
|
||||||
}
|
//math_operator!(Div,div,div_assign);
|
||||||
}
|
//
|
||||||
}
|
////------------------------------------------------------------------------------
|
||||||
}
|
//
|
||||||
|
//#[cfg(test)]
|
||||||
math_operator!(Add,add,add_assign);
|
//mod tests {
|
||||||
|
// use cryptonum::unsigned::U512;
|
||||||
//------------------------------------------------------------------------------
|
// use quickcheck::{Arbitrary,Gen};
|
||||||
|
// use std::cmp::{max,min};
|
||||||
impl<T> SubAssign for Signed<T>
|
// use super::*;
|
||||||
where
|
//
|
||||||
T: Clone + Ord,
|
// impl<T: Arbitrary + CryptoNumBase> Arbitrary for Signed<T> {
|
||||||
T: AddAssign + SubAssign,
|
// fn arbitrary<G: Gen>(g: &mut G) -> Signed<T> {
|
||||||
{
|
// let value = T::arbitrary(g);
|
||||||
fn sub_assign(&mut self, other: Signed<T>) {
|
// if value.is_zero() {
|
||||||
let mut other2 = other.clone();
|
// Signed {
|
||||||
other2.positive = !other.positive;
|
// positive: true,
|
||||||
self.add_assign(other2);
|
// value: value
|
||||||
}
|
// }
|
||||||
}
|
// } else {
|
||||||
|
// Signed {
|
||||||
impl<'a,T> SubAssign<&'a Signed<T>> for Signed<T>
|
// positive: g.gen_weighted_bool(2),
|
||||||
where
|
// value: value
|
||||||
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();
|
// quickcheck! {
|
||||||
other2.positive = !other.positive;
|
// fn double_negation(x: Signed<U512>) -> bool {
|
||||||
self.add_assign(other2);
|
// &x == (- (- &x))
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
math_operator!(Sub,sub,sub_assign);
|
// quickcheck! {
|
||||||
|
// fn add_associates(x: Signed<U512>, y: Signed<U512>, z: Signed<U512>)
|
||||||
//------------------------------------------------------------------------------
|
// -> bool
|
||||||
|
// {
|
||||||
impl<T> MulAssign for Signed<T>
|
// let mut a = x.clone();
|
||||||
where
|
// let mut b = y.clone();
|
||||||
T: MulAssign
|
// let mut c = z.clone();
|
||||||
{
|
//
|
||||||
fn mul_assign(&mut self, other: Signed<T>) {
|
// // we shift these right because rollover makes for weird behavior
|
||||||
self.positive = !(self.positive ^ other.positive);
|
// a.value >>= 2;
|
||||||
self.value *= other.value;
|
// b.value >>= 2;
|
||||||
}
|
// c.value >>= 2;
|
||||||
}
|
//
|
||||||
|
// (&a + (&b + &c)) == ((&a + &b) + &c)
|
||||||
impl<'a,T> MulAssign<&'a Signed<T>> for Signed<T>
|
// }
|
||||||
where
|
// fn add_commutes(x: Signed<U512>, y: Signed<U512>) -> bool {
|
||||||
T: MulAssign + MulAssign<&'a T>
|
// (&x + &y) == (&y + &x)
|
||||||
{
|
// }
|
||||||
fn mul_assign(&mut self, other: &'a Signed<T>) {
|
// fn add_identity(x: Signed<U512>) -> bool {
|
||||||
self.positive = !(self.positive ^ other.positive);
|
// let zero = Signed{ positive: true, value: U512::zero() };
|
||||||
self.value *= &other.value;
|
// (&x + &zero) == &x
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
math_operator!(Mul,mul,mul_assign);
|
// quickcheck! {
|
||||||
|
// fn sub_is_add_negation(x: Signed<U512>, y: Signed<U512>) -> bool {
|
||||||
//------------------------------------------------------------------------------
|
// (&x - &y) == (&x + (- &y))
|
||||||
|
// }
|
||||||
impl<T> DivAssign for Signed<T>
|
// }
|
||||||
where
|
//
|
||||||
T: DivAssign
|
// quickcheck! {
|
||||||
{
|
// fn mul_associates(x: Signed<U512>, y: Signed<U512>, z: Signed<U512>)
|
||||||
fn div_assign(&mut self, other: Signed<T>) {
|
// -> bool
|
||||||
self.positive = !(self.positive ^ other.positive);
|
// {
|
||||||
self.value /= other.value;
|
// let mut a = x.clone();
|
||||||
}
|
// let mut b = y.clone();
|
||||||
}
|
// let mut c = z.clone();
|
||||||
|
//
|
||||||
impl<'a,T> DivAssign<&'a Signed<T>> for Signed<T>
|
// // we shift these right because rollover makes for weird behavior
|
||||||
where
|
// a.value >>= 258;
|
||||||
T: DivAssign + DivAssign<&'a T>
|
// b.value >>= 258;
|
||||||
{
|
// c.value >>= 258;
|
||||||
fn div_assign(&mut self, other: &'a Signed<T>) {
|
//
|
||||||
self.positive = !(self.positive ^ other.positive);
|
// (&a * (&b * &c)) == ((&a * &b) * &c)
|
||||||
self.value /= &other.value;
|
// }
|
||||||
}
|
// fn mul_commutes(x: Signed<U512>, y: Signed<U512>) -> bool {
|
||||||
}
|
// (&x * &y) == (&y * &x)
|
||||||
|
// }
|
||||||
math_operator!(Div,div,div_assign);
|
// fn mul_identity(x: Signed<U512>) -> bool {
|
||||||
|
// let one = Signed{ positive: true, value: U512::from_u8(1) };
|
||||||
//------------------------------------------------------------------------------
|
// (&x * &one) == &x
|
||||||
|
// }
|
||||||
#[cfg(test)]
|
// }
|
||||||
mod tests {
|
//
|
||||||
use cryptonum::unsigned::U512;
|
// quickcheck! {
|
||||||
use quickcheck::{Arbitrary,Gen};
|
// fn add_mul_distribution(x:Signed<U512>,y:Signed<U512>,z:Signed<U512>)
|
||||||
use std::cmp::{max,min};
|
// -> bool
|
||||||
use super::*;
|
// {
|
||||||
|
// let mut a = x.clone();
|
||||||
impl<T: Arbitrary + CryptoNumBase> Arbitrary for Signed<T> {
|
// let mut b = y.clone();
|
||||||
fn arbitrary<G: Gen>(g: &mut G) -> Signed<T> {
|
// let mut c = z.clone();
|
||||||
let value = T::arbitrary(g);
|
//
|
||||||
if value.is_zero() {
|
// // we shift these right because rollover makes for weird behavior
|
||||||
Signed {
|
// a.value >>= 258;
|
||||||
positive: true,
|
// b.value >>= 258;
|
||||||
value: value
|
// c.value >>= 258;
|
||||||
}
|
//
|
||||||
} else {
|
// (&a * (&b + &c)) == ((&a * &b) + (&a * &c))
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -56,3 +56,18 @@ pub trait CryptoNumFastMod {
|
|||||||
/// Faster modulo through the use of the Barrett constant, above.
|
/// Faster modulo through the use of the Barrett constant, above.
|
||||||
fn fastmod(&self, &Self::BarrettMu) -> Self;
|
fn fastmod(&self, &Self::BarrettMu) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait CryptoNumSigned {
|
||||||
|
/// The unsigned type that this type is related to.
|
||||||
|
type Unsigned;
|
||||||
|
|
||||||
|
/// Generate a new signed number based on the given unsigned number.
|
||||||
|
fn new(x: Self::Unsigned) -> Self;
|
||||||
|
/// Get the absolute value of the signed number, turning it back into an
|
||||||
|
/// unsigned number.
|
||||||
|
fn abs(&self) -> Self::Unsigned;
|
||||||
|
/// Test if the number is negative.
|
||||||
|
fn is_negative(&self) -> bool;
|
||||||
|
/// Test if the number is positive.
|
||||||
|
fn is_positive(&self) -> bool;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user