@@ -140,8 +140,8 @@ func (P *jacobianPoint) toAffine() *affinePoint {
140140
141141func (P * jacobianPoint ) cmov (Q * jacobianPoint , b int ) { P .p2Point .cmov (& Q .p2Point , b ) }
142142
143- // add calculates P=Q+R such that Q and R are different than the identity point,
144- // and Q!==R. This function cannot be used for doublings.
143+ // add calculates P=Q+R such that Q and R are different than the identity point.
144+ // This function can be used for doublings.
145145func (P * jacobianPoint ) add (Q , R * jacobianPoint ) {
146146 if Q .isZero () {
147147 * P = * R
@@ -171,6 +171,14 @@ func (P *jacobianPoint) add(Q, R *jacobianPoint) {
171171 fp384Sqr (HH , H ) // HH = H ^ 2
172172 fp384Mul (HHH , H , HH ) // HHH = H * HH
173173 fp384Sub (RR , S2 , S1 ) // r = S2 - S1
174+
175+ // Detect point doubling
176+ if zero := (fp384 {}); * H == zero && * RR == zero {
177+ * P = * Q
178+ P .double ()
179+ return
180+ }
181+
174182 fp384Mul (V , U1 , HH ) // V = U1 * HH
175183 fp384Sqr (t2 , RR ) // t2 = r ^ 2
176184 fp384Add (t3 , V , V ) // t3 = V + V
@@ -187,6 +195,7 @@ func (P *jacobianPoint) add(Q, R *jacobianPoint) {
187195// mixadd calculates P=Q+R such that P and Q different than the identity point,
188196// and Q not in {P,-P, O}.
189197func (P * jacobianPoint ) mixadd (Q * jacobianPoint , R * affinePoint ) {
198+ // See https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-madd-2007-bl
190199 if Q .isZero () {
191200 * P = * R .toJacobian ()
192201 return
@@ -237,6 +246,7 @@ func (P *jacobianPoint) mixadd(Q *jacobianPoint, R *affinePoint) {
237246}
238247
239248func (P * jacobianPoint ) double () {
249+ // See https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
240250 delta , gamma , alpha , alpha2 := & fp384 {}, & fp384 {}, & fp384 {}, & fp384 {}
241251 fp384Sqr (delta , & P .z )
242252 fp384Sqr (gamma , & P .y )
0 commit comments