Hi,
ML-DSA signature generation performs a testing of intermediate values followed
by a rejection of them if they do not meet certain criteria. For ML-DSA 87/65
there are 3 rejections possible, for ML-DSA44 there are four.
To support testing of those rejection code paths, test vectors are provided
for all ML-DSA types and all external interface types at [1] - search for
dilithium_*_rejection_vectors_*.h. Note, all test vectors generate valid
signatures that can be verified with the signature verification operation.
The description of how to generate and how to validate the test vectors are
given in [2]. The generation of the ML-DSA44 vectors took particularly long (a
number of days to generate one vector each) due to the low probability to
trigger one of the rejection code paths (the one checking for ct0).
If you want to use them in your code, please verify whether these vectors
indeed cover all rejection code paths in your code, as this may not be
guaranteed depending on the particulars of your implementation.
Note for those interested in FIPS 140: According to IG 10.3.A it is mandatory
that a power-on self test uses a test vector that (a) triggers an external
interface, and (b) covers all possible rejection code paths. This IG, however,
references a document from ACVP that gives sample test vectors. For me, those
vectors only covered 2 rejection code paths, but not all. Furthermore, those
ACVP vectors only cover the internal interface. Therefore, it may make sense
that either you use the ones mentioned above as a basis or generate your own
vectors.
[1]
https://github.com/smuellerDD/leancrypto/tree/master/ml-dsa/tests
[2]
https://github.com/smuellerDD/leancrypto/blob/master/
README.debugging.md#generation-of-ml-dsa-signature-generation-rejection-test-
vectors
Ciao
Stephan