Read this first
Conformance to FIPS 203 (ML-KEM) is not "it passes the known-answer vectors." The load-bearing requirements live on the paths the honest vectors never touch: the §7.2 encapsulation-key modulus check, the §7.3 ciphertext length check, and constant-time implicit rejection. Work through the checklist below against the exact implementation you ship — not a reference build — and re-run it every release.
Below is the concrete checklist we run against any ML-KEM implementation. It is deliberately narrow: this is a conformance checklist, distinct from a FIPS 140-3 module validation and from a security audit — see ACVP vs conformance vs FIPS 140-3 for where the boundaries sit. Each item maps to a normative requirement in FIPS 203 or to a class of vector you must feed the implementation to exercise it.
Input validation (§7.2 and §7.3)
- **§7.2 — encapsulation-key modulus check.** Every coefficient of the encapsulation key must be reduced mod q = 3329. Feed a key with a single out-of-range coefficient and confirm the implementation rejects it. No honest vector contains such a key, so a build that skips this check still passes the KATs.
- **§7.3 — ciphertext type/length check.** Decapsulation must verify the ciphertext is the correct length for the parameter set before processing it. Feed a wrong-length ciphertext and confirm it is rejected rather than parsed.
- **Both directions, all parameter sets.** Run the malformed-input checks for ML-KEM-512, ML-KEM-768, and ML-KEM-1024 — a check present for one parameter set is sometimes absent for another.
Implicit rejection
- **Deterministic pseudo-random secret, not an error.** On an invalid ciphertext, decapsulation must return a deterministic pseudo-random shared secret — never an error or an exception. Confirm the same invalid ciphertext yields the same secret across runs.
- **Indistinguishable by timing.** The reject path must be indistinguishable, by timing, from the accept path. A branch that shortcuts on failure turns the reject into an observable event and an oracle. Confirm there is no data-dependent early return on the failure path.
Sizes and encoding
- **Exact byte sizes.** For ML-KEM-768: encapsulation key 1184 B, decapsulation key 2400 B, ciphertext 1088 B, shared secret 32 B. Verify the exact sizes for the parameter set in use (ML-KEM-512 and ML-KEM-1024 differ). A right-shaped-but-wrong-length artifact must be rejected, not truncated or padded.
- **ByteEncode / ByteDecode round-trip.** Byte-encoding and decoding of polynomial vectors must match FIPS 203. Encode then decode and confirm you recover the original; a round-trip mismatch is a conformance defect.
- **Cross-implementation agreement.** Keys and ciphertexts produced by one conformant implementation must decode and interoperate with another. Disagreement points to an encoding deviation.
Versioning and vectors
- **Final FIPS 203, not a Kyber round.** Confirm the implementation targets final ML-KEM, not an earlier CRYSTALS-Kyber round — they are not interoperable. Where a project still says "Kyber", check the actual parameters and encoding against FIPS 203.
- **KATs are necessary but not sufficient.** Passing NIST ACVP known-answer vectors confirms the happy path is byte-correct; it exercises honest inputs only and cannot reach §7.2/§7.3 or the reject path.
- **Add adversarial vectors.** Feed malformed-input vectors — out-of-range coefficients, malformed keys, wrong-length ciphertexts — such as those the C2SP/CCTV project publishes, to actually exercise the checks above.
"It passes the KATs" and "it's a popular, audited library" are not evidence of §7.2/§7.3 conformance
Adoption and an audit report tell you a project is scrutinized on the happy path — precisely the part the KATs already cover. Real, widely deployed implementations have passed every known-answer vector while skipping the §7.2 modulus check or leaking the reject path by timing. The only evidence of conformance is exercising the reject behaviour directly with adversarial vectors, re-run on every release so a dependency bump or optimization cannot quietly drop a check. Emit findings as SARIF so they land in your existing review flow.
How quantakrypto helps
We run this checklist against the implementation you actually ship, not a reference build. We conformance-test the §7.2/§7.3 input checks, implicit-rejection timing, sizes and encoding using adversarial vectors the KATs miss (certification), assess whether it is exploitable in your deployment (audit), and sequence the change into your rollout without breaking production (migration). The deliverable is a dated, signed conformance report backed by malformed-input vectors and re-run on every release — see conformance testing for the method. Evidence, not a vendor's assurance.