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 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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
Reference in New Issue
Block a user