Key Generation
August 25, 20264 min readbeginner
Module-LWE hands us a trapdoor almost directly, and key generation is mostly that observation plus engineering.
Module-LWE hands us a trapdoor almost directly, and key generation is mostly that observation plus engineering.
Pick a uniform matrix and a short secret vector . Compute
with a short error . The Module-LWE assumption from Chapter 4 says the pair is indistinguishable from uniform to any polynomial-time attacker, classical or quantum. So is a public key, and is the trapdoor.
Everything below is the practical version of that.
01.The steps
K1. Derive two seeds. Start from 32 random bytes and hash:
where is SHA3-512, whose 64 output bytes split into two 32-byte halves. The first seed will produce the matrix, the second will produce the secret and error.
K2. Expand into . Feed into SHAKE128, an extendable output function that produces an arbitrarily long pseudorandom byte stream, and rejection-sample that stream into elements of . The result is a matrix whose ring elements are uniform over .
Rejection sampling is needed because the stream produces 12-bit values in and only those below are usable. Values at or above are discarded rather than reduced, because reducing would make small residues more likely than large ones and the matrix would not be uniform. The cost is that roughly one in five candidates is thrown away.
The important property is that this is deterministic. Anybody holding reconstructs exactly the same .
That is worth a moment, because it is the first of several "regenerate rather than transmit" decisions. Storing outright would cost bytes, which at is bytes. Storing costs . The matrix travels as a seed and is rebuilt at both ends.
K3. Sample and . From , draw every coefficient of both vectors from the centred binomial distribution described in Chapter 3. For each coefficient is
with the four values independent uniform bits, giving a small symmetric distribution on peaked at zero.
Both vectors are short. That is what makes usable as a trapdoor, and it is why the scheme is a lattice scheme rather than linear algebra.
K4. Compute . This is ring multiplications, and they are done in the NTT domain using Chapter 4's transform. Both and are kept in NTT domain afterwards.
K5. Serialise.
where the hat marks NTT representation.
For that gives a public key of bytes, and a secret key of bytes for the encryption layer, which the wrapper in The Fujisaki-Okamoto Wrapper later extends.
02.Why the public key is stored transformed
Step K4 said and stay in the NTT domain, and FIPS 203 specifies the public key that way on the wire. That is not an implementation detail, it is part of the standard.
The reason is that the public key is used repeatedly. Every client that ever connects to Bob runs encryption against the same , and encryption needs and in transformed form. If the key were stored in coefficient form, every client would begin by performing forward transforms that produce the same result every time.
Storing it transformed removes all of them. It is the pattern flagged in Chapter 4: keep data in the NTT domain as long as possible, and let the transform boundaries fall where data genuinely enters or leaves.
There is a small cost. The transformed representation is not compressible in the way the coefficient form would be, which is part of why public keys are not compressed while ciphertexts are. Compression and Ciphertext Size returns to that.
03.Where the security sits
Restating what an attacker faces after key generation.
They see , from which they can reconstruct exactly. They see . They want .
That is precisely a Module-LWE instance: recover the short secret from . By the assumption, and via Regev's reduction behind it, doing so is at least as hard as approximating the shortest vector in a lattice of dimension .
Nothing about publishing helps them, because was never secret. The secret is , and it is hidden by .