static JacobianEcPoint doubleJacobianPoint(JacobianEcPoint p, BigInteger a, BigInteger modulus) {
    // http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
    if (p.y.equals(BigInteger.ZERO)) {
      return JacobianEcPoint.INFINITY;
    }
    BigInteger xx = p.x.multiply(p.x).mod(modulus);
    BigInteger yy = p.y.multiply(p.y).mod(modulus);
    BigInteger yyyy = yy.multiply(yy).mod(modulus);
    BigInteger zz = p.z.multiply(p.z).mod(modulus);
    BigInteger x1yy = p.x.add(yy);
    BigInteger s = x1yy.multiply(x1yy).mod(modulus).subtract(xx).subtract(yyyy).multiply(TWO);
    BigInteger m = xx.multiply(THREE).add(a.multiply(zz).multiply(zz).mod(modulus));
    BigInteger t = m.multiply(m).mod(modulus).subtract(s.multiply(TWO)).mod(modulus);
    BigInteger x3 = t;
    BigInteger y3 =
        m.multiply(s.subtract(t)).mod(modulus).subtract(yyyy.multiply(EIGHT)).mod(modulus);
    BigInteger y1z1 = p.y.add(p.z);
    BigInteger z3 = y1z1.multiply(y1z1).mod(modulus).subtract(yy).subtract(zz).mod(modulus);
    return new JacobianEcPoint(x3, y3, z3);
  }
Jacobian representation of elliptic curve points.

<p>The point (X, Y) is represented by a triple (x, y, z), where X = x/z^2 and Y = y/z^3.
java_src/src/main/java/com/google/crypto/tink/internal/EllipticCurvesUtil.java