BSD-3-Clause licensed by Olivier Chéron
Maintained by [email protected]
This version can be pinned in stack with:mlkem-0.2.2.0@sha256:c16cb61190e915593767e716dd08957607f6045a01d7c3a1313fbd74eb31c75d,4759

Module documentation for 0.2.2.0

Used by 1 package in nightly-2026-06-30(full list with versions):

ML-KEM

BSD Haskell Hackage

Module-Lattice-based Key-Encapsulation Mechanism implemented in Haskell.

See FIPS 203.

Example session:

> import Crypto.PubKey.ML_KEM
> import Data.Proxy
> let params = Proxy :: Proxy ML_KEM_768
> (encapKey, decapKey) <- generate params
> (sharedKey, ciphertext) <- encapsulate encapKey
> let sharedKey' = decapsulate decapKey ciphertext
> sharedKey == sharedKey'
True

Notes

The library does its best to destroy secrets and intermediate buffers from memory after use, despite the implementation in functional style. This relies on finalization by the garbage collector and is not guaranteed to run before the program exits. Also, depending on optimizations applied, lambdas may capture variables and move them to the heap. This could theoretically include machine words containing secret information that would not then be destroyed. Cautious users can run the benchmarks with info-table profiling and verify that closures containing non pointers capture only non-secret variables like loop indices or algorithm parameters.

Best performance is obtained with the LLVM code generator. On ARM, define macro __ARM_FEATURE_UNALIGNED if unaligned access is supported by the target.

Randomness is provided either from explicit inputs or through a user-selected instance of the MonadRandom type class from crypton. A good implementation would combine multiple sources of entropy, reseed periodically, and protect its internal state in memory.

Testing

The test suite executes all NIST test vectors but necessary files are not included in the package to limit its size. Instead, two files are downloaded from the project repository during execution, and this relies on commands sh and curl to run the script tests/get-vectors.sh. If not applicable to your environment, please execute the same steps manually. It will be needed only the first time.

Changes

Changelog for mlkem

0.2.2.0 - 2026-06-28

  • Clearing buffers containing secrets is more resilient and takes into account the possibility of asynchronous exceptions

  • Improve optimizations a bit more. Sometimes vector rewrite rules were not triggered early enough to fuse polynomial allocations at element level.

  • Modular reduction and constant-time selection now use an arithmetic shift instead of a logical shift. This makes no difference with LLVM but saves one instruction with the NCG.

0.2.1.0 - 2026-05-28

  • Function generateOpen is added to return not only the key pair but also the seed that was used

  • Optimizations to remove intermediate allocations where possible

0.2.0.0 - 2026-03-26

  • Flag use_crypton is now enabled by default. It requires crypton >= 1.1.1 and changes the dependency to ram instead of memory

  • Dependency to basement is replaced with primitive

0.1.1.0 - 2025-11-30

  • Fixed encoding and decoding on big-endian architectures

  • Fall back to bytes when the architecture does not support unaligned memory access

0.1.0.0 - 2025-11-02

  • First version. Released on an unsuspecting world.