Calix PQC
Validation report

Checked against NIST, in the open.

Engine p-pqc 0.2.0 (commit d41bbe1, 23 Oct 2026). Test run of 14 Nov 2026: rustc 1.95.0, Apple M3 Pro, release profile.

52tests passed · 0 failed · 5 long-run on demand
212 / 212ACVP cases matched via acvptool (23 Oct 2026)
2252reference cases in the files below
8 / 8seeded ML-DSA faults caught

Result matrix

AlgorithmSuiteCoverageResult
ML-KEM-768
FIPS 203
NIST ACVPkeyGen (d,z → ek,dk) · encapsulation · decapsulation incl. modified ciphertext · encapsulation-key check · decapsulation-key checkPASS
ML-KEM-768C2SP/CCTV780 malformed encapsulation keys rejected · strcmp-style comparison bug · unlucky SampleNTT (> 575 XOF bytes) · accumulated RNG stream (10,000)PASS
ML-KEM-768Go stdlib crypto/mlkemaccumulated vectors, 100 and 10,000 cases per build; 1,000,000 on demandPASS
ML-DSA-65
FIPS 204
NIST ACVPkeyGen · sigGen deterministic + hedged × external (with context) / internal / external-μ · sigVer incl. altered message, c̃, z and hintsPASS
ML-DSA-65RustCrypto ml-dsa 0.1.1byte-for-byte comparison: keys, signatures, verdicts, one-bit-flip behaviour — 300 cases per runPASS
AES-256-GCM
SP 800-38D
NIST CAVP375 encrypt + 375 decrypt cases (key 256, IV 96, tag 128); the 191 FAIL cases are rejectedPASS
HMAC_DRBG
SP 800-90A
NIST CAVP480 SHA-512 cases: 240 without reseed, 240 with reseedPASS
Timingtests/ct/no-div.shno division/remainder instruction on any p_pqc function that handles secrets (WASM release + native debug)PASS

NIST ACVP tooling — offline run

The library is wrapped for BoringSSL's acvptool and every case is compared with NIST's expected answer. Result recorded 23 Oct 2026: 212 of 212 match, 115 of them ML-DSA-65. Deliberately broken builds (always-pass key check, swapped DRBG reseed inputs, always-pass GCM open, dropped final DRBG update) all turned it red.

SuiteCasesResult
ML-KEM-768 keyGen25MATCH
ML-KEM-768 encapDecap55MATCH
ML-DSA-65 keyGen25MATCH
ML-DSA-65 sigGen (internal + external μ)60MATCH
ML-DSA-65 sigVer30MATCH
hmacDRBG SHA2-51215MATCH
ACVP-AES-256-GCM2MATCH
Total212212 / 212
Test vectors

The exact files we test against.

Served unmodified from this site. NIST vectors are U.S. Government works in the public domain; C2SP/CCTV vectors are CC0 1.0. Case counts and checksums are computed from the bytes in this server's binary, not typed in. Fetched 8 Oct 2026 (ML-KEM), 15 Oct (CAVP), 23 Oct (ML-DSA) from usnistgov/ACVP-Server @ ad33b3d9 and C2SP/CCTV @ f086168f.

