Remove the cryptonum stuff; it's been moved to a different crate.

This commit is contained in:
2018-10-27 15:15:23 -07:00
parent 43b73139cd
commit ef54ed4cda
215 changed files with 0 additions and 773902 deletions

View File

@@ -1,133 +0,0 @@
use cryptonum::basetypes::*;
use std::ops::Add;
pub trait UnsafeAdd {
fn unsafe_add(self, other: &Self) -> Self;
}
macro_rules! generate_adders
{
($name: ident, $size: expr) => {
impl UnsafeAdd for $name {
fn unsafe_add(self, other: &$name) -> $name {
let mut result = $name::zero();
let mut carry = 0;
for i in 0..$size/64 {
let x128 = self.values[i] as u128;
let y128 = other.values[i] as u128;
let bigger = x128 + y128 + carry;
carry = bigger >> 64;
result.values[i] = bigger as u64;
}
result
}
}
};
($name: ident, $bigger: ident, $size: expr) => {
generate_adders!($name, $size);
impl<'a,'b> Add<&'a $name> for &'b $name {
type Output = $bigger;
fn add(self, other: &$name) -> $bigger {
let mut result = $bigger::zero();
let mut carry = 0;
for i in 0..$size/64 {
let x128 = self.values[i] as u128;
let y128 = other.values[i] as u128;
let bigger = x128 + y128 + carry;
carry = bigger >> 64;
result.values[i] = bigger as u64;
}
result.values[$size/64] = carry as u64;
result
}
}
impl Add<$name> for $name {
type Output = $bigger;
fn add(self, other: $name) -> $bigger {
&self + &other
}
}
}
}
generate_adders!(U192, U256, 192);
generate_adders!(U256, U320, 256);
generate_adders!(U384, U448, 384);
generate_adders!(U512, U576, 512);
generate_adders!(U576, U640, 576);
generate_adders!(U1024, U1088, 1024);
generate_adders!(U2048, U2112, 2048);
generate_adders!(U3072, U3136, 3072);
generate_adders!(U4096, U4160, 4096);
generate_adders!(U7680, U7744, 7680);
generate_adders!(U8192, U8256, 8192);
generate_adders!(U15360, U15424, 15360);
generate_adders!(U320, 320);
generate_adders!(U448, 448);
generate_adders!(U768, 768);
generate_adders!(U832, 832);
generate_adders!(U1088, 1088);
generate_adders!(U1216, 1216);
generate_adders!(U2112, 2112);
generate_adders!(U3136, 3136);
generate_adders!(U4160, 4160);
generate_adders!(U6144, 6144);
generate_adders!(U6208, 6208);
generate_adders!(U8256, 8256);
generate_adders!(U15424, 15424);
generate_adders!(U16384, 16384);
generate_adders!(U16448, 16448);
generate_adders!(U30720, 30720);
generate_adders!(U30784, 30784);
macro_rules! generate_tests {
( $( ($name:ident, $bigger: ident) ),* ) => {
#[cfg(test)]
mod normal {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/addition{}.test",
stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, cbytes) = case.get("c").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let c = $bigger::from_bytes(cbytes);
assert_eq!(&a + &b, c);
});
}
)*
}
}
}
generate_tests!((U192, U256),
(U256, U320),
(U384, U448),
(U512, U576),
(U576, U640),
(U1024, U1088),
(U2048, U2112),
(U3072, U3136),
(U4096, U4160),
(U8192, U8256),
(U15360, U15424));

View File

@@ -1,240 +0,0 @@
use cryptonum::addition::UnsafeAdd;
use cryptonum::basetypes::*;
use std::cmp::min;
macro_rules! generate_barretts {
($bname:ident,$name:ident,$big:ident,$bg2:ident,$dbl:ident,$size:expr) =>
{
#[derive(Debug,PartialEq)]
pub struct $bname {
pub(crate) k: usize,
pub(crate) m: $big,
pub(crate) mu: $big
}
impl $bname {
pub fn new(m: &$name) -> $bname {
// Step #1: Figure out k
let mut k = 0;
for i in 0..$size/64 {
if m.values[i] != 0 {
k = i;
}
}
k += 1;
// Step #2: Compute b
let mut b = $bg2::zero();
b.values[2*k] = 1;
// Step #3: Divide b by m.
let bigm = $bg2::from(m);
let (quot, _) = b.divmod(&bigm);
let resm = $big::from(m);
let mu = $big::from(&quot);
// Done!
$bname{ k: k, m: resm, mu: mu }
}
pub fn ok_for_reduce(&self, x: &$dbl) -> bool {
for i in self.k*2 .. x.values.len() {
if x.values[i] != 0 {
return false
}
}
true
}
pub fn reduce(&self, x: &$dbl) -> $name {
assert!(self.ok_for_reduce(x));
let m2: $bg2 = $bg2::from(&self.m);
// 1. q1←⌊x/bk1⌋, q2←q1 · μ, q3←⌊q2/bk+1⌋.
let q1: $big = x.shiftr(self.k - 1);
let q2: $bg2 = q1.unsafe_mul(&self.mu);
let q3: $big = q2.check_shiftr(self.k + 1);
// 2. r1←x mod bk+1, r2←q3 · m mod bk+1, r←r1 r2.
let mut r: $bg2 = x.mask(self.k + 1);
let mut r2: $bg2 = q3.unsafe_mul(&self.m);
r2.mask_inplace(self.k + 1);
let went_negative = &r < &r2;
r -= &r2;
// 3. If r<0 then r←r+bk+1.
if went_negative {
let mut bk1 = $bg2::zero();
bk1.values[self.k+1] = 1;
r = r.unsafe_add(&bk1);
}
// 4. While r≥m do: r←rm.
while &r > &m2 {
r -= &m2;
}
// Done!
$name::from(&r)
}
}
impl $dbl {
fn shiftr(&self, x: usize) -> $big {
let mut res = $big::zero();
for i in 0..self.values.len()-x {
if i >= res.values.len() {
assert_eq!(self.values[i+x], 0);
} else {
res.values[i] = self.values[i+x];
}
}
res
}
fn mask(&self, len: usize) -> $bg2 {
let mut res = $bg2::zero();
let copylen = min(len, self.values.len());
for i in 0..copylen {
res.values[i] = self.values[i];
}
res
}
}
impl $big {
fn unsafe_mul(&self, rhs: &$big) -> $bg2 {
let mut w = $bg2::zero();
let len = rhs.values.len();
for i in 0..len {
let mut carry = 0;
for j in 0..len {
if i+j >= w.values.len() {
continue;
}
let old = w.values[i+j] as u128;
let x128 = self.values[j] as u128;
let y128 = rhs.values[i] as u128;
let uv = old + (x128 * y128) + carry;
w.values[i+j] = uv as u64;
carry = uv >> 64;
}
if i+len < w.values.len() {
w.values[i+len] = carry as u64;
}
}
w
}
}
impl $bg2 {
fn check_shiftr(&self, x: usize) -> $big {
let mut res = $big::zero();
for i in 0..self.values.len()-x {
if i >= res.values.len() {
assert_eq!(self.values[i+x], 0);
} else {
res.values[i] = self.values[i+x];
}
}
res
}
fn mask_inplace(&mut self, len: usize) {
let dellen = min(len, self.values.len());
for i in dellen..self.values.len() {
self.values[i] = 0;
}
}
}
}
}
generate_barretts!(BarrettU192, U192, U256, U448, U384, 192);
generate_barretts!(BarrettU256, U256, U320, U576, U512, 256);
generate_barretts!(BarrettU384, U384, U448, U832, U768, 384);
generate_barretts!(BarrettU512, U512, U576, U1088, U1024, 512);
generate_barretts!(BarrettU576, U576, U640, U1216, U1152, 576);
generate_barretts!(BarrettU1024, U1024, U1088, U2112, U2048, 1024);
generate_barretts!(BarrettU2048, U2048, U2112, U4160, U4096, 2048);
generate_barretts!(BarrettU3072, U3072, U3136, U6208, U6144, 3072);
generate_barretts!(BarrettU4096, U4096, U4160, U8256, U8192, 4096);
generate_barretts!(BarrettU8192, U8192, U8256, U16448, U16384, 8192);
generate_barretts!(BarrettU15360, U15360, U15424, U30784, U30720, 15360);
macro_rules! generate_tests {
( $( ($bname:ident,$name:ident,$big:ident,$dbl:ident,$size:expr) ),* ) => {
#[cfg(test)]
mod generation {
use cryptonum::encoding::{Decoder,raw_decoder};
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/barrett_gen{}.test",
stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (neg0, mbytes) = case.get("m").unwrap();
let (neg1, ubytes) = case.get("u").unwrap();
let (neg2, kbytes) = case.get("k").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let m = $name::from_bytes(mbytes);
let u = $big::from_bytes(ubytes);
let mut kbig = [0; 1];
raw_decoder(&kbytes, &mut kbig);
let k = kbig[0] as usize;
let r = $bname::new(&m);
assert_eq!(k,r.k);
assert_eq!(u,r.mu);
});
}
)*
}
#[cfg(test)]
mod reduction {
use cryptonum::encoding::{Decoder,raw_decoder};
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/barrett_reduce{}.test",
stringify!($name));
run_test(fname.to_string(), 5, |case| {
let (neg0, mbytes) = case.get("m").unwrap();
let (neg1, ubytes) = case.get("u").unwrap();
let (neg2, kbytes) = case.get("k").unwrap();
let (neg3, xbytes) = case.get("x").unwrap();
let (neg4, rbytes) = case.get("r").unwrap();
assert!(!neg0 && !neg1 && !neg2 && !neg3 && !neg4);
let m = $big::from_bytes(mbytes);
let u = $big::from_bytes(ubytes);
let mut kbig = [0; 1];
raw_decoder(&kbytes, &mut kbig);
let k = kbig[0] as usize;
let x = $dbl::from_bytes(xbytes);
let r = $name::from_bytes(rbytes);
let bu = $bname{ k: k, m: m, mu: u };
let r2 = bu.reduce(&x);
assert_eq!(r, r2);
});
}
)*
}
}
}
generate_tests!((BarrettU192, U192, U256, U384, 192),
(BarrettU256, U256, U320, U512, 256),
(BarrettU384, U384, U448, U768, 384),
(BarrettU512, U512, U576, U1024, 512),
(BarrettU576, U576, U640, U1152, 576),
(BarrettU1024, U1024, U1088, U2048, 1024),
(BarrettU2048, U2048, U2112, U4096, 2048),
(BarrettU3072, U3072, U3136, U6144, 3072),
(BarrettU4096, U4096, U4160, U8192, 4096),
(BarrettU8192, U8192, U8256, U16384, 8192),
(BarrettU15360, U15360, U15424, U30720, 15360));

View File

