Extend modular addition to Barrett constants.
This commit is contained in:
@@ -5,6 +5,7 @@ use cryptonum::comparison::bignum_ge;
|
||||
use cryptonum::subtraction::raw_subtraction;
|
||||
use std::ops::{Add,AddAssign};
|
||||
|
||||
#[inline(always)]
|
||||
pub fn raw_addition(x: &mut [u64], y: &[u64]) -> u64 {
|
||||
assert_eq!(x.len(), y.len());
|
||||
|
||||
@@ -132,7 +133,7 @@ macro_rules! generate_tests {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod slow_modular {
|
||||
mod modular {
|
||||
use cryptonum::encoding::Decoder;
|
||||
use super::*;
|
||||
use testing::run_test;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use cryptonum::{U192, U256, U384, U512, U576,
|
||||
U1024, U2048, U3072, U4096, U8192,
|
||||
U15360};
|
||||
use cryptonum::addition::raw_addition;
|
||||
use cryptonum::addition::{ModAdd,raw_addition};
|
||||
use cryptonum::comparison::{bignum_cmp,bignum_ge};
|
||||
use cryptonum::division::divmod;
|
||||
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);
|
||||
});
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ pub trait ModMul<T=Self> {
|
||||
}
|
||||
|
||||
// This is algorithm 14.12 from "Handbook of Applied Cryptography"
|
||||
#[inline(always)]
|
||||
pub fn raw_multiplication(x: &[u64], y: &[u64], w: &mut [u64])
|
||||
{
|
||||
assert_eq!(x.len(), y.len());
|
||||
|
||||
@@ -7,6 +7,7 @@ pub trait ModSquare<T=Self>
|
||||
}
|
||||
|
||||
// This is algorithm 14.16 from "Handbook of Applied Cryptography".
|
||||
#[inline(always)]
|
||||
pub fn raw_square(x: &[u64], result: &mut [u64])
|
||||
{
|
||||
assert_eq!(x.len() * 2, result.len());
|
||||
|
||||
@@ -4,6 +4,7 @@ use cryptonum::{U192, U256, U384, U512, U576,
|
||||
use cryptonum::addition::raw_addition;
|
||||
use std::ops::{Sub,SubAssign};
|
||||
|
||||
#[inline(always)]
|
||||
pub fn raw_subtraction(x: &mut [u64], y: &[u64])
|
||||
{
|
||||
assert_eq!(x.len(), y.len());
|
||||
|
||||
Reference in New Issue
Block a user