Class X25519


  • @Alpha
    public final class X25519
    extends java.lang.Object
    Defines the ECDH Curve25519 function, also known as the X25519 function.

    This implementation is based on curve255-donna.

    Warning

    Do not use this API or any other APIs including fields and methods marked with the @Alpha annotation. They can be modified in any way, or even removed, at any time. They are in the package, but not for official, production release, but only for testing.

    Usage

     Alice:
     byte[] privateKeyA = X25519.generatePrivateKey();
     byte[] publicKeyA = X25519.publicFromPrivate(privateKeyA);
     Bob:
     byte[] privateKeyB = X25519.generatePrivateKey();
     byte[] publicKeyB = X25519.publicFromPrivate(privateKeyB);
    
     Alice sends publicKeyA to Bob and Bob sends publicKeyB to Alice.
     Alice:
     byte[] sharedSecretA = X25519.computeSharedSecret(privateKeyA, publicKeyB);
     Bob:
     byte[] sharedSecretB = X25519.computeSharedSecret(privateKeyB, publicKeyA);
     such that sharedSecretA == sharedSecretB.
     
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      static byte[] computeSharedSecret​(byte[] privateKey, byte[] peersPublicValue)
      Returns the 32-byte shared key (i.e., privateKey·peersPublicValue on the curve).
      static byte[] generatePrivateKey()
      Returns a 32-byte private key for Curve25519.
      static byte[] publicFromPrivate​(byte[] privateKey)
      Returns the 32-byte Diffie-Hellman public value based on the given privateKey (i.e., privateKey·[9] on the curve).
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • generatePrivateKey

        public static byte[] generatePrivateKey()
        Returns a 32-byte private key for Curve25519.

        Note from BoringSSL: All X25519 implementations should decode scalars correctly (see https://tools.ietf.org/html/rfc7748#section-5). However, if an implementation doesn't then it might interoperate with random keys a fraction of the time because they'll, randomly, happen to be correctly formed.

        Thus we do the opposite of the masking here to make sure that our private keys are never correctly masked and so, hopefully, any incorrect implementations are deterministically broken.

        This does not affect security because, although we're throwing away entropy, a valid implementation of computeSharedSecret should throw away the exact same bits anyway.

      • computeSharedSecret

        public static byte[] computeSharedSecret​(byte[] privateKey,
                                                 byte[] peersPublicValue)
                                          throws java.security.InvalidKeyException
        Returns the 32-byte shared key (i.e., privateKey·peersPublicValue on the curve).
        Parameters:
        privateKey - 32-byte private key
        peersPublicValue - 32-byte public value
        Returns:
        the 32-byte shared key
        Throws:
        java.security.InvalidKeyException - when privateKey is not 32-byte or peersPublicValue is invalid.
      • publicFromPrivate

        public static byte[] publicFromPrivate​(byte[] privateKey)
                                        throws java.security.InvalidKeyException
        Returns the 32-byte Diffie-Hellman public value based on the given privateKey (i.e., privateKey·[9] on the curve).
        Parameters:
        privateKey - 32-byte private key
        Returns:
        32-byte Diffie-Hellman public value
        Throws:
        java.security.InvalidKeyException - when the privateKey is not 32 bytes.