public static ECPoint multiplyByGenerator(BigInteger x, ECParameterSpec spec)
      throws GeneralSecurityException {
    if (!EllipticCurvesUtil.isNistEcParameterSpec(spec)) {
      throw new GeneralSecurityException("spec must be NIST P256, P384 or P521");
    }
    if (x.signum() != 1) {
      throw new GeneralSecurityException("k must be positive");
    }
    if (x.compareTo(spec.getOrder()) >= 0) {
      throw new GeneralSecurityException("k must be smaller than the order of the generator");
    }
    EllipticCurve curve = spec.getCurve();
    ECPoint generator = spec.getGenerator();
    checkPointOnCurve(generator, curve);
    BigInteger a = spec.getCurve().getA();
    BigInteger modulus = getModulus(curve);

    JacobianEcPoint r0 = toJacobianEcPoint(ECPoint.POINT_INFINITY, modulus);
    JacobianEcPoint r1 = toJacobianEcPoint(generator, modulus);
    for (int i = x.bitLength(); i >= 0; i--) {
      if (x.testBit(i)) {
        r0 = addJacobianPoints(r0, r1, a, modulus);
        r1 = doubleJacobianPoint(r1, a, modulus);
      } else {
        r1 = addJacobianPoints(r0, r1, a, modulus);
        r0 = doubleJacobianPoint(r0, a, modulus);
      }
    }
    ECPoint output = r0.toECPoint(modulus);
    checkPointOnCurve(output, curve);
    return output;
  }
Calculates x times the generator of the give elliptic curve spec using the Montgomery ladder.

<p>This should only be used to validate keys, and not to sign or verify messages.

<p>See: <a href="https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication">Elliptic
curve point multiplication</a>.

@param x must be larger than 0 and smaller than the order of the generator.
@return the ECPoint that is x times the generator.
java_src/src/main/java/com/google/crypto/tink/internal/EllipticCurvesUtil.java