@@ -1,200 +0,0 @@
use std::fmt;
use std::fmt::Write;
pub trait CryptoNum {
fn zero() -> Self;
fn is_odd(&self) -> bool;
fn is_even(&self) -> bool;
fn is_zero(&self) -> bool;
}
macro_rules! generate_unsigned
{
($name: ident, $size: expr) => {
pub struct $name {
pub(crate) values: [u64; $size/64]
}
impl Clone for $name {
fn clone(&self) -> $name {
let mut result = $name{ values: [0; $size/64] };
result.values.copy_from_slice(&self.values);
result
}
}
impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, stringify!($name))?;
write!(f, "{{ ")?;
for x in self.values.iter() {
write!(f, "{:X} ", *x)?;
}
write!(f, "}} ")
}
}
impl fmt::UpperHex for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for x in self.values.iter().rev() {
f.write_char(tochar_upper(x >> 60))?;
f.write_char(tochar_upper(x >> 56))?;
f.write_char(tochar_upper(x >> 52))?;
f.write_char(tochar_upper(x >> 48))?;
f.write_char(tochar_upper(x >> 44))?;
f.write_char(tochar_upper(x >> 40))?;
f.write_char(tochar_upper(x >> 36))?;
f.write_char(tochar_upper(x >> 32))?;
f.write_char(tochar_upper(x >> 28))?;
f.write_char(tochar_upper(x >> 24))?;
f.write_char(tochar_upper(x >> 20))?;
f.write_char(tochar_upper(x >> 16))?;
f.write_char(tochar_upper(x >> 12))?;
f.write_char(tochar_upper(x >> 8))?;
f.write_char(tochar_upper(x >> 4))?;
f.write_char(tochar_upper(x >> 0))?;
}
Ok(())
}
}
impl fmt::LowerHex for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for x in self.values.iter().rev() {
f.write_char(tochar_lower(x >> 60))?;
f.write_char(tochar_lower(x >> 56))?;
f.write_char(tochar_lower(x >> 52))?;
f.write_char(tochar_lower(x >> 48))?;
f.write_char(tochar_lower(x >> 44))?;
f.write_char(tochar_lower(x >> 40))?;
f.write_char(tochar_lower(x >> 36))?;
f.write_char(tochar_lower(x >> 32))?;
f.write_char(tochar_lower(x >> 28))?;
f.write_char(tochar_lower(x >> 24))?;
f.write_char(tochar_lower(x >> 20))?;
f.write_char(tochar_lower(x >> 16))?;
f.write_char(tochar_lower(x >> 12))?;
f.write_char(tochar_lower(x >> 8))?;
f.write_char(tochar_lower(x >> 4))?;
f.write_char(tochar_lower(x >> 0))?;
}
Ok(())
}
}
impl CryptoNum for $name {
fn zero() -> $name {
$name{ values: [0; $size/64 ] }
}
fn is_odd(&self) -> bool {
(self.values[0] & 1) == 1
}
fn is_even(&self) -> bool {
(self.values[0] & 1) == 0
}
fn is_zero(&self) -> bool {
for x in self.values.iter() {
if *x != 0 {
return false;
}
}
true
}
}
}
}
fn tochar_upper(x: u64) -> char {
match (x as u8) & (0xF as u8) {
0x0 => '0',
0x1 => '1',
0x2 => '2',
0x3 => '3',
0x4 => '4',
0x5 => '5',
0x6 => '6',
0x7 => '7',
0x8 => '8',
0x9 => '9',
0xA => 'A',
0xB => 'B',
0xC => 'C',
0xD => 'D',
0xE => 'E',
0xF => 'F',
_ => panic!("the world is broken")
}
}
fn tochar_lower(x: u64) -> char {
match (x as u8) & (0xF as u8) {
0x0 => '0',
0x1 => '1',
0x2 => '2',
0x3 => '3',
0x4 => '4',
0x5 => '5',
0x6 => '6',
0x7 => '7',
0x8 => '8',
0x9 => '9',
0xA => 'a',
0xB => 'b',
0xC => 'c',
0xD => 'd',
0xE => 'e',
0xF => 'f',
_ => panic!("the world is broken")
}
}
generate_unsigned!(U192, 192);
generate_unsigned!(U256, 256);
generate_unsigned!(U320, 320); // this is just for expansion
generate_unsigned!(U384, 384);
generate_unsigned!(U448, 448); // this is just for expansion
generate_unsigned!(U512, 512);
generate_unsigned!(U576, 576);
generate_unsigned!(U640, 640); // this is just for expansion
generate_unsigned!(U768, 768); // this is just for expansion
generate_unsigned!(U832, 832); // this is just for Barrett
generate_unsigned!(U896, 896); // this is just for Barrett
generate_unsigned!(U1024, 1024);
generate_unsigned!(U1088, 1088); // this is just for expansion
generate_unsigned!(U1152, 1152); // this is just for expansion
generate_unsigned!(U1216, 1216); // this is just for Barrett
generate_unsigned!(U1536, 1536); // this is just for expansion
generate_unsigned!(U1664, 1664); // this is just for Barrett
generate_unsigned!(U2048, 2048);
generate_unsigned!(U2112, 2112); // this is just for expansion
generate_unsigned!(U2176, 2176); // this is just for Barrett
generate_unsigned!(U2304, 2304); // this is just for expansion
generate_unsigned!(U2432, 2432); // this is just for Barrett
generate_unsigned!(U3072, 3072);
generate_unsigned!(U3136, 3136); // this is just for expansion
generate_unsigned!(U4096, 4096);
generate_unsigned!(U4160, 4160); // this is just for expansion
generate_unsigned!(U4224, 4224); // this is just for Barrett
generate_unsigned!(U6144, 6144); // this is just for expansion
generate_unsigned!(U6208, 6208); // this is just for Barrett
generate_unsigned!(U7680, 7680); // Useful for RSA key generation
generate_unsigned!(U7744, 7744); // Addition on previous
generate_unsigned!(U8192, 8192);
generate_unsigned!(U8256, 8256); // this is just for expansion
generate_unsigned!(U8320, 8320); // this is just for Barrett
generate_unsigned!(U12288, 12288); // this is just for expansion
generate_unsigned!(U12416, 12416); // this is just for Barrett
generate_unsigned!(U15360, 15360);
generate_unsigned!(U15424, 15424); // this is just for expansion
generate_unsigned!(U16384, 16384); // this is just for expansion
generate_unsigned!(U16448, 16448); // this is just for Barrett
generate_unsigned!(U16512, 16512); // this is just for Barrett
generate_unsigned!(U30720, 30720); // this is just for expansion
generate_unsigned!(U30784, 30784); // this is just for Barrett
generate_unsigned!(U32768, 32768); // this is just for expansion
generate_unsigned!(U32896, 32896); // this is just for Barrett
generate_unsigned!(U61440, 61440); // this is just for expansion
generate_unsigned!(U61568, 61568); // this is just for Barrett

View File

