The Signature Construction: Fiat-Shamir with Aborts
ML-DSA uses a "commit → challenge → respond" (sigma protocol) structure:
[Sign(sk, msg)]
y ← small random polynomial (nonce/commitment randomness)
w = A·y (commitment)
c ← H(w, msg, pk) (challenge hash, "Fiat-Shamir")
z = y + c·s (response)
if z is "too large": ABORT and retry with fresh y
signature = (c, z, hint)
[Verify(pk, msg, sig)]
recover w' from (z, hint, c, pk)
check c == H(w', msg, pk)
The abort step is critical: it prevents leaking information about the secret s
through a large response. This is conceptually similar to why ECDSA needs random k.