// CONFORMANCE_REPORT · NO_LOGIN_REQUIRED
236 known-answer vector cases against NIST’s published ACVP files and the classical standards. 195 further published vectors are not run — listed below with the reason for each, because an inventory that lists only its successes is not an inventory.
This is not a FIPS 140 certificate
No CAVP algorithm certificate. No CMVP module certificate. No FIPS 140-3 validation. CAVP validation precedes CMVP validation and both are performed by an accredited Cryptographic and Security Testing laboratory — not by us. liboqs is not a FIPS-certified module. What follows is ACVP-aligned automated test evidence: self-reported, and checkable in the specific ways set out under what you can verify.
commit dc771528a82b · tree clean · liboqs 0.16.0 · github-actions
// RESULTS_SUMMARY
In plain terms
Standards bodies publish official test inputs with known correct answers. This is how many of them we ran, broken down by algorithm, and how many passed.
One row per test group. Counts are read from the run record itself — no figure on this page is typed by hand.
| Standard | Algorithm | Function | Entry point | Executed | Passed | Failed |
|---|---|---|---|---|---|---|
| RFC 8032 §6.1 | Ed25519 | verify | EVP_DigestVerify | 5 | 5 | 0 |
| Dobbertin et al., 1996 | RIPEMD-160 | digest | Hash160::ripemd160 | 6 | 6 | 0 |
| FIPS 203 | ML-KEM | keyGen | OQS_KEM_keypair_derand | 75 | 75 | 0 |
| FIPS 203 | ML-KEM | encapsulation | OQS_KEM_encaps_derand | 75 | 75 | 0 |
| FIPS 203 | ML-KEM | decapsulation | OQS_KEM_decaps | 30 | 30 | 0 |
| FIPS 204 | ML-DSA | sigVer | OQS_SIG_verify_with_ctx_str | 45 | 45 | 0 |
| TOTAL | 236 | 236 | 0 | |||
The negative cases carry the weight. 36 of these cases expect rejection — modified message, modified commitment, modified hint, modified z, a truncated signature, an all-zero signature. A verifier that returned true unconditionally would pass all 200 positive cases and fail every one of the 36.
// PER_CASE_RESULTS
In plain terms
One line per individual test. The tcId is NIST's own numbering, so you can look any row up in their published files directly.
Output values are published as SHA-256 rather than raw bytes — a single ML-KEM-1024 decapsulation key is 3168 bytes. Equality of the expected and computed digests is the result, shown rather than asserted; the workbook and JSON carry both digests per case.
| Group | Param set | tgId | tcId | Case | Expected | Actual | Result |
|---|---|---|---|---|---|---|---|
| ed25519 | — | — | — | RFC 8032 §6.1 Vector 1 — empty message; paired with a tampered-signature rejection | conformant | conformant | PASS |
| ed25519 | — | — | — | RFC 8032 §6.1 Vector 2 — 1-byte message 0x72; paired with a wrong-public-key rejection | conformant | conformant | PASS |
| ed25519 | — | — | — | RFC 8032 §6.1 Vector 3 — 2-byte message af 82; paired with an altered-message rejection | conformant | conformant | PASS |
| ed25519 | — | — | — | Truncated 31-byte signature must be rejected | conformant | conformant | PASS |
| ed25519 | — | — | — | All-zero 64-byte signature must be rejected (low-order / degenerate point) | conformant | conformant | PASS |
| ripemd160 | — | — | — | "" | 9c1185a5c5e9fc5461280897… | 9c1185a5c5e9fc5461280897… | PASS |
| ripemd160 | — | — | — | "a" | 0bdc9d2d256b3ee9daae347b… | 0bdc9d2d256b3ee9daae347b… | PASS |
| ripemd160 | — | — | — | "abc" | 8eb208f7e05d987a9b044a8e… | 8eb208f7e05d987a9b044a8e… | PASS |
| ripemd160 | — | — | — | "message digest" | 5d0689ef49d2fae572b881b1… | 5d0689ef49d2fae572b881b1… | PASS |
| ripemd160 | — | — | — | "abcdefghijklmnopqrstuvwxyz" | f71c27109c692c1b56bbdceb… | f71c27109c692c1b56bbdceb… | PASS |
| ripemd160 | — | — | — | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" | b0e20b6e3116640286ed3a87… | b0e20b6e3116640286ed3a87… | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 1 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 2 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 3 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 4 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 5 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 6 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 7 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 8 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 9 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 10 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 11 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 12 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 13 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 14 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 15 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 16 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 17 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 18 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 19 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 20 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 21 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 22 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 23 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 24 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-512 | 1 | 25 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 26 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 27 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 28 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 29 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 30 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 31 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 32 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 33 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 34 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 35 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 36 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 37 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 38 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 39 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 40 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 41 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 42 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 43 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 44 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 45 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 46 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 47 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 48 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 49 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-768 | 2 | 50 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 51 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 52 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 53 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 54 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 55 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 56 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 57 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 58 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 59 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 60 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 61 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 62 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 63 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 64 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 65 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 66 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 67 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 68 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 69 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 70 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 71 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 72 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 73 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 74 | — | MATCH | MATCH | PASS |
| mlkem-keygen | ML-KEM-1024 | 3 | 75 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 1 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 2 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 3 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 4 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 5 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 6 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 7 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 8 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 9 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 10 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 11 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 12 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 13 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 14 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 15 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 16 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 17 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 18 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 19 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 20 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 21 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 22 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 23 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 24 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-512 | 1 | 25 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 26 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 27 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 28 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 29 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 30 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 31 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 32 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 33 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 34 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 35 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 36 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 37 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 38 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 39 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 40 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 41 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 42 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 43 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 44 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 45 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 46 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 47 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 48 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 49 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-768 | 2 | 50 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 51 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 52 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 53 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 54 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 55 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 56 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 57 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 58 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 59 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 60 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 61 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 62 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 63 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 64 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 65 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 66 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 67 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 68 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 69 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 70 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 71 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 72 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 73 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 74 | — | MATCH | MATCH | PASS |
| mlkem-encaps | ML-KEM-1024 | 3 | 75 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-512 | 4 | 76 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-512 | 4 | 77 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-512 | 4 | 78 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-512 | 4 | 79 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-512 | 4 | 80 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-512 | 4 | 81 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-512 | 4 | 82 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-512 | 4 | 83 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-512 | 4 | 84 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-512 | 4 | 85 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-768 | 5 | 86 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-768 | 5 | 87 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-768 | 5 | 88 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-768 | 5 | 89 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-768 | 5 | 90 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-768 | 5 | 91 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-768 | 5 | 92 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-768 | 5 | 93 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-768 | 5 | 94 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-768 | 5 | 95 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-1024 | 6 | 96 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-1024 | 6 | 97 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-1024 | 6 | 98 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-1024 | 6 | 99 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-1024 | 6 | 100 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-1024 | 6 | 101 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-1024 | 6 | 102 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-1024 | 6 | 103 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-1024 | 6 | 104 | — | MATCH | MATCH | PASS |
| mlkem-decaps | ML-KEM-1024 | 6 | 105 | — | MATCH | MATCH | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 1 | modified message | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 2 | modified signature - commitment | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 3 | valid signature and message - signature should verify successfully | ACCEPT | ACCEPT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 4 | modified signature - commitment | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 5 | modified signature - z | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 6 | modified signature - z | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 7 | modified signature - hint | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 8 | modified signature - commitment | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 9 | modified signature - hint | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 10 | modified message | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 11 | valid signature and message - signature should verify successfully | ACCEPT | ACCEPT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 12 | modified signature - z | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 13 | modified signature - hint | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 14 | modified message | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-44 | 1 | 15 | valid signature and message - signature should verify successfully | ACCEPT | ACCEPT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 31 | modified signature - z | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 32 | modified signature - hint | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 33 | valid signature and message - signature should verify successfully | ACCEPT | ACCEPT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 34 | modified signature - commitment | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 35 | modified message | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 36 | modified signature - z | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 37 | modified signature - commitment | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 38 | modified signature - hint | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 39 | modified message | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 40 | modified signature - z | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 41 | modified signature - hint | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 42 | modified signature - commitment | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 43 | valid signature and message - signature should verify successfully | ACCEPT | ACCEPT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 44 | valid signature and message - signature should verify successfully | ACCEPT | ACCEPT | PASS |
| mldsa-sigver | ML-DSA-65 | 3 | 45 | modified message | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 61 | modified message | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 62 | modified message | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 63 | valid signature and message - signature should verify successfully | ACCEPT | ACCEPT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 64 | modified signature - commitment | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 65 | modified signature - hint | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 66 | modified message | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 67 | valid signature and message - signature should verify successfully | ACCEPT | ACCEPT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 68 | modified signature - commitment | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 69 | modified signature - hint | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 70 | valid signature and message - signature should verify successfully | ACCEPT | ACCEPT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 71 | modified signature - commitment | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 72 | modified signature - z | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 73 | modified signature - z | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 74 | modified signature - hint | REJECT | REJECT | PASS |
| mldsa-sigver | ML-DSA-87 | 5 | 75 | modified signature - z | REJECT | REJECT | PASS |
ML-DSA tcIds run 1–15, 31–45 and 61–75. The gaps are the excluded pre-hash and internal-interface groups, removed rather than renumbered, so any tcId here resolves directly against NIST’s published files.
// EXCLUSIONS
In plain terms
Official tests we did not run, and exactly why not. These are listed because leaving them out silently is how a test report flatters itself.
Of the 420 vectors NIST publishes for ML-KEM and ML-DSA, 225 are reachable through the liboqs public API and run here. The other 195 are listed below with a reason rather than skipped quietly. Every reason is checkable against liboqs, which is public.
These assert that a malformed encapsulation or decapsulation key is rejected. liboqs exposes no public key-validity entry point -- validity is checked internally, with no API to invoke it standalone.
Pre-hashed message with an embedded hash OID. liboqs exposes no pre-hash entry point.
The internal interface bypasses the domain separator and context encoding. liboqs exposes only the external interface.
keyGen needs the seed xi and sigGen needs the per-signature value rnd; the liboqs public API accepts neither. A sign-then-verify round trip is deliberately NOT substituted -- it proves the pair agrees with itself, which is exactly what a conformance vector exists to rule out. Round-trip coverage lives in tests/unit/test_PqcHybrid.cpp and tests/integration/test_SignPqc.cpp, which is the correct place for it.
No request enum and no wired PKCS#11 mechanism in A3E9. No vectors vendored and no claim made, even though sig_slh_dsa.h is present in the installed liboqs.
// UNCOVERED_SOFTWARE
In plain terms
Cryptography that runs inside A3E9's own software and has no official test vectors wired up yet. We list it because someone reading our source would find it anyway.
14 of the 18 cryptographic algorithms in A3E9's signed bill of materials have no published-vector coverage in this report. This list is derived from that inventory rather than written by hand — wiring a known-answer test removes a row automatically, and adding a primitive to the product adds one. A boundary drawn only around the tested parts would be a boundary drawn to flatter.
| Primitive | Used for | Vectors exist | Status |
|---|---|---|---|
| 2-key Triple DES (TDEA, EDE mode) | DUKPT key derivation and PIN block encryption/translation (src/DUKPT.cpp, ANSI X9.24-1:2009) for payment-terminal PIN handling (Module 9B). LEGACY ALGORITHM: NIST SP 800-131A deprecated 3DES for new use after 2023; retained here only for interoperability with the existing installed base of retail payment terminals (VX-series, most ATMs globally) that only speak classic 3DES DUKPT. AES-DUKPT (ANSI X9.24-3:2017) is documented as the modern successor in src/DUKPT.h but is not implemented in this codebase. | NIST TDES (withdrawn 2024) | not wired |
| AES-CBC / AES-ECB (unauthenticated modes) | Raw AES block modes exposed through the Encrypt/Decrypt RPCs for interoperability with counterparty systems that mandate them (src/SigningServer.cpp). Neither mode provides integrity -- AES-256-GCM (alg-aes256-gcm) is the mode A3E9 uses for its own envelopes, and these are listed here so the inventory is complete rather than because they are recommended. | NIST CAVP / ACVP AES | not wired |
| AES-CMAC | HSM-backed payment message authentication code (src/CryptoOps.cpp computeMAC()/verifyMAC(), CKM_AES_CMAC, ISO 16609) -- the modern replacement for legacy retail-MAC schemes in the payment-MAC module (Module 9A). | NIST CAVP / ACVP CMAC | not wired |
| AES Key Wrap (RFC 3394 / RFC 5649) | Key transport for the DORA cross-vendor KeySyncEngine wrap/unwrap path (src/dora/KeySyncEngine.cpp) and the WrapKey/UnwrapKey RPCs. CKM_AES_KEY_WRAP / CKM_AES_KEY_WRAP_PAD, with the per-vendor variant selected from VendorProfile (AWS CloudHSM uses CKM_CLOUDHSM_AES_KEY_WRAP_PKCS5_PAD). IMPORTANT SCOPE NOTE: this path can never move a real signing key -- every signing key A3E9 generates is CKA_EXTRACTABLE=CK_FALSE (FIPS 140-2 Level 3) and wrapping requires CKA_EXTRACTABLE=CK_TRUE. It applies only to transportable material (KEKs, and key shares under the MPC vendor-binding model). | NIST CAVP / ACVP KW / KWP | not wired |
| AES-256-GCM | HSM-backed authenticated symmetric encryption (src/CryptoOps.cpp encrypt()/decrypt(), CKM_AES_GCM, 12-byte IV, 128-bit tag). CloudHSM shim enforces a 16 KB plaintext ceiling per operation; the plaintext is buffered and chunked above that limit (see src/shims/CloudHsmShim.h normalization 3.13). | NIST CAVP / ACVP AES-GCM | not wired |
| OpenSSL default DRBG (RAND_bytes) | Random salt generation for the Privacy-Preserving Hardware Binding protocol (tools/hsm_bind_token.cpp, 16-byte salt), Craton PIN salts, and other software-path randomness needs outside the HSM boundary. Implementation is whatever OpenSSL 3.0's default RAND provider supplies (CTR-DRBG per NIST SP 800-90A on a standard OpenSSL 3.0 build); not independently verified as FIPS-validated in this deployment. | NIST SP 800-90A ACVP DRBG | not wired |
| ECDSA (NIST P-256) | General-purpose HSM-backed signing for client keys on the P-256 curve (src/CryptoOps.cpp sign()/verify()). Caller pre-hashes with SHA-256 in software before CKM_ECDSA (SoftHSM2/most vendors); hardware HSMs supporting CKM_ECDSA_SHA256 hash internally. | NIST CAVP / ACVP ECDSA | not wired |
| ECDSA (secp256k1) | HSM-backed signing for Ethereum/EVM (Keccak-256 pre-hash, src/CryptoOps.cpp signEVM/verifyEVM) and Bitcoin (SHA-256d pre-hash, signBitcoin) client keys. Not a NIST-recommended curve; standard choice for these blockchain ecosystems specifically. | no NIST vectors -- non-NIST curve | not wired |
| HMAC-SHA256 | Tamper-evident HMAC chain over the audit log (vendor/a3e9-audit AuditLogger::buildJson()) -- each entry's hmac field covers the previous entry's hmac (prev_hmac), so deleting or editing any entry breaks the chain. Key supplied via HSM_AUDIT_HMAC_KEY (CI/CD-injected secret, never stored in a config file). Uses OpenSSL's one-shot HMAC() convenience function -- no manually-managed HMAC_CTX in this codebase. | RFC 4231 | not wired |
| Keccak-256 | Ethereum address derivation and EVM transaction/message pre-hash (src/Keccak256.cpp). Note: this is the original Keccak padding as used by Ethereum, NOT the standardized FIPS 202 SHA3-256 (different padding byte) -- the two produce different digests for the same input and must not be confused. | published Keccak team vectors (not SHA-3/FIPS 202) | not wired |
| PBKDF2-HMAC-SHA256 | Password-based key derivation for Craton SO/user PIN storage (src/craton_hsm/CratonSlotTable.cpp): 16-byte RAND_bytes salt, 100,000 iterations, 32-byte derived key, persisted as '<saltHex>:<iterations>:<derivedKeyHex>' and verified with a constant-time CRYPTO_memcmp. Meets NIST SP 800-132 (random salt, key stretching). This replaced the bare unsalted SHA-256(pin) that earlier revisions of this CBOM described as an open hardening gap -- the gap is closed. | RFC 6070 | not wired |
| RSA PKCS#1 v1.5 / OAEP (key transport) | RSA encryption/key-transport mechanisms surfaced through the vendor adapter and attribute-template layers (CKM_RSA_PKCS, CKM_RSA_PKCS_OAEP). PKCS#1 v1.5 encryption is retained only for vendor interoperability -- OAEP is the padding A3E9 selects where the vendor supports it. Distinct from alg-rsa-pss, which covers the signing path. | NIST CAVP / ACVP RSA | not wired |
| RSA (2048/4096) with PSS-SHA256 | HSM-backed signing for client RSA keys (src/CryptoOps.cpp signRSA/verifyRSA), CKM_RSA_PKCS_PSS, MGF1-SHA256, salt length 32 bytes. Caller pre-hashes with SHA-256 in software before calling C_Sign. Padding scheme is PSS, which has no dedicated enum value in the CycloneDX padding vocabulary as of the 1.6 schema (pkcs5/pkcs7/pkcs1v15/oaep/raw/other/unknown) -- recorded as 'other'. | NIST CAVP / ACVP RSA | not wired |
| SHA-256 | Three distinct uses: (1) LicenseFile::computeBindingHash() -- SHA-256(salt || tenant_id || token_serial) for Privacy-Preserving Hardware Binding (Part 1 licensing); (2) pre-hash for ECDSA P-256 signing and SHA-256d for Bitcoin; (3) the underlying PRF for PBKDF2 PIN derivation and the audit-log HMAC chain (see alg-pbkdf2 and alg-hmac-sha256). | NIST CAVP / ACVP SHA-2 | not wired |
— uncovered[] is derived as (CBOM algorithm assets - assets with a KAT group), so wiring a known-answer test removes a primitive from it with no manual edit.
— The CBOM's under-claim gate keys on CKM_* tokens, so a primitive added purely in software through OpenSSL EVP would not trip it. Coverage of PKCS#11 mechanisms is enforced; software additions depend on the CBOM being updated.
— vendor/a3e9-attestation is outside the CBOM scan roots (private submodule, absent from a plain clone), so a novel primitive added inside it would not appear here.
// WHAT_YOU_CAN_VERIFY
In plain terms
Our product source is private, so you cannot re-run our tests. This is precisely what you can still check for yourself, and the one thing you cannot.
The A3E9 repository is private. Rather than implying a reproduction path that does not exist, here is the exact boundary between what is independently checkable and what is self-reported.
The vectors are NIST's own published bytes
usnistgov/ACVP-Server is public. Clone it, check out the commit recorded in vectorSources[], apply the trim documented in tests/vectors/acvp/README.md, and compare against the SHA-256 digests in this report.
The expected answers were not softened
Every expectedSha256 in cases[] is recomputable from those public upstream files.
The exclusions are honest
liboqs is public. Confirm there is no public key-validity entry point, no pre-hash entry point, only the external signature interface, and no seed or per-signature randomness injection on keypair/sign. Every exclusion reason resolves against that codebase.
The arithmetic holds
Group counts sum to totals.executed; 420 minus the executed PQC vectors equals the excluded count; accept plus reject equals the total.
NOT verifiable without access: that the computed column came from a real run
computedSha256 == expectedSha256 is by definition what a pass looks like, so a fabricated report is indistinguishable from a real one to an outside reader. These results are self-reported, and nothing published alongside this file corroborates them today. A detached signature over this record, and build provenance tying it to a specific CI run, would each narrow that gap; neither is published yet. Until one is, this row is the honest limit of what the report can offer, and no other row should be read as covering it.
// VECTOR_PROVENANCE
| File | Upstream | Commit | SHA-256 | Licence |
|---|---|---|---|---|
| ml-kem-keygen.json | usnistgov/ACVP-Server | 975de31eb83d | b7fe094055e02d19871b4105f6101acf7dcb0b11185636fdeb447ee654c02e4d | US Government work, public domain |
| ml-kem-encapdecap.json | usnistgov/ACVP-Server | 975de31eb83d | 1eac6102952f1c46f7c26a97b93eafb7c08a8134f1b57d0d2d934e3ee0197f0d | US Government work, public domain |
| ml-dsa-sigver.json | usnistgov/ACVP-Server | 975de31eb83d | 70bb6d1c3e9b0a18ba824a6366cfb75f3e00559473f3eafde3b0aca7127158a4 | US Government work, public domain |
// WHAT_THIS_DOES_NOT_PROVE
In plain terms
The honest limits of everything above, in one place. If anything elsewhere on this site sounds like a bigger claim, this section is the one that is right.
Listed here rather than discovered three documents in.
// NOT_CLAIMED
// NEXT
The PDF is the filing copy, the workbook sorts and filters all 236 cases, and the JSON is the run record itself — served byte-identical to what the test binary emitted, not re-serialized by this page.
What a token adds
Nothing on this page needs one — the 236 cases, the 195 exclusions and the 14 uncovered primitives are all here. What a token adds is the step this record cannot take on its own: driving a signature through the live signer and matching the image it ran on back to the build recorded above. This report says the algorithms are correct; only the running system can show you that it is the one described here.