Shift fe_mul to normal Rust multiplication operations.

This commit is contained in:
2019-05-25 16:37:04 -07:00
parent 16cf6172ce
commit 25746af626
2 changed files with 290 additions and 314 deletions

View File

@@ -316,28 +316,30 @@ fn addsub() {
}); });
} }
pub fn fe_mul(h: &mut FieldElement, f: &FieldElement, g: &FieldElement) impl<'a> MulAssign<&'a FieldElement> for FieldElement
{ {
let f0 : i32 = f.value[0]; fn mul_assign(&mut self, v: &FieldElement)
let f1 : i32 = f.value[1]; {
let f2 : i32 = f.value[2]; let f0 : i32 = self.value[0];
let f3 : i32 = f.value[3]; let f1 : i32 = self.value[1];
let f4 : i32 = f.value[4]; let f2 : i32 = self.value[2];
let f5 : i32 = f.value[5]; let f3 : i32 = self.value[3];
let f6 : i32 = f.value[6]; let f4 : i32 = self.value[4];
let f7 : i32 = f.value[7]; let f5 : i32 = self.value[5];
let f8 : i32 = f.value[8]; let f6 : i32 = self.value[6];
let f9 : i32 = f.value[9]; let f7 : i32 = self.value[7];
let g0 : i32 = g.value[0]; let f8 : i32 = self.value[8];
let g1 : i32 = g.value[1]; let f9 : i32 = self.value[9];
let g2 : i32 = g.value[2]; let g0 : i32 = v.value[0];
let g3 : i32 = g.value[3]; let g1 : i32 = v.value[1];
let g4 : i32 = g.value[4]; let g2 : i32 = v.value[2];
let g5 : i32 = g.value[5]; let g3 : i32 = v.value[3];
let g6 : i32 = g.value[6]; let g4 : i32 = v.value[4];
let g7 : i32 = g.value[7]; let g5 : i32 = v.value[5];
let g8 : i32 = g.value[8]; let g6 : i32 = v.value[6];
let g9 : i32 = g.value[9]; let g7 : i32 = v.value[7];
let g8 : i32 = v.value[8];
let g9 : i32 = v.value[9];
let g1_19 : i32 = 19 * g1; /* 1.959375*2^29 */ let g1_19 : i32 = 19 * g1; /* 1.959375*2^29 */
let g2_19 : i32 = 19 * g2; /* 1.959375*2^30; still ok */ let g2_19 : i32 = 19 * g2; /* 1.959375*2^30; still ok */
let g3_19 : i32 = 19 * g3; let g3_19 : i32 = 19 * g3;
@@ -522,17 +524,31 @@ pub fn fe_mul(h: &mut FieldElement, f: &FieldElement, g: &FieldElement)
/* |h0| <= 2^25; from now on fits into int32 unchanged */ /* |h0| <= 2^25; from now on fits into int32 unchanged */
/* |h1| <= 1.01*2^24 */ /* |h1| <= 1.01*2^24 */
h.value[0] = h0 as i32; self.value[0] = h0 as i32;
h.value[1] = h1 as i32; self.value[1] = h1 as i32;
h.value[2] = h2 as i32; self.value[2] = h2 as i32;
h.value[3] = h3 as i32; self.value[3] = h3 as i32;
h.value[4] = h4 as i32; self.value[4] = h4 as i32;
h.value[5] = h5 as i32; self.value[5] = h5 as i32;
h.value[6] = h6 as i32; self.value[6] = h6 as i32;
h.value[7] = h7 as i32; self.value[7] = h7 as i32;
h.value[8] = h8 as i32; self.value[8] = h8 as i32;
h.value[9] = h9 as i32; self.value[9] = h9 as i32;
} }
}
impl<'a,'b> Mul<&'a FieldElement> for &'b FieldElement
{
type Output = FieldElement;
fn mul(self, g: &FieldElement) -> FieldElement
{
let mut res = self.clone();
res *= g;
res
}
}
#[cfg(test)] #[cfg(test)]
#[test] #[test]
@@ -547,8 +563,7 @@ fn mul() {
let a = test_from_bytes(&abytes); let a = test_from_bytes(&abytes);
let b = test_from_bytes(&bbytes); let b = test_from_bytes(&bbytes);
let c = test_from_bytes(&cbytes); let c = test_from_bytes(&cbytes);
let mut r = FieldElement::new(); let r = &a * &b;
fe_mul(&mut r, &a, &b);
assert_eq!(r, c); assert_eq!(r, c);
}); });
} }
@@ -711,72 +726,61 @@ pub fn fe_invert(z: &FieldElement) -> FieldElement
temp.overwrite_with(&t1); temp.overwrite_with(&t1);
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
} }
temp.overwrite_with(&t1); t1 *= &z;
fe_mul(&mut t1, &z, &temp); t0 *= &t1;
temp.overwrite_with(&t0);
fe_mul(&mut t0, &temp, &t1);
fe_square(&mut t2, &t0); fe_square(&mut t2, &t0);
temp.overwrite_with(&t1); t1 *= &t2;
fe_mul(&mut t1, &temp, &t2);
fe_square(&mut t2, &t1); fe_square(&mut t2, &t1);
for _ in 1..5 { for _ in 1..5 {
temp.overwrite_with(&t2); temp.overwrite_with(&t2);
fe_square(&mut t2, &temp); fe_square(&mut t2, &temp);
} }
temp.overwrite_with(&t1); t1 *= &t2;
fe_mul(&mut t1, &t2, &temp);
fe_square(&mut t2, &t1); fe_square(&mut t2, &t1);
for _ in 1..10 { for _ in 1..10 {
temp.overwrite_with(&t2); temp.overwrite_with(&t2);
fe_square(&mut t2, &temp); fe_square(&mut t2, &temp);
} }
temp.overwrite_with(&t2); t2 *= &t1;
fe_mul(&mut t2, &temp, &t1);
fe_square(&mut t3, &t2); fe_square(&mut t3, &t2);
for _ in 1..20 { for _ in 1..20 {
temp.overwrite_with(&t3); temp.overwrite_with(&t3);
fe_square(&mut t3, &temp); fe_square(&mut t3, &temp);
} }
temp.overwrite_with(&t2); t2 *= &t3;
fe_mul(&mut t2, &t3, &temp);
temp.overwrite_with(&t2); temp.overwrite_with(&t2);
fe_square(&mut t2, &temp); fe_square(&mut t2, &temp);
for _ in 1..10 { for _ in 1..10 {
temp.overwrite_with(&t2); temp.overwrite_with(&t2);
fe_square(&mut t2, &temp); fe_square(&mut t2, &temp);
} }
temp.overwrite_with(&t1); t1 *= &t2;
fe_mul(&mut t1, &t2, &temp);
fe_square(&mut t2, &t1); fe_square(&mut t2, &t1);
for _ in 1..50 { for _ in 1..50 {
temp.overwrite_with(&t2); temp.overwrite_with(&t2);
fe_square(&mut t2, &temp); fe_square(&mut t2, &temp);
} }
temp.overwrite_with(&t2); t2 *= &t1;
fe_mul(&mut t2, &temp, &t1);
fe_square(&mut t3, &t2); fe_square(&mut t3, &t2);
for _ in 1..100 { for _ in 1..100 {
temp.overwrite_with(&t3); temp.overwrite_with(&t3);
fe_square(&mut t3, &temp); fe_square(&mut t3, &temp);
} }
temp.overwrite_with(&t2); t2 *= &t3;
fe_mul(&mut t2, &t3, &temp);
temp.overwrite_with(&t2); temp.overwrite_with(&t2);
fe_square(&mut t2, &temp); fe_square(&mut t2, &temp);
for _ in 1..50 { for _ in 1..50 {
temp.overwrite_with(&t2); temp.overwrite_with(&t2);
fe_square(&mut t2, &temp); fe_square(&mut t2, &temp);
} }
temp.overwrite_with(&t1); t1 *= &t2;
fe_mul(&mut t1, &t2, &temp);
temp.overwrite_with(&t1); temp.overwrite_with(&t1);
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
for _ in 1..5 { for _ in 1..5 {
temp.overwrite_with(&t1); temp.overwrite_with(&t1);
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
} }
fe_mul(&mut out, &t1, &t0); &t1 * &t0
out
} }
#[cfg(test)] #[cfg(test)]
@@ -1043,7 +1047,8 @@ fn square2() {
}); });
} }
pub fn fe_pow22523(out: &mut FieldElement, z: &FieldElement) { pub fn fe_pow22523(z: &FieldElement) -> FieldElement
{
let mut t0 = FieldElement::new(); let mut t0 = FieldElement::new();
let mut t1 = FieldElement::new(); let mut t1 = FieldElement::new();
let mut t2 = FieldElement::new(); let mut t2 = FieldElement::new();
@@ -1055,72 +1060,62 @@ pub fn fe_pow22523(out: &mut FieldElement, z: &FieldElement) {
let temp = t1.clone(); let temp = t1.clone();
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
} }
temp = t1.clone(); t1 *= &z;
fe_mul(&mut t1, &z, &temp); t0 *= &t1;
temp = t0.clone();
fe_mul(&mut t0, &temp, &t1);
temp = t0.clone(); temp = t0.clone();
fe_square(&mut t0, &temp); fe_square(&mut t0, &temp);
temp = t0.clone(); t0 *= &t1;
fe_mul(&mut t0, &t1, &temp);
fe_square(&mut t1, &t0); fe_square(&mut t1, &t0);
for _ in 1..5 { for _ in 1..5 {
temp = t1.clone(); temp = t1.clone();
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
} }
temp = t0.clone(); t0 *= &t1;
fe_mul(&mut t0, &t1, &temp);
fe_square(&mut t1, &t0); fe_square(&mut t1, &t0);
for _ in 1..10 { for _ in 1..10 {
temp = t1.clone(); temp = t1.clone();
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
} }
temp = t1.clone(); t1 *= &t0;
fe_mul(&mut t1, &temp, &t0);
fe_square(&mut t2, &t1); fe_square(&mut t2, &t1);
for _ in 1..20 { for _ in 1..20 {
temp = t2.clone(); temp = t2.clone();
fe_square(&mut t2, &temp); fe_square(&mut t2, &temp);
} }
temp = t1.clone(); t1 *= &t2;
fe_mul(&mut t1, &t2, &temp);
temp = t1.clone(); temp = t1.clone();
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
for _ in 1..10 { for _ in 1..10 {
temp = t1.clone(); temp = t1.clone();
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
} }
temp = t0.clone(); t0 *= &t1;
fe_mul(&mut t0, &t1, &temp);
fe_square(&mut t1, &t0); fe_square(&mut t1, &t0);
for _ in 1..50 { for _ in 1..50 {
temp = t1.clone(); temp = t1.clone();
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
} }
temp = t1.clone(); t1 *= &t0;
fe_mul(&mut t1, &temp, &t0);
fe_square(&mut t2, &t1); fe_square(&mut t2, &t1);
for _ in 1..100 { for _ in 1..100 {
temp = t2.clone(); temp = t2.clone();
fe_square(&mut t2, &temp); fe_square(&mut t2, &temp);
} }
temp = t1.clone(); t1 *= &t2;
fe_mul(&mut t1, &t2, &temp);
temp = t1.clone(); temp = t1.clone();
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
for _ in 1..50 { for _ in 1..50 {
temp = t1.clone(); temp = t1.clone();
fe_square(&mut t1, &temp); fe_square(&mut t1, &temp);
} }
temp = t0.clone(); t0 *= &t1;
fe_mul(&mut t0, &t1, &temp);
temp = t0.clone(); temp = t0.clone();
fe_square(&mut t0, &temp); fe_square(&mut t0, &temp);
for _ in 1..2 { for _ in 1..2 {
temp = t0.clone(); temp = t0.clone();
fe_square(&mut t0, &temp); fe_square(&mut t0, &temp);
} }
fe_mul(out, &t0, &z); &t0 * &z
} }
#[cfg(test)] #[cfg(test)]
@@ -1134,8 +1129,7 @@ fn pow22523() {
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 = fe_pow22523(&a);
fe_pow22523(&mut r, &a);
assert_eq!(r, c); assert_eq!(r, c);
}); });
} }

