class X25519 {

  @SuppressWarnings("NarrowingCompoundAssignment")
  public static byte[] computeSharedSecret(byte[] privateKey, byte[] peersPublicValue)
      throws InvalidKeyException {
    if (privateKey.length != Field25519.FIELD_LEN) {
      throw new InvalidKeyException("Private key must have 32 bytes.");
    }
    long[] x = new long[Field25519.LIMB_CNT + 1];

    byte[] e = Arrays.copyOf(privateKey, Field25519.FIELD_LEN);
    e[0] &= 248;
    e[31] &= 127;
    e[31] |= 64;

    Curve25519.curveMult(x, e, peersPublicValue);
    return Field25519.contract(x);
  }

}