@@ -1,855 +0,0 @@
macro_rules! construct_unsigned {
($type: ident, $modname: ident, $count: expr) => {
#[derive(Clone)]
pub struct $type {
contents: [u64; $count]
}
impl PartialEq for $type {
fn eq(&self, other: &$type) -> bool {
for i in 0..$count {
if self.contents[i] != other.contents[i] {
return false;
}
}
true
}
}
impl Eq for $type {}
impl Debug for $type {
fn fmt(&self, f: &mut Formatter) -> Result<(),Error> {
f.write_str("CryptoNum{{ ")?;
f.debug_list().entries(self.contents.iter()).finish()?;
f.write_str(" }}")
}
}
impl $type {
/// 0!
pub fn zero() -> $type {
$type { contents: [0; $count] }
}
/// The maximum possible value we can hold.
pub fn max() -> $type {
$type { contents: [0xFFFFFFFFFFFFFFFF; $count] }
}
from_to!($type, $count, u8, from_u8, to_u8);
from_to!($type, $count, u16, from_u16, to_u16);
from_to!($type, $count, u32, from_u32, to_u32);
from_to!($type, $count, u64, from_u64, to_u64);
}
impl PartialOrd for $type {
fn partial_cmp(&self, other: &$type) -> Option<Ordering> {
Some(generic_cmp(&self.contents, &other.contents))
}
}
impl Ord for $type {
fn cmp(&self, other: &$type) -> Ordering {
generic_cmp(&self.contents, &other.contents)
}
}
impl Not for $type {
type Output = $type;
fn not(self) -> $type {
let mut output = self.clone();
generic_not(&mut output.contents);
output
}
}
impl<'a> Not for &'a $type {
type Output = $type;
fn not(self) -> $type {
let mut output = self.clone();
generic_not(&mut output.contents);
output
}
}
opers2!($type,BitOrAssign,bitor_assign,BitOr,bitor,generic_bitor);
opers2!($type,BitAndAssign,bitand_assign,BitAnd,bitand,generic_bitand);
opers2!($type,BitXorAssign,bitxor_assign,BitXor,bitxor,generic_bitxor);
shifts!($type, usize);
shifts!($type, u64);
shifts!($type, i64);
shifts!($type, u32);
shifts!($type, i32);
shifts!($type, u16);
shifts!($type, i16);
shifts!($type, u8);
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(&copy, &rhs.contents,
&mut self.contents, &mut dead);
}
}
impl<'a> DivAssign<&'a $type> for $type {
fn div_assign(&mut self, rhs: &$type) {
let mut dead = [0; $count];
let copy = self.contents.clone();
generic_div(&copy, &rhs.contents,
&mut self.contents, &mut dead);
}
}
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(&copy, &rhs.contents,
&mut dead, &mut self.contents);
}
}
impl<'a> RemAssign<&'a $type> for $type {
fn rem_assign(&mut self, rhs: &$type) {
let mut dead = [0; $count];
let copy = self.contents.clone();
generic_div(&copy, &rhs.contents,
&mut dead, &mut self.contents);
}
}
impl Rem<$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> 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 CryptoNum for $type {
fn divmod(&self, a: &$type, q: &mut $type, r: &mut $type) {
generic_div(&self.contents, &a.contents,
&mut q.contents, &mut r.contents);
}
fn to_bytes(&self) -> Vec<u8> {
let mut res = Vec::with_capacity($count * 8);
for x in self.contents.iter() {
res.push( (x >> 56) as u8 );
res.push( (x >> 48) as u8 );
res.push( (x >> 40) as u8 );
res.push( (x >> 32) as u8 );
res.push( (x >> 24) as u8 );
res.push( (x >> 16) as u8 );
res.push( (x >> 8) as u8 );
res.push( (x >> 0) as u8 );
}
res
}
fn from_bytes(x: &[u8]) -> $type {
let mut res = $type::zero();
let mut i = 0;
assert!(x.len() >= ($count * 8));
for chunk in x.chunks(8) {
assert!(chunk.len() == 8);
res.contents[i] = ((chunk[0] as u64) << 56) |
((chunk[1] as u64) << 48) |
((chunk[2] as u64) << 40) |
((chunk[3] as u64) << 32) |
((chunk[4] as u64) << 24) |
((chunk[5] as u64) << 16) |
((chunk[6] as u64) << 8) |
((chunk[7] as u64) << 0);
i += 1;
}
assert!(i == $count);
res
}
}
#[cfg(test)]
mod $modname {
use quickcheck::{Arbitrary,Gen};
use super::*;
impl Arbitrary for $type {
fn arbitrary<G: Gen>(g: &mut G) -> $type {
let mut res = [0; $count];
for i in 0..$count {
res[i] = g.next_u64();
}
$type{ contents: res }
}
}
#[test]
fn test_builders() {
let mut buffer = [0; $count];
assert_eq!($type{ contents: buffer }, $type::from_u8(0));
buffer[0] = 0x7F;
assert_eq!($type{ contents: buffer }, $type::from_u8(0x7F));
buffer[0] = 0x7F7F;
assert_eq!($type{ contents: buffer }, $type::from_u16(0x7F7F));
buffer[0] = 0xCA5CADE5;
assert_eq!($type{ contents: buffer },
$type::from_u32(0xCA5CADE5));
assert_eq!($type{ contents: buffer },
$type::from_u64(0xCA5CADE5));
buffer[0] = 0xFFFFFFFFFFFFFFFF;
assert_eq!($type{ contents: buffer },
$type::from_u64(0xFFFFFFFFFFFFFFFF));
}
#[test]
fn test_max() {
assert_eq!($type::from_u64(u64::max_value()).to_u64(),
u64::max_value());
assert_eq!($type::max().to_u64(), u64::max_value());
assert_eq!($type::max() + $type::from_u8(1), $type::zero());
}
quickcheck! {
fn builder_u8_upgrade_u16(x: u8) -> bool {
$type::from_u8(x) == $type::from_u16(x as u16)
}
fn builder_u16_upgrade_u32(x: u16) -> bool {
$type::from_u16(x) == $type::from_u32(x as u32)
}
fn builder_u32_upgrade_u64(x: u32) -> bool {
$type::from_u32(x) == $type::from_u64(x as u64)
}
fn builder_u8_roundtrips(x: u8) -> bool {
x == $type::from_u8(x).to_u8()
}
fn builder_u16_roundtrips(x: u16) -> bool {
x == $type::from_u16(x).to_u16()
}
fn builder_u32_roundtrips(x: u32) -> bool {
x == $type::from_u32(x).to_u32()
}
fn builder_u64_roundtrips(x: u64) -> bool {
x == $type::from_u64(x).to_u64()
}
}
quickcheck! {
fn partial_ord64_works(x: u64, y: u64) -> bool {
let xbig = $type::from_u64(x);
let ybig = $type::from_u64(y);
xbig.partial_cmp(&ybig) == x.partial_cmp(&y)
}
fn ord64_works(x: u64, y: u64) -> bool {
let xbig = $type::from_u64(x);
let ybig = $type::from_u64(y);
xbig.cmp(&ybig) == x.cmp(&y)
}
}
quickcheck! {
fn and_annulment(x: $type) -> bool {
(x & $type::zero()) == $type::zero()
}
fn or_annulment(x: $type) -> bool {
(x | $type::max()) == $type::max()
}
fn and_identity(x: $type) -> bool {
(&x & $type::max()) == x
}
fn or_identity(x: $type) -> bool {
(&x | $type::zero()) == x
}
fn and_idempotent(x: $type) -> bool {
(&x & &x) == x
}
fn or_idempotent(x: $type) -> bool {
(&x | &x) == x
}
fn and_complement(x: $type) -> bool {
(&x & &x) == x
}
fn or_complement(x: $type) -> bool {
(&x | !&x) == $type::max()
}
fn and_commutative(x: $type, y: $type) -> bool {
(&x & &y) == (&y & &x)
}
fn or_commutative(x: $type, y: $type) -> bool {
(&x | &y) == (&y | &x)
}
fn double_negation(x: $type) -> bool {
!!&x == x
}
fn or_distributive(a: $type, b: $type, c: $type) -> bool {
(&a & (&b | &c)) == ((&a & &b) | (&a & &c))
}
fn and_distributive(a: $type, b: $type, c: $type) -> bool {
(&a | (&b & &c)) == ((&a | &b) & (&a | &c))
}
fn or_absorption(a: $type, b: $type) -> bool {
(&a | (&a & &b)) == a
}
fn and_absorption(a: $type, b: $type) -> bool {
(&a & (&a | &b)) == a
}
fn or_associative(a: $type, b: $type, c: $type) -> bool {
(&a | (&b | &c)) == ((&a | &b) | &c)
}
fn and_associative(a: $type, b: $type, c: $type) -> bool {
(&a & (&b & &c)) == ((&a & &b) & &c)
}
fn xor_as_defined(a: $type, b: $type) -> bool {
(&a ^ &b) == ((&a | &b) & !(&a & &b))
}
fn small_or_check(x: u64, y: u64) -> bool {
let x512 = $type::from_u64(x);
let y512 = $type::from_u64(y);
let z512 = x512 | y512;
z512.to_u64() == (x | y)
}
fn small_and_check(x: u64, y: u64) -> bool {
let x512 = $type::from_u64(x);
let y512 = $type::from_u64(y);
let z512 = x512 & y512;
z512.to_u64() == (x & y)
}
fn small_xor_check(x: u64, y: u64) -> bool {
let x512 = $type::from_u64(x);
let y512 = $type::from_u64(y);
let z512 = x512 ^ y512;
z512.to_u64() == (x ^ y)
}
fn small_neg_check(x: u64) -> bool {
let x512 = $type::from_u64(x);
let z512 = !x512;
z512.to_u64() == !x
}
}
#[test]
fn shl_tests() {
let ones = [1; $count];
assert_eq!($type{ contents: ones.clone() } << 0,
$type{ contents: ones.clone() });
let mut notones = [0; $count];
for i in 0..$count {
notones[i] = (i + 1) as u64;
}
assert_eq!($type{ contents: notones.clone() } << 0,
$type{ contents: notones.clone() });
assert_eq!($type{ contents: ones.clone() } << ($count * 64),
$type::from_u64(0));
assert_eq!($type::from_u8(2) << 1, $type::from_u8(4));
let mut buffer = [0; $count];
buffer[1] = 1;
assert_eq!($type::from_u8(1) << 64,
$type{ contents: buffer.clone() });
buffer[0] = 0xFFFFFFFFFFFFFFFE;
assert_eq!($type::from_u64(0xFFFFFFFFFFFFFFFF) << 1,
$type{ contents: buffer.clone() });
buffer[0] = 0;
buffer[1] = 4;
assert_eq!($type::from_u8(1) << 66,
$type{ contents: buffer.clone() });
assert_eq!($type::from_u8(1) << 1, $type::from_u8(2));
}
#[test]
fn shr_tests() {
let ones = [1; $count];
assert_eq!($type{ contents: ones.clone() } >> 0,
$type{ contents: ones.clone() });
let mut notones = [0; $count];
for i in 0..$count {
notones[i] = (i + 1) as u64;
}
assert_eq!($type{ contents: ones.clone() } >> 0,
$type{ contents: ones.clone() });
assert_eq!($type{ contents: ones.clone() } >> ($count * 64),
$type::from_u8(0));
assert_eq!($type::from_u8(2) >> 1,
$type::from_u8(1));
let mut oneleft = [0; $count];
oneleft[1] = 1;
assert_eq!($type{ contents: oneleft.clone() } >> 1,
$type::from_u64(0x8000000000000000));
assert_eq!($type{ contents: oneleft.clone() } >> 64,
$type::from_u64(1));
oneleft[1] = 4;
assert_eq!($type{ contents: oneleft.clone() } >> 66,
$type::from_u64(1));
}
quickcheck! {
fn shift_mask_equivr(x: $type, in_shift: usize) -> bool {
let shift = in_shift % ($count * 64);
let mask = $type::max() << shift;
let masked_x = &x & mask;
let shift_maskr = (x >> shift) << shift;
shift_maskr == masked_x
}
fn shift_mask_equivl(x: $type, in_shift: usize) -> bool {
let shift = in_shift % ($count * 64);
let mask = $type::max() >> shift;
let masked_x = &x & mask;
let shift_maskl = (x << shift) >> shift;
shift_maskl == masked_x
}
}
#[test]
fn add_tests() {
let ones = [1; $count];
let twos = [2; $count];
assert_eq!($type{ contents: ones.clone() } +
$type{ contents: ones.clone() },
$type{ contents: twos.clone() });
let mut buffer = [0; $count];
buffer[1] = 1;
assert_eq!($type::from_u64(1) + $type::from_u64(0xFFFFFFFFFFFFFFFF),
$type{ contents: buffer.clone() });
let mut high = [0; $count];
high[$count - 1] = 0xFFFFFFFFFFFFFFFF;
buffer[1] = 0;
buffer[$count - 1] = 1;
assert_eq!($type{ contents: buffer } + $type{ contents: high },
$type{ contents: [0; $count] });
}
quickcheck! {
fn add_symmetry(a: $type, b: $type) -> bool {
(&a + &b) == (&b + &a)
}
fn add_commutivity(a: $type, b: $type, c: $type) -> bool {
(&a + (&b + &c)) == ((&a + &b) + &c)
}
fn add_identity(a: $type) -> bool {
(&a + $type::zero()) == a
}
}
#[test]
fn sub_tests() {
let ones = [1; $count];
assert_eq!($type{ contents: ones.clone() } -
$type{ contents: ones.clone() },
$type::from_u64(0));
let mut buffer = [0; $count];
buffer[1] = 1;
assert_eq!($type{ contents: buffer.clone() } - $type::from_u64(1),
$type::from_u64(0xFFFFFFFFFFFFFFFF));
assert_eq!($type::zero() - $type::from_u8(1), $type::max());
}
quickcheck! {
fn sub_destroys(a: $type) -> bool {
(&a - &a) == $type::zero()
}
fn sub_add_ident(a: $type, b: $type) -> bool {
((&a - &b) + &b) == a
}
}
#[test]
fn mul_tests() {
assert_eq!($type::from_u8(1) * $type::from_u8(1),
$type::from_u8(1));
assert_eq!($type::from_u8(1) * $type::from_u8(0),
$type::from_u8(0));
assert_eq!($type::from_u8(1) * $type::from_u8(2),
$type::from_u8(2));
let mut temp = $type::zero();
temp.contents[0] = 1;
temp.contents[1] = 0xFFFFFFFFFFFFFFFE;
assert_eq!($type::from_u64(0xFFFFFFFFFFFFFFFF) *
$type::from_u64(0xFFFFFFFFFFFFFFFF),
temp);
let effs = $type{ contents: [0xFFFFFFFFFFFFFFFF; $count] };
assert_eq!($type::from_u8(1) * &effs, effs);
temp = effs.clone();
temp.contents[0] = temp.contents[0] - 1;
assert_eq!($type::from_u8(2) * &effs, temp);
}
quickcheck! {
fn mul_symmetry(a: $type, b: $type) -> bool {
(&a * &b) == (&b * &a)
}
fn mul_commutivity(a: $type, b: $type, c: $type) -> bool {
(&a * (&b * &c)) == ((&a * &b) * &c)
}
fn mul_identity(a: $type) -> bool {
(&a * $type::from_u64(1)) == a
}
fn mul_zero(a: $type) -> bool {
(&a * $type::zero()) == $type::zero()
}
}
quickcheck! {
fn addmul_distribution(a: $type, b: $type, c: $type) -> bool {
(&a * (&b + &c)) == ((&a * &b) + (&a * &c))
}
fn submul_distribution(a: $type, b: $type, c: $type) -> bool {
(&a * (&b - &c)) == ((&a * &b) - (&a * &c))
}
fn mul2shift1_equiv(a: $type) -> bool {
(&a << 1) == (&a * $type::from_u64(2))
}
fn mul16shift4_equiv(a: $type) -> bool {
(&a << 4) == (&a * $type::from_u64(16))
}
}
#[test]
fn div_tests() {
assert_eq!($type::from_u8(2) / $type::from_u8(2),
$type::from_u8(1));
assert_eq!($type::from_u8(2) / $type::from_u8(1),
$type::from_u8(2));
assert_eq!($type::from_u8(4) / $type::from_u8(3),
$type::from_u8(1));
assert_eq!($type::from_u8(4) / $type::from_u8(5),
$type::from_u8(0));
assert_eq!($type::from_u8(4) / $type::from_u8(4),
$type::from_u8(1));
let mut temp1 = $type::zero();
let mut temp2 = $type::zero();
temp1.contents[$count - 1] = 4;
temp2.contents[$count - 1] = 4;
assert_eq!(&temp1 / temp2, $type::from_u8(1));
assert_eq!(&temp1 / $type::from_u8(1), temp1);
temp1.contents[$count - 1] = u64::max_value();
assert_eq!(&temp1 / $type::from_u8(1), temp1);
}
#[test]
#[should_panic]
fn div0_fails() {
$type::from_u64(0xabcd) / $type::zero();
}
#[test]
fn mod_tests() {
assert_eq!($type::from_u8(4) % $type::from_u8(5),
$type::from_u8(4));
assert_eq!($type::from_u8(5) % $type::from_u8(4),
$type::from_u8(1));
let fives = $type{ contents: [5; $count] };
let fours = $type{ contents: [4; $count] };
let ones = $type{ contents: [1; $count] };
assert_eq!(fives % fours, ones);
}
#[test]
fn divmod_tests() {
let a = $type::from_u64(4);
let b = $type::from_u64(3);
let mut q = $type::zero();
let mut r = $type::zero();
a.divmod(&b, &mut q, &mut r);
let mut x = [0; $count];
x[0] = 1;
assert_eq!(q, $type{ contents: x });
assert_eq!(r, $type{ contents: x });
}
quickcheck! {
#[ignore]
fn div_identity(a: $type) -> bool {
&a / $type::from_u64(1) == a
}
fn div_self_is_one(a: $type) -> bool {
if a == $type::zero() {
return true;
}
&a / &a == $type::from_u64(1)
}
fn euclid_is_alive(a: $type, b: $type) -> bool {
let mut q = $type::zero();
let mut r = $type::zero();
a.divmod(&b, &mut q, &mut r);
a == ((b * q) + r)
}
}
quickcheck! {
fn serialization_inverts(a: $type) -> bool {
let bytes = a.to_bytes();
let b = $type::from_bytes(&bytes);
a == b
}
}
}
};
}
macro_rules! from_to {
($type: ident, $count: expr, $base: ty, $from: ident, $to: ident) => {
/// Convert the given base type into this type. This is always safe.
pub fn $from(x: $base) -> $type {
let mut res = $type { contents: [0; $count] };
res.contents[0] = x as u64;
res
}
/// Convert this back into a base type. This is the equivalent of
/// masking off the relevant number of bits, and should work just
/// like the `as` keyword with normal word types.
pub fn $to(&self) -> $base {
self.contents[0] as $base
}
};
}
macro_rules! shifts {
($type: ident, $shtype: ty) => {
shifts!($type, $shtype, ShlAssign, shl_assign, Shl, shl, generic_shl);
shifts!($type, $shtype, ShrAssign, shr_assign, Shr, shr, generic_shr);
};
($type: ident, $shtype: ty, $asncl: ident, $asnfn: ident,
$cl: ident, $fn: ident, $impl: ident) => {
impl $asncl<$shtype> for $type {
fn $asnfn(&mut self, amount: $shtype) {
let copy = self.contents.clone();
$impl(&mut self.contents, &copy, amount as usize);
}
}
impl $cl<$shtype> for $type {
type Output = $type;
fn $fn(self, rhs: $shtype) -> $type {
let mut res = self.clone();
$impl(&mut res.contents, &self.contents, rhs as usize);
res
}
}
impl<'a> $cl<$shtype> for &'a $type {
type Output = $type;
fn $fn(self, rhs: $shtype) -> $type {
let mut res = self.clone();
$impl(&mut res.contents, &self.contents, rhs as usize);
res
}
}
}
}
macro_rules! opers2 {
($type:ident,$asncl:ident,$asnfn:ident,$cl:ident,$fn: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 {
fn $asnfn(&mut self, other: &$type) {
$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 {
($type:ident,$asncl:ident,$asnfn:ident,$cl:ident,$fn:ident,$impl:ident) => {
impl $asncl for $type {
fn $asnfn(&mut self, other: $type) {
let copy = self.contents.clone();
$impl(&mut self.contents, &copy, &other.contents);
}
}
impl<'a> $asncl<&'a $type> for $type {
fn $asnfn(&mut self, other: &$type) {
let copy = self.contents.clone();
$impl(&mut self.contents, &copy, &other.contents);
}
}
impl $cl for $type {
type Output = $type;
fn $fn(self, rhs: $type) -> $type {
let mut copy = self.clone();
$impl(&mut copy.contents, &self.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, &self.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, &self.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, &self.contents, &rhs.contents);
copy
}
}
}
}

View File

@@ -1,92 +0,0 @@
use cryptonum::basetypes::*;
use std::cmp::{Ord,Ordering};
macro_rules! generate_compares
{
($name: ident, $size: expr) => {
impl PartialEq for $name {
fn eq(&self, other: &$name) -> bool {
for i in 0..($size/64) {
if self.values[i] != other.values[i] {
return false;
}
}
true
}
}
impl Eq for $name {}
impl Ord for $name {
fn cmp(&self, other: &$name) -> Ordering {
let mut i = (($size / 64) - 1) as isize;
while i >= 0 {
let iu = i as usize;
match self.values[iu].cmp(&other.values[iu]) {
Ordering::Greater => return Ordering::Greater,
Ordering::Less => return Ordering::Less,
Ordering::Equal => i -= 1
}
}
Ordering::Equal
}
}
impl PartialOrd for $name {
fn partial_cmp(&self, other: &$name) -> Option<Ordering> {
Some(self.cmp(other))
}
}
}
}
generate_compares!(U192, 192);
generate_compares!(U256, 256);
generate_compares!(U320, 320); // this is just for expansion
generate_compares!(U384, 384);
generate_compares!(U448, 448); // this is just for expansion
generate_compares!(U512, 512);
generate_compares!(U576, 576);
generate_compares!(U640, 640); // this is just for expansion
generate_compares!(U768, 768); // this is just for expansion
generate_compares!(U832, 832); // this is just for Barrett
generate_compares!(U896, 896); // this is just for Barrett
generate_compares!(U1024, 1024);
generate_compares!(U1088, 1088); // this is just for expansion
generate_compares!(U1152, 1152); // this is just for expansion
generate_compares!(U1216, 1216); // this is just for Barrett
generate_compares!(U1536, 1536); // this is just for expansion
generate_compares!(U1664, 1664); // this is just for Barrett
generate_compares!(U2048, 2048);
generate_compares!(U2112, 2112); // this is just for expansion
generate_compares!(U2176, 2176); // this is just for Barrett
generate_compares!(U2304, 2304); // this is just for expansion
generate_compares!(U2432, 2432); // this is just for Barrett
generate_compares!(U3072, 3072);
generate_compares!(U3136, 3136); // this is just for expansion
generate_compares!(U4096, 4096);
generate_compares!(U4160, 4160); // this is just for expansion
generate_compares!(U4224, 4224); // this is just for Barrett
generate_compares!(U6144, 6144); // this is just for expansion
generate_compares!(U6208, 6208); // this is just for Barrett
generate_compares!(U7680, 7680);
generate_compares!(U7744, 7744);
generate_compares!(U8192, 8192);
generate_compares!(U8256, 8256); // this is just for expansion
generate_compares!(U8320, 8320); // this is just for Barrett
generate_compares!(U12288, 12288); // this is just for expansion
generate_compares!(U12416, 12416); // this is just for Barrett
generate_compares!(U15360, 15360);
generate_compares!(U15424, 15424); // this is just for expansion
generate_compares!(U16384, 16384); // this is just for expansion
generate_compares!(U16448, 16448); // this is just for Barrett
generate_compares!(U16512, 16512); // this is just for Barrett
generate_compares!(U30720, 30720); // this is just for expansion
generate_compares!(U30784, 30784); // this is just for Barrett
generate_compares!(U32768, 32768); // this is just for expansion
generate_compares!(U32896, 32896); // this is just for Barrett
generate_compares!(U61440, 61440); // this is just for expansion
generate_compares!(U61568, 61568); // this is just for Barrett

View File

@@ -1,143 +0,0 @@
use cryptonum::basetypes::*;
use cryptonum::encoding::Encoder;
use num::bigint::BigUint;
use num::{FromPrimitive,ToPrimitive};
macro_rules! generate_basetype_froms
{
($name: ident) => {
generate_basetype_from!($name, u8);
generate_basetype_from!($name, u16);
generate_basetype_from!($name, u32);
generate_basetype_from!($name, u64);
generate_basetype_from!($name, usize);
impl From<u128> for $name {
fn from(x: u128) -> $name {
let mut base = $name::zero();
base.values[0] = x as u64;
base.values[1] = (x >> 64) as u64;
base
}
}
impl From<BigUint> for $name {
fn from(mut x: BigUint) -> $name {
let mut res = $name::zero();
let mask = BigUint::from_u64(0xFFFFFFFFFFFFFFFF).unwrap();
for digit in res.values.iter_mut() {
*digit = (&x & &mask).to_u64().unwrap();
x >>= 64;
}
res
}
}
impl From<$name> for BigUint {
fn from(x: $name) -> BigUint {
let bytes: Vec<u8> = x.to_bytes();
BigUint::from_bytes_be(&bytes)
}
}
}
}
macro_rules! generate_basetype_from
{
($name: ident, $basetype: ident) => {
impl From<$basetype> for $name {
fn from(x: $basetype) -> $name {
let mut base = $name::zero();
base.values[0] = x as u64;
base
}
}
impl From<$name> for $basetype {
fn from(x: $name) -> $basetype {
x.values[0] as $basetype
}
}
}
}
macro_rules! convert_from_smaller
{
($name: ident, $smalltype: ident) => {
impl<'a> From<&'a $smalltype> for $name {
fn from(x: &$smalltype) -> $name {
let mut base = $name::zero();
for (idx, val) in x.values.iter().enumerate() {
base.values[idx] = *val;
}
base
}
}
impl From<$smalltype> for $name {
fn from(x: $smalltype) -> $name {
let mut base = $name::zero();
for (idx, val) in x.values.iter().enumerate() {
base.values[idx] = *val;
}
base
}
}
}
}
macro_rules! convert_from_larger
{
($name: ident, $bigtype: ident) => {
impl<'a> From<&'a $bigtype> for $name {
fn from(x: &$bigtype) -> $name {
let mut base = $name::zero();
for i in 0..base.values.len() {
base.values[i] = x.values[i];
}
base
}
}
}
}
macro_rules! convert_bignums
{
($smaller: ident, $bigger: ident) => {
convert_from_smaller!($bigger, $smaller);
convert_from_larger!($smaller, $bigger);
}
}
macro_rules! expand_bignums
{
($smaller: ident, $bigger: ident $(, $rest: ident)* ) => {
convert_bignums!($smaller, $bigger);
expand_bignums!($smaller, $($rest),*);
};
($smaller: ident, $(,)*) => {};
() => {}
}
macro_rules! exhaustive_expansion
{
() => {};
($last: ident) => {
generate_basetype_froms!($last);
};
($smallest: ident $(, $other: ident)*) => {
generate_basetype_froms!($smallest);
expand_bignums!($smallest, $($other),*);
exhaustive_expansion!($($other),*);
};
}
exhaustive_expansion!(U192, U256, U320, U384, U448, U512, U576,
U640, U768, U832, U896, U1024, U1088, U1152,
U1216, U1536, U1664, U2048, U2112, U2176, U2304,
U2432, U3072, U3136, U4096, U4224, U4160, U6144,
U6208, U7680, U7744, U8192, U8256, U8320, U12288,
U12416, U15360, U15424, U16384, U16448, U16512, U30720,
U30784, U32768, U32896, U61440, U61568);

View File

@@ -1,257 +0,0 @@
use cryptonum::basetypes::*;
pub trait ModReduce<T=Self> {
fn reduce(&self, value: &T) -> T;
}
macro_rules! safesubidx
{
($array: expr, $index: expr, $amt: expr) => ({
let idx = $index;
let amt = $amt;
if idx < amt {
0
} else {
$array[idx-amt]
}
})
}
macro_rules! generate_dividers
{
($name: ident, $bigger: ident) => {
impl $name {
// This is based on algorithm 14.20 from the Handbook of Applied
// Cryptography, slightly modified.
pub fn divmod(&self, rhs: &$name) -> ($name, $name) {
// if the divisor is larger, then the answer is pretty simple
if rhs > self {
return ($name::zero(), self.clone());
}
// compute the basic number sizes
let mut n = match get_number_size(&self.values) {
None => 0,
Some(v) => v
};
let t = match get_number_size(&rhs.values) {
None => panic!("Division by zero!"),
Some(v) => v
};
assert!(t <= n);
// now generate mutable versions we can mess with
let mut x = $bigger::from(self);
let mut y = $bigger::from(rhs);
// If we want this to perform reasonable, it's useful if the
// value of y[t] is shifted so that the high bit is set.
let lambda_shift = y.values[t].leading_zeros() as usize;
if lambda_shift != 0 {
shiftl(&mut x.values, lambda_shift);
shiftl(&mut y.values, lambda_shift);
n = get_number_size(&x.values).unwrap();
}
// now go!
// 1. For j from 0 to (n-t) do: q[j] = 0;
// [NB: I take some liberties with this concept]
let mut q = $bigger::zero();
// 2. While (x >= y * b^(n-t)) do the following:
let mut ybnt = $bigger::zero();
for i in 0..self.values.len() {
ybnt.values[(n-t)+i] = y.values[i];
if (n-t)+i >= ybnt.values.len() {
break;
}
}
while x > ybnt {
q.values[n - t] += 1;
x -= &ybnt;
}
// 3. For i from n down to t+1 do the following:
let mut i = n;
while i >= (t + 1) {
// 3.1. If x[i] = y[t]
if x.values[i] == y.values[t] {
// ... then set q[i-t-1] = b - 1
q.values[i-t-1] = 0xFFFFFFFFFFFFFFFF;
} else {
// ... otherwise set q[i-t-1] =
// floor((x[i] * b + x[i-1]) / y[t])
let xib = (x.values[i] as u128) << 64;
let xi1 = safesubidx!(x.values,i,1) as u128;
let yt = y.values[t] as u128;
let qit1 = (xib + xi1) / yt;
q.values[i-t-1] = qit1 as u64;
}
// 3.2. While q[i-t-1] * (y[t]*b + y[t-1]) >
// (x[i] * b^2 + x[i-1] * b + x[i-2])
loop {
// three is very close to 2.
let qit1 = U192::from(safesubidx!(q.values,i-t,1));
let mut ybits = U192::zero();
ybits.values[0] = safesubidx!(y.values, t, 1);
ybits.values[1] = y.values[t];
let qiybs = &qit1 * &ybits;
let mut xbits = U384::zero();
xbits.values[0] = safesubidx!(x.values,i,2);
xbits.values[1] = safesubidx!(x.values,i,1);
xbits.values[2] = x.values[i];
if !(&qiybs > &xbits) {
break;
}
// ... do q[i-t-1] = q[i-t-1] - 1
q.values[i-t-1] -= 1;
}
// 3.3. x = x - q[i-t-1] * y * b^(i-t-1)
// 3.4. If x < 0
// then set x = x + y * b^(i-t-1) and
// q[i-t-1] = q[i-t-1] - 1
let mut qbit1 = $name::zero();
qbit1.values[i-t-1] = q.values[i-t-1];
let smallery = $name::from(&y);
let mut subpart = &smallery * &qbit1;
if subpart > x {
let mut addback = $bigger::zero();
for (idx, val) in y.values.iter().enumerate() {
let dest = idx + (i - t - 1);
if dest < addback.values.len() {
addback.values[dest] = *val;
}
}
q.values[i-t-1] -= 1;
subpart -= &addback;
}
assert!(subpart <= x);
x -= &subpart;
i -= 1;
}
// 4. r = x ... sort of. Remember, we potentially did a bit of shifting
// around at the very beginning, which we now need to account for. On the
// bright side, we only need to account for this in the remainder.
let mut r = $name::from(&x);
shiftr(&mut r.values, lambda_shift);
// 5. Return (q,r)
let resq = $name::from(&q);
(resq, r)
}
}
impl ModReduce for $name {
fn reduce(&self, value: &$name) -> $name {
let (_, res) = self.divmod(value);
res
}
}
}
}
fn shiftl(x: &mut [u64], amt: usize)
{
let mut carry = 0;
for v in x.iter_mut() {
let new_carry = *v >> (64 - amt);
*v = (*v << amt) | carry;
carry = new_carry;
}
assert!(carry == 0);
}
fn shiftr(x: &mut [u64], amt: usize)
{
let mut carry = 0;
for val in x.iter_mut().rev() {
let mask = !(0xFFFFFFFFFFFFFFFF << amt);
let newcarry = *val & mask;
*val = (*val >> amt) | carry;
carry = newcarry;
}
}
fn get_number_size(v: &[u64]) -> Option<usize>
{
for (idx, val) in v.iter().enumerate().rev() {
if *val != 0 {
return Some(idx);
}
}
None
}
generate_dividers!(U192, U384);
generate_dividers!(U256, U512);
generate_dividers!(U384, U768);
generate_dividers!(U448, U896);
generate_dividers!(U512, U1024);
generate_dividers!(U576, U1152);
generate_dividers!(U768, U1536);
generate_dividers!(U832, U1664);
generate_dividers!(U1024, U2048);
generate_dividers!(U1088, U2176);
generate_dividers!(U1152, U2304);
generate_dividers!(U1216, U2432);
generate_dividers!(U2048, U4096);
generate_dividers!(U2112, U4224);
generate_dividers!(U3072, U6144);
generate_dividers!(U4096, U8192);
generate_dividers!(U4160, U8320);
generate_dividers!(U6144, U12288);
generate_dividers!(U6208, U12416);
generate_dividers!(U7680, U15360);
generate_dividers!(U8192, U16384);
generate_dividers!(U8256, U16512);
generate_dividers!(U15360, U30720);
generate_dividers!(U16384, U32768);
generate_dividers!(U16448, U32896);
generate_dividers!(U30720, U61440);
generate_dividers!(U30784, U61568);
#[cfg(test)]
mod normal {
use testing::run_test;
use cryptonum::Decoder;
use cryptonum::{U192,U256,U384,U512,U576,U1024,
U2048,U3072,U4096,U8192,U15360};
macro_rules! generate_tests {
($name: ident) => (
#[cfg(test)]
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/division{}.test",
stringify!($name));
run_test(fname.to_string(), 4, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, qbytes) = case.get("q").unwrap();
let (neg3, rbytes) = case.get("r").unwrap();
assert!(!neg0 && !neg1 && !neg2 && !neg3);
let a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let q = $name::from_bytes(qbytes);
let r = $name::from_bytes(rbytes);
let (myq, myr) = a.divmod(&b);
assert_eq!(q, myq);
assert_eq!(r, myr);
});
}
)
}
generate_tests!(U192);
generate_tests!(U256);
generate_tests!(U384);
generate_tests!(U512);
generate_tests!(U576);
generate_tests!(U1024);
generate_tests!(U2048);
generate_tests!(U3072);
generate_tests!(U4096);
generate_tests!(U8192);
generate_tests!(U15360);
}

