A Worked Toy Example
August 25, 20266 min readbeginner
At the real parameters nothing can be checked by hand. This note shrinks every dimension until the whole scheme fits on a page, and runs it.
At the real parameters nothing can be checked by hand. This note shrinks every dimension until the whole scheme fits on a page, and runs it.
Fix the ring to with , module rank , and errors drawn from . The message is a single bit. Every product below is in , meaning reduce with and then modulo .
01.Key generation
Take
Compute . Working the first component, :
The first product is .
The second is . The term reduces: , so . That gives .
Adding those and the error :
using .
The same procedure on the second row gives
So the public key is and the secret key is .
02.Encryption
Encrypt the bit . It encodes to in the constant coefficient, so .
Take
Compute , remembering the transpose, so the first component uses the first column of :
Compute :
The ciphertext is . No compression in this toy version.
03.Decryption
Bob computes , which comes to
and then
reducing .
The constant coefficient is . Encode put there for a bit and for a bit, so the distance to is zero and the distance to is eight. The nearer anchor is .
Decoded bit: . Correct.
04.Checking the error equation
Why Decryption Works claimed that with . Verify it directly on these numbers.
Computing that expression gives
whose coefficients written in centred form, taking values above as negative, are
And indeed
The cancellation happened exactly as the algebra promised, on real numbers, with no approximation.
05.The interesting part: a decryption failure
Look at the last coefficient of . It is .
The tolerance from Why Decryption Works is , and here
So . That coefficient has broken the bound.
Trace the consequence. The message occupied only the constant coefficient, so coefficient 3 of is and should decode to a bit. But , and on the circle modulo the distance from to the anchor is , while the distance to the anchor is . The nearer anchor is , so it decodes to .
Wrong. Had the message been four bits rather than one, this instance would have decrypted three of them correctly and the fourth incorrectly.
This is a genuine decryption failure, produced by honest parties following the protocol exactly. Nobody cheated and nothing was mis-computed.
It happens because leaves a tolerance of , and errors that are sums of several products of values in reach without difficulty. The toy parameters have essentially no margin.
Compare the real ones. At the tolerance is , and the noise is a sum of products of centred binomial values with over coefficients. Reaching requires the far tail of that distribution, which is why the published failure probability is below .
So the toy example demonstrates two things at once: that the algebra works, and that the parameters are what make it usable. Shrinking for legibility broke the scheme, which is the most direct available evidence that the real values were chosen rather than picked.
06.Chapter summary
ML-KEM is Module-LWE with the sharp edges removed.
The narrow job is establishing a shared symmetric key over an open channel, and the KEM formulation returns the key rather than accepting one, which keeps user data out of the public-key primitive and makes the security analysis tractable.
The construction has two layers. The inner one is a public-key encryption scheme where key generation publishes and keeps , encryption sends alongside , and decryption computes . The term appears twice with opposite signs and cancels, which is the whole construction, and the transpose in encryption exists precisely to make it happen.
What survives the cancellation is the encoded message plus a small error . Decoding is correct exactly when for every coefficient, and every parameter in the scheme is calibrated against that inequality. Encoding a bit to or maximises the tolerance. Compression widths differ because the noise on arrives multiplied by the secret while the noise on arrives alone.
The outer layer is the Fujisaki-Okamoto transform, which makes encryption deterministic in the message, verifies ciphertexts by re-encrypting them, and returns a pseudorandom dummy key on mismatch rather than an error. That implicit rejection is what defeats an active attacker, and it costs a full extra encryption on every decapsulation.
Every random value the scheme needs comes from Keccak in one parameterisation or another, so one hash engine serves the whole design.
Three parameter sets share and and differ only in module rank and noise widths, so one arithmetic datapath serves all of them. ML-KEM-768 is the recommended default, at 1184-byte public keys and 1088-byte ciphertexts.
The next chapter builds ML-DSA, which solves the other half of the problem. Encryption protects secrecy. Signatures protect authenticity, and the same lattice machinery does both.