View File

@@ -48,39 +48,30 @@ impl Point {
let hy = FieldElement::from_bytes(s); let hy = FieldElement::from_bytes(s);
let hz = FieldElement::one(); let hz = FieldElement::one();
fe_square(&mut u, &hy); fe_square(&mut u, &hy);
fe_mul(&mut v, &u, &D); v = &u * &D;
temp = u.clone(); temp = u.clone();
u = &temp - &hz; /* u = y^2-1 */ u = &temp - &hz; /* u = y^2-1 */
v += &hz; v += &hz;
fe_square(&mut v3, &v); fe_square(&mut v3, &v);
temp = v3.clone(); v3 *= &v; /* v3 = v^3 */
fe_mul(&mut v3, &temp, &v); /* v3 = v^3 */
let mut hx = FieldElement::zero(); let mut hx = FieldElement::zero();
fe_square(&mut hx, &v3); fe_square(&mut hx, &v3);
temp = hx.clone(); hx *= &v;
fe_mul(&mut hx, &temp, &v); hx *= &u; /* x = uv^7 */
temp = hx.clone(); hx = fe_pow22523(&hx); /* x = (uv^7)^((q-5)/8) */
fe_mul(&mut hx, &temp, &u); /* x = uv^7 */ hx *= &v3;
hx *= &u; /* x = uv^3(uv^7)^((q-5)/8) */
temp = hx.clone();
fe_pow22523(&mut hx, &temp); /* x = (uv^7)^((q-5)/8) */
temp = hx.clone();
fe_mul(&mut hx, &temp, &v3);
temp = hx.clone();
fe_mul(&mut hx, &temp, &u); /* x = uv^3(uv^7)^((q-5)/8) */
fe_square(&mut vxx, &hx); fe_square(&mut vxx, &hx);
temp = vxx.clone(); vxx *= &v;
fe_mul(&mut vxx, &temp, &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) {
check = &vxx + &u; check = &vxx + &u;
if fe_isnonzero(&check) { if fe_isnonzero(&check) {
return None; return None;
} }
temp = hx.clone(); hx *= &SQRTM1;
fe_mul(&mut hx, &temp, &SQRTM1);
} }
if fe_isnegative(&hx) != ((s[31] >> 7) == 1) { if fe_isnegative(&hx) != ((s[31] >> 7) == 1) {
@@ -88,8 +79,7 @@ impl Point {
fe_neg(&mut hx, &temp); fe_neg(&mut hx, &temp);
} }
let mut ht = FieldElement::zero(); let ht = &hx * &hy;
fe_mul(&mut ht, &hx, &hy);
return Some(Point{ x: hx, y: hy, z: hz, t: ht }); return Some(Point{ x: hx, y: hy, z: hz, t: ht });
} }
@@ -264,24 +254,24 @@ fn x25519_ge_p3_to_cached(r: &mut Cached, p: &Point)
r.yplusx = &p.y + &p.x; r.yplusx = &p.y + &p.x;
r.yminusx = &p.y - &p.x; r.yminusx = &p.y - &p.x;
r.z.overwrite_with(&p.z); r.z.overwrite_with(&p.z);
fe_mul(&mut r.t2d, &p.t, &D2); r.t2d = &p.t * &D2;
} }
/* r = p */ /* r = p */
fn x25519_ge_p1p1_to_p2(r: &mut Point2, p: &PointP1P1) fn x25519_ge_p1p1_to_p2(r: &mut Point2, p: &PointP1P1)
{ {
fe_mul(&mut r.x, &p.x, &p.t); r.x = &p.x * &p.t;
fe_mul(&mut r.y, &p.y, &p.z); r.y = &p.y * &p.z;
fe_mul(&mut r.z, &p.z, &p.t); r.z = &p.z * &p.t;
} }
/* r = p */ /* r = p */
fn x25519_ge_p1p1_to_p3(r: &mut Point, p: &PointP1P1) fn x25519_ge_p1p1_to_p3(r: &mut Point, p: &PointP1P1)
{ {
fe_mul(&mut r.x, &p.x, &p.t); r.x = &p.x * &p.t;
fe_mul(&mut r.y, &p.y, &p.z); r.y = &p.y * &p.z;
fe_mul(&mut r.z, &p.z, &p.t); r.z = &p.z * &p.t;
fe_mul(&mut r.t, &p.x, &p.y); r.t = &p.x * &p.y;
} }
#[cfg(test)] #[cfg(test)]
@@ -380,10 +370,9 @@ fn ge_madd(r: &mut PointP1P1, p: &Point, q: &Precomp)
{ {
r.x = &p.y + &p.x; r.x = &p.y + &p.x;
r.y = &p.y - &p.x; r.y = &p.y - &p.x;
fe_mul(&mut r.z, &r.x, &q.yplusx); r.z = &r.x * &q.yplusx;
let temp = r.y.clone(); r.y *= &q.yminusx;
fe_mul(&mut r.y, &temp, &q.yminusx); r.t = &q.xy2d * &p.t;
fe_mul(&mut r.t, &q.xy2d, &p.t);
let t0 = &p.z + &p.z; let t0 = &p.z + &p.z;
r.x = &r.z - &r.y; r.x = &r.z - &r.y;
r.y += &r.z; r.y += &r.z;
@@ -396,10 +385,9 @@ fn ge_msub(r: &mut PointP1P1, p: &Point, q: &Precomp)
{ {
r.x = &p.y + &p.x; r.x = &p.y + &p.x;
r.y = &p.y - &p.x; r.y = &p.y - &p.x;
fe_mul(&mut r.z, &r.x, &q.yminusx); r.z = &r.x * &q.yminusx;
let temp = r.y.clone(); r.y *= &q.yplusx;
fe_mul(&mut r.y, &temp, &q.yplusx); r.t = &q.xy2d * &p.t;
fe_mul(&mut r.t, &q.xy2d, &p.t);
let t0 = &p.z + &p.z; let t0 = &p.z + &p.z;
r.x = &r.z - &r.y; r.x = &r.z - &r.y;
r.y += &r.z; r.y += &r.z;
@@ -436,18 +424,15 @@ fn x25519_ge_add(r: &mut PointP1P1, p: &Point, q: &Cached)
{ {
r.x = &p.y + &p.x; r.x = &p.y + &p.x;
r.y = &p.y - &p.x; r.y = &p.y - &p.x;
fe_mul(&mut r.z, &r.x, &q.yplusx); r.z = &r.x * &q.yplusx;
let mut temp = r.y.clone(); r.y *= &q.yminusx;
fe_mul(&mut r.y, &temp, &q.yminusx); r.t = &q.t2d * &p.t;
fe_mul(&mut r.t, &q.t2d, &p.t); r.x = &p.z * &q.z;
fe_mul(&mut r.x, &p.z, &q.z);
let t0 = &r.x + &r.x; let t0 = &r.x + &r.x;
r.x = &r.z - &r.y; r.x = &r.z - &r.y;
temp = r.y.clone(); r.y += &r.z;
r.y = &r.z + &temp;
r.z = &t0 + &r.t; r.z = &t0 + &r.t;
temp = r.t.clone(); r.t = &t0 - &r.t;
r.t = &t0 - &temp;
} }
/* r = p - q */ /* r = p - q */
@@ -455,18 +440,15 @@ fn x25519_ge_sub(r: &mut PointP1P1, p: &Point, q: &Cached)
{ {
r.x = &p.y + &p.x; r.x = &p.y + &p.x;
r.y = &p.y - &p.x; r.y = &p.y - &p.x;
fe_mul(&mut r.z, &r.x, &q.yminusx); r.z = &r.x * &q.yminusx;
let mut temp = r.y.clone(); r.y *= &q.yplusx;
fe_mul(&mut r.y, &temp, &q.yplusx); r.t = &q.t2d * &p.t;
fe_mul(&mut r.t, &q.t2d, &p.t); r.x = &p.z * &q.z;
fe_mul(&mut r.x, &p.z, &q.z);
let t0 = &r.x + &r.x; let t0 = &r.x + &r.x;
r.x = &r.z - &r.y; r.x = &r.z - &r.y;
temp = r.y.clone(); r.y += &r.z;
r.y = &r.z + &temp;
r.z = &t0 - &r.t; r.z = &t0 - &r.t;
temp = r.t.clone(); r.t += &t0;
r.t = &t0 + &temp;
} }
#[cfg(test)] #[cfg(test)]
@@ -1826,8 +1808,8 @@ fn into_encoded_point(x: &FieldElement, y: &FieldElement, z: &FieldElement) -> V
let mut y_over_z = FieldElement::new(); let mut y_over_z = FieldElement::new();
let recip = fe_invert(z); let recip = fe_invert(z);
fe_mul(&mut x_over_z, x, &recip); x_over_z = x * &recip;
fe_mul(&mut y_over_z, y, &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