FileAlgorithmSourceCasesSizeSHA-256
acvp_mlkem768_keygen.jsonML-KEM-768
FIPS 203
NIST ACVP-Server · ML-KEM-keyGen-FIPS20325181 KBe6287329c59d9c15…07912129
acvp_mlkem768_encapdecap.jsonML-KEM-768
FIPS 203
NIST ACVP-Server · ML-KEM-encapDecap-FIPS20355471 KBd618f903c2f4a78e…c3d80917
cctv_mlkem768_modulus.txt.gzML-KEM-768
FIPS 203 §7.2
C2SP/CCTV · modulus (malformed encapsulation keys)78017 KB22308df988866e27…1a526af7
cctv_mlkem768_strcmp.txtML-KEM-768
FIPS 203
C2SP/CCTV · strcmp (implicit-rejection compare)17 KB2b09aa46d8b1c7b9…0079e4fa
cctv_mlkem768_unluckysample.txtML-KEM-768
FIPS 203
C2SP/CCTV · unlucky SampleNTT (>575 XOF bytes)19 KBfede6f787581dc70…5ad0ba90
acvp_mldsa65_keygen.jsonML-DSA-65
FIPS 204
NIST ACVP-Server · ML-DSA-keyGen-FIPS20425296 KB1ada1753be37ad1c…679d910d
acvp_mldsa65_siggen.jsonML-DSA-65
FIPS 204
NIST ACVP-Server · ML-DSA-sigGen-FIPS204902.1 MB2de2974ac48aac12…0493726f
acvp_mldsa65_sigver.jsonML-DSA-65
FIPS 204
NIST ACVP-Server · ML-DSA-sigVer-FIPS204451.0 MB9d739151c8a95cc8…3c4caf85
cavp_gcmEncryptExtIV256.rspAES-256-GCM
SP 800-38D
NIST CAVP · gcmEncryptExtIV256 (IV 96 · tag 128)375122 KBcd8a650547395705…b79ec932
cavp_gcmDecrypt256.rspAES-256-GCM
SP 800-38D
NIST CAVP · gcmDecrypt256 (191 FAIL cases must be rejected)375114 KBc8a930fc764549ac…02e71e3f
cavp_hmac_drbg_sha512_no_reseed.rspHMAC_DRBG SHA-512
SP 800-90A
NIST CAVP · drbgvectors_no_reseed240195 KB5acecc271a74f753…a8e330f8
cavp_hmac_drbg_sha512_pr_false.rspHMAC_DRBG SHA-512
SP 800-90A
NIST CAVP · drbgvectors_pr_false (with reseed)240228 KBdeb68ec5f17362f4…40595bfc

Verify what you downloaded:

curl -O https://ppqc.psystem.cloud/vectors/SHA256SUMS
curl -O https://ppqc.psystem.cloud/vectors/acvp_mldsa65_keygen.json
shasum -a 256 -c SHA256SUMS --ignore-missing

Look at the bytes

First case of each file, hex, cut for display — straight from the embedded vectors.

ML-KEM-768 · ACVP keyGen · FIPS 203

d  (32 B) E582B7D75E6C80B05AE392A1FC9F7153B12390FD99930368CC67A768BAEBC8A0
z  (32 B) 1CDACB8740C0B87C4A379575F187B367CBFA3B300BF591B109F79816E9CBE8F0
ek (1184 B)
28C793778741B80B02B4339F2AA4347255B099F17264E1B8CC0A2C7C2A1A79F7997B907FD0496C6E6C8AD7714F5F339D
75F11F625591A869BE1175AE47F05FD4313468232BA6957D7807B824F445AC99A0D568AB1AD54DCA8249D1482E61275F
52248C77F61A4248753188CD1794CD0A465EC0DC4B025985C461B74E76286E4C37E77405695CC9FD0654374B427A2034
…

ML-DSA-65 · ACVP keyGen · FIPS 204

ξ seed (32 B) A991FD42B071D49C48AE3E75C647459E0DAAD1E1BA356A04801912D3294BCFF8
pk (1952 B)
36DB0B5DCE98BD190CB139E80B71B49C7D7040B71C5A1F3412C46BDE939192B1B57CCB88AC2714C1240CB0EB62C689E0
31AEA3D9F3EB3ED7BFA45931D288DCAE3413199B31A7032560DCE8A61E195D13A1440615C2F3AA7DD28C5B1B742BFA40
0052186721F13D3DF9DCFAEE348B10D66913C7148913E085E1A4A03C659398DADC6A8E0E0C1A7F9F44D30436DB90FD65
…

ML-DSA-65 · ACVP sigVer · a signature that must be rejected

testPassed false   reason modified message
message 6885 B   context 1EA2A2DDC0C2352D5F50835314720BD773D744B2E3321A   signature 3309 B

Raw test log

Output of cargo test --release, sorted alphabetically, nothing else changed.

