Convert negation and inverstion into more reasonable operations.
This commit is contained in:
@@ -719,14 +719,15 @@ fn square() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_invert(z: &FieldElement) -> FieldElement
|
impl FieldElement {
|
||||||
{
|
pub fn invert(&self) -> FieldElement
|
||||||
let mut t0 = z.square();
|
{
|
||||||
|
let mut t0 = self.square();
|
||||||
let mut t1 = t0.square();
|
let mut t1 = t0.square();
|
||||||
for _ in 1..2 {
|
for _ in 1..2 {
|
||||||
t1.square_mut();
|
t1.square_mut();
|
||||||
}
|
}
|
||||||
t1 *= &z;
|
t1 *= &self;
|
||||||
t0 *= &t1;
|
t0 *= &t1;
|
||||||
let mut t2 = t0.square();
|
let mut t2 = t0.square();
|
||||||
t1 *= &t2;
|
t1 *= &t2;
|
||||||
@@ -770,6 +771,7 @@ pub fn fe_invert(z: &FieldElement) -> FieldElement
|
|||||||
t1.square_mut();
|
t1.square_mut();
|
||||||
}
|
}
|
||||||
&t1 * &t0
|
&t1 * &t0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -783,15 +785,23 @@ fn invert() {
|
|||||||
assert!(!nega && !negc);
|
assert!(!nega && !negc);
|
||||||
let a = test_from_bytes(&abytes);
|
let a = test_from_bytes(&abytes);
|
||||||
let c = test_from_bytes(&cbytes);
|
let c = test_from_bytes(&cbytes);
|
||||||
let r = fe_invert(&a);
|
let r = a.invert();
|
||||||
assert_eq!(r, c);
|
assert_eq!(r, c);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_neg(h: &mut FieldElement, f: &FieldElement)
|
impl<'a> Neg for &'a FieldElement {
|
||||||
{
|
type Output = FieldElement;
|
||||||
for i in 0..NUM_ELEMENT_LIMBS {
|
|
||||||
h.value[i] = -f.value[i];
|
fn neg(self) -> FieldElement
|
||||||
|
{
|
||||||
|
FieldElement {
|
||||||
|
value: [ -self.value[0], -self.value[1],
|
||||||
|
-self.value[2], -self.value[3],
|
||||||
|
-self.value[4], -self.value[5],
|
||||||
|
-self.value[6], -self.value[7],
|
||||||
|
-self.value[8], -self.value[9], ]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,8 +816,7 @@ fn negate() {
|
|||||||
assert!(!nega && !negc);
|
assert!(!nega && !negc);
|
||||||
let a = test_from_bytes(&abytes);
|
let a = test_from_bytes(&abytes);
|
||||||
let c = test_from_bytes(&cbytes);
|
let c = test_from_bytes(&cbytes);
|
||||||
let mut r = FieldElement::new();
|
let r = -&a;
|
||||||
fe_neg(&mut r, &a);
|
|
||||||
assert_eq!(r, c);
|
assert_eq!(r, c);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,21 +39,14 @@ impl Point {
|
|||||||
/// statically timed, so don't use it if that's important to you.
|
/// statically timed, so don't use it if that's important to you.
|
||||||
pub fn from_bytes(s: &[u8]) -> Option<Point>
|
pub fn from_bytes(s: &[u8]) -> Option<Point>
|
||||||
{
|
{
|
||||||
let mut u = FieldElement::new();
|
|
||||||
let mut v = FieldElement::new();
|
|
||||||
let mut v3 = FieldElement::new();
|
|
||||||
let mut vxx = FieldElement::new();
|
|
||||||
let mut temp;
|
|
||||||
|
|
||||||
let hy = FieldElement::from_bytes(s);
|
let hy = FieldElement::from_bytes(s);
|
||||||
let hz = FieldElement::one();
|
let hz = FieldElement::one();
|
||||||
u = hy.square();
|
let mut u = hy.square();
|
||||||
v = &u * &D;
|
let mut v = &u * &D;
|
||||||
temp = u.clone();
|
u = &u - &hz; /* u = y^2-1 */
|
||||||
u = &temp - &hz; /* u = y^2-1 */
|
|
||||||
v += &hz;
|
v += &hz;
|
||||||
|
|
||||||
v3 = v.square();
|
let mut v3 = v.square();
|
||||||
v3 *= &v; /* v3 = v^3 */
|
v3 *= &v; /* v3 = v^3 */
|
||||||
let mut hx = v3.square();
|
let mut hx = v3.square();
|
||||||
hx *= &v;
|
hx *= &v;
|
||||||
@@ -62,7 +55,7 @@ impl Point {
|
|||||||
hx *= &v3;
|
hx *= &v3;
|
||||||
hx *= &u; /* x = uv^3(uv^7)^((q-5)/8) */
|
hx *= &u; /* x = uv^3(uv^7)^((q-5)/8) */
|
||||||
|
|
||||||
vxx = hx.square();
|
let mut vxx = hx.square();
|
||||||
vxx *= &v;
|
vxx *= &v;
|
||||||
let mut check = &vxx - &u; /* vx^2-u */
|
let mut check = &vxx - &u; /* vx^2-u */
|
||||||
if fe_isnonzero(&check) {
|
if fe_isnonzero(&check) {
|
||||||
@@ -74,8 +67,7 @@ impl Point {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if fe_isnegative(&hx) != ((s[31] >> 7) == 1) {
|
if fe_isnegative(&hx) != ((s[31] >> 7) == 1) {
|
||||||
temp = hx.clone();
|
hx = -&hx;
|
||||||
fe_neg(&mut hx, &temp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let ht = &hx * &hy;
|
let ht = &hx * &hy;
|
||||||
@@ -89,9 +81,8 @@ impl Point {
|
|||||||
|
|
||||||
pub fn invert(&mut self)
|
pub fn invert(&mut self)
|
||||||
{
|
{
|
||||||
let tmp = self.clone();
|
self.x = -&self.x;
|
||||||
fe_neg(&mut self.x, &tmp.x);
|
self.t = -&self.t;
|
||||||
fe_neg(&mut self.t, &tmp.t);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,13 +310,11 @@ fn conversion() {
|
|||||||
/* r = 2 * p */
|
/* r = 2 * p */
|
||||||
fn ge_p2_dbl(r: &mut PointP1P1, p: &Point2)
|
fn ge_p2_dbl(r: &mut PointP1P1, p: &Point2)
|
||||||
{
|
{
|
||||||
let mut t0 = FieldElement::new();
|
|
||||||
|
|
||||||
r.x = p.x.square();
|
r.x = p.x.square();
|
||||||
r.z = p.y.square();
|
r.z = p.y.square();
|
||||||
fe_sq2(&mut r.t, &p.z);
|
fe_sq2(&mut r.t, &p.z);
|
||||||
r.y = &p.x + &p.y;
|
r.y = &p.x + &p.y;
|
||||||
t0 = r.y.square();
|
let t0 = r.y.square();
|
||||||
r.y = &r.z + &r.x;
|
r.y = &r.z + &r.x;
|
||||||
r.z -= &r.x;
|
r.z -= &r.x;
|
||||||
r.x = &t0 - &r.y;
|
r.x = &t0 - &r.y;
|
||||||
@@ -513,7 +502,7 @@ fn table_select(t: &mut Precomp, pos: i32, b: i8)
|
|||||||
cmov(t, &K25519_PRECOMP[pos as usize][7], equal(babs, 8));
|
cmov(t, &K25519_PRECOMP[pos as usize][7], equal(babs, 8));
|
||||||
minust.yplusx.overwrite_with(&t.yminusx);
|
minust.yplusx.overwrite_with(&t.yminusx);
|
||||||
minust.yminusx.overwrite_with(&t.yplusx);
|
minust.yminusx.overwrite_with(&t.yplusx);
|
||||||
fe_neg(&mut minust.xy2d, &t.xy2d);
|
minust.xy2d = -&t.xy2d;
|
||||||
cmov(t, &minust, bnegative != 0);
|
cmov(t, &minust, bnegative != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1803,12 +1792,9 @@ pub fn curve25519_scalar_mask(a: &mut [u8])
|
|||||||
//
|
//
|
||||||
fn into_encoded_point(x: &FieldElement, y: &FieldElement, z: &FieldElement) -> Vec<u8>
|
fn into_encoded_point(x: &FieldElement, y: &FieldElement, z: &FieldElement) -> Vec<u8>
|
||||||
{
|
{
|
||||||
let mut x_over_z = FieldElement::new();
|
let recip = z.invert();
|
||||||
let mut y_over_z = FieldElement::new();
|
let x_over_z = x * &recip;
|
||||||
|
let y_over_z = y * &recip;
|
||||||
let recip = fe_invert(z);
|
|
||||||
x_over_z = x * &recip;
|
|
||||||
y_over_z = y * &recip;
|
|
||||||
let mut bytes = y_over_z.to_bytes();
|
let mut bytes = y_over_z.to_bytes();
|
||||||
let sign_bit = if fe_isnegative(&x_over_z) { 1 } else { 0 };
|
let sign_bit = if fe_isnegative(&x_over_z) { 1 } else { 0 };
|
||||||
// The preceding computations must execute in constant time, but this
|
// The preceding computations must execute in constant time, but this
|
||||||
|
|||||||
Reference in New Issue
Block a user