diff --git a/src/ed25519/fe.rs b/src/ed25519/fe.rs index 19e4099..04e7547 100644 --- a/src/ed25519/fe.rs +++ b/src/ed25519/fe.rs @@ -11,6 +11,8 @@ use std::io::Cursor; #[cfg(test)] use testing::run_test; +use std::ops::*; + // This is all an extremely straightforward translation of the usual C // implementation, as linked in ring and other libraries. @@ -248,17 +250,47 @@ quickcheck! { } } -pub fn fe_add(h: &mut FieldElement, f: &FieldElement, g: &FieldElement) +impl<'a> AddAssign<&'a FieldElement> for FieldElement { - for i in 0..10 { - h.value[i] = f.value[i] + g.value[i] + fn add_assign(&mut self, v: &FieldElement) + { + for i in 0..10 { + self.value[i] = v.value[i] + self.value[i]; + } } } -pub fn fe_sub(h: &mut FieldElement, f: &FieldElement, g: &FieldElement) +impl<'a,'b> Add<&'a FieldElement> for &'b FieldElement { - for i in 0..10 { - h.value[i] = f.value[i] - g.value[i] + type Output = FieldElement; + + fn add(self, g: &FieldElement) -> FieldElement + { + let mut res = self.clone(); + res += g; + res + } +} + +impl<'a> SubAssign<&'a FieldElement> for FieldElement +{ + fn sub_assign(&mut self, v: &FieldElement) + { + for i in 0..10 { + self.value[i] = self.value[i] - v.value[i]; + } + } +} + +impl<'a,'b> Sub<&'a FieldElement> for &'b FieldElement +{ + type Output = FieldElement; + + fn sub(self, g: &FieldElement) -> FieldElement + { + let mut res = self.clone(); + res -= g; + res } } @@ -273,14 +305,12 @@ fn addsub() { let (negd, dbytes) = case.get("d").unwrap(); assert!(!nega && !negb && !negc && !negd); - let a = test_from_bytes(&abytes); - let b = test_from_bytes(&bbytes); - let c = test_from_bytes(&cbytes); - let d = test_from_bytes(&dbytes); - let mut r = FieldElement::new(); - let mut s = FieldElement::new(); - fe_add(&mut r, &a, &b); - fe_sub(&mut s, &a, &b); + let a = test_from_bytes(&abytes); + let b = test_from_bytes(&bbytes); + let c = test_from_bytes(&cbytes); + let d = test_from_bytes(&dbytes); + let r = &a + &b; + let s = &a - &b; assert_eq!(r, c, "field addition"); assert_eq!(s, d, "field subtraction"); }); diff --git a/src/ed25519/mod.rs b/src/ed25519/mod.rs index 9ef5e88..9a3cf3f 100644 --- a/src/ed25519/mod.rs +++ b/src/ed25519/mod.rs @@ -51,6 +51,7 @@ impl ED25519KeyPair } } +#[derive(Debug,PartialEq)] pub struct ED25519Private { seed: [u8; 32], @@ -87,26 +88,25 @@ impl ED25519Private { ctx.input(&self.prefix); ctx.input(&msg); let nonce = digest_scalar(ctx.result().as_slice()); - println!("ME:nonce: {:?}", nonce); let mut r = Point::new(); x25519_ge_scalarmult_base(&mut r, &nonce); - println!("ME:r.x: {:?}", r.x); - println!("ME:r.y: {:?}", r.y); - println!("ME:r.z: {:?}", r.z); - println!("ME:r.t: {:?}", r.t); let signature_r = r.encode(); - println!("ME:signature_r: {:?}", signature_r); let hram_digest = eddsa_digest(&signature_r, &self.public, &msg); let hram = digest_scalar(&hram_digest); - println!("ME:hram: {:?}", hram); x25519_sc_muladd(&mut signature_s, &hram, &self.private, &nonce); let mut result = Vec::with_capacity(64); result.extend_from_slice(&signature_r); result.extend_from_slice(&signature_s); result } + + pub fn to_bytes(&self) -> Vec + { + self.seed.to_vec() + } } +#[derive(Debug,PartialEq)] pub struct ED25519Public { public: [u8; 32] @@ -120,7 +120,22 @@ impl<'a> From<&'a ED25519Private> for ED25519Public } } +pub enum ED25519PublicImportError +{ + WrongNumberOfBytes(usize) +} + impl ED25519Public { + pub fn new(bytes: &[u8]) -> Result + { + if bytes.len() != 32 { + return Err(ED25519PublicImportError::WrongNumberOfBytes(bytes.len())); + } + let mut res = ED25519Public { public: [0; 32] }; + res.public.copy_from_slice(bytes); + Ok(res) + } + pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool { assert_eq!(sig.len(), 64); @@ -141,6 +156,11 @@ impl ED25519Public { let r_check = r.encode(); signature_r.to_vec() == r_check } + + pub fn to_bytes(&self) -> Vec + { + self.public.to_vec() + } } fn eddsa_digest(signature_r: &[u8], public_key: &[u8], msg: &[u8]) -> Vec @@ -176,11 +196,8 @@ fn run_signing_testcase(case: HashMap)>) privpub.append(&mut ubytes.clone()); let sig = keypair.private.sign(&mbytes); assert_eq!(sig.len(), sbytes.len()); - println!("sig: {:?}", sbytes); - println!("sig': {:?}", sig); assert!(sig.iter().eq(sbytes.iter())); assert!(keypair.public.verify(&mbytes, &sig)); - println!("DONE"); } #[cfg(test)] diff --git a/src/ed25519/point.rs b/src/ed25519/point.rs index 43c1cde..24927bb 100644 --- a/src/ed25519/point.rs +++ b/src/ed25519/point.rs @@ -43,7 +43,6 @@ impl Point { let mut v = FieldElement::new(); let mut v3 = FieldElement::new(); let mut vxx = FieldElement::new(); - let mut check = FieldElement::new(); let mut temp; let hy = FieldElement::from_bytes(s); @@ -51,9 +50,8 @@ impl Point { fe_square(&mut u, &hy); fe_mul(&mut v, &u, &D); temp = u.clone(); - fe_sub(&mut u, &temp, &hz); /* u = y^2-1 */ - temp = v.clone(); - fe_add(&mut v, &temp, &hz); /* v = dy^2+1 */ + u = &temp - &hz; /* u = y^2-1 */ + v += &hz; fe_square(&mut v3, &v); temp = v3.clone(); @@ -75,9 +73,9 @@ impl Point { fe_square(&mut vxx, &hx); temp = vxx.clone(); fe_mul(&mut vxx, &temp, &v); - fe_sub(&mut check, &vxx, &u); /* vx^2-u */ + let mut check = &vxx - &u; /* vx^2-u */ if fe_isnonzero(&check) { - fe_add(&mut check, &vxx, &u); /* vx^2+u */ + check = &vxx + &u; if fe_isnonzero(&check) { return None; } @@ -263,8 +261,8 @@ const D2: FieldElement = FieldElement { fn x25519_ge_p3_to_cached(r: &mut Cached, p: &Point) { - fe_add(&mut r.yplusx, &p.y, &p.x); - fe_sub(&mut r.yminusx, &p.y, &p.x); + r.yplusx = &p.y + &p.x; + r.yminusx = &p.y - &p.x; r.z.overwrite_with(&p.z); fe_mul(&mut r.t2d, &p.t, &D2); } @@ -337,14 +335,12 @@ fn ge_p2_dbl(r: &mut PointP1P1, p: &Point2) fe_square(&mut r.x, &p.x); fe_square(&mut r.z, &p.y); fe_sq2(&mut r.t, &p.z); - fe_add(&mut r.y, &p.x, &p.y); + r.y = &p.x + &p.y; fe_square(&mut t0, &r.y); - fe_add(&mut r.y, &r.z, &r.x); - let mut temp = r.z.clone(); - fe_sub(&mut r.z, &temp, &r.x); - fe_sub(&mut r.x, &t0, &r.y); - temp = r.t.clone(); - fe_sub(&mut r.t, &temp, &r.z); + r.y = &r.z + &r.x; + r.z -= &r.x; + r.x = &t0 - &r.y; + r.t -= &r.z; } /* r = 2 * p */ @@ -382,43 +378,33 @@ fn double() { /* r = p + q */ fn ge_madd(r: &mut PointP1P1, p: &Point, q: &Precomp) { - let mut t0 = FieldElement::new(); - let mut temp; - - fe_add(&mut r.x, &p.y, &p.x); - fe_sub(&mut r.y, &p.y, &p.x); + r.x = &p.y + &p.x; + r.y = &p.y - &p.x; fe_mul(&mut r.z, &r.x, &q.yplusx); - temp = r.y.clone(); + let temp = r.y.clone(); fe_mul(&mut r.y, &temp, &q.yminusx); fe_mul(&mut r.t, &q.xy2d, &p.t); - fe_add(&mut t0, &p.z, &p.z); - fe_sub(&mut r.x, &r.z, &r.y); - temp = r.y.clone(); - fe_add(&mut r.y, &r.z, &temp); - fe_add(&mut r.z, &t0, &r.t); - temp = r.t.clone(); - fe_sub(&mut r.t, &t0, &temp); + let t0 = &p.z + &p.z; + r.x = &r.z - &r.y; + r.y += &r.z; + r.z = &t0 + &r.t; + r.t = &t0 - &r.t; } /* r = p - q */ fn ge_msub(r: &mut PointP1P1, p: &Point, q: &Precomp) { - let mut t0 = FieldElement::new(); - let mut temp; - - fe_add(&mut r.x, &p.y, &p.x); - fe_sub(&mut r.y, &p.y, &p.x); + r.x = &p.y + &p.x; + r.y = &p.y - &p.x; fe_mul(&mut r.z, &r.x, &q.yminusx); - temp = r.y.clone(); + let temp = r.y.clone(); fe_mul(&mut r.y, &temp, &q.yplusx); fe_mul(&mut r.t, &q.xy2d, &p.t); - fe_add(&mut t0, &p.z, &p.z); - fe_sub(&mut r.x, &r.z, &r.y); - temp = r.y.clone(); - fe_add(&mut r.y, &r.z, &temp); - fe_sub(&mut r.z, &t0, &r.t); - temp = r.t.clone(); - fe_add(&mut r.t, &t0, &temp); + let t0 = &p.z + &p.z; + r.x = &r.z - &r.y; + r.y += &r.z; + r.z = &t0 - &r.t; + r.t += &t0; } #[cfg(test)] @@ -448,45 +434,39 @@ fn maddsub() { /* r = p + q */ fn x25519_ge_add(r: &mut PointP1P1, p: &Point, q: &Cached) { - let mut t0 = FieldElement::new(); - let mut temp; - - fe_add(&mut r.x, &p.y, &p.x); - fe_sub(&mut r.y, &p.y, &p.x); + r.x = &p.y + &p.x; + r.y = &p.y - &p.x; fe_mul(&mut r.z, &r.x, &q.yplusx); - temp = r.y.clone(); + let mut temp = r.y.clone(); fe_mul(&mut r.y, &temp, &q.yminusx); fe_mul(&mut r.t, &q.t2d, &p.t); fe_mul(&mut r.x, &p.z, &q.z); - fe_add(&mut t0, &r.x, &r.x); - fe_sub(&mut r.x, &r.z, &r.y); + let t0 = &r.x + &r.x; + r.x = &r.z - &r.y; temp = r.y.clone(); - fe_add(&mut r.y, &r.z, &temp); - fe_add(&mut r.z, &t0, &r.t); + r.y = &r.z + &temp; + r.z = &t0 + &r.t; temp = r.t.clone(); - fe_sub(&mut r.t, &t0, &temp); + r.t = &t0 - &temp; } /* r = p - q */ fn x25519_ge_sub(r: &mut PointP1P1, p: &Point, q: &Cached) { - let mut t0 = FieldElement::new(); - let mut temp; - - fe_add(&mut r.x, &p.y, &p.x); - fe_sub(&mut r.y, &p.y, &p.x); + r.x = &p.y + &p.x; + r.y = &p.y - &p.x; fe_mul(&mut r.z, &r.x, &q.yminusx); - temp = r.y.clone(); + let mut temp = r.y.clone(); fe_mul(&mut r.y, &temp, &q.yplusx); fe_mul(&mut r.t, &q.t2d, &p.t); fe_mul(&mut r.x, &p.z, &q.z); - fe_add(&mut t0, &r.x, &r.x); - fe_sub(&mut r.x, &r.z, &r.y); + let t0 = &r.x + &r.x; + r.x = &r.z - &r.y; temp = r.y.clone(); - fe_add(&mut r.y, &r.z, &temp); - fe_sub(&mut r.z, &t0, &r.t); + r.y = &r.z + &temp; + r.z = &t0 - &r.t; temp = r.t.clone(); - fe_add(&mut r.t, &t0, &temp); + r.t = &t0 + &temp; } #[cfg(test)] @@ -1758,29 +1738,29 @@ pub fn curve25519_scalar_mask(a: &mut [u8]) // fe_cswap(&mut x2, &mut x3, swap != 0); // fe_cswap(&mut z2, &mut z3, swap != 0); // swap = b; -// fe_sub(&mut tmp0, &x3, &z3); -// fe_sub(&mut tmp1, &x2, &z2); +// tmp0 = &x3 - &z3; +// tmp1 = &x2 - &z2; // tmp2 = x2.clone(); -// fe_add(&mut x2, &tmp2, &z2); -// fe_add(&mut z2, &x3, &z3); +// x2 = &tmp2 + &z2; +// z2 = &x3 + &z3; // fe_mul(&mut z3, &tmp0, &x2); // tmp2 = z2.clone(); // fe_mul(&mut z2, &tmp2, &tmp1); // fe_square(&mut tmp0, &tmp1); // fe_square(&mut tmp1, &x2); -// fe_add(&mut x3, &z3, &z2); +// x3 = &z3 + &z2; // tmp2 = z2.clone(); -// fe_sub(&mut z2, &z3, &tmp2); +// z2 = &z3 - &tmp2; // fe_mul(&mut x2, &tmp1, &tmp0); // tmp2 = tmp1.clone(); -// fe_sub(&mut tmp1, &tmp2, &tmp0); +// tmp1 = &tmp2 - &tmp0; // tmp2 = z2.clone(); // fe_square(&mut z2, &tmp2); // fe_mul121666(&mut z3, &tmp1); // tmp2 = x3.clone(); // fe_square( &mut x3, &tmp2); // tmp2 = tmp0.clone(); -// fe_add(&mut tmp0, &tmp2, &z3); +// tmp0 = &tmp2 + &z3; // fe_mul(&mut z3, &x1, &z2); // fe_mul(&mut z2, &tmp1, &tmp0); // if pos == 0 { @@ -1815,8 +1795,8 @@ pub fn curve25519_scalar_mask(a: &mut [u8]) // * u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */ // let mut zplusy = FieldElement::new(); // let mut zminusy = FieldElement::new(); -// fe_add(&mut zplusy, &A.z, &A.y); -// fe_sub(&mut zminusy, &A.z, &A.y); +// zplusy = &A.z + &A.y; +// zminusy = &A.z - &A.y; // let zminusy_inv = fe_invert(&zminusy); // let copy = zplusy.clone(); // fe_mul(&mut zplusy, ©, &zminusy_inv);