Extend modular addition to Barrett constants.

This commit is contained in:
2018-06-18 08:42:01 -07:00
parent a6def22bd1
commit 011ebc0c99
5 changed files with 58 additions and 2 deletions

View File

@@ -5,6 +5,7 @@ use cryptonum::comparison::bignum_ge;
use cryptonum::subtraction::raw_subtraction; use cryptonum::subtraction::raw_subtraction;
use std::ops::{Add,AddAssign}; use std::ops::{Add,AddAssign};
#[inline(always)]
pub fn raw_addition(x: &mut [u64], y: &[u64]) -> u64 { pub fn raw_addition(x: &mut [u64], y: &[u64]) -> u64 {
assert_eq!(x.len(), y.len()); assert_eq!(x.len(), y.len());
@@ -132,7 +133,7 @@ macro_rules! generate_tests {
} }
#[cfg(test)] #[cfg(test)]
mod slow_modular { mod modular {
use cryptonum::encoding::Decoder; use cryptonum::encoding::Decoder;
use super::*; use super::*;
use testing::run_test; use testing::run_test;

View File

@@ -1,7 +1,7 @@
use cryptonum::{U192, U256, U384, U512, U576, use cryptonum::{U192, U256, U384, U512, U576,
U1024, U2048, U3072, U4096, U8192, U1024, U2048, U3072, U4096, U8192,
U15360}; U15360};
use cryptonum::addition::raw_addition; use cryptonum::addition::{ModAdd,raw_addition};
use cryptonum::comparison::{bignum_cmp,bignum_ge}; use cryptonum::comparison::{bignum_cmp,bignum_ge};
use cryptonum::division::divmod; use cryptonum::division::divmod;
use cryptonum::multiplication::raw_multiplication; use cryptonum::multiplication::raw_multiplication;
@@ -101,6 +101,27 @@ macro_rules! generate_barrett_implementations {
} }
} }
} }
impl ModAdd<$bname> for $name {
fn modadd(&mut self, y: &$name, m: &$bname) {
let carry = raw_addition(&mut self.values, &y.values);
let msized = &m.m[0..$size/64];
if carry > 0 {
let mut left = [0; $size/64 + 1];
(&mut left[0..$size/64]).copy_from_slice(&self.values);
left[$size/64] = carry;
let mut right = [0; $size/64 + 1];
(&mut right[0..$size/64]).copy_from_slice(msized);
raw_subtraction(&mut left, &right);
for i in 0..self.values.len() {
self.values[i] = left[i];
}
}
if bignum_ge(&self.values, msized) {
raw_subtraction(&mut self.values, msized);
}
}
}
}; };
} }
@@ -202,6 +223,37 @@ macro_rules! generate_tests {
} }
)* )*
} }
#[cfg(test)]
mod modadd {
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 = $name::from_bytes(mbytes);
let mu = $bname::new(&m);
let c = $name::from_bytes(cbytes);
a.modadd(&b, &mu);
assert_eq!(a, c);
});
}
)*
}
} }
} }

View File

@@ -9,6 +9,7 @@ pub trait ModMul<T=Self> {
} }
// This is algorithm 14.12 from "Handbook of Applied Cryptography" // This is algorithm 14.12 from "Handbook of Applied Cryptography"
#[inline(always)]
pub fn raw_multiplication(x: &[u64], y: &[u64], w: &mut [u64]) pub fn raw_multiplication(x: &[u64], y: &[u64], w: &mut [u64])
{ {
assert_eq!(x.len(), y.len()); assert_eq!(x.len(), y.len());

View File

@@ -7,6 +7,7 @@ pub trait ModSquare<T=Self>
} }
// This is algorithm 14.16 from "Handbook of Applied Cryptography". // This is algorithm 14.16 from "Handbook of Applied Cryptography".
#[inline(always)]
pub fn raw_square(x: &[u64], result: &mut [u64]) pub fn raw_square(x: &[u64], result: &mut [u64])
{ {
assert_eq!(x.len() * 2, result.len()); assert_eq!(x.len() * 2, result.len());

View File

@@ -4,6 +4,7 @@ use cryptonum::{U192, U256, U384, U512, U576,
use cryptonum::addition::raw_addition; use cryptonum::addition::raw_addition;
use std::ops::{Sub,SubAssign}; use std::ops::{Sub,SubAssign};
#[inline(always)]
pub fn raw_subtraction(x: &mut [u64], y: &[u64]) pub fn raw_subtraction(x: &mut [u64], y: &[u64])
{ {
assert_eq!(x.len(), y.len()); assert_eq!(x.len(), y.len());