ECDH: X25519

HACL* implements the X25519 Elliptic Curve Diffie Hellman (ECDH) construction IETF RFC 7748. The library includes two implementations of this construction, both with the same API, but meant for use on different platforms:

  • Hacl_Curve25519_51.h contains a portable C implementation that is optimized for use on 64-bit platforms that support 128-bit arithmetic, but it will still compile and execute on 32-bit platforms (using an emulated 128-bit arithmetic library provided by KreMLin).
  • Hacl_Curve25519_64.h contains a hybrid C/assembly implementation: the field arithmetic functions are in Intel assembly (generated by Vale) and rely on the Intel ADX and BMI2 instruction sets; the elliptic curve functions and the main API are in portable C.

Both versions provide functions that can be used to generate Curve25519 keypairs and use them to compute ECDH shared secrets.

Key Generation

Any 32 byte array can be used as a Curve25519 private key. In practice, private keys should be generated using a cryptographically strong pseudo-random number generator (CSPRNG). In some cases, the private key may be derived as the result of a key derivation function such as HKDF.

Given a private key, the corresponding public key can be computed using the secret_to_public function:

void Hacl_Curve25519_51_secret_to_public(uint8_t *pub, uint8_t *priv);

void Hacl_Curve25519_64_secret_to_public(uint8_t *pub, uint8_t *priv);

The first argument is a pointer to the output public key pub; the second argument is a pointer to the input private key priv.

ECDH Shared Secret

The ECDH operation is implemented by the following function:

bool Hacl_Curve25519_51_ecdh(uint8_t *out, uint8_t *priv, uint8_t *pub);

bool Hacl_Curve25519_64_ecdh(uint8_t *out, uint8_t *priv, uint8_t *pub);

The first argument is a pointer to the output shared secret out; the second argument is the private key of the caller priv; the last argument is the public key of the peer pub. The size of all three arrays must be (at least) 32 bytes.

The function returns a boolean since it may fail. If the computed shared secret is an array of all zeroes, then the function ecdh returns false to indicate that the operation failed. Otherwise, it returns true.

Other Curves: P-256

A development branch includes a verified implementation of P-256, which has not yet been merged to master. Contact the HACL* maintainers if you wish to use this code.