Chapter 7Modular Reduction and the Keccak Sponge

Exercises

August 25, 20267 min readbeginner

Take q = 8380417 and k = 48. Compute m = 2^48/q and check that Barrett leaves r [0, 2q) after step B3.

01.1. Barrett for the signature modulus

Take q=8380417q = 8380417 and k=48k = 48. Compute m=⌊248/q⌋m = \lfloor 2^{48}/q \rfloor and check that Barrett leaves r∈[0,2q)r \in [0, 2q) after step B3.

Answer.

m  =  ⌊2488380417⌋  =  33587228.m \;=\; \left\lfloor \frac{2^{48}}{8380417} \right\rfloor \;=\; 33587228 .

The choice k=48k = 48 satisfies 2k>q22^k > q^2, since q2≈7.02×1013q^2 \approx 7.02 \times 10^{13} and 248≈2.81×10142^{48} \approx 2.81 \times 10^{14}.

Sampling 5000 random inputs from [0,q2)[0, q^2) and running steps B1 to B3 gives r∈[0,2q)r \in [0, 2q) every time, with zero violations, so one conditional subtraction in B4 always suffices.

Worth contrasting with the constant in Barrett Reduction. There the manuscript's mm was one too large and the bound failed on some inputs. Here the constant is derived correctly and the bound holds. Same algorithm, and the difference between working and subtly broken is one unit in a precomputed integer.

02.2. A Montgomery round trip at real parameters

For q=3329q = 3329 and R=216R = 2^{16}, find q′q', put x=2048x = 2048 into Montgomery form, square it, reduce, convert back, and compare with x2 mod qx^2 \bmod q.

Answer. Solving qq′≡−1(mod216)q q' \equiv -1 \pmod{2^{16}} gives

q′  =  3327,since 3329×3327 mod 65536=65535=R−1.q' \;=\; 3327, \qquad \text{since } 3329 \times 3327 \bmod 65536 = 65535 = R - 1 .

Convert: x~=2048×65536 mod 3329=2435\tilde{x} = 2048 \times 65536 \bmod 3329 = 2435.

Square in the Montgomery domain: T=24352=5929225T = 2435^2 = 5929225, and one Montgomery reduction gives 3838.

Convert back with a second reduction of T=38T = 38: the result is 30933093.

Check directly: 20482=41943042048^2 = 4194304, and 4194304 mod 3329=30934194304 \bmod 3329 = 3093. They agree.

Notice that the intermediate 3838 is meaningless on its own. It is x2R mod qx^2 R \bmod q, which is the Montgomery form of the answer, and reading it as an ordinary residue would be wrong. That is the standard trap when debugging this code: values in the middle of a transform are not the numbers they look like.

03.3. Solinas reduction, written out

Show that q=223−213+1q = 2^{23} - 2^{13} + 1 reduces any x∈[0,246)x \in [0, 2^{46}) using shifts and adds only. How many conditional subtractions finish it?

Answer. Split x=xH⋅223+xLx = x_H \cdot 2^{23} + x_L with both parts below 2232^{23}. Since 223≡213−1(modq)2^{23} \equiv 2^{13} - 1 \pmod q,

x  ≡  xL  +  (xH≪13)  −  xH(modq).x \;\equiv\; x_L \;+\; (x_H \ll 13) \;-\; x_H \pmod q .

That is one shift, one addition and one subtraction.

Bounding the result: xL<223x_L < 2^{23} and xH≪13<236x_H \ll 13 < 2^{36}, so the fold can reach about 2362^{36}, which is far above q≈223q \approx 2^{23}. One pass is not enough.

Apply the same fold again to the result. Each pass roughly replaces a value of magnitude 2a2^a with one of magnitude 2a−102^{a-10}, since the high part shrinks by 23 bits and grows back by 13. Starting just below 2462^{46}, the passes measure out as 2362^{36}, then 2272^{27}, then 2242^{24}, at which point the value sits at about 1.01×q1.01 \times q.

From there one or two conditional subtractions land it in [0,q)[0, q). So the whole reduction is three folds and at most two conditional subtractions, all shifts, adds and compares, and no multiplication at any point.

The worked example in Special-Prime Tricks shows a single fold taking 12,345,678,90112{,}345{,}678{,}901 to 18,085,49418{,}085{,}494, which is 2.16×q2.16 \times q and therefore needs exactly two more subtractions.

04.4. Counting SHAKE calls

For ML-KEM-768, how many SHAKE128 permutations does expanding AA take, assuming 672 bytes per ring element? Compare with the SHAKE256 budget for sampling s\mathbf{s} and e\mathbf{e}.

