mlkem.h

All headers

ML-KEM-768.

This implements the Module-Lattice-Based Key-Encapsulation Mechanism from https://csrc.nist.gov/pubs/fips/204/final

  1. MLKEM768_public_key
  2. MLKEM768_private_key
  3. MLKEM768_PUBLIC_KEY_BYTES
  4. MLKEM_SEED_BYTES
  5. MLKEM768_generate_key
  6. MLKEM768_private_key_from_seed
  7. MLKEM768_public_from_private
  8. MLKEM768_CIPHERTEXT_BYTES
  9. MLKEM_SHARED_SECRET_BYTES
  10. MLKEM768_encap
  11. MLKEM768_decap
  12. Serialisation of keys
  13. MLKEM768_marshal_public_key
  14. MLKEM768_parse_public_key
  15. MLKEM768_PRIVATE_KEY_BYTES
  16. MLKEM768_parse_private_key
  17. ML-KEM-1024
  18. MLKEM1024_public_key
  19. MLKEM1024_private_key
  20. MLKEM1024_PUBLIC_KEY_BYTES
  21. MLKEM1024_generate_key
  22. MLKEM1024_private_key_from_seed
  23. MLKEM1024_public_from_private
  24. MLKEM1024_CIPHERTEXT_BYTES
  25. MLKEM1024_encap
  26. MLKEM1024_decap
  27. Serialisation of ML-KEM-1024 keys
  28. MLKEM1024_marshal_public_key
  29. MLKEM1024_parse_public_key
  30. MLKEM1024_PRIVATE_KEY_BYTES
  31. MLKEM1024_parse_private_key

MLKEM768_public_key contains an ML-KEM-768 public key. The contents of this object should never leave the address space since the format is unstable.

struct MLKEM768_public_key {
  union {
    uint8_t bytes[512 * (3 + 9) + 32 + 32];
    uint16_t alignment;
  } opaque;
};

MLKEM768_private_key contains an ML-KEM-768 private key. The contents of this object should never leave the address space since the format is unstable.

struct MLKEM768_private_key {
  union {
    uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32];
    uint16_t alignment;
  } opaque;
};

MLKEM768_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM-768 public key.

#define MLKEM768_PUBLIC_KEY_BYTES 1184

MLKEM_SEED_BYTES is the number of bytes in an ML-KEM seed.

#define MLKEM_SEED_BYTES 64

MLKEM768_generate_key generates a random public/private key pair, writes the encoded public key to out_encoded_public_key and sets out_private_key to the private key. If optional_out_seed is not NULL then the seed used to generate the private key is written to it.

OPENSSL_EXPORT void MLKEM768_generate_key(
    uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
    uint8_t optional_out_seed[MLKEM_SEED_BYTES],
    struct MLKEM768_private_key *out_private_key);

MLKEM768_private_key_from_seed derives a private key from a seed that was generated by MLKEM768_generate_key. It fails and returns 0 if seed_len is incorrect, otherwise it writes *out_private_key and returns 1.

OPENSSL_EXPORT int MLKEM768_private_key_from_seed(
    struct MLKEM768_private_key *out_private_key, const uint8_t *seed,
    size_t seed_len);

MLKEM768_public_from_private sets *out_public_key to the public key that corresponds to private_key. (This is faster than parsing the output of MLKEM768_generate_key if, for some reason, you need to encapsulate to a key that was just generated.)

OPENSSL_EXPORT void MLKEM768_public_from_private(
    struct MLKEM768_public_key *out_public_key,
    const struct MLKEM768_private_key *private_key);

MLKEM768_CIPHERTEXT_BYTES is number of bytes in the ML-KEM-768 ciphertext.

#define MLKEM768_CIPHERTEXT_BYTES 1088

MLKEM_SHARED_SECRET_BYTES is the number of bytes in an ML-KEM shared secret.

#define MLKEM_SHARED_SECRET_BYTES 32

MLKEM768_encap encrypts a random shared secret for public_key, writes the ciphertext to out_ciphertext, and writes the random shared secret to out_shared_secret.

OPENSSL_EXPORT void MLKEM768_encap(
    uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES],
    uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
    const struct MLKEM768_public_key *public_key);

MLKEM768_decap decrypts a shared secret from ciphertext using private_key and writes it to out_shared_secret. If ciphertext_len is incorrect it returns 0, otherwise it returns 1. If ciphertext is invalid (but of the correct length), out_shared_secret is filled with a key that will always be the same for the same ciphertext and private_key, but which appears to be random unless one has access to private_key. These alternatives occur in constant time. Any subsequent symmetric encryption using out_shared_secret must use an authenticated encryption scheme in order to discover the decapsulation failure.

OPENSSL_EXPORT int MLKEM768_decap(
    uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
    const uint8_t *ciphertext, size_t ciphertext_len,
    const struct MLKEM768_private_key *private_key);

Serialisation of keys.

MLKEM768_marshal_public_key serializes public_key to out in the standard format for ML-KEM-768 public keys. It returns one on success or zero on allocation error.

OPENSSL_EXPORT int MLKEM768_marshal_public_key(
    CBB *out, const struct MLKEM768_public_key *public_key);

MLKEM768_parse_public_key parses a public key, in the format generated by MLKEM768_marshal_public_key, from in and writes the result to out_public_key. It returns one on success or zero on parse error or if there are trailing bytes in in.

OPENSSL_EXPORT int MLKEM768_parse_public_key(
    struct MLKEM768_public_key *out_public_key, CBS *in);

MLKEM768_PRIVATE_KEY_BYTES is the length of the data produced by MLKEM768_marshal_private_key.

#define MLKEM768_PRIVATE_KEY_BYTES 2400

MLKEM768_parse_private_key parses a private key, in NIST's format for private keys, from in and writes the result to out_private_key. It returns one on success or zero on parse error or if there are trailing bytes in in. This format is verbose and should be avoided. Private keys should be stored as seeds and parsed using MLKEM768_private_key_from_seed.

OPENSSL_EXPORT int MLKEM768_parse_private_key(
    struct MLKEM768_private_key *out_private_key, CBS *in);

ML-KEM-1024

ML-KEM-1024 also exists. You should prefer ML-KEM-768 where possible.

MLKEM1024_public_key contains an ML-KEM-1024 public key. The contents of this object should never leave the address space since the format is unstable.

struct MLKEM1024_public_key {
  union {
    uint8_t bytes[512 * (4 + 16) + 32 + 32];
    uint16_t alignment;
  } opaque;
};

MLKEM1024_private_key contains a ML-KEM-1024 private key. The contents of this object should never leave the address space since the format is unstable.

struct MLKEM1024_private_key {
  union {
    uint8_t bytes[512 * (4 + 4 + 16) + 32 + 32 + 32];
    uint16_t alignment;
  } opaque;
};

MLKEM1024_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM-1024 public key.

#define MLKEM1024_PUBLIC_KEY_BYTES 1568

MLKEM1024_generate_key generates a random public/private key pair, writes the encoded public key to out_encoded_public_key and sets out_private_key to the private key. If optional_out_seed is not NULL then the seed used to generate the private key is written to it.

OPENSSL_EXPORT void MLKEM1024_generate_key(
    uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES],
    uint8_t optional_out_seed[MLKEM_SEED_BYTES],
    struct MLKEM1024_private_key *out_private_key);

MLKEM1024_private_key_from_seed derives a private key from a seed that was generated by MLKEM1024_generate_key. It fails and returns 0 if seed_len is incorrect, otherwise it writes *out_private_key and returns 1.

OPENSSL_EXPORT int MLKEM1024_private_key_from_seed(
    struct MLKEM1024_private_key *out_private_key, const uint8_t *seed,
    size_t seed_len);

MLKEM1024_public_from_private sets *out_public_key to the public key that corresponds to private_key. (This is faster than parsing the output of MLKEM1024_generate_key if, for some reason, you need to encapsulate to a key that was just generated.)

OPENSSL_EXPORT void MLKEM1024_public_from_private(
    struct MLKEM1024_public_key *out_public_key,
    const struct MLKEM1024_private_key *private_key);

MLKEM1024_CIPHERTEXT_BYTES is number of bytes in the ML-KEM-1024 ciphertext.

#define MLKEM1024_CIPHERTEXT_BYTES 1568

MLKEM1024_encap encrypts a random shared secret for public_key, writes the ciphertext to out_ciphertext, and writes the random shared secret to out_shared_secret.

OPENSSL_EXPORT void MLKEM1024_encap(
    uint8_t out_ciphertext[MLKEM1024_CIPHERTEXT_BYTES],
    uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
    const struct MLKEM1024_public_key *public_key);

MLKEM1024_decap decrypts a shared secret from ciphertext using private_key and writes it to out_shared_secret. If ciphertext_len is incorrect it returns 0, otherwise it returns 1. If ciphertext is invalid (but of the correct length), out_shared_secret is filled with a key that will always be the same for the same ciphertext and private_key, but which appears to be random unless one has access to private_key. These alternatives occur in constant time. Any subsequent symmetric encryption using out_shared_secret must use an authenticated encryption scheme in order to discover the decapsulation failure.

OPENSSL_EXPORT int MLKEM1024_decap(
    uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
    const uint8_t *ciphertext, size_t ciphertext_len,
    const struct MLKEM1024_private_key *private_key);

Serialisation of ML-KEM-1024 keys.

MLKEM1024_marshal_public_key serializes public_key to out in the standard format for ML-KEM-1024 public keys. It returns one on success or zero on allocation error.

OPENSSL_EXPORT int MLKEM1024_marshal_public_key(
    CBB *out, const struct MLKEM1024_public_key *public_key);

MLKEM1024_parse_public_key parses a public key, in the format generated by MLKEM1024_marshal_public_key, from in and writes the result to out_public_key. It returns one on success or zero on parse error or if there are trailing bytes in in.

OPENSSL_EXPORT int MLKEM1024_parse_public_key(
    struct MLKEM1024_public_key *out_public_key, CBS *in);

MLKEM1024_PRIVATE_KEY_BYTES is the length of the data produced by MLKEM1024_marshal_private_key.

#define MLKEM1024_PRIVATE_KEY_BYTES 3168

MLKEM1024_parse_private_key parses a private key, in NIST's format for private keys, from in and writes the result to out_private_key. It returns one on success or zero on parse error or if there are trailing bytes in in. This format is verbose and should be avoided. Private keys should be stored as seeds and parsed using MLKEM1024_private_key_from_seed.

OPENSSL_EXPORT int MLKEM1024_parse_private_key(
    struct MLKEM1024_private_key *out_private_key, CBS *in);