public static void curveMult(long[] resultx, byte[] n, byte[] qBytes) throws InvalidKeyException {
    byte[] qBytesWithoutMsb = validatePubKeyAndClearMsb(qBytes);

    long[] q = Field25519.expand(qBytesWithoutMsb);
    long[] nqpqx = new long[19];
    long[] nqpqz = new long[19];
    nqpqz[0] = 1;
    long[] nqx = new long[19];
    nqx[0] = 1;
    long[] nqz = new long[19];
    long[] nqpqx2 = new long[19];
    long[] nqpqz2 = new long[19];
    nqpqz2[0] = 1;
    long[] nqx2 = new long[19];
    long[] nqz2 = new long[19];
    nqz2[0] = 1;
    long[] t = new long[19];

    System.arraycopy(q, 0, nqpqx, 0, Field25519.LIMB_CNT);

    for (int i = 0; i < Field25519.FIELD_LEN; i++) {
      int b = n[Field25519.FIELD_LEN - i - 1] & 0xff;
      for (int j = 0; j < 8; j++) {
        int bit = (b >> (7 - j)) & 1;

        swapConditional(nqx, nqpqx, bit);
        swapConditional(nqz, nqpqz, bit);
        monty(nqx2, nqz2, nqpqx2, nqpqz2, nqx, nqz, nqpqx, nqpqz, q);
        swapConditional(nqx2, nqpqx2, bit);
        swapConditional(nqz2, nqpqz2, bit);

        t = nqx;
        nqx = nqx2;
        nqx2 = t;
        t = nqz;
        nqz = nqz2;
        nqz2 = t;
        t = nqpqx;
        nqpqx = nqpqx2;
        nqpqx2 = t;
        t = nqpqz;
        nqpqz = nqpqz2;
        nqpqz2 = t;
      }
    }

    // Computes nqx/nqz.
    long[] zmone = new long[Field25519.LIMB_CNT];
    Field25519.inverse(zmone, nqz);
    Field25519.mult(resultx, nqx, zmone);

    // Nowadays it should be standard to protect public key crypto against flaws. I.e. if there is a
    // computation error through a faulty CPU or if the implementation contains a bug, then if
    // possible this should be detected at run time.
    //
    // The situation is a bit more tricky for X25519 where for example the implementation
    // proposed in https://tools.ietf.org/html/rfc7748 only uses the x-coordinate. However, a
    // verification is still possible, but depends on the actual computation.
    //
    // Tink's Java implementation is equivalent to RFC7748. We will use the loop invariant in the
    // Montgomery ladder to detect fault computation. In particular, we use the following invariant:
    // q, resultx, nqpqx/nqpqx  are x coordinates of 3 collinear points q, n*q, (n + 1)*q.
    if (!isCollinear(q, resultx, nqpqx, nqpqz)) {
      throw new IllegalStateException(
          "Arithmetic error in curve multiplication with the public key: " + Hex.encode(qBytes));
    }
  }
Calculates nQ where Q is the x-coordinate of a point on the curve.

@param resultx the x projective coordinate of the resulting curve point (short form).
@param n a little endian, 32-byte number.
@param qBytes a little endian, 32-byte number representing the public point' x coordinate.
@throws InvalidKeyException iff the public key is in the banned list or its length is not
    32-byte.
@throws IllegalStateException iff there is arithmetic error.
java_src/src/main/java/com/google/crypto/tink/internal/Curve25519.java