View File

@@ -1,224 +0,0 @@
use cryptonum::basetypes::*;
pub trait Decoder {
fn from_bytes(x: &[u8]) -> Self;
}
pub trait Encoder {
fn to_bytes(&self) -> Vec<u8>;
}
pub(crate) fn raw_decoder(input: &[u8], output: &mut [u64])
{
let mut item = 0;
let mut shift = 0;
let mut idx = 0;
for v in input.iter().rev() {
item |= (*v as u64) << shift;
shift += 8;
if shift == 64 {
shift = 0;
output[idx] = item;
idx += 1;
item = 0;
}
}
if item != 0 {
output[idx] = item;
}
}
macro_rules! generate_decoder {
($name: ident) => {
impl Decoder for $name {
fn from_bytes(x: &[u8]) -> $name {
let mut res = $name::zero();
raw_decoder(x, &mut res.values);
res
}
}
}
}
macro_rules! generate_encoder {
($name: ident) => {
impl Encoder for $name {
fn to_bytes(&self) -> Vec<u8> {
let mut res = Vec::with_capacity(self.values.len() * 8);
for v in self.values.iter().rev() {
let val = *v;
res.push( (val >> 56) as u8);
res.push( (val >> 48) as u8);
res.push( (val >> 40) as u8);
res.push( (val >> 32) as u8);
res.push( (val >> 24) as u8);
res.push( (val >> 16) as u8);
res.push( (val >> 8) as u8);
res.push( (val >> 0) as u8);
}
res
}
}
}
}
macro_rules! generate_codec
{
($name: ident) => {
generate_decoder!($name);
generate_encoder!($name);
}
}
generate_codec!(U192);
generate_codec!(U256);
generate_codec!(U320); // this is just for expansion
generate_codec!(U384);
generate_codec!(U448); // this is just for expansion
generate_codec!(U512);
generate_codec!(U576);
generate_codec!(U640); // this is just for expansion
generate_codec!(U768); // this is just for expansion
generate_codec!(U832); // this is just for expansion
generate_codec!(U896); // this is just for expansion
generate_codec!(U1024);
generate_codec!(U1088); // this is just for expansion
generate_codec!(U1152); // this is just for expansion
generate_codec!(U1216); // this is just for expansion
generate_codec!(U1536); // this is just for expansion
generate_codec!(U1664); // this is just for expansion
generate_codec!(U2048);
generate_codec!(U2112); // this is just for expansion
generate_codec!(U2176); // this is just for expansion
generate_codec!(U2304); // this is just for expansion
generate_codec!(U2432); // this is just for expansion
generate_codec!(U3072);
generate_codec!(U3136); // this is just for expansion
generate_codec!(U4224); // this is just for expansion
generate_codec!(U4096);
generate_codec!(U4160); // this is just for expansion
generate_codec!(U6144); // this is just for expansion
generate_codec!(U6208); // this is just for expansion
generate_codec!(U7680);
generate_codec!(U7744);
generate_codec!(U8192);
generate_codec!(U8256); // this is just for expansion
generate_codec!(U8320); // this is just for expansion
generate_codec!(U12288); // this is just for expansion
generate_codec!(U12416); // this is just for expansion
generate_codec!(U15360);
generate_codec!(U15424); // this is just for expansion
generate_codec!(U16384); // this is just for expansion
generate_codec!(U16448); // this is just for expansion
generate_codec!(U16512); // this is just for expansion
generate_codec!(U30720); // this is just for expansion
generate_codec!(U30784); // this is just for expansion
generate_codec!(U32768); // this is just for expansion
generate_codec!(U32896); // this is just for expansion
generate_codec!(U61440); // this is just for expansion
generate_codec!(U61568); // this is just for expansion
macro_rules! generate_tests
{
( $( ($name: ident, $num: ident, $size: expr) ),* ) => {
$(
#[cfg(test)]
mod $name {
use cryptonum::basetypes::{CryptoNum,$num};
use cryptonum::encoding::{Decoder,Encoder};
use quickcheck::{Arbitrary,Gen};
#[derive(Clone,Debug)]
struct MyBuffer {
x: Vec<u8>
}
impl Arbitrary for $num {
fn arbitrary<G: Gen>(g: &mut G) -> $num {
let mut res = $num::zero();
for v in res.values.iter_mut() {
*v = g.gen::<u64>();
}
res
}
}
impl Arbitrary for MyBuffer {
fn arbitrary<G: Gen>(g: &mut G) -> MyBuffer {
let len = $size / 8;
let mut res = Vec::with_capacity(len);
for _ in 0..len {
res.push(g.gen::<u8>());
}
MyBuffer{ x: res }
}
}
quickcheck! {
fn i2o2i(x: $num) -> bool {
let bstr = x.to_bytes();
let x2 = $num::from_bytes(&bstr);
x == x2
}
fn o2i2o(x: MyBuffer) -> bool {
let val = $num::from_bytes(&x.x);
let x2 = val.to_bytes();
x.x == x2
}
}
}
)*
}
}
generate_tests!((u192, U192, 192),
(u256, U256, 256),
(u320, U320, 320), // this is just for expansion
(u384, U384, 384),
(u448, U448, 448), // this is just for expansion
(u512, U512, 512),
(u576, U576, 576),
(u640, U640, 640), // this is just for expansion
(u768, U768, 768), // this is just for expansion
(u832, U832, 832), // this is just for Barrett
(u896, U896, 896), // this is just for Barrett
(u1024, U1024, 1024),
(u1088, U1088, 1088), // this is just for expansion
(u1152, U1152, 1152), // this is just for expansion
(u1216, U1216, 1216), // this is just for Barrett
(u1536, U1536, 1536), // this is just for expansion
(u1664, U1664, 1664), // this is just for Barrett
(u2048, U2048, 2048),
(u2112, U2112, 2112), // this is just for expansion
(u2176, U2176, 2176), // this is just for Barrett
(u2304, U2304, 2304), // this is just for expansion
(u2432, U2432, 2432), // this is just for Barrett
(u3072, U3072, 3072),
(u3136, U3136, 3136), // this is just for expansion
(u4096, U4096, 4096),
(u4160, U4160, 4160), // this is just for expansion
(u4224, U4224, 4224), // this is just for Barrett
(u6144, U6144, 6144), // this is just for expansion
(u6208, U6208, 6208), // this is just for Barrett
(u7680, U7680, 7680),
(u7744, U7744, 7744),
(u8192, U8192, 8192),
(u8256, U8256, 8256), // this is just for expansion
(u8320, U8320, 8320), // this is just for Barrett
(u12288, U12288, 12288), // this is just for expansion
(u12416, U12416, 12416), // this is just for Barrett
(u15360, U15360, 15360),
(u15424, U15424, 15424), // this is just for expansion
(u16384, U16384, 16384), // this is just for expansion
(u16448, U16448, 16448), // this is just for Barrett
(u16512, U16512, 16512), // this is just for Barrett
(u30720, U30720, 30720), // this is just for expansion
(u30784, U30784, 30784), // this is just for Barrett
(u32768, U32768, 32768), // this is just for expansion
(u32896, U32896, 32896), // this is just for Barrett
(u61440, U61440, 61440), // this is just for expansion
(u61568, U61568, 61568)); // this is just for Barrett

