I've discovered Aquilo in Factorio, and looking at how the tech tree involves quantum computing, it is time to prepare.

It's time to implement ML-KEM.

Let's start with a simplified version, using n = 8, p = 41, and zeta = 3.

The first thing we need are addition and multiplication in the NTT domain

Factorio is very helpful here, since all values are vectors of 64 bit integers.

ML-KEM needs vectors of 12 bit integers, so 64 bit is plenty

Adding is super easy. We chain adders set to Each (red), Each (green) with Modulo Combiners set to Each and our modulus p.
I've split the 8 values that make up a scalar into a pair of 4 values, assigned to the 4 basic ores (iron ore, copper ore, coal, and stone). Why we will see in the next part.

Next, we need multiplication. Here is where the split representation comes in handy, since ML-KEM does not do a full NTT, but leaves out the last step, resulting in real and imaginary values.

To multiply to scalars, we first multiply (each red, each green) all four combinations of the inputs. The imaginary-imaginary part needs to be adjusted further, and multiplied with a constant, depending on zeta. We chose zeta = 3, so our values are coal = 3, stone = 27 (3^3), iron ore 38 (3^5 mod 41), and copper ore 14 (3^7 mod 41). It's basically like complex numbers, but with the value of i^2 changing around.

After multiplying that in, we then add it to the real-real multiplication. We also add the mixed pairs, and compute modulo 41 at the end. Since we at most multiply 3 6-bit integers (and later 12 bit for the full version), we don't have to be careful with reducing beforehand.

@sophieschmieg Oh no, now I may *have* to start playing. 🔥🤦🏻‍♂️