diff --git a/src/ed25519/fe.rs b/src/ed25519/fe.rs index 0d6baa7..dd65946 100644 --- a/src/ed25519/fe.rs +++ b/src/ed25519/fe.rs @@ -719,57 +719,59 @@ fn square() { }); } -pub fn fe_invert(z: &FieldElement) -> FieldElement -{ - let mut t0 = z.square(); - let mut t1 = t0.square(); - for _ in 1..2 { +impl FieldElement { + pub fn invert(&self) -> FieldElement + { + let mut t0 = self.square(); + let mut t1 = t0.square(); + for _ in 1..2 { + t1.square_mut(); + } + t1 *= &self; + t0 *= &t1; + let mut t2 = t0.square(); + t1 *= &t2; + t2 = t1.square(); + for _ in 1..5 { + t2.square_mut(); + } + t1 *= &t2; + t2 = t1.square(); + for _ in 1..10 { + t2.square_mut(); + } + t2 *= &t1; + let mut t3 = t2.square(); + for _ in 1..20 { + t3.square_mut(); + } + t2 *= &t3; + t2.square_mut(); + for _ in 1..10 { + t2.square_mut(); + } + t1 *= &t2; + t2 = t1.square(); + for _ in 1..50 { + t2.square_mut(); + } + t2 *= &t1; + t3 = t2.square(); + for _ in 1..100 { + t3.square_mut(); + } + t2 *= &t3; + t2.square_mut(); + for _ in 1..50 { + t2.square_mut(); + } + t1 *= &t2; t1.square_mut(); + for _ in 1..5 { + t1.square_mut(); + } + &t1 * &t0 } - t1 *= &z; - t0 *= &t1; - let mut t2 = t0.square(); - t1 *= &t2; - t2 = t1.square(); - for _ in 1..5 { - t2.square_mut(); - } - t1 *= &t2; - t2 = t1.square(); - for _ in 1..10 { - t2.square_mut(); - } - t2 *= &t1; - let mut t3 = t2.square(); - for _ in 1..20 { - t3.square_mut(); - } - t2 *= &t3; - t2.square_mut(); - for _ in 1..10 { - t2.square_mut(); - } - t1 *= &t2; - t2 = t1.square(); - for _ in 1..50 { - t2.square_mut(); - } - t2 *= &t1; - t3 = t2.square(); - for _ in 1..100 { - t3.square_mut(); - } - t2 *= &t3; - t2.square_mut(); - for _ in 1..50 { - t2.square_mut(); - } - t1 *= &t2; - t1.square_mut(); - for _ in 1..5 { - t1.square_mut(); - } - &t1 * &t0 } #[cfg(test)] @@ -783,15 +785,23 @@ fn invert() { assert!(!nega && !negc); let a = test_from_bytes(&abytes); let c = test_from_bytes(&cbytes); - let r = fe_invert(&a); + let r = a.invert(); assert_eq!(r, c); }); } -pub fn fe_neg(h: &mut FieldElement, f: &FieldElement) -{ - for i in 0..NUM_ELEMENT_LIMBS { - h.value[i] = -f.value[i]; +impl<'a> Neg for &'a FieldElement { + type Output = FieldElement; + + 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); let a = test_from_bytes(&abytes); let c = test_from_bytes(&cbytes); - let mut r = FieldElement::new(); - fe_neg(&mut r, &a); + let r = -&a; assert_eq!(r, c); }); } diff --git a/src/ed25519/point.rs b/src/ed25519/point.rs index 4b81152..3653b0c 100644 --- a/src/ed25519/point.rs +++ b/src/ed25519/point.rs @@ -39,21 +39,14 @@ impl Point { /// statically timed, so don't use it if that's important to you. pub fn from_bytes(s: &[u8]) -> Option { - 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 hz = FieldElement::one(); - u = hy.square(); - v = &u * &D; - temp = u.clone(); - u = &temp - &hz; /* u = y^2-1 */ + let mut u = hy.square(); + let mut v = &u * &D; + u = &u - &hz; /* u = y^2-1 */ v += &hz; - v3 = v.square(); + let mut v3 = v.square(); v3 *= &v; /* v3 = v^3 */ let mut hx = v3.square(); hx *= &v; @@ -62,7 +55,7 @@ impl Point { hx *= &v3; hx *= &u; /* x = uv^3(uv^7)^((q-5)/8) */ - vxx = hx.square(); + let mut vxx = hx.square(); vxx *= &v; let mut check = &vxx - &u; /* vx^2-u */ if fe_isnonzero(&check) { @@ -74,8 +67,7 @@ impl Point { } if fe_isnegative(&hx) != ((s[31] >> 7) == 1) { - temp = hx.clone(); - fe_neg(&mut hx, &temp); + hx = -&hx; } let ht = &hx * &hy; @@ -89,9 +81,8 @@ impl Point { pub fn invert(&mut self) { - let tmp = self.clone(); - fe_neg(&mut self.x, &tmp.x); - fe_neg(&mut self.t, &tmp.t); + self.x = -&self.x; + self.t = -&self.t; } } @@ -319,13 +310,11 @@ fn conversion() { /* r = 2 * p */ fn ge_p2_dbl(r: &mut PointP1P1, p: &Point2) { - let mut t0 = FieldElement::new(); - r.x = p.x.square(); r.z = p.y.square(); fe_sq2(&mut r.t, &p.z); r.y = &p.x + &p.y; - t0 = r.y.square(); + let t0 = r.y.square(); r.y = &r.z + &r.x; r.z -= &r.x; 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)); minust.yplusx.overwrite_with(&t.yminusx); minust.yminusx.overwrite_with(&t.yplusx); - fe_neg(&mut minust.xy2d, &t.xy2d); + minust.xy2d = -&t.xy2d; 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 { - let mut x_over_z = FieldElement::new(); - let mut y_over_z = FieldElement::new(); - - let recip = fe_invert(z); - x_over_z = x * &recip; - y_over_z = y * &recip; + let recip = z.invert(); + let x_over_z = x * &recip; + let y_over_z = y * &recip; let mut bytes = y_over_z.to_bytes(); let sign_bit = if fe_isnegative(&x_over_z) { 1 } else { 0 }; // The preceding computations must execute in constant time, but this