View File

@@ -1,26 +0,0 @@
//! # Simple-Crypto CryptoNum
//!
//! This module is designed to provide large, fixed-width number support for
//! the rest of the Simple-Crypto libraries. Feel free to use it other places,
//! of course, but that's its origin.
//!
mod addition;
mod barrett;
mod basetypes;
mod comparison;
mod conversions;
mod division;
mod encoding;
mod modmath;
mod multiplication;
mod shifts;
mod signed;
mod squaring;
mod subtraction;
pub use self::barrett::*;
pub use self::basetypes::*;
pub use self::encoding::{Decoder,Encoder};
pub use self::signed::Signed;
#[allow(unused)]
pub(crate) use self::modmath::{ModExp,ModInv};

View File

@@ -1,543 +0,0 @@
use cryptonum::addition::UnsafeAdd;
use cryptonum::basetypes::*;
use cryptonum::barrett::*;
use cryptonum::signed::*;
pub trait ModAdd<T2> {
fn modadd(&mut self, y: &Self, m: &T2);
}
pub trait ModMul<T> {
fn modmul(&mut self, x: &Self, m: &T);
}
pub trait ModSquare<T> {
fn modsq(&mut self, m: &T);
}
pub trait ModExp<T> {
fn modexp(&self, e: &Self, m: &T) -> Self;
}
pub trait ModInv
where Self: Sized
{
fn modinv(&self, phi: Self) -> Option<Self>;
}
macro_rules! generate_modmath_funs
{
($name: ident, $big: ident, $dbl: ident, $bar: ident, $size: expr) => {
impl ModAdd<$big> for $name {
fn modadd(&mut self, y: &$name, m: &$big) {
let mut base = &self.clone() + y;
if &base > m {
base -= m;
if &base > m {
base -= m;
}
}
self.values.copy_from_slice(&base.values[0..$size/64]);
}
}
impl ModMul<$name> for $name {
fn modmul(&mut self, x: &$name, m: &$name) {
let mulres = (self as &$name) * &x;
let bigm = $dbl::from(m);
let (_, bigres) = mulres.divmod(&bigm);
self.values.copy_from_slice(&bigres.values[0..$size/64]);
}
}
impl ModMul<$bar> for $name {
fn modmul(&mut self, x: &$name, m: &$bar) {
let mut mulres = (self as &$name) * &x;
let bigres = m.reduce(&mut mulres);
self.values.copy_from_slice(&bigres.values[0..$size/64]);
}
}
impl ModSquare<$name> for $name {
fn modsq(&mut self, m: &$name) {
let bigsquare = self.square();
let bigm = $dbl::from(m);
let (_, res) = bigsquare.divmod(&bigm);
self.values.copy_from_slice(&res.values[0..$size/64]);
}
}
impl ModSquare<$bar> for $name {
fn modsq(&mut self, m: &$bar) {
let bigsquare = self.square();
let bigres = m.reduce(&bigsquare);
self.values.copy_from_slice(&bigres.values[0..$size/64]);
}
}
impl<T> ModExp<T> for $name
where $name: ModMul<T> + ModSquare<T>
{
#[inline]
fn modexp(&self, ine: &$name, m: &T) -> $name {
// S <- g
let mut s = self.clone();
// A <- 1
let mut a = $name::from(1u64);
// We do a quick skim through and find the highest index that
// actually has a value in it.
let mut e = ine.clone();
// While e != 0 do the following:
while e.values.iter().any(|x| *x != 0) {
// If e is odd then A <- A * S
if e.values[0] & 1 != 0 {
a.modmul(&s, m);
}
// e <- floor(e / 2)
let mut carry = 0;
e.values.iter_mut().rev().for_each(|x| {
let new_carry = *x & 1;
*x = (*x >> 1) | (carry << 63);
carry = new_carry;
});
// If e != 0 then S <- S * S
s.modsq(m);
}
// Return A
a
}
}
impl ModInv for $name {
fn modinv(&self, phi: $name)
-> Option<$name>
{
let (_, _d, v) = self.egcd(phi);
if v != Signed::new(false, $name::from(1u64)) {
return None;
}
panic!("modinv stuff")
}
}
impl $name {
fn egcd(&self, rhs: $name)
-> (Signed<$name>, Signed<$name>, Signed<$name>)
{
println!("---------------------------------------------------");
// INPUT: two positive integers x and y.
let mut x = Signed::new(false, self.clone());
let mut y = Signed::new(false, rhs);
// OUTPUT: integers a, b, and v such that ax + by = v,
// where v = gcd(x, y).
// 1. g←1.
let mut gshift = 0;
// 2. While x and y are both even, do the following: x←x/2,
// y←y/2, g←2g.
while x.is_even() && y.is_even() {
x >>= 1;
y >>= 1;
gshift += 1;
}
// 3. u←x, v←y, A←1, B←0, C←0, D←1.
let mut u: Signed<$name> = x.clone();
let mut v: Signed<$name> = y.clone();
#[allow(non_snake_case)]
let mut A: Signed<$name> = Signed::new(false, $name::from(1u64));
#[allow(non_snake_case)]
let mut B: Signed<$name> = Signed::new(false, $name::zero());
#[allow(non_snake_case)]
let mut C: Signed<$name> = Signed::new(false, $name::zero());
#[allow(non_snake_case)]
let mut D: Signed<$name> = Signed::new(false, $name::from(1u64));
loop {
println!("START");
println!("u: {}{:X}", pos_space(&u), u);
println!("v: {}{:X}", pos_space(&v), v);
println!("A: {}{:X}", pos_space(&A), A);
println!("B: {}{:X}", pos_space(&B), B);
println!("C: {}{:X}", pos_space(&C), C);
println!("D: {}{:X}", pos_space(&D), D);
// 4. While u is even do the following:
while u.is_even() {
// 4.1 u←u/2.
u >>= 1;
// 4.2 If A≡B≡0 (mod 2) then A←A/2, B←B/2; otherwise,
// A←(A + y)/2, B←(B x)/2.
if A.is_even() && B.is_even() {
A >>= 1;
B >>= 1;
} else {
let mut big_A: Signed<$big> = &A + &y;
big_A >>= 1;
A = Signed::new(big_A.negative, $name::from(&big_A.value));
B -= &x;
B >>= 1;
}
}
println!("AFTER 4");
println!("u: {}{:X}", pos_space(&u), u);
println!("v: {}{:X}", pos_space(&v), v);
println!("A: {}{:X}", pos_space(&A), A);
println!("B: {}{:X}", pos_space(&B), B);
println!("C: {}{:X}", pos_space(&C), C);
println!("D: {}{:X}", pos_space(&D), D);
// 5. While v is even do the following:
while v.is_even() {
// 5.1 v←v/2.
v >>= 1;
// 5.2 If C ≡ D ≡ 0 (mod 2) then C←C/2, D←D/2; otherwise,
// C←(C + y)/2, D←(D x)/2.
if C.is_even() && D.is_even() {
C >>= 1;
D >>= 1;
} else {
C = C.unsafe_add(&y);
C >>= 1;
D -= &x;
D >>= 1;
}
}
println!("AFTER 5");
println!("u: {}{:X}", pos_space(&u), u);
println!("v: {}{:X}", pos_space(&v), v);
println!("A: {}{:X}", pos_space(&A), A);
println!("B: {}{:X}", pos_space(&B), B);
println!("C: {}{:X}", pos_space(&C), C);
println!("D: {}{:X}", pos_space(&D), D);
// 6. If u≥v then u←uv, A←AC,B←BD;
// otherwise,v←vu, C←CA, D←DB.
if u >= v {
u -= &v;
A -= &C;
B -= &D;
} else {
v -= &u;
C -= &A;
D -= &B;
}
// 7. If u = 0, then a←C, b←D, and return(a, b, g · v);
// otherwise, go to step 4.
println!("AFTER 6");
println!("u: {}{:X}", pos_space(&u), u);
println!("v: {}{:X}", pos_space(&v), v);
println!("A': {}{:X}", pos_space(&A), A);
println!("B': {}{:X}", pos_space(&B), B);
println!("C': {}{:X}", pos_space(&C), C);
println!("D': {}{:X}", pos_space(&D), D);
if u.is_zero() {
return (C, D, v << gshift);
}
}
}
}
}
}
generate_modmath_funs!(U192, U256, U384, BarrettU192, 192);
generate_modmath_funs!(U256, U320, U512, BarrettU256, 256);
generate_modmath_funs!(U384, U448, U768, BarrettU384, 384);
generate_modmath_funs!(U512, U576, U1024, BarrettU512, 512);
generate_modmath_funs!(U1024, U1088, U2048, BarrettU1024, 1024);
generate_modmath_funs!(U2048, U2112, U4096, BarrettU2048, 2048);
generate_modmath_funs!(U3072, U3136, U6144, BarrettU3072, 3072);
generate_modmath_funs!(U4096, U4160, U8192, BarrettU4096, 4096);
generate_modmath_funs!(U8192, U8256, U16384, BarrettU8192, 8192);
generate_modmath_funs!(U15360, U15424, U30720, BarrettU15360, 15360);
macro_rules! generate_tests {
( $( ($name:ident, $barrett: ident, $bigger: ident, $dbl: ident) ),* ) => {
#[cfg(test)]
mod addition {
use cryptonum::encoding::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/modadd{}.test",
stringify!($name));
run_test(fname.to_string(), 4, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, cbytes) = case.get("c").unwrap();
let (neg3, mbytes) = case.get("m").unwrap();
assert!(!neg0 && !neg1 && !neg2 && !neg3);
let mut a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let m = $bigger::from_bytes(mbytes);
let c = $name::from_bytes(cbytes);
a.modadd(&b, &m);
assert_eq!(a, c);
});
}
)*
}
#[cfg(test)]
mod multiplication {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/modmul{}.test",
stringify!($name));
run_test(fname.to_string(), 4, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, mbytes) = case.get("m").unwrap();
let (neg3, cbytes) = case.get("c").unwrap();
assert!(!neg0 && !neg1 && !neg2 && !neg3);
let mut a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let m = $name::from_bytes(mbytes);
let c = $name::from_bytes(cbytes);
a.modmul(&b, &m);
assert_eq!(a, c);
});
}
)*
}
#[cfg(test)]
mod barrett_multiplication {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/barrett_mul{}.test",
stringify!($name));
run_test(fname.to_string(), 6, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, mbytes) = case.get("m").unwrap();
let (neg3, rbytes) = case.get("r").unwrap();
let (neg4, kbytes) = case.get("k").unwrap();
let (neg5, ubytes) = case.get("u").unwrap();
assert!(!neg0&&!neg1&&!neg2&&!neg3&&!neg4&&!neg5);
let mut a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let m = $bigger::from_bytes(mbytes);
let r = $name::from_bytes(rbytes);
let k = $name::from_bytes(kbytes);
let u = $bigger::from_bytes(ubytes);
let mu = $barrett{ k: k.values[0] as usize, m:m, mu:u };
a.modmul(&b, &mu);
assert_eq!(a, r);
});
}
)*
}
#[cfg(test)]
mod modsq {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/modsq{}.test",
stringify!($name));
run_test(fname.to_string(), 5, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg2, mbytes) = case.get("m").unwrap();
let (neg3, rbytes) = case.get("r").unwrap();
assert!(!neg0&&!neg2&&!neg3);
let mut a = $name::from_bytes(abytes);
let m = $name::from_bytes(mbytes);
let r = $name::from_bytes(rbytes);
a.modsq(&m);
assert_eq!(a, r);
});
}
)*
}
#[cfg(test)]
mod barrett_squaring {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/modsq{}.test",
stringify!($name));
run_test(fname.to_string(), 5, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg2, mbytes) = case.get("m").unwrap();
let (neg3, rbytes) = case.get("r").unwrap();
let (neg4, kbytes) = case.get("k").unwrap();
let (neg5, ubytes) = case.get("u").unwrap();
assert!(!neg0&&!neg2&&!neg3&&!neg4&&!neg5);
let mut a = $name::from_bytes(abytes);
let m = $bigger::from_bytes(mbytes);
let r = $name::from_bytes(rbytes);
let k = $name::from_bytes(kbytes);
let u = $bigger::from_bytes(ubytes);
let mu = $barrett{ k: k.values[0] as usize, m:m, mu:u };
a.modsq(&mu);
assert_eq!(a, r);
});
}
)*
}
#[cfg(test)]
mod modexp {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
#[ignore]
fn $name() {
let fname = format!("tests/math/modexp{}.test",
stringify!($name));
run_test(fname.to_string(), 6, |case| {
let (neg0, bbytes) = case.get("b").unwrap();
let (neg1, ebytes) = case.get("e").unwrap();
let (neg2, mbytes) = case.get("m").unwrap();
let (neg3, rbytes) = case.get("r").unwrap();
assert!(!neg0&&!neg1&&!neg2&&!neg3);
let b = $name::from_bytes(bbytes);
let e = $name::from_bytes(ebytes);
let m = $name::from_bytes(mbytes);
let r = $name::from_bytes(rbytes);
let me = b.modexp(&e, &m);
assert_eq!(me, r);
});
}
)*
}
#[cfg(test)]
mod barrett_exponentiation {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/modexp{}.test",
stringify!($name));
run_test(fname.to_string(), 6, |case| {
let (neg0, bbytes) = case.get("b").unwrap();
let (neg1, ebytes) = case.get("e").unwrap();
let (neg2, mbytes) = case.get("m").unwrap();
let (neg3, rbytes) = case.get("r").unwrap();
let (neg4, kbytes) = case.get("k").unwrap();
let (neg5, ubytes) = case.get("u").unwrap();
assert!(!neg0&&!neg1&&!neg2&&!neg3&&!neg4&&!neg5);
let b = $name::from_bytes(bbytes);
let e = $name::from_bytes(ebytes);
let m = $bigger::from_bytes(mbytes);
let r = $name::from_bytes(rbytes);
let k = $name::from_bytes(kbytes);
let u = $bigger::from_bytes(ubytes);
let mu = $barrett{ k: k.values[0] as usize, m:m, mu:u };
let me = b.modexp(&e, &mu);
assert_eq!(me, r);
});
}
)*
}
#[cfg(test)]
mod egcd {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/egcd{}.test",
stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (nega, abytes) = case.get("a").unwrap();
let (negb, bbytes) = case.get("b").unwrap();
let (negg, gbytes) = case.get("g").unwrap();
assert!(!nega && !negb);
let a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let ug = $dbl::from_bytes(gbytes);
let g = Signed::new(*negg, ug.clone());
let (mys, myt, myg) = a.egcd(b.clone());
let mybigg = Signed::new(g.negative, $dbl::from(&myg.value));
println!("mybigg: {}{:X}", pos_space(&mybigg), mybigg.value);
println!("g : {}{:X}", pos_space(&g), g.value);
assert_eq!(mybigg, g);
let part1: $dbl = &mys.value * &a;
let part2: $dbl = &myt.value * &b;
let mut spart1 = Signed::new(mys.negative, part1);
let spart2 = Signed::new(myt.negative, part2);
spart1 -= &spart2;
println!("spart1: {}{:X}", pos_space(&spart1), spart1);
println!("spart1: {}{:X}", pos_space(&spart2), spart2);
assert_eq!(spart1, g);
});
}
)*
}
}
}
generate_tests!((U192, BarrettU192, U256, U384),
(U256, BarrettU256, U320, U512),
(U384, BarrettU384, U448, U768),
(U512, BarrettU512, U576, U1024),
(U1024, BarrettU1024, U1088, U2048),
(U2048, BarrettU2048, U2112, U4096),
(U3072, BarrettU3072, U3136, U6144),
(U4096, BarrettU4096, U4160, U8192),
(U8192, BarrettU8192, U8256, U16384),
(U15360, BarrettU15360, U15424, U30720));
//generate_tests!((U192, I192, BarrettU192, U256),
// (U256, I256, BarrettU256, U320),
// (U384, I384, BarrettU384, U448),
// (U512, I512, BarrettU512, U576),
// (U1024, I1024, BarrettU1024, U1088),
// (U2048, I2048, BarrettU2048, U2112),
// (U3072, I3072, BarrettU3072, U3136),
// (U4096, I4096, BarrettU4096, U4160),
// (U8192, I8192, BarrettU8192, U8256),
// (U15360, I15360, BarrettU15360, U15424));
fn pos_space<T>(x: &Signed<T>) -> &'static str {
if !x.negative {
return " ";
}
""
}

