- let s = self.x.times_four().mul(&self.y.square());
- let z_2 = self.z.square();
- let z_4 = z_2.square();
- let y_2 = self.y.square();
- let y_4 = y_2.square();
- let x_2 = self.x.square();
- let m = x_2.times_three().add(&C::A.mul(&z_4));
- let x = m.square().sub(&s.double());
- let y = m.mul(&s.sub(&x)).sub(&y_4.times_eight());
- let z = self.y.double().mul(&self.z);
+ // https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
+ // delta = Z1^2
+ // gamma = Y1^2
+ // beta = X1*gamma
+ // alpha = 3*(X1-delta)*(X1+delta)
+ // X3 = alpha^2-8*beta
+ // Z3 = (Y1+Z1)^2-gamma-delta
+ // Y3 = alpha*(4*beta-X3)-8*gamma^2
+
+ let delta = self.z.square();
+ let gamma = self.y.square();
+ let beta = self.x.mul(&gamma);
+ let alpha = self.x.sub(&delta).times_three().mul(&self.x.add(&delta));
+ let x = alpha.square().sub(&beta.times_eight());
+ let y = alpha.mul(&beta.times_four().sub(&x)).sub(&gamma.square().times_eight());
+ let z = self.y.add(&self.z).square().sub(&gamma).sub(&delta);