Boring crypto that simply works

Key Exchange

Elliptic Curve Diffie-Hellman key exchange (x25519).


#include <monocypher.h>

int crypto_key_exchange(uint8_t       shared_key      [32],
                        const uint8_t your_secret_key [32],
                        const uint8_t their_public_key[32]);

void crypto_key_exchange_public_key(
    uint8_t       your_public_key[32],
    const uint8_t your_secret_key[32]);


crypto_key_exchange() computes a shared key with your secret key and their public key.

crypto_key_exchange_public_key() deterministically computes the public key from a random secret key.

The arguments are:

Return values

Some public keys force the shared key to a known constant. crypto_key_exchange() returns -1 if it detects such a public key, otherwise it returns 0. This never happens with legitimate public keys.

The return value has been deprecated. crypto_key_exchange() will return void starting with the next major release of Monocypher. Some poorly designed protocols require to test for "contributory" behaviour, which ensures that no untrusted party forces the shared secret to a known constant. Protocols should instead be designed in such a way that no such check is necessary, namely by authenticating the other party or exchanging keys over a trusted channel.

crypto_key_exchange_public_key returns nothing.


Generate a public key from a randomly generated secret key:

const uint8_t sk[32]; /* Random secret key */
uint8_t       pk[32]; /* Public key        */
crypto_key_exchange_public_key(pk, sk);
/* Wipe secrets if they are no longer needed */
crypto_wipe(sk, 32);

Generate a shared, symmetric key with your secret key and their public key. (The other party will generate the same shared key with your public key and their secret key.)

const uint8_t their_pk  [32]; /* Their public key   */
const uint8_t your_sk   [32]; /* Your secret key    */
uint8_t       shared_key[32]; /* Shared session key */
crypto_key_exchange(shared_key, your_sk, their_pk);
/* Wipe secrets if they are no longer needed */
crypto_wipe(your_sk, 32);


These functions implement X25519, described in RFC 7748. crypto_key_exchange() uses HChacha20 as well.

Security considerations

If either of the long term secret keys leaks, it may compromise all past messages. This can be avoided by using protocols that provide forward secrecy, such as the X3DH key agreement protocol.

Implementation details

crypto_key_exchange_public_key() is an alias to crypto_x25519_public_key().