View File

@@ -1,103 +0,0 @@
use cryptonum::basetypes::*;
use std::ops::Mul;
macro_rules! generate_multipliers
{
($name: ident, $bigger: ident, $size: expr) => {
impl<'a,'b> Mul<&'a $name> for &'b $name {
type Output = $bigger;
fn mul(self, rhs: &$name) -> $bigger {
let mut w = $bigger::zero();
let len = $size/64;
for i in 0..len {
let mut carry = 0;
for j in 0..len {
let old = w.values[i+j] as u128;
let x128 = self.values[j] as u128;
let y128 = rhs.values[i] as u128;
let uv = old + (x128 * y128) + carry;
w.values[i+j] = uv as u64;
carry = uv >> 64;
}
w.values[i+len] = carry as u64;
}
w
}
}
}
}
generate_multipliers!(U192, U384, 192);
generate_multipliers!(U256, U512, 256);
generate_multipliers!(U384, U768, 384);
generate_multipliers!(U448, U896, 448);
generate_multipliers!(U512, U1024, 512);
generate_multipliers!(U576, U1152, 576);
generate_multipliers!(U768, U1536, 768);
generate_multipliers!(U832, U1664, 832);
generate_multipliers!(U1024, U2048, 1024);
generate_multipliers!(U1088, U2176, 1088);
generate_multipliers!(U1152, U2304, 1152);
generate_multipliers!(U1216, U2432, 1216);
generate_multipliers!(U1536, U3072, 1536);
generate_multipliers!(U2048, U4096, 2048);
generate_multipliers!(U2112, U4224, 2112);
generate_multipliers!(U3072, U6144, 3072);
generate_multipliers!(U4096, U8192, 4096);
generate_multipliers!(U4160, U8320, 4160);
generate_multipliers!(U6144, U12288, 6144);
generate_multipliers!(U6208, U12416, 6208);
generate_multipliers!(U7680, U15360, 7680);
generate_multipliers!(U8192, U16384, 8192);
generate_multipliers!(U8256, U16512, 8256);
generate_multipliers!(U15360, U30720, 15360);
generate_multipliers!(U16384, U32768, 16384);
generate_multipliers!(U16448, U32896, 16448);
generate_multipliers!(U30720, U61440, 30720);
generate_multipliers!(U30784, U61568, 30784);
macro_rules! generate_tests {
( $( ($name:ident, $bigger:ident) ),* ) => {
#[cfg(test)]
mod normal {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/multiplication{}.test",
stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, cbytes) = case.get("c").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let c = $bigger::from_bytes(cbytes);
assert_eq!(&a * &b, c);
});
}
)*
}
}
}
generate_tests!((U192, U384),
(U256, U512),
(U384, U768),
(U512, U1024),
(U576, U1152),
(U1024, U2048),
(U2048, U4096),
(U3072, U6144),
(U4096, U8192),
(U8192, U16384),
(U15360, U30720));

