@@ -103,30 +103,29 @@ impl<const A: i32, const B: i32> ops::Add for EPoint<A, B> {
103
103
return EPoint :: < A , B > :: infinity ( ) ;
104
104
}
105
105
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
+ } ;
121
124
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 ) ;
124
125
let x = s * s - self_coords. x - other_coords. x ;
125
126
let y = s * ( self_coords. x - x) - self_coords. y ;
126
127
127
- return Self {
128
- p : Some ( Coordinates { x, y } ) ,
129
- } ;
128
+ return EPoint :: < A , B > :: new ( x, y) ;
130
129
}
131
130
}
132
131
@@ -191,6 +190,14 @@ mod tests {
191
190
assert_eq ! ( res, a + a) ;
192
191
}
193
192
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
+
194
201
#[ test]
195
202
fn test_add ( ) {
196
203
let a = TEST_EC . point_at ( -1 , -1 ) . unwrap ( ) ;
0 commit comments