A3E9 logoA3E9

// CONFORMANCE_REPORT · NO_LOGIN_REQUIRED

Every Vector We Ran, and Every One We Didn’t.

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.

Raw JSON run record

commit dc771528a82b · tree clean · liboqs 0.16.0 · github-actions

// RESULTS_SUMMARY

What Ran, and What It Came Back With.

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.

StandardAlgorithmFunctionEntry pointExecutedPassedFailed
RFC 8032 §6.1Ed25519verifyEVP_DigestVerify550
Dobbertin et al., 1996RIPEMD-160digestHash160::ripemd160660
FIPS 203ML-KEMkeyGenOQS_KEM_keypair_derand75750
FIPS 203ML-KEMencapsulationOQS_KEM_encaps_derand75750
FIPS 203ML-KEMdecapsulationOQS_KEM_decaps30300
FIPS 204ML-DSAsigVerOQS_SIG_verify_with_ctx_str45450
TOTAL2362360

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

Every Case, With Its Upstream Identifier.

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.

showing 236
GroupParam settgIdtcIdCaseExpectedActualResult
ed25519RFC 8032 §6.1 Vector 1 — empty message; paired with a tampered-signature rejectionconformantconformantPASS
ed25519RFC 8032 §6.1 Vector 2 — 1-byte message 0x72; paired with a wrong-public-key rejectionconformantconformantPASS
ed25519RFC 8032 §6.1 Vector 3 — 2-byte message af 82; paired with an altered-message rejectionconformantconformantPASS
ed25519Truncated 31-byte signature must be rejectedconformantconformantPASS
ed25519All-zero 64-byte signature must be rejected (low-order / degenerate point)conformantconformantPASS
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-keygenML-KEM-51211MATCHMATCHPASS
mlkem-keygenML-KEM-51212MATCHMATCHPASS
mlkem-keygenML-KEM-51213MATCHMATCHPASS
mlkem-keygenML-KEM-51214MATCHMATCHPASS
mlkem-keygenML-KEM-51215MATCHMATCHPASS
mlkem-keygenML-KEM-51216MATCHMATCHPASS
mlkem-keygenML-KEM-51217MATCHMATCHPASS
mlkem-keygenML-KEM-51218MATCHMATCHPASS
mlkem-keygenML-KEM-51219MATCHMATCHPASS
mlkem-keygenML-KEM-512110MATCHMATCHPASS
mlkem-keygenML-KEM-512111MATCHMATCHPASS
mlkem-keygenML-KEM-512112MATCHMATCHPASS
mlkem-keygenML-KEM-512113MATCHMATCHPASS
mlkem-keygenML-KEM-512114MATCHMATCHPASS
mlkem-keygenML-KEM-512115MATCHMATCHPASS
mlkem-keygenML-KEM-512116MATCHMATCHPASS
mlkem-keygenML-KEM-512117MATCHMATCHPASS
mlkem-keygenML-KEM-512118MATCHMATCHPASS
mlkem-keygenML-KEM-512119MATCHMATCHPASS
mlkem-keygenML-KEM-512120MATCHMATCHPASS
mlkem-keygenML-KEM-512121MATCHMATCHPASS
mlkem-keygenML-KEM-512122MATCHMATCHPASS
mlkem-keygenML-KEM-512123MATCHMATCHPASS
mlkem-keygenML-KEM-512124MATCHMATCHPASS
mlkem-keygenML-KEM-512125MATCHMATCHPASS
mlkem-keygenML-KEM-768226MATCHMATCHPASS
mlkem-keygenML-KEM-768227MATCHMATCHPASS
mlkem-keygenML-KEM-768228MATCHMATCHPASS
mlkem-keygenML-KEM-768229MATCHMATCHPASS
mlkem-keygenML-KEM-768230MATCHMATCHPASS
mlkem-keygenML-KEM-768231MATCHMATCHPASS
mlkem-keygenML-KEM-768232MATCHMATCHPASS
mlkem-keygenML-KEM-768233MATCHMATCHPASS
mlkem-keygenML-KEM-768234MATCHMATCHPASS
mlkem-keygenML-KEM-768235MATCHMATCHPASS
mlkem-keygenML-KEM-768236MATCHMATCHPASS
mlkem-keygenML-KEM-768237MATCHMATCHPASS
mlkem-keygenML-KEM-768238MATCHMATCHPASS
mlkem-keygenML-KEM-768239MATCHMATCHPASS
mlkem-keygenML-KEM-768240MATCHMATCHPASS
mlkem-keygenML-KEM-768241MATCHMATCHPASS
mlkem-keygenML-KEM-768242MATCHMATCHPASS
mlkem-keygenML-KEM-768243MATCHMATCHPASS
mlkem-keygenML-KEM-768244MATCHMATCHPASS
mlkem-keygenML-KEM-768245MATCHMATCHPASS
mlkem-keygenML-KEM-768246MATCHMATCHPASS
mlkem-keygenML-KEM-768247MATCHMATCHPASS
mlkem-keygenML-KEM-768248MATCHMATCHPASS
mlkem-keygenML-KEM-768249MATCHMATCHPASS
mlkem-keygenML-KEM-768250MATCHMATCHPASS
mlkem-keygenML-KEM-1024351MATCHMATCHPASS
mlkem-keygenML-KEM-1024352MATCHMATCHPASS
mlkem-keygenML-KEM-1024353MATCHMATCHPASS
mlkem-keygenML-KEM-1024354MATCHMATCHPASS
mlkem-keygenML-KEM-1024355MATCHMATCHPASS
mlkem-keygenML-KEM-1024356MATCHMATCHPASS
mlkem-keygenML-KEM-1024357MATCHMATCHPASS
mlkem-keygenML-KEM-1024358MATCHMATCHPASS
mlkem-keygenML-KEM-1024359MATCHMATCHPASS
mlkem-keygenML-KEM-1024360MATCHMATCHPASS
mlkem-keygenML-KEM-1024361MATCHMATCHPASS
mlkem-keygenML-KEM-1024362MATCHMATCHPASS
mlkem-keygenML-KEM-1024363MATCHMATCHPASS
mlkem-keygenML-KEM-1024364MATCHMATCHPASS
mlkem-keygenML-KEM-1024365MATCHMATCHPASS
mlkem-keygenML-KEM-1024366MATCHMATCHPASS
mlkem-keygenML-KEM-1024367MATCHMATCHPASS
mlkem-keygenML-KEM-1024368MATCHMATCHPASS
mlkem-keygenML-KEM-1024369MATCHMATCHPASS
mlkem-keygenML-KEM-1024370MATCHMATCHPASS
mlkem-keygenML-KEM-1024371MATCHMATCHPASS
mlkem-keygenML-KEM-1024372MATCHMATCHPASS
mlkem-keygenML-KEM-1024373MATCHMATCHPASS
mlkem-keygenML-KEM-1024374MATCHMATCHPASS
mlkem-keygenML-KEM-1024375MATCHMATCHPASS
mlkem-encapsML-KEM-51211MATCHMATCHPASS
mlkem-encapsML-KEM-51212MATCHMATCHPASS
mlkem-encapsML-KEM-51213MATCHMATCHPASS
mlkem-encapsML-KEM-51214MATCHMATCHPASS
mlkem-encapsML-KEM-51215MATCHMATCHPASS
mlkem-encapsML-KEM-51216MATCHMATCHPASS
mlkem-encapsML-KEM-51217MATCHMATCHPASS
mlkem-encapsML-KEM-51218MATCHMATCHPASS
mlkem-encapsML-KEM-51219MATCHMATCHPASS
mlkem-encapsML-KEM-512110MATCHMATCHPASS
mlkem-encapsML-KEM-512111MATCHMATCHPASS
mlkem-encapsML-KEM-512112MATCHMATCHPASS
mlkem-encapsML-KEM-512113MATCHMATCHPASS
mlkem-encapsML-KEM-512114MATCHMATCHPASS
mlkem-encapsML-KEM-512115MATCHMATCHPASS
mlkem-encapsML-KEM-512116MATCHMATCHPASS
mlkem-encapsML-KEM-512117MATCHMATCHPASS
mlkem-encapsML-KEM-512118MATCHMATCHPASS
mlkem-encapsML-KEM-512119MATCHMATCHPASS
mlkem-encapsML-KEM-512120MATCHMATCHPASS
mlkem-encapsML-KEM-512121MATCHMATCHPASS
mlkem-encapsML-KEM-512122MATCHMATCHPASS
mlkem-encapsML-KEM-512123MATCHMATCHPASS
mlkem-encapsML-KEM-512124MATCHMATCHPASS
mlkem-encapsML-KEM-512125MATCHMATCHPASS
mlkem-encapsML-KEM-768226MATCHMATCHPASS
mlkem-encapsML-KEM-768227MATCHMATCHPASS
mlkem-encapsML-KEM-768228MATCHMATCHPASS
mlkem-encapsML-KEM-768229MATCHMATCHPASS
mlkem-encapsML-KEM-768230MATCHMATCHPASS
mlkem-encapsML-KEM-768231MATCHMATCHPASS
mlkem-encapsML-KEM-768232MATCHMATCHPASS
mlkem-encapsML-KEM-768233MATCHMATCHPASS
mlkem-encapsML-KEM-768234MATCHMATCHPASS
mlkem-encapsML-KEM-768235MATCHMATCHPASS
mlkem-encapsML-KEM-768236MATCHMATCHPASS
mlkem-encapsML-KEM-768237MATCHMATCHPASS
mlkem-encapsML-KEM-768238MATCHMATCHPASS
mlkem-encapsML-KEM-768239MATCHMATCHPASS
mlkem-encapsML-KEM-768240MATCHMATCHPASS
mlkem-encapsML-KEM-768241MATCHMATCHPASS
mlkem-encapsML-KEM-768242MATCHMATCHPASS
mlkem-encapsML-KEM-768243MATCHMATCHPASS
mlkem-encapsML-KEM-768244MATCHMATCHPASS
mlkem-encapsML-KEM-768245MATCHMATCHPASS
mlkem-encapsML-KEM-768246MATCHMATCHPASS
mlkem-encapsML-KEM-768247MATCHMATCHPASS
mlkem-encapsML-KEM-768248MATCHMATCHPASS
mlkem-encapsML-KEM-768249MATCHMATCHPASS
mlkem-encapsML-KEM-768250MATCHMATCHPASS
mlkem-encapsML-KEM-1024351MATCHMATCHPASS
mlkem-encapsML-KEM-1024352MATCHMATCHPASS
mlkem-encapsML-KEM-1024353MATCHMATCHPASS
mlkem-encapsML-KEM-1024354MATCHMATCHPASS
mlkem-encapsML-KEM-1024355MATCHMATCHPASS
mlkem-encapsML-KEM-1024356MATCHMATCHPASS
mlkem-encapsML-KEM-1024357MATCHMATCHPASS
mlkem-encapsML-KEM-1024358MATCHMATCHPASS
mlkem-encapsML-KEM-1024359MATCHMATCHPASS
mlkem-encapsML-KEM-1024360MATCHMATCHPASS
mlkem-encapsML-KEM-1024361MATCHMATCHPASS
mlkem-encapsML-KEM-1024362MATCHMATCHPASS
mlkem-encapsML-KEM-1024363MATCHMATCHPASS
mlkem-encapsML-KEM-1024364MATCHMATCHPASS
mlkem-encapsML-KEM-1024365MATCHMATCHPASS
mlkem-encapsML-KEM-1024366MATCHMATCHPASS
mlkem-encapsML-KEM-1024367MATCHMATCHPASS
mlkem-encapsML-KEM-1024368MATCHMATCHPASS
mlkem-encapsML-KEM-1024369MATCHMATCHPASS
mlkem-encapsML-KEM-1024370MATCHMATCHPASS
mlkem-encapsML-KEM-1024371MATCHMATCHPASS
mlkem-encapsML-KEM-1024372MATCHMATCHPASS
mlkem-encapsML-KEM-1024373MATCHMATCHPASS
mlkem-encapsML-KEM-1024374MATCHMATCHPASS
mlkem-encapsML-KEM-1024375MATCHMATCHPASS
mlkem-decapsML-KEM-512476MATCHMATCHPASS
mlkem-decapsML-KEM-512477MATCHMATCHPASS
mlkem-decapsML-KEM-512478MATCHMATCHPASS
mlkem-decapsML-KEM-512479MATCHMATCHPASS
mlkem-decapsML-KEM-512480MATCHMATCHPASS
mlkem-decapsML-KEM-512481MATCHMATCHPASS
mlkem-decapsML-KEM-512482MATCHMATCHPASS
mlkem-decapsML-KEM-512483MATCHMATCHPASS
mlkem-decapsML-KEM-512484MATCHMATCHPASS
mlkem-decapsML-KEM-512485MATCHMATCHPASS
mlkem-decapsML-KEM-768586MATCHMATCHPASS
mlkem-decapsML-KEM-768587MATCHMATCHPASS
mlkem-decapsML-KEM-768588MATCHMATCHPASS
mlkem-decapsML-KEM-768589MATCHMATCHPASS
mlkem-decapsML-KEM-768590MATCHMATCHPASS
mlkem-decapsML-KEM-768591MATCHMATCHPASS
mlkem-decapsML-KEM-768592MATCHMATCHPASS
mlkem-decapsML-KEM-768593MATCHMATCHPASS
mlkem-decapsML-KEM-768594MATCHMATCHPASS
mlkem-decapsML-KEM-768595MATCHMATCHPASS
mlkem-decapsML-KEM-1024696MATCHMATCHPASS
mlkem-decapsML-KEM-1024697MATCHMATCHPASS
mlkem-decapsML-KEM-1024698MATCHMATCHPASS
mlkem-decapsML-KEM-1024699MATCHMATCHPASS
mlkem-decapsML-KEM-10246100MATCHMATCHPASS
mlkem-decapsML-KEM-10246101MATCHMATCHPASS
mlkem-decapsML-KEM-10246102MATCHMATCHPASS
mlkem-decapsML-KEM-10246103MATCHMATCHPASS
mlkem-decapsML-KEM-10246104MATCHMATCHPASS
mlkem-decapsML-KEM-10246105MATCHMATCHPASS
mldsa-sigverML-DSA-4411modified messageREJECTREJECTPASS
mldsa-sigverML-DSA-4412modified signature - commitmentREJECTREJECTPASS
mldsa-sigverML-DSA-4413valid signature and message - signature should verify successfullyACCEPTACCEPTPASS
mldsa-sigverML-DSA-4414modified signature - commitmentREJECTREJECTPASS
mldsa-sigverML-DSA-4415modified signature - zREJECTREJECTPASS
mldsa-sigverML-DSA-4416modified signature - zREJECTREJECTPASS
mldsa-sigverML-DSA-4417modified signature - hintREJECTREJECTPASS
mldsa-sigverML-DSA-4418modified signature - commitmentREJECTREJECTPASS
mldsa-sigverML-DSA-4419modified signature - hintREJECTREJECTPASS
mldsa-sigverML-DSA-44110modified messageREJECTREJECTPASS
mldsa-sigverML-DSA-44111valid signature and message - signature should verify successfullyACCEPTACCEPTPASS
mldsa-sigverML-DSA-44112modified signature - zREJECTREJECTPASS
mldsa-sigverML-DSA-44113modified signature - hintREJECTREJECTPASS
mldsa-sigverML-DSA-44114modified messageREJECTREJECTPASS
mldsa-sigverML-DSA-44115valid signature and message - signature should verify successfullyACCEPTACCEPTPASS
mldsa-sigverML-DSA-65331modified signature - zREJECTREJECTPASS
mldsa-sigverML-DSA-65332modified signature - hintREJECTREJECTPASS
mldsa-sigverML-DSA-65333valid signature and message - signature should verify successfullyACCEPTACCEPTPASS
mldsa-sigverML-DSA-65334modified signature - commitmentREJECTREJECTPASS
mldsa-sigverML-DSA-65335modified messageREJECTREJECTPASS
mldsa-sigverML-DSA-65336modified signature - zREJECTREJECTPASS
mldsa-sigverML-DSA-65337modified signature - commitmentREJECTREJECTPASS
mldsa-sigverML-DSA-65338modified signature - hintREJECTREJECTPASS
mldsa-sigverML-DSA-65339modified messageREJECTREJECTPASS
mldsa-sigverML-DSA-65340modified signature - zREJECTREJECTPASS
mldsa-sigverML-DSA-65341modified signature - hintREJECTREJECTPASS
mldsa-sigverML-DSA-65342modified signature - commitmentREJECTREJECTPASS
mldsa-sigverML-DSA-65343valid signature and message - signature should verify successfullyACCEPTACCEPTPASS
mldsa-sigverML-DSA-65344valid signature and message - signature should verify successfullyACCEPTACCEPTPASS
mldsa-sigverML-DSA-65345modified messageREJECTREJECTPASS
mldsa-sigverML-DSA-87561modified messageREJECTREJECTPASS
mldsa-sigverML-DSA-87562modified messageREJECTREJECTPASS
mldsa-sigverML-DSA-87563valid signature and message - signature should verify successfullyACCEPTACCEPTPASS
mldsa-sigverML-DSA-87564modified signature - commitmentREJECTREJECTPASS
mldsa-sigverML-DSA-87565modified signature - hintREJECTREJECTPASS
mldsa-sigverML-DSA-87566modified messageREJECTREJECTPASS
mldsa-sigverML-DSA-87567valid signature and message - signature should verify successfullyACCEPTACCEPTPASS
mldsa-sigverML-DSA-87568modified signature - commitmentREJECTREJECTPASS
mldsa-sigverML-DSA-87569modified signature - hintREJECTREJECTPASS
mldsa-sigverML-DSA-87570valid signature and message - signature should verify successfullyACCEPTACCEPTPASS
mldsa-sigverML-DSA-87571modified signature - commitmentREJECTREJECTPASS
mldsa-sigverML-DSA-87572modified signature - zREJECTREJECTPASS
mldsa-sigverML-DSA-87573modified signature - zREJECTREJECTPASS
mldsa-sigverML-DSA-87574modified signature - hintREJECTREJECTPASS
mldsa-sigverML-DSA-87575modified signature - zREJECTREJECTPASS

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

