diff --git a/src/pasta/curves.rs b/src/pasta/curves.rs index 57e5c2c..94fcc32 100644 --- a/src/pasta/curves.rs +++ b/src/pasta/curves.rs @@ -800,15 +800,14 @@ macro_rules! impl_projective_curve_specific { let yy = self.y.square(); let a = yy.square(); let zz = self.z.square(); - let s = (self.x + yy).square() - xx - a; - let s = s + s; - let m = xx + xx + xx + $name::curve_constant_a() * zz.square(); - let x3 = m.square() - (s + s); - let a = a + a; - let a = a + a; - let a = a + a; + let s = ((self.x + yy).square() - xx - a).double(); + let m = xx.double() + xx + $name::curve_constant_a() * zz.square(); + let x3 = m.square() - s.double(); + let a = a.double(); + let a = a.double(); + let a = a.double(); let y3 = m * (s - x3) - a; - let z3 = (self.x + self.y).square() - yy - zz; + let z3 = (self.y + self.z).square() - yy - zz; let tmp = $name { x: x3, diff --git a/src/pasta/pallas.rs b/src/pasta/pallas.rs index 4af4ae7..2bce353 100644 --- a/src/pasta/pallas.rs +++ b/src/pasta/pallas.rs @@ -14,6 +14,79 @@ pub type Point = Ep; /// A Pallas point in the affine coordinate space (or the point at infinity). pub type Affine = EpAffine; +#[test] +fn test_iso_map() { + use crate::arithmetic::Curve; + + // This is a regression test (it's the same input to iso_map as for hash_to_curve + // with domain prefix "z.cash:test", Shake128, and input b"hello"). + let r = super::IsoEp::new_jacobian( + Base::from_raw([ + 0xc37f111df5c4419e, + 0x593c053e5e2337ad, + 0x9c6cfc47bce1aba6, + 0x0a881e4d556945aa, + ]), + Base::from_raw([ + 0xf234e04434502b47, + 0x6979f7f2b0acf188, + 0xa62eec46f662cb4e, + 0x035e5c8a06d5cfb4, + ]), + Base::from_raw([ + 0x11ab791d4fb6f6b4, + 0x575baa717958ef1f, + 0x6ac4e343558dcbf3, + 0x3af37975b0933125, + ]), + ) + .unwrap(); + let p = + super::hashtocurve::iso_map::<_, Affine, super::IsoEpAffine>(&r, &Ep::ISOGENY_CONSTANTS); + let (x, y, z) = p.jacobian_coordinates(); + assert!( + format!("{:?}", x) == "0x318cc15f281662b3f26d0175cab97b924870c837879cac647e877be51a85e898" + ); + assert!( + format!("{:?}", y) == "0x1e91e2fa2a5a6a5bc86ff9564ae9336084470e7119dffcb85ae8c1383a3defd7" + ); + assert!( + format!("{:?}", z) == "0x1e049436efa754f5f189aec69c2c3a4a559eca6a12b45c3f2e4a769deeca6187" + ); +} + +#[test] +fn test_iso_map_identity() { + use crate::arithmetic::Curve; + + let r = super::IsoEp::new_jacobian( + Base::from_raw([ + 0xc37f111df5c4419e, + 0x593c053e5e2337ad, + 0x9c6cfc47bce1aba6, + 0x0a881e4d556945aa, + ]), + Base::from_raw([ + 0xf234e04434502b47, + 0x6979f7f2b0acf188, + 0xa62eec46f662cb4e, + 0x035e5c8a06d5cfb4, + ]), + Base::from_raw([ + 0x11ab791d4fb6f6b4, + 0x575baa717958ef1f, + 0x6ac4e343558dcbf3, + 0x3af37975b0933125, + ]), + ) + .unwrap(); + let r = (r * -Fq::one()) + r; + assert!(bool::from(r.is_on_curve())); + let p = + super::hashtocurve::iso_map::<_, Affine, super::IsoEpAffine>(&r, &Ep::ISOGENY_CONSTANTS); + assert!(bool::from(p.is_on_curve())); +} + #[test] fn test_map_to_curve_pallas() { use crate::arithmetic::Curve; @@ -31,4 +104,7 @@ fn test_map_to_curve_pallas() { assert!( format!("{:?}", z) == "0x1e049436efa754f5f189aec69c2c3a4a559eca6a12b45c3f2e4a769deeca6187" ); + assert!(bool::from(p.is_on_curve())); + let p = (p * -Fq::one()) + p; + assert!(bool::from(p.is_on_curve())); }