View File

@@ -1,160 +0,0 @@
use cryptonum::basetypes::*;
use std::ops::{Shl,ShrAssign};
macro_rules! generate_shifts
{
($num: ident, $size: expr) => {
impl ShrAssign<usize> for $num {
fn shr_assign(&mut self, amt: usize) {
let digits = amt / 64;
let bits = amt % 64;
let mut carry = 0;
let mask = !(0xFFFFFFFFFFFFFFFF << bits);
let copy = self.values.clone();
let shift = (64 - bits) as u32;
for (idx, val) in self.values.iter_mut().enumerate().rev() {
let target = idx + digits;
let base = if target >= ($size/64) { 0 } else { copy[target] };
let (new_carry, _) = (base & mask).overflowing_shl(shift);
*val = (base >> bits) | carry;
carry = new_carry;
}
}
}
impl Shl<usize> for $num {
type Output = $num;
fn shl(mut self, amt: usize) -> $num {
let digits = amt / 64;
let bits = amt % 64;
let mut carry = 0;
let copy = self.values.clone();
let shift = 64 - bits;
for (idx, val) in self.values.iter_mut().enumerate() {
let base = if idx >= digits { copy[idx - digits] } else { 0 };
let new_carry = if shift == 64 { 0 } else { base >> shift };
*val = (base << bits) | carry;
carry = new_carry;
}
self
}
}
}
}
generate_shifts!(U192, 192);
generate_shifts!(U256, 256);
generate_shifts!(U320, 320); // this is just for expansion
generate_shifts!(U384, 384);
generate_shifts!(U448, 448); // this is just for expansion
generate_shifts!(U512, 512);
generate_shifts!(U576, 576);
generate_shifts!(U640, 640); // this is just for expansion
generate_shifts!(U768, 768); // this is just for expansion
generate_shifts!(U832, 832); // this is just for Barrett
generate_shifts!(U896, 896); // this is just for Barrett
generate_shifts!(U1024, 1024);
generate_shifts!(U1088, 1088); // this is just for expansion
generate_shifts!(U1152, 1152); // this is just for expansion
generate_shifts!(U1216, 1216); // this is just for Barrett
generate_shifts!(U1536, 1536); // this is just for expansion
generate_shifts!(U1664, 1664); // this is just for Barrett
generate_shifts!(U2048, 2048);
generate_shifts!(U2112, 2112); // this is just for expansion
generate_shifts!(U2176, 2176); // this is just for Barrett
generate_shifts!(U2304, 2304); // this is just for expansion
generate_shifts!(U2432, 2432); // this is just for Barrett
generate_shifts!(U3072, 3072);
generate_shifts!(U3136, 3136); // this is just for expansion
generate_shifts!(U4096, 4096);
generate_shifts!(U4160, 4160); // this is just for expansion
generate_shifts!(U4224, 4224); // this is just for Barrett
generate_shifts!(U6144, 6144); // this is just for expansion
generate_shifts!(U6208, 6208); // this is just for Barrett
generate_shifts!(U7680, 7680); // Useful for RSA key generation
generate_shifts!(U7744, 7744); // Addition on previous
generate_shifts!(U8192, 8192);
generate_shifts!(U8256, 8256); // this is just for expansion
generate_shifts!(U8320, 8320); // this is just for Barrett
generate_shifts!(U12288, 12288); // this is just for expansion
generate_shifts!(U12416, 12416); // this is just for Barrett
generate_shifts!(U15360, 15360);
generate_shifts!(U15424, 15424); // this is just for expansion
generate_shifts!(U16384, 16384); // this is just for expansion
generate_shifts!(U16448, 16448); // this is just for Barrett
generate_shifts!(U16512, 16512); // this is just for Barrett
generate_shifts!(U30720, 30720); // this is just for expansion
generate_shifts!(U30784, 30784); // this is just for Barrett
generate_shifts!(U32768, 32768); // this is just for expansion
generate_shifts!(U32896, 32896); // this is just for Barrett
generate_shifts!(U61440, 61440); // this is just for expansion
generate_shifts!(U61568, 61568); // this is just for Barrett
macro_rules! generate_tests {
( $( $name:ident ), * ) => {
#[cfg(test)]
mod left {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/shift{}.test",
stringify!($name));
run_test(fname.to_string(), 4, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg3, lbytes) = case.get("l").unwrap();
assert!(!neg0 && !neg1 && !neg3);
let a = $name::from_bytes(abytes);
let bigb = $name::from_bytes(bbytes);
let b = usize::from(bigb);
let l = $name::from_bytes(lbytes);
let res = a << b;
assert_eq!(res, l);
});
}
)*
}
#[cfg(test)]
mod right {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/shift{}.test",
stringify!($name));
run_test(fname.to_string(), 4, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, rbytes) = case.get("r").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let mut a = $name::from_bytes(abytes);
let bigb = $name::from_bytes(bbytes);
let b = usize::from(bigb);
let r = $name::from_bytes(rbytes);
a >>= b;
assert_eq!(a, r);
});
}
)*
}
}
}
generate_tests!(U192, U256, U384, U512, U576, U1024, U2048, U3072,
U4096, U8192, U15360);

View File