What Was Not Run, and Why.

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.

ML-KEM encapsulationKeyCheck / decapsulationKeyCheck60 vectors · not reachableFIPS 203

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.

ML-DSA sigVer, preHash (HashML-DSA)45 vectors · not reachableFIPS 204

Pre-hashed message with an embedded hash OID. liboqs exposes no pre-hash entry point.

ML-DSA sigVer, internal interface90 vectors · not reachableFIPS 204

The internal interface bypasses the domain separator and context encoding. liboqs exposes only the external interface.

ML-DSA keyGen and sigGen— · not vendoredFIPS 204

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.

SLH-DSA— · not implementedFIPS 205

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

A3E9 Software With No Vector Coverage Yet.

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.

PrimitiveUsed forVectors existStatus
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 AESnot wired
AES-CMACHSM-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 CMACnot 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 / KWPnot wired
AES-256-GCMHSM-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-GCMnot 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 DRBGnot 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 ECDSAnot 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 curvenot wired
HMAC-SHA256Tamper-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 4231not wired
Keccak-256Ethereum 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-SHA256Password-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 6070not 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 RSAnot wired
RSA (2048/4096) with PSS-SHA256HSM-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 RSAnot wired
SHA-256Three 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-2not 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

What You Can Check Without Trusting Us.

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