# p-pqc 0.2.0 — cargo test --release
# run: 2026-11-14 · rustc 1.95.0 (59807616e 2026-04-14) · Darwin arm64 · Apple M3 Pro
test fips203_tests::fips203_acvp_decapsulation ... ok
test fips203_tests::fips203_acvp_decapsulation_key_check ... ok
test fips203_tests::fips203_acvp_encapsulation ... ok
test fips203_tests::fips203_acvp_encapsulation_key_check ... ok
test fips203_tests::fips203_acvp_keygen ... ok
test fips203_tests::fips203_cctv_accumulated_10k ... ok
test fips203_tests::fips203_cctv_accumulated_1m ... ignored (on demand)
test fips203_tests::fips203_cctv_accumulated_rng_stream_start ... ok
test fips203_tests::fips203_cctv_modulus_bad_encapsulation_keys ... ok
test fips203_tests::fips203_cctv_strcmp ... ok
test fips203_tests::fips203_cctv_unlucky_sample_ntt ... ok
test fips203_tests::fips203_go_accumulated_100 ... ok
test fips203_tests::fips203_go_accumulated_10k ... ok
test fips203_tests::fips203_go_accumulated_1m ... ignored (on demand)
test fips204_tests::fips204_acvp_keygen ... ok
test fips204_tests::fips204_acvp_siggen ... ok
test fips204_tests::fips204_acvp_sigver ... ok
test fips204_tests::fips204_rustcrypto_cross_check ... ok
test fips204_tests::fips204_rustcrypto_cross_check_10k ... ignored (on demand)
test kyber768::tests::compress_nhan_dich_bang_cong_thuc_chia ... ok
test kyber768::tests::poly_compress10_dong_goi_dung ... ok
test kyber768::tests::qmod_bang_rem_euclid ... ok
test mldsa65::bench::mldsa65_bench ... ignored (on demand)
test mldsa65::mldsa65_export_for_cross_check ... ignored (on demand)
test mldsa65::tests::decompose_matches_definition ... ok
test mldsa65::tests::make_hint_matches_fips_definition ... ok
test mldsa65::tests::ntt_roundtrip ... ok
test mldsa65::tests::power2round_matches_definition ... ok
test mldsa65::tests::rejects_non_canonical_hints ... ok
test mldsa65::tests::sign_verify_roundtrip_and_tamper ... ok
test nist_cavp_tests::cavp_aes256gcm_decrypt ... ok
test nist_cavp_tests::cavp_aes256gcm_encrypt ... ok
test nist_cavp_tests::cavp_hmac_drbg_sha512_no_reseed ... ok
test nist_cavp_tests::cavp_hmac_drbg_sha512_reseed ... ok
test nist_cavp_tests::drbg_fill_large_request ... ok
test nist_cavp_tests::drbg_refuses_past_reseed_interval ... ok
test nist_cavp_tests::drbg_reseeds_after_fork ... ok
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
test result: ok. 52 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 1.79s
test tests::test_aesgcm_blob_layout ... ok
test tests::test_aesgcm_blob_matches_spec ... ok
test tests::test_aesgcm_header_is_authenticated ... ok
test tests::test_chacha_blob_still_decrypts ... ok
test tests::test_crafted_kem_len_large ... ok
test tests::test_crafted_kem_len_small ... ok
test tests::test_crafted_kem_len_zero ... ok
test tests::test_encrypt_decrypt_roundtrip ... ok
test tests::test_encrypt_is_randomized ... ok
test tests::test_fips203_kat_vs_reference ... ok
test tests::test_kem_roundtrip ... ok
test tests::test_keygen_sizes ... ok
test tests::test_legacy_r3_blob_still_decrypts ... ok
test tests::test_legacy_r3_kem_differs_from_mlkem ... ok
test tests::test_mldsa_c_abi ... ok
test tests::test_reject_dk_hash_mismatch ... ok
test tests::test_reject_ek_coeff_out_of_range ... ok
test tests::test_tamper_detection ... ok
test tests::test_unknown_blob_version_rejected ... ok
test tests::test_wrong_key ... ok
test result: ok. 52 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out; finished in 1.79s

Reproduce it

# unit + NIST vectors + cross-checks
cargo test --release
# 1,000,000-case accumulated runs (minutes)
cargo test --release -- --ignored fips203
# 10,000-case independent ML-DSA comparison
cargo test --release -- --ignored fips204
# no-division check on secret-handling code
tests/ct/no-div.sh
# NIST ACVP via BoringSSL acvptool
ACVPTOOL=/path/to/acvptool tests/acvp/run-offline.sh

Not yet done

Accredited-lab submission

CAVP certificate numbers and CMVP/FIPS 140-3 module validation need an NIST-accredited CST laboratory. Prerequisite algorithms (SHA-3, SHAKE, SHA-2, HMAC, AES-ECB) are not yet registered in our ACVP wrapper.

External security audit

An internal review has already produced fixes (division on secrets, DRBG reseed after fork). An independent third-party audit is planned, not completed.