Skip to content

Commit d6de01e

Browse files
committed
feat: improve addition logic, add safe point return using the
constructor
1 parent a6f81f5 commit d6de01e

File tree

1 file changed

+27
-20
lines changed

1 file changed

+27
-20
lines changed

src/ec.rs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -103,30 +103,29 @@ impl<const A: i32, const B: i32> ops::Add for EPoint<A, B> {
103103
return EPoint::<A, B>::infinity();
104104
}
105105

106-
// 3. Points are the same point.
107-
if self == other {
108-
// Special case: If the y coord is 0, the tangent line is vertical since the elliptic
109-
// curve is symmetrical wrt. the x axis. This results on a point on the infinity.
110-
if self_coords.y == 0 {
111-
return Self::infinity();
112-
}
113-
114-
let s = (3 * self_coords.x * self_coords.x + A) / (2 * self_coords.y);
115-
let x = s * s - 2 * self_coords.x;
116-
let y = s * (self_coords.x - x) - self_coords.y;
117-
return Self {
118-
p: Some(Coordinates { x, y }),
119-
};
120-
}
106+
// 3. Either the points are the same point (P1 = P2) or are different (P1 != P2)
107+
// The only difference between the two cases is how we calculate the slope. For P1 == P2,
108+
// the line is tangent to the curve. For P1 != P2 the line intersects the curve at both
109+
// points. Furthermore, when P1 == P2 and P1.y == 0 the tangent line is vertical and the
110+
// resulting point lies at infinity.
111+
let s = match self == other {
112+
// 3.1. Points are the same point.
113+
true => match self_coords.y {
114+
// Special case: If the y coord is 0, the tangent line is vertical since the elliptic
115+
// curve is symmetrical wrt. the x axis. This results on a point on the infinity.
116+
0 => return EPoint::<A, B>::infinity(),
117+
_ => (3 * self_coords.x * self_coords.x + A) / (2 * self_coords.y),
118+
},
119+
// 3.2. Points are different.
120+
// The denominator cannot be zero since if P1.x != P2.x is handled at (2) and
121+
// P1.x == P2.x is handled at 3.1.
122+
false => (other_coords.y - self_coords.y) / (other_coords.x - self_coords.x),
123+
};
121124

122-
// 4. The general case, where points are distinct, none is infinity and they are not additive inverses.
123-
let s = (other_coords.y - self_coords.y) / (other_coords.x - self_coords.x);
124125
let x = s * s - self_coords.x - other_coords.x;
125126
let y = s * (self_coords.x - x) - self_coords.y;
126127

127-
return Self {
128-
p: Some(Coordinates { x, y }),
129-
};
128+
return EPoint::<A, B>::new(x, y);
130129
}
131130
}
132131

@@ -191,6 +190,14 @@ mod tests {
191190
assert_eq!(res, a + a);
192191
}
193192

193+
#[test]
194+
fn test_add_same_at_y0() {
195+
let ec = ECurve::<1, 10>::new();
196+
let p = ec.point_at(-2, 0);
197+
198+
assert_eq!(ec.point_at_ifty(), p.unwrap() + p.unwrap());
199+
}
200+
194201
#[test]
195202
fn test_add() {
196203
let a = TEST_EC.point_at(-1, -1).unwrap();

0 commit comments

Comments
 (0)