FileUpstreamCommitSHA-256Licence
ml-kem-keygen.jsonusnistgov/ACVP-Server975de31eb83db7fe094055e02d19871b4105f6101acf7dcb0b11185636fdeb447ee654c02e4dUS Government work, public domain
ml-kem-encapdecap.jsonusnistgov/ACVP-Server975de31eb83d1eac6102952f1c46f7c26a97b93eafb7c08a8134f1b57d0d2d934e3ee0197f0dUS Government work, public domain
ml-dsa-sigver.jsonusnistgov/ACVP-Server975de31eb83d70bb6d1c3e9b0a18ba824a6366cfb75f3e00559473f3eafde3b0aca7127158a4US Government work, public domain

// WHAT_THIS_DOES_NOT_PROVE

The Limits, Stated Up Front.

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.

  • Passing known-answer vectors is not a FIPS 140 certificate. CAVP algorithm validation precedes CMVP module validation, and both are performed by an accredited Cryptographic and Security Testing laboratory -- not by us.
  • liboqs is not a FIPS-certified module.
  • 195 of the 420 published ML-KEM/ML-DSA vectors are unreachable through the liboqs public API and are excluded with a stated reason, not silently skipped.
  • Part of A3E9's own software cryptography has no published-vector coverage yet -- see `uncovered`. It is declared rather than omitted.
  • Only SoftHSM2 and Craton have been exercised against real PKCS#11 modules. Thales, AWS CloudHSM and Utimaco are written but unvalidated on hardware.
  • The A3E9 source repository is private, so these results cannot be independently re-run. The vectors, the expected answers and every exclusion reason ARE independently checkable -- see `verification`.

// NOT_CLAIMED

CAVP algorithm certificateCMVP module certificateFIPS 140-3 validationEntropy-source (SP 800-90B / ESV) assessmentPhysical or tamper testingNon-invasive-attack mitigation

// NEXT

Take the Record With You.

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.

Raw JSON run record