Answer. The matrix has k2=9k^2 = 9 ring elements, so 9×672=60489 \times 672 = 6048 bytes. SHAKE128 has rate 1344 bits, which is 168 bytes per permutation, giving

6048/168  =  36 permutations.6048 / 168 \;=\; 36 \text{ permutations}.

For the secrets, each of s\mathbf{s} and e\mathbf{e} needs k⋅n⋅η1/4=3×256×2/4=384k \cdot n \cdot \eta_1 / 4 = 3 \times 256 \times 2 / 4 = 384 bytes, so 768768 bytes together. SHAKE256 has rate 1088 bits, which is 136 bytes, giving

⌈768/136⌉  =  6 permutations.\lceil 768 / 136 \rceil \;=\; 6 \text{ permutations}.

So matrix expansion costs six times as much hashing as secret sampling, which is why SHAKE128 with its higher rate is used there and SHAKE256 with its stronger capacity is reserved for the secrets. The choice in The Sponge Construction is a throughput decision, and this is the arithmetic behind it.

The 672 bytes per ring element is itself a consequence of rejection sampling: 256 coefficients need 384 bytes of 12-bit values if nothing is rejected, and roughly one candidate in five is discarded, so the budget is padded.

05.5. Gate count for one Keccak round

Answer. Counting XORs per round on the 1600-bit state.

θ\theta: five column parities, each four XORs on 64-bit lanes, so 5×4×64=12805 \times 4 \times 64 = 1280. Then DD is one XOR per column, 5×64=3205 \times 64 = 320. Then DD is XORed into all 25 lanes, 25×64=160025 \times 64 = 1600. Total about 32003200.

ρ\rho and π\pi: zero gates. Both are fixed rewiring.

χ\chi: per output bit, one NOT, one AND and one XOR, so 16001600 XORs and 16001600 ANDs.

ι\iota: 64 XORs, and only on lane (0,0)(0,0).

So roughly 49004900 XOR gates and 16001600 AND gates per round.

For a one-round-per-cycle datapath, add 1600 flip-flops for the state. At a rough two to four LUTs per gate-equivalent on an FPGA, that lands in the fifteen to twenty thousand LUT range quoted in Hardware Footprint, and the Chapter Summary, which is the consistency check worth making.

The ratio is the interesting part. Three quarters of the logic is θ\theta, the diffusion layer, and the single non-linear step is a sixth of it. Keccak is cheap because non-linearity is cheap here.

06.6. Reduction for a unified engine

Argue which reduction method you would use for each modulus in a design serving both standards, and whether one datapath can cover both.

Answer. There is no single right answer, and the exercise is to commit to one and be able to defend it.

For ML-DSA, the Solinas fold from Special-Prime Tricks is hard to argue against. It needs no multiplier at all, so it is strictly cheaper than any general method in both area and latency. Any design not using it is leaving free performance behind.

For ML-KEM, the choice is between Montgomery and Plantard. Montgomery is proven, widely implemented and well understood. Plantard offers ten to twenty percent more clock frequency on current FPGA fabric and is under-represented in the literature. For a research design where the point is to explore, Plantard is the more interesting commitment.

Can one datapath cover both? Not the reduction tail. A shift-and-add network for a 23-bit Solinas prime and a multiplier-based reducer for a 12-bit generic prime are different circuits, not one circuit with a mode bit. A unified design either instantiates both and multiplexes, paying area for whichever is idle, or gives up the Solinas advantage and uses the general method for both.

The first architectural decision to commit to is therefore the one above the reduction: whether the butterfly datapath is parameterised by coefficient width. If it is, then two reduction tails behind a shared butterfly is a coherent design. If not, the two schemes get separate engines and the only sharing is the Keccak block.

07.7. Break the naive padding

Show that appending zeros instead of pad10*1 allows a collision, and construct one.

Answer. With a zero-fill rule, any input and that same input followed by zero bytes pad to the identical block sequence.

Take SHAKE128, whose rate is 168 bytes. The input "abc" pads to "abc" followed by 165 zero bytes. The input "abc" followed by a single zero byte pads to "abc", one zero byte, and 164 more zero bytes.

Both produce exactly the same 168-byte block, so both absorb identically and squeeze identical output. Two distinct inputs, one output. A collision found by inspection, with no computation at all.

The pad10*1 rule stops this because the terminating 11 bit lands at a position determined by the input length. The two inputs above differ in length by one byte, so their terminators fall in different places, and the padded blocks differ.

This is why the padding rule is part of the specification rather than an implementation detail, and why the domain byte from The Sponge Construction rides along with it.

FeedbackBook mode
post-quantum-cryptographycryptographymathematics