Skip to content

Commit 4109e5e

Browse files
gendxcpu
andauthored
Add ML-DSA test vectors (FIPS 204 standard). (C2SP#146)
This commit adds test vectors for ML-DSA, based on the FIPS 204 standard. These tests aim to cover the following cases: - Baseline (signing a "Hello world" message). - Keys and signatures of the wrong length. - Signature with bit flips. - Signature hints with a non-canonical encoding: - hints that aren't sorted, - hints are not strictly sorted (i.e. the same hint is repeated), - too many hints (potentially causing a buffer overflow), - non-zero padding after the hints. - Secret keys with the `s1` or `s2` vectors out of the `[-eta, eta]` range. - Public key with the `t1` component set to zero (allowing trivial forgeries, but the verification algorithm should still accept signatures for this key). - Boundary conditions in the signature rejection loop (aiming to detect incorrect comparisons): - `z_max` equals `gamma1 - beta - 1` and `gamma1 - beta`, - `r0_max` equals `gamma2 - beta - 1` and `gamma2 - beta`, - `h_ones` equals `omega` and `omega + 1`, - in the case of ML-DSA-44, `|ct0|_max` equals `gamma2 - 1` and `gamma2`. - A "large" number of SHAKE bytes and of SHAKE blocks generated in the `expand_a`, `expand_s`, `rej_ntt_poly` and `rej_bounded_poly` functions. - Boundary conditions in arithmetic functions: - `power_2_round` function: when the remainder (found in `t0`) is equal to 4096 or -4095, - `decompose` (via `high_bits` or `low_bits`): when the condition `r_plus - r_0 = q - 1` happens. Beyond the baseline API, also covered are: - The `context` value: empty (default), regular length, or context too long. **What isn't covered:** - The randomized variant (only the deterministic variant is covered). - The pre-hased variant "HashML-DSA" (only the regular variant is covered). Signature generation tests are split by those that take the private key in seed form and those that use the expanded encoding. Co-authored-by: Daniel McCarney <daniel@binaryparadox.net>
1 parent 9ff10ee commit 4109e5e

13 files changed

+8109
-0
lines changed

schemas/mldsa_sign_common.json

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"definitions": {
4+
"MlDsaSignTestVector": {
5+
"type": "object",
6+
"properties": {
7+
"tcId": {
8+
"type": "integer",
9+
"description": "Identifier of the test case"
10+
},
11+
"comment": {
12+
"type": "string",
13+
"description": "A brief description of the test case"
14+
},
15+
"msg": {
16+
"type": "string",
17+
"format": "HexBytes",
18+
"description": "The message to sign"
19+
},
20+
"ctx": {
21+
"type": "string",
22+
"format": "HexBytes",
23+
"description": "[optional] The additional context string (empty if not provided)"
24+
},
25+
"sig": {
26+
"type": "string",
27+
"format": "HexBytes",
28+
"description": "The encoded signature (empty in case of expected failure)"
29+
},
30+
"result": {
31+
"type": "string",
32+
"description": "Test result",
33+
"enum": ["valid", "invalid"]
34+
},
35+
"flags": {
36+
"type": "array",
37+
"items": {
38+
"type": "string"
39+
},
40+
"description": "A list of flags"
41+
}
42+
},
43+
"additionalProperties": false,
44+
"required": ["tcId", "comment", "msg", "sig", "result", "flags"]
45+
}
46+
}
47+
}

schemas/mldsa_sign_noseed_schema.json

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"type": "object",
3+
"definitions": {
4+
"MlDsaSignTestGroup": {
5+
"type": "object",
6+
"properties": {
7+
"type": {
8+
"enum": ["MlDsaSign"]
9+
},
10+
"privateKey": {
11+
"type": "string",
12+
"format": "HexBytes",
13+
"description": "Encoded ML-DSA private key"
14+
},
15+
"tests": {
16+
"type": "array",
17+
"items": {
18+
"$ref": "mldsa_sign_common.json#/definitions/MlDsaSignTestVector"
19+
}
20+
},
21+
"source": {
22+
"$ref": "common.json#/definitions/Source"
23+
}
24+
},
25+
"additionalProperties": false,
26+
"required": ["type", "privateKey", "tests", "source"]
27+
}
28+
},
29+
"properties": {
30+
"algorithm": {
31+
"type": "string",
32+
"description": "the primitive tested in the test file"
33+
},
34+
"header": {
35+
"type": "array",
36+
"items": {
37+
"type": "string"
38+
},
39+
"description": "additional documentation"
40+
},
41+
"notes": {
42+
"type": "object",
43+
"description": "a description of the labels used in the test vectors"
44+
},
45+
"numberOfTests": {
46+
"type": "integer",
47+
"description": "the number of test vectors in this test"
48+
},
49+
"schema": {
50+
"enum": ["mldsa_sign_noseed_schema.json"]
51+
},
52+
"testGroups": {
53+
"type": "array",
54+
"items": {
55+
"$ref": "#/definitions/MlDsaSignTestGroup"
56+
}
57+
}
58+
},
59+
"additionalProperties": false,
60+
"required": ["algorithm", "header", "notes", "numberOfTests", "schema", "testGroups"]
61+
}

