mirror of
https://github.com/saymrwulf/curve25519-dalek-source.git
synced 2026-09-07 20:50:39 +00:00
Add a carry-reduction during subtraction.
This commit is contained in:
parent
b75a88458a
commit
d2a51197d7
1 changed files with 34 additions and 19 deletions
53
src/field.rs
53
src/field.rs
|
|
@ -144,29 +144,41 @@ impl<'b> SubAssign<&'b FieldElement> for FieldElement {
|
||||||
}
|
}
|
||||||
#[cfg(feature="radix_51")]
|
#[cfg(feature="radix_51")]
|
||||||
fn sub_assign(&mut self, _rhs: &'b FieldElement) {
|
fn sub_assign(&mut self, _rhs: &'b FieldElement) {
|
||||||
// To avoid underflow, first add p
|
let result = (self as &FieldElement) - _rhs;
|
||||||
// XXX how many copies should we add to preserve headroom?
|
for i in 0..5 {
|
||||||
self.0[0] += 2*constants::p.0[0];
|
self.0[i] = result.0[i];
|
||||||
self.0[1] += 2*constants::p.0[1];
|
}
|
||||||
self.0[2] += 2*constants::p.0[2];
|
|
||||||
self.0[3] += 2*constants::p.0[3];
|
|
||||||
self.0[4] += 2*constants::p.0[4];
|
|
||||||
// then subtract _rhs
|
|
||||||
self.0[0] -= _rhs.0[0];
|
|
||||||
self.0[1] -= _rhs.0[1];
|
|
||||||
self.0[2] -= _rhs.0[2];
|
|
||||||
self.0[3] -= _rhs.0[3];
|
|
||||||
self.0[4] -= _rhs.0[4];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b> Sub<&'b FieldElement> for &'a FieldElement {
|
impl<'a, 'b> Sub<&'b FieldElement> for &'a FieldElement {
|
||||||
type Output = FieldElement;
|
type Output = FieldElement;
|
||||||
|
#[cfg(feature="radix_25_5")]
|
||||||
fn sub(self, _rhs: &'b FieldElement) -> FieldElement {
|
fn sub(self, _rhs: &'b FieldElement) -> FieldElement {
|
||||||
let mut output = self.clone();
|
let mut output = self.clone();
|
||||||
output -= _rhs;
|
output -= _rhs;
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
#[cfg(feature="radix_51")]
|
||||||
|
fn sub(self, _rhs: &'b FieldElement) -> FieldElement {
|
||||||
|
// To avoid underflow, first add a multiple of p.
|
||||||
|
// Choose 16*p = p << 4 to be larger than 54-bit _rhs.
|
||||||
|
//
|
||||||
|
// If we could statically track the bitlengths of the limbs
|
||||||
|
// of every FieldElement, we could choose a multiple of p
|
||||||
|
// just bigger than _rhs and avoid having to do a reduction.
|
||||||
|
//
|
||||||
|
// Since we don't yet have type-level integers to do this, we
|
||||||
|
// have to add an explicit reduction call here, which is a
|
||||||
|
// significant cost.
|
||||||
|
FieldElement::reduce([
|
||||||
|
(self.0[0] + 36028797018963664u64) - _rhs.0[0],
|
||||||
|
(self.0[1] + 36028797018963952u64) - _rhs.0[1],
|
||||||
|
(self.0[2] + 36028797018963952u64) - _rhs.0[2],
|
||||||
|
(self.0[3] + 36028797018963952u64) - _rhs.0[3],
|
||||||
|
(self.0[4] + 36028797018963952u64) - _rhs.0[4],
|
||||||
|
])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b> MulAssign<&'b FieldElement> for FieldElement {
|
impl<'b> MulAssign<&'b FieldElement> for FieldElement {
|
||||||
|
|
@ -251,12 +263,15 @@ impl FieldElement {
|
||||||
/// Invert the sign of this field element
|
/// Invert the sign of this field element
|
||||||
#[cfg(feature="radix_51")]
|
#[cfg(feature="radix_51")]
|
||||||
pub fn negate(&mut self) {
|
pub fn negate(&mut self) {
|
||||||
// XXX how many copies of p
|
// See commentary in the Sub impl
|
||||||
self.0[0] = constants::p.0[0] - self.0[0];
|
let neg = FieldElement::reduce([
|
||||||
self.0[1] = constants::p.0[1] - self.0[1];
|
36028797018963664u64 - self.0[0],
|
||||||
self.0[2] = constants::p.0[2] - self.0[2];
|
36028797018963952u64 - self.0[1],
|
||||||
self.0[3] = constants::p.0[3] - self.0[3];
|
36028797018963952u64 - self.0[2],
|
||||||
self.0[4] = constants::p.0[4] - self.0[4];
|
36028797018963952u64 - self.0[3],
|
||||||
|
36028797018963952u64 - self.0[4],
|
||||||
|
]);
|
||||||
|
self.0 = neg.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct zero.
|
/// Construct zero.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue