Glossary

Kyber

Kyber, formally CRYSTALS-Kyber, is a post-quantum key-encapsulation mechanism that lets two parties agree on a shared secret key over an open channel. NIST standardized it as ML-KEM in FIPS 203, published August 13, 2024. The names are not interchangeable: ML-KEM is derived from Kyber and differs from the earlier submission, so ML-KEM implementations are not wire-compatible with old Kyber ones.

How it works

A KEM has three operations. The receiver runs KeyGen to get an encapsulation key (public) and a decapsulation key (private). The sender runs Encaps on the public key and gets a 32-byte shared secret plus a ciphertext. The receiver runs Decaps on that ciphertext and recovers the same 32 bytes. The shared secret then keys a symmetric cipher such as AES-GCM. FIPS 203 bases the security on the Module Learning with Errors problem, which is believed hard even for quantum computers.

FIPS 203 defines three parameter sets, all with polynomial degree n = 256 and modulus q = 3329:

  • ML-KEM-512: security category 1, k = 2.
  • ML-KEM-768: security category 3, k = 3.
  • ML-KEM-1024: security category 5, k = 4.

The next run uses a pure-Python implementation of ML-KEM (kyber-py 1.2.0) to print the real sizes in bytes and check that both sides agree.

from kyber_py.ml_kem import ML_KEM_512, ML_KEM_768, ML_KEM_1024
for n, k in (("ML-KEM-512", ML_KEM_512), ("ML-KEM-768", ML_KEM_768), ("ML-KEM-1024", ML_KEM_1024)):
    ek, dk = k.keygen()
    K, c = k.encaps(ek)
    K2 = k.decaps(dk, c)
    print(n, len(ek), len(dk), len(c), len(K), K == K2)
ML-KEM-512 800 1632 768 32 True
ML-KEM-768 1184 2400 1088 32 True
ML-KEM-1024 1568 3168 1568 32 True

The columns are encapsulation key, decapsulation key, ciphertext and shared secret, all matching Table 3 of FIPS 203. That library is a teaching implementation, so use a vetted library in production.

How big is a Kyber public key?

An ML-KEM-768 encapsulation key is 1,184 bytes and its ciphertext is 1,088 bytes. The size follows the formula 384k + 32 bytes for the key, so 800 bytes for ML-KEM-512 and 1,568 for ML-KEM-1024. An X25519 public key, in comparison, is 32 bytes, which is why post-quantum handshakes carry far more data.

What happens when a Kyber ciphertext is damaged?

Decapsulation does not raise an error. It returns a different 32-byte secret. After flipping one bit of an ML-KEM-768 ciphertext, comparing the result to the original secret printed True for the intact ciphertext and False for the altered one. FIPS 203 says well-formed input never explicitly fails, which prevents leaking the failure to an attacker.

Common pitfalls

  • Treating Kyber and ML-KEM as the same wire format: FIPS 203 Appendix C lists differences from the CRYSTALS-Kyber submission. Use ML-KEM for anything that must follow the standard.
  • Using the shared secret directly as a key: FIPS 203 approves key derivation per SP 800-56C. Run it through a KDF with context first.
  • Expecting encryption of data: a KEM only agrees on a key. Encrypt the data with a symmetric cipher.
  • Reusing randomness: FIPS 203 requires an approved random bit generator with at least 128, 192 or 256 bits of strength for the three sets.
  • Skipping key checks: FIPS 203 specifies input checks on the encapsulation key length before use. Reject keys that are not exactly 384k + 32 bytes.

Related terms

  • Dilithium — the lattice signature scheme from the same CRYSTALS family.
  • X25519 — the classical key exchange Kyber is often paired with.
  • RSA — the classical algorithm quantum computers threaten.
  • ECC — the elliptic-curve family also at risk from quantum attacks.
  • TLS — the protocol where hybrid key exchange is deployed.
  • AES-GCM — the cipher keyed by the shared secret.

See also