diff --git a/src/curve.rs b/src/curve.rs index 3b1ae200..4e23c704 100644 --- a/src/curve.rs +++ b/src/curve.rs @@ -14,6 +14,7 @@ pub struct Point { y: F, } +// Since EVERY point is either at "infinity" or not, the coproduct makes sense. #[derive(Clone, Copy)] pub enum PointOrInfinity { Point(Point), @@ -30,6 +31,7 @@ impl Curve { } } + // inverse pub fn negate(&self, p: PointOrInfinity) -> PointOrInfinity { match p { PointOrInfinity::Point(p) => PointOrInfinity::Point(Point { x: p.x, y: -p.y }), @@ -37,6 +39,7 @@ impl Curve { } } + // outer add does infinitity check pub fn add(&self, p: PointOrInfinity, q: PointOrInfinity) -> PointOrInfinity { match (p, q) { (PointOrInfinity::Infinity, _) => q, @@ -49,21 +52,24 @@ impl Curve { } fn add_points(&self, p: Point, q: Point) -> Point { - let (x1, y1) = (p.x, p.y); - let (x2, y2) = (q.x, q.y); + // https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplicationcv + let (x_p, y_p) = (p.x, p.y); + let (x_q, y_q) = (q.x, q.y); - if x1 == x2 && y1 == -y2 { + // check for zero + if x_p == x_q && y_p == -y_q { return Point { x: F::zero(), y: F::zero() }; } - let m = if x1 == x2 && y1 == y2 { - (self.three * x1 * x1 + self.a) / (self.two * y1) + // Check if point is itself, if it is you double (which is easier) + let lamda = if x_p == x_q && y_p == y_q { + (self.three * x_p * x_p + self.a) / (self.two * y_p) } else { - (y2 - y1) / (x2 - x1) + (y_q - y_p) / (x_q - x_p) }; - let x = m * m - x1 - x2; - let y = m * (x1 - x) - y1; + let x = lamda * lamda - x_p - x_q; + let y = lamda * (x_p - x) - y_p; Point { x, y } }