Key encapsulation

Example

unsigned char pk[crypto_kem_PUBLICKEYBYTES];
unsigned char sk[crypto_kem_SECRETKEYBYTES];
unsigned char ciphertext[crypto_kem_CIPHERTEXTBYTES];
unsigned char client_key[crypto_kem_SHAREDSECRETBYTES];
unsigned char server_key[crypto_kem_SHAREDSECRETBYTES];

crypto_kem_keypair(pk, sk);

if (crypto_kem_enc(ciphertext, client_key, pk) != 0) {
    /* error */
}
if (crypto_kem_dec(server_key, ciphertext, sk) != 0) {
    /* error */
}

Purpose

A key encapsulation mechanism creates a shared secret for a recipient using the public key of that recipient.

The sender obtains the shared secret directly during encapsulation. The recipient obtains the same shared secret by decapsulating the ciphertext with the secret key.

This is useful for bootstrapping session keys or building hybrid encryption schemes.

For most applications, the high-level crypto_kem_*() API should be preferred. In libsodium, it uses X-Wing, a hybrid post-quantum KEM combining ML-KEM768 and X25519.

Usage

The crypto_kem_keypair() function creates a new key pair. It puts the public key into pk and the secret key into sk.

The crypto_kem_seed_keypair() function computes a deterministic key pair from seed (crypto_kem_SEEDBYTES bytes).

The crypto_kem_enc() function creates a ciphertext ct for the recipient public key pk and stores the shared secret into ss.

It returns 0 on success and -1 on failure.

The crypto_kem_dec() function verifies and decapsulates the ciphertext ct using the recipient secret key sk, and stores the shared secret into ss.

It returns 0 on success and -1 on failure.

Using the shared secret

The shared secret is crypto_kem_SHAREDSECRETBYTES bytes long.

In many protocols, the shared secret is immediately fed to a KDF in order to derive multiple context-specific keys. HKDF is a good fit for this.

Algorithm details

The high-level crypto_kem_*() API uses X-Wing and reports "xwing" via crypto_kem_PRIMITIVE.

X-Wing combines ML-KEM768 with X25519 in order to provide protection against both classical and quantum adversaries.

For libsodium applications, it should be the default choice.

Constants

  • crypto_kem_PUBLICKEYBYTES

  • crypto_kem_SECRETKEYBYTES

  • crypto_kem_CIPHERTEXTBYTES

  • crypto_kem_SHAREDSECRETBYTES

  • crypto_kem_SEEDBYTES

  • crypto_kem_PRIMITIVE

Notes

Unlike traditional Diffie-Hellman style key exchange, encapsulation is asymmetric: only the recipient needs a long-term key pair, and the sender does not need to publish a public key in order to create a shared secret.

If the application needs sender authentication in addition to confidentiality, combine key encapsulation with a signature scheme or an authenticated key exchange.

This API was introduced in libsodium 1.0.22.

Last updated