@@ -1,311 +0,0 @@
use cryptonum::addition::UnsafeAdd;
use cryptonum::basetypes::*;
use cryptonum::encoding::Decoder;
use std::fmt;
use std::cmp::{Ord,Ordering};
use std::ops::{Add,Shl,ShrAssign,Sub,SubAssign};
pub struct Signed<T> {
pub(crate) negative: bool,
pub(crate) value: T
}
impl<T> Signed<T> {
pub fn new(negative: bool, value: T) -> Signed<T> {
Signed{ negative: negative, value: value }
}
}
impl<T: Clone> Clone for Signed<T> {
fn clone(&self) -> Self {
Signed{ negative: self.negative, value: self.value.clone() }
}
}
impl<T: CryptoNum> CryptoNum for Signed<T> {
fn zero() -> Signed<T> {
Signed::new(false, T::zero())
}
fn is_odd(&self) -> bool {
self.value.is_odd()
}
fn is_even(&self) -> bool {
self.value.is_even()
}
fn is_zero(&self) -> bool {
self.value.is_zero()
}
}
impl<T: Decoder> Decoder for Signed<T> {
fn from_bytes(x: &[u8]) -> Signed<T> {
let x: T = T::from_bytes(x);
Signed{ negative: false, value: x }
}
}
impl<T: fmt::Debug> fmt::Debug for Signed<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.negative {
write!(f, "NEGATIVE:")?;
} else {
write!(f, "POSITIVE:")?;
}
self.value.fmt(f)
}
}
impl<T: fmt::UpperHex> fmt::UpperHex for Signed<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.negative {
write!(f, "-")?;
}
self.value.fmt(f)
}
}
impl<T: fmt::LowerHex> fmt::LowerHex for Signed<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.negative {
write!(f, "-")?;
}
self.value.fmt(f)
}
}
impl<T: PartialEq> PartialEq for Signed<T> {
fn eq(&self, other: &Signed<T>) -> bool {
(self.negative == other.negative) && (self.value == other.value)
}
}
impl<T: Eq> Eq for Signed<T> {}
impl<T> ShrAssign<usize> for Signed<T>
where
T: ShrAssign<usize> + UnsafeAdd + CryptoNum + From<u64> + Clone + fmt::UpperHex,
T: Shl<usize,Output=T> + PartialEq
{
fn shr_assign(&mut self, rhs: usize) {
// arithmatic right shift is normal right shift, but always rounding
// to negative infinity. To implement this, we first shift right by
// rhs bits, and then shift that value back left rhs bits. If the two
// are the same, we just cleared out even bits, and there's no rounding
// to worry about. If they aren't the same, then we add one back.
let original = self.value.clone();
self.value.shr_assign(rhs);
if self.negative {
let review = self.value.clone() << rhs;
if review != original {
self.value = self.value.clone().unsafe_add(&T::from(1u64));
}
}
}
}
impl<T> UnsafeAdd for Signed<T>
where
T: UnsafeAdd + SubAssign + Sub<Output=T>,
T: PartialOrd + Ord,
T: Clone
{
fn unsafe_add(mut self, rhs: &Signed<T>) -> Signed<T> {
if self.negative == rhs.negative {
Signed{
negative: self.negative,
value: self.value.unsafe_add(&rhs.value)
}
} else {
if self.value > rhs.value {
self.value -= rhs.value.clone();
} else {
self.value = rhs.value.clone() - self.value.clone();
self.negative = rhs.negative;
}
self
}
}
}
impl<'a,'b,T,U> Add<&'a Signed<T>> for &'b Signed<T>
where
&'a T: Add<&'b T,Output=U> + Sub<&'b T,Output=T>,
T: PartialOrd + Ord,
T: Clone,
U: From<T>
{
type Output = Signed<U>;
fn add(self, rhs: &Signed<T>) -> Signed<U> {
if self.negative == rhs.negative {
Signed {
negative: self.negative,
value: &self.value + &rhs.value
}
} else {
if self.value > rhs.value {
Signed {
negative: self.negative,
value: U::from(&self.value - &rhs.value)
}
} else {
Signed {
negative: rhs.negative,
value: U::from(&rhs.value - &self.value)
}
}
}
}
}
impl<'a,T> SubAssign<&'a Signed<T>> for Signed<T>
where
T: SubAssign<T>,
T: Sub<T,Output=T>,
T: UnsafeAdd,
T: PartialOrd,
T: Clone
{
fn sub_assign(&mut self, rhs: &Signed<T>) {
if self.negative == rhs.negative {
if &self.value >= &rhs.value {
self.value -= rhs.value.clone();
} else {
self.value = rhs.value.clone() - self.value.clone();
self.negative = !self.negative;
}
} else {
self.value = rhs.value.clone().unsafe_add(&self.value);
}
}
}
impl<T: Ord + PartialOrd> PartialOrd for Signed<T> {
fn partial_cmp(&self, other: &Signed<T>) -> Option<Ordering> {
Some(self.cmp(&other))
}
}
impl<T: Ord + PartialOrd> Ord for Signed<T> {
fn cmp(&self, other: &Signed<T>) -> Ordering {
match (self.negative, other.negative) {
(false, false) => self.value.cmp(&other.value),
(true, false) => Ordering::Greater,
(false, true) => Ordering::Less,
(true, true) => self.value.cmp(&other.value).reverse()
}
}
}
impl<T> Shl<usize> for Signed<T>
where T: Shl<usize,Output=T>
{
type Output = Signed<T>;
fn shl(mut self, amt: usize) -> Signed<T> {
self.value = self.value << amt;
self
}
}
macro_rules! generate_tests {
( $( $name:ident ),* ) => {
#[cfg(test)]
mod shr {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/sigshr{}.test",
stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (nega, abytes) = case.get("a").unwrap();
let (negb, bbytes) = case.get("b").unwrap();
let (negx, xbytes) = case.get("x").unwrap();
assert!(!negb);
let ua = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let ux = $name::from_bytes(xbytes);
let mut a = Signed::new(*nega, ua);
let x = Signed::new(*negx, ux);
a >>= usize::from(b);
assert_eq!(a, x);
});
}
)*
}
#[cfg(test)]
mod add {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/sigadd{}.test",
stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (nega, abytes) = case.get("a").unwrap();
let (negb, bbytes) = case.get("b").unwrap();
let (negx, xbytes) = case.get("x").unwrap();
let ua = $name::from_bytes(abytes);
let ub = $name::from_bytes(bbytes);
let ux = $name::from_bytes(xbytes);
let a = Signed::new(*nega, ua);
let b = Signed::new(*negb, ub);
let x = Signed::new(*negx, ux);
let res = a.unsafe_add(&b);
assert_eq!(res, x);
});
}
)*
}
#[cfg(test)]
mod sub {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/sigsub{}.test",
stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (nega, abytes) = case.get("a").unwrap();
let (negb, bbytes) = case.get("b").unwrap();
let (negx, xbytes) = case.get("x").unwrap();
let ua = $name::from_bytes(abytes);
let ub = $name::from_bytes(bbytes);
let ux = $name::from_bytes(xbytes);
let mut a = Signed::new(*nega, ua);
let b = Signed::new(*negb, ub);
let b2 = b.clone();
let x = Signed::new(*negx, ux);
a -= &b2;
assert_eq!(a, x);
assert_eq!(b, b2);
});
}
)*
}
}
}
generate_tests!(U192, U256, U384, U512, U1024,
U2048, U3072, U4096, U8192, U15360);

View File

@@ -1,115 +0,0 @@
use cryptonum::basetypes::*;
macro_rules! generate_squarers
{
($name: ident, $bigger: ident, $size: expr) => {
impl $name {
pub fn square(&self) -> $bigger {
let mut w = [0; $size/32];
let t = $size / 64;
for i in 0..t {
let x128 = self.values[i] as u128;
let mut uvb = (w[2*i] as u128) + (x128 * x128);
w[2*i] = uvb & 0xFFFFFFFFFFFFFFFF;
let mut c = uvb >> 64;
for j in (i+1)..t {
let xj128 = self.values[j] as u128;
let xi128 = self.values[i] as u128;
// this first product is safely 128 bits or less,
// because the input arguments are both 64 bits.
let xij128 = xj128 * xi128;
// this next bit may overflow, but will do so by exactly
// one bit.
let twoxij128 = xij128 << 1;
let carried_shl = (xij128 & (1 << 127)) != 0;
// this next bit may *also* overflow, but should also do
// so by no more than one bit.
let (new,carry1) = twoxij128.overflowing_add(c);
// ditto ...
let wij = w[i+j];
let (uvb2,carry2) = new.overflowing_add(wij as u128);
// for the value we're going to save for this digit, we
// only care about the low bits, so we can forget about
// the carry stuff.
w[i+j] = uvb2 & 0xFFFFFFFFFFFFFFFF;
// for c, though, we do care about the carries, above.
// Fortunately, they were both by only one bit, so we
// should be able to just back-fix them.
c = uvb2 >> 64;
if carried_shl { c += 1 << 64; }
if carry1 { c += 1 << 64; }
if carry2 { c += 1 << 64; }
}
w[i+t] = c;
}
let mut res = $bigger::zero();
for i in 0..w.len() { res.values[i] = w[i] as u64; }
res
}
}
//
// impl ModSquare for $name {
// fn modsq(&self, m: &$name) -> $name {
// let bigsquare = self.square();
// let bigm = $bigger::from(m);
// let bigres = bigsquare.reduce(&bigm);
// $name::from(bigres)
// }
// }
}
}
generate_squarers!(U192, U384, 192);
generate_squarers!(U256, U512, 256);
generate_squarers!(U384, U768, 384);
generate_squarers!(U512, U1024, 512);
generate_squarers!(U576, U1152, 576);
generate_squarers!(U1024, U2048, 1024);
generate_squarers!(U2048, U4096, 2048);
generate_squarers!(U3072, U6144, 3072);
generate_squarers!(U4096, U8192, 4096);
generate_squarers!(U8192, U16384, 8192);
generate_squarers!(U15360, U30720,15360);
macro_rules! generate_tests {
( $( ($name:ident, $bigger:ident) ),* ) => {
#[cfg(test)]
mod normal {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/squaring{}.test",
stringify!($name));
run_test(fname.to_string(), 2, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, rbytes) = case.get("r").unwrap();
assert!(!neg0 && !neg1);
let a = $name::from_bytes(abytes);
let r = $bigger::from_bytes(rbytes);
let myres = a.square();
assert_eq!(r, myres);
});
}
)*
}
}
}
generate_tests!((U192, U384),
(U256, U512),
(U384, U768),
(U512, U1024),
(U576, U1152),
(U1024, U2048),
(U2048, U4096),
(U3072, U6144),
(U4096, U8192),
(U8192, U16384),
(U15360, U30720));

View File

@@ -1,142 +0,0 @@
use cryptonum::basetypes::*;
use std::ops::{Sub,SubAssign};
macro_rules! generate_subbers
{
($name: ident, $size: expr) => {
impl<'a> SubAssign<&'a $name> for $name {
fn sub_assign(&mut self, rhs: &$name) {
// negate the right hand size
let mut negatedy: $name = rhs.clone();
for i in 0..$size/64 {
negatedy.values[i] = !negatedy.values[i];
}
// add one
let mut bigger = 1 + (negatedy.values[0] as u128);
let mut carry = bigger >> 64;
negatedy.values[0] = bigger as u64;
for i in 1..$size/64 {
bigger = carry + (negatedy.values[i] as u128);
negatedy.values[i] = bigger as u64;
carry = bigger >> 64;
}
// then add it to ourselves
carry = 0;
for i in 0..$size/64 {
let x128 = self.values[i] as u128;
let y128 = negatedy.values[i] as u128;
bigger = x128 + y128 + carry;
carry = bigger >> 64;
self.values[i] = bigger as u64;
}
}
}
impl SubAssign for $name {
fn sub_assign(&mut self, rhs: $name) {
self.sub_assign(&rhs);
}
}
impl<'a,'b> Sub<&'b $name> for &'a $name {
type Output = $name;
fn sub(self, rhs: &$name) -> $name {
let mut res = self.clone();
res -= rhs;
res
}
}
impl Sub for $name {
type Output = $name;
fn sub(mut self, rhs: $name) -> $name {
self -= rhs;
self
}
}
}
}
generate_subbers!(U192, 192);
generate_subbers!(U256, 256);
generate_subbers!(U320, 320); // this is just for expansion
generate_subbers!(U384, 384);
generate_subbers!(U448, 448); // this is just for expansion
generate_subbers!(U512, 512);
generate_subbers!(U576, 576);
generate_subbers!(U640, 640); // this is just for expansion
generate_subbers!(U768, 768); // this is just for expansion
generate_subbers!(U832, 832); // this is just for Barrett
generate_subbers!(U896, 896); // this is just for Barrett
generate_subbers!(U1024, 1024);
generate_subbers!(U1088, 1088); // this is just for expansion
generate_subbers!(U1152, 1152); // this is just for expansion
generate_subbers!(U1216, 1216); // this is just for Barrett
generate_subbers!(U1536, 1536); // this is just for expansion
generate_subbers!(U1664, 1664); // this is just for Barrett
generate_subbers!(U2048, 2048);
generate_subbers!(U2112, 2112); // this is just for expansion
generate_subbers!(U2176, 2176); // this is just for Barrett
generate_subbers!(U2304, 2304); // this is just for expansion
generate_subbers!(U2432, 2432); // this is just for Barrett
generate_subbers!(U3072, 3072);
generate_subbers!(U3136, 3136); // this is just for expansion
generate_subbers!(U4096, 4096);
generate_subbers!(U4160, 4160); // this is just for expansion
generate_subbers!(U4224, 4224); // this is just for Barrett
generate_subbers!(U6144, 6144); // this is just for expansion
generate_subbers!(U6208, 6208); // this is just for Barrett
generate_subbers!(U7680, 7680);
generate_subbers!(U8192, 8192);
generate_subbers!(U8256, 8256); // this is just for expansion
generate_subbers!(U8320, 8320); // this is just for Barrett
generate_subbers!(U12288, 12288); // this is just for expansion
generate_subbers!(U12416, 12416); // this is just for Barrett
generate_subbers!(U15360, 15360);
generate_subbers!(U15424, 15424); // this is just for expansion
generate_subbers!(U16384, 16384); // this is just for expansion
generate_subbers!(U16448, 16448); // this is just for Barrett
generate_subbers!(U16512, 16512); // this is just for Barrett
generate_subbers!(U30720, 30720); // this is just for expansion
generate_subbers!(U30784, 30784); // this is just for Barrett
generate_subbers!(U32768, 32768); // this is just for expansion
generate_subbers!(U32896, 32896); // this is just for Barrett
generate_subbers!(U61440, 61440); // this is just for expansion
generate_subbers!(U61568, 61568); // this is just for Barrett
macro_rules! generate_tests {
( $( $name:ident ),* ) => {
#[cfg(test)]
mod normal {
use cryptonum::Decoder;
use super::*;
use testing::run_test;
$(
#[test]
#[allow(non_snake_case)]
fn $name() {
let fname = format!("tests/math/subtraction{}.test",
stringify!($name));
run_test(fname.to_string(), 3, |case| {
let (neg0, abytes) = case.get("a").unwrap();
let (neg1, bbytes) = case.get("b").unwrap();
let (neg2, cbytes) = case.get("c").unwrap();
assert!(!neg0 && !neg1 && !neg2);
let mut a = $name::from_bytes(abytes);
let b = $name::from_bytes(bbytes);
let c = $name::from_bytes(cbytes);
a -= &b;
assert_eq!(a, c);
});
}
)*
}
}
}
generate_tests!(U192, U256, U384, U512, U576,
U1024, U2048, U3072, U4096, U8192,
U15360);

View File

@@ -1,3 +0,0 @@
pub trait FromHex {
fn from_hex(s: String) -> Self;
}