schemas/mldsa_sign_seed_schema.json

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"type": "object",
3+
"definitions": {
4+
"MlDsaSignTestGroup": {
5+
"type": "object",
6+
"properties": {
7+
"type": {
8+
"enum": ["MlDsaSign"]
9+
},
10+
"privateSeed": {
11+
"type": "string",
12+
"format": "HexBytes",
13+
"description": "32-byte seed that generated the private key"
14+
},
15+
"tests": {
16+
"type": "array",
17+
"items": {
18+
"$ref": "mldsa_sign_common.json#/definitions/MlDsaSignTestVector"
19+
}
20+
},
21+
"source": {
22+
"$ref": "common.json#/definitions/Source"
23+
}
24+
},
25+
"additionalProperties": false,
26+
"required": ["type", "privateSeed", "tests", "source"]
27+
}
28+
},
29+
"properties": {
30+
"algorithm": {
31+
"type": "string",
32+
"description": "the primitive tested in the test file"
33+
},
34+
"header": {
35+
"type": "array",
36+
"items": {
37+
"type": "string"
38+
},
39+
"description": "additional documentation"
40+
},
41+
"notes": {
42+
"type": "object",
43+
"description": "a description of the labels used in the test vectors"
44+
},
45+
"numberOfTests": {
46+
"type": "integer",
47+
"description": "the number of test vectors in this test"
48+
},
49+
"schema": {
50+
"enum": ["mldsa_sign_seed_schema.json"]
51+
},
52+
"testGroups": {
53+
"type": "array",
54+
"items": {
55+
"$ref": "#/definitions/MlDsaSignTestGroup"
56+
}
57+
}
58+
},
59+
"additionalProperties": false,
60+
"required": ["algorithm", "header", "notes", "numberOfTests", "schema", "testGroups"]
61+
}

schemas/mldsa_verify_schema.json

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{
2+
"type": "object",
3+
"definitions": {
4+
"MlDsaVerifyTestGroup": {
5+
"type": "object",
6+
"properties": {
7+
"type": {
8+
"enum": ["MlDsaVerify"]
9+
},
10+
"public_key": {
11+
"type": "string",
12+
"format": "HexBytes",
13+
"description": "Encoded ML-DSA public key"
14+
},
15+
"tests": {
16+
"type": "array",
17+
"items": {
18+
"$ref": "#/definitions/MlDsaVerifyTestVector"
19+
}
20+
},
21+
"source": {
22+
"$ref": "common.json#/definitions/Source"
23+
}
24+
}
25+
},
26+
"MlDsaVerifyTestVector": {
27+
"type": "object",
28+
"properties": {
29+
"tcId": {
30+
"type": "integer",
31+
"description": "Identifier of the test case"
32+
},
33+
"comment": {
34+
"type": "string",
35+
"description": "A brief description of the test case"
36+
},
37+
"msg": {
38+
"type": "string",
39+
"format": "HexBytes",
40+
"description": "The message to verify"
41+
},
42+
"ctx": {
43+
"type": "string",
44+
"format": "HexBytes",
45+
"description": "[optional] The additional context string (empty if not provided)"
46+
},
47+
"sig": {
48+
"type": "string",
49+
"format": "HexBytes",
50+
"description": "The encoded signature"
51+
},
52+
"result": {
53+
"type": "string",
54+
"description": "Test result",
55+
"enum": ["valid", "invalid"]
56+
},
57+
"flags": {
58+
"type": "array",
59+
"items": {
60+
"type": "string"
61+
},
62+
"description": "A list of flags"
63+
}
64+
}
65+
}
66+
},
67+
"properties": {
68+
"algorithm": {
69+
"type": "string",
70+
"description": "the primitive tested in the test file"
71+
},
72+
"header": {
73+
"type": "array",
74+
"items": {
75+
"type": "string"
76+
},
77+
"description": "additional documentation"
78+
},
79+
"notes": {
80+
"type": "object",
81+
"description": "a description of the labels used in the test vectors"
82+
},
83+
"numberOfTests": {
84+
"type": "integer",
85+
"description": "the number of test vectors in this test"
86+
},
87+
"schema": {
88+
"enum": ["mldsa_verify_schema.json"]
89+
},
90+
"testGroups": {
91+
"type": "array",
92+
"items": {
93+
"$ref": "#/definitions/MlDsaVerifyTestGroup"
94+
}
95+
}
96+
}
97+
}

testvectors_v1/mldsa_44_sign_noseed_test.json

Lines changed: 896 additions & 0 deletions
Large diffs are not rendered by default.

testvectors_v1/mldsa_44_sign_seed_test.json

Lines changed: 774 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)