Remove the cryptonum stuff; it's been moved to a different crate.
This commit is contained in:
@@ -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));
|
||||
@@ -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(");
|
||||
// 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/bk−1⌋, 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←r−m.
|
||||
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));
|
||||
@@ -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
|
||||
@@ -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(©, &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(©, &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(©, &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(©, &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, ©, 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, ©, &other.contents);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> $asncl<&'a $type> for $type {
|
||||
fn $asnfn(&mut self, other: &$type) {
|
||||
let copy = self.contents.clone();
|
||||
$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, &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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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};
|
||||
@@ -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←u−v, A←A−C,B←B−D;
|
||||
// otherwise,v←v−u, C←C−A, D←D−B.
|
||||
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 " ";
|
||||
}
|
||||
""
|
||||
}
|
||||
@@ -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));
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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));
|
||||
@@ -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);
|
||||
@@ -1,3 +0,0 @@
|
||||
pub trait FromHex {
|
||||
fn from_hex(s: String) -> Self;
|
||||
}
|
||||
Reference in New Issue
Block a user