Skip to main content
Evidence · NIST vectors · own-code replay · formal proofs · model checking · fuzzing · side-channel

QNSQY validation: nine separate, published evidence streams. 19,769 NIST ACVP vectors through the open-source libraries QNSQY ships, 0 fail; 4,884 Wycheproof vectors, 0 fail; 1.01 billion fuzz executions, 0 crashes; 6 machine-checked protocol proofs; 185 Kani model-checking harnesses verified.

Quantum Sequrity (QNSQY) is a post-quantum cryptography tool for protecting data. A cryptographic product must answer two different questions: are the algorithm libraries it ships correct, and is the code written around them correct? A vendor can pass every library-level test vector and still get its own integration wrong, so this page separates the two and evidences both, through nine separate evidence streams: NIST ACVP vectors replayed against the upstream crates, NIST vectors replayed through QNSQY's own code, Project Wycheproof adversarial vectors, machine-checked formal verification (protocol proofs, plus Kani bounded model checking of Rust code), constant-time (timing side-channel) measurement, coverage-guided fuzzing, memory-safety analysis, static and supply-chain scanning, and per-release verification (automated suites, CLI acceptance, application-security tests). Two of these, the NIST ACVP replay and the protocol proofs, are independently reproducible by anyone from the published artifacts (a standalone harness and runnable prover models, no QNSQY source required); the others are evidenced by their published raw logs and summaries (the Kani model checking by its summary in Section 4.7), since they run against QNSQY's closed source. QNSQY holds no government or accredited certification: no FIPS 140-3 / CMVP, SOC 2, or ISO 27001. See the assurance summary for the evidence matrix; Section 5 (Limitations) defines the boundaries of this evidence.

Nine separate evidence streams

Cryptographic assurance rests on nine separate evidence streams, alongside the current third-party-certification status; two of them, the NIST ACVP replay and the protocol proofs, can be reproduced by anyone from the published artifacts. The first two answer different questions and are deliberately kept separate: stream 1 tests the upstream algorithm libraries QNSQY ships, stream 2 tests the code QNSQY wrote around them. Each is summarized below and tabulated in the assurance summary; full method and raw logs are in the numbered sections.

1. Algorithm correctness (upstream crates)

19,769 / 0

NIST's official ACVP test vectors (ACVP-Server v1.1.0.43) replayed against the upstream crate versions the 7.2.41 binary links; every answer correct, 0 fail, 3,018 of them post-quantum (2026-09-24 run). Tests the libraries, not our integration. Details →

2. Own-code correctness

231 tests / 0

NIST vectors replayed a second time, through QNSQY's own entry points (mostly the qnsqy_core library) instead of the crates': ML-KEM, ML-DSA, SLH-DSA, LMS, X25519, hash and HMAC. 22 own-code suites, 231 tests, 0 fail (7.2.41 vector sweep, 2026-09-24). This is the stream that tests the code we wrote. Details →

3. Adversarial input rejection

4,884 / 0

Google's Project Wycheproof adversarial vectors on the current C2SP files (7.2.41 run): tampered, forged and malformed inputs are refused. The ML-KEM and ML-DSA sets also run through QNSQY's own key-exchange and signing code. Details →

4. Machine-checked proofs

6 proofs + 185 Kani

Machine-checked protocol proofs (ProVerif, Tamarin, CryptoVerif) verifying secrecy and authentication properties under a defined adversary model, plus 185 Kani bounded-model-checking harnesses (120 in the product crate, 65 in the core crate), each verified within its stated bounds. Details →

5. No timing leaks

no leak

Side-channel timing measured on the running binary (dudect): no leak detected in the secret-comparison helpers. dudect can reveal a leak but cannot prove there is none. Details →

6. Fuzz robustness

1.01B execs / 0

33 coverage-guided fuzz targets, 15 minutes each, on the 7.2.41 code (commit 1001b06b): 1,012,281,408 executions, 0 crashes. Earlier campaigns, and the one third-party panic they surfaced, are disclosed in Section 4.3, not filtered. Details →

7. Memory-safe

Rust + audited

Written in Rust; all 189 low-level unsafe blocks hand-audited; miri found no undefined behavior in the safe-math core it covered. Soundness defects the audit did find are tracked and being fixed. Details →

8. Code + supply chain

0 high/crit (SAST)

Semgrep static analysis: 0 high/critical. Dependency + secret scans run every build; the cargo-deny advisory gate currently fails non-zero on unmaintained pqcrypto and pre-1.0 RC crypto crates that do ship in the binary (plus build-only npm dev-tooling). Details →

9. Release verification

2,038 + 1,392 + 701

Per-release: 2,038 automated tests across 62 suites (0 fail), a 1,392-operation CLI acceptance run, and 701 passing application-security tests on the billing API mapped to OWASP ASVS and other published standards. Self-administered, not an audit. Details →

Independent certification

Not yet

No FIPS 140-3 / CMVP, SOC 2, or ISO 27001 as of this date; CMVP is on the roadmap, no application submitted. Why →

Sweep Summary

QNSQY replays NIST's official ACVP test vectors against the exact upstream Rust crate versions its binary links. The harness calls those crates directly (the one exception: the ML-KEM key-check vectors go through QNSQY's own FIPS 203 key validation), so this establishes that the algorithm implementations QNSQY depends on are conformant; it does not, on its own, exercise QNSQY's integration of them. The current sweep, run 2026-09-24 for QNSQY 7.2.41 against ACVP-Server v1.1.0.43 (commit 975de31eb83d87039ec88934fdc47d8c312b892d):

Vectors Passed

19,769

Out of 31,071 vectors attempted in 55 ACVP directories. Of these, 3,018 are post-quantum (ML-KEM + ML-DSA + SLH-DSA), 12,375 are HMAC, the remaining 4,376 cover classical hash, AEAD, and elliptic-curve primitives. Every non-skipped vector matches NIST's expected output byte-for-byte. This sweep drives the vectors into the Rust crates QNSQY ships, so it is evidence about those libraries, not QNSQY's own code. For NIST vectors replayed through QNSQY's own code, see 4.5 Own-code vector replay.

Failures

0

No discrepancies, no waivers, no retries. Any failure would be reported per vector in the raw log.

Skips Documented

11,302

30 of these are a real coverage gap in an upstream Rust crate: AES-GCM tags shorter than 96 bits, which aes-gcm 0.10 rejects at the type level. The other 11,272 are vectors outside QNSQY's algorithm scope: 9,071 bit-oriented hash inputs or outputs, 2,000 SP 800-56C TwoStep KDA encodings, 148 Ed448 or Ed25519ph, 51 Curve448 and 2 SHAKE Monte Carlo variable-output tests. Section 3 itemises every category.

ACVP-Server commit975de31eb83d87039ec88934fdc47d8c312b892d (v1.1.0.43)
Sweep wall-clock1,014.23 seconds (2026-09-24 run, single machine). Other hardware will differ.
QNSQY commitv7.2.41, commit ee3c5c6b
Raw logacvp-7.2.41-v1.1.0.43.log (one line per vector; grep-able)
Earlier sweep18,703 passed, 0 failed, 11,259 skipped of 29,962 on ACVP-Server v1.1.0.42 (commit 15c0f3deeefbfa8cb6cd32a99e1ca3b738c66bf0, first published 2026-06-03): acvp-RUN-final.log, acvp-summary.json / .csv
PDF report (earlier sweep)QNSQY-ACVP-Validation-Report.pdf (Markdown)

This is NOT a NIST endorsement.

What this page presents is byte-for-byte ACVP test-vector replay against the production Rust crates QNSQY ships. ACVP replay is one input a CMVP-accredited lab consults; it is not a substitute for CMVP evaluation, accredited-lab testing, or NIST validation. QNSQY is not NIST-certified, not NIST-approved, not FIPS 140-3 validated, and not listed on the NIST Cryptographic Module Validation Program. The surrounding boundary, role, self-test, and operational requirements have not been independently evaluated. CMVP is on the roadmap; no application has been submitted to NIST as of this date.

Project Wycheproof adversarial vectors

The ACVP sweep above proves QNSQY computes the correct answer on valid input. Project Wycheproof exercises the complementary property: that invalid, malformed, and adversarially crafted inputs are rejected. QNSQY runs Google's official Project Wycheproof v1 adversarial test vectors on every build. On the current C2SP testvectors_v1 files (fetched 2026-09-24 for 7.2.41), 4,884 vectors execute, with zero failures, covering ML-KEM, ML-DSA, Ed25519, X25519, AES-256-GCM, ChaCha20-Poly1305, XChaCha20-Poly1305, HKDF and HMAC. Each harness fails the build if any valid vector is rejected, if any invalid vector is accepted, or if zero vectors execute, which prevents a vacuous pass.

The vectors exercise the reject paths that matter for security: tampered AES-GCM authentication tags, malleable Ed25519 signatures, malformed public keys, and twisted-curve points. The AES-256-GCM and XChaCha20-Poly1305 vectors test QNSQY's own AEAD code. The Ed25519, X25519, ML-DSA-44/65/87, ML-KEM-512/768/1024, HKDF-SHA256/512, HMAC-SHA256/512, and IETF ChaCha20-Poly1305 vectors test the exact RustCrypto and dalek crate versions QNSQY ships; in the 7.2.41 run the ML-KEM and ML-DSA sets also run through QNSQY's own key-exchange and signing code, in both QNSQY code bases. The remaining vectors in the imported corpus are skipped because they use parameters QNSQY does not offer, for example AES with 128- or 192-bit keys where QNSQY is 256-bit only; every skip is logged with a reason and none is counted as a pass.

The vectors are Google's Project Wycheproof v1 corpus, fetched verbatim from the public C2SP/wycheproof repository, exercised by four Rust harnesses (one each for AEAD, EdDSA/X25519, ML-DSA/ML-KEM, and HKDF/HMAC), plus an own-code harness that runs the ML-KEM and ML-DSA sets through QNSQY's own code. The corpus is public; QNSQY's harness source is proprietary and not shared, so this stream is evidenced by its result, not by an external re-run.

This is NOT a certification.

Like the ACVP replay, this is byte-for-byte test-vector replay against the production crates QNSQY ships. It is a strong, reproducible signal that the cryptographic primitives accept what they should and reject what they should. It is not a NIST or CMVP or FIPS 140-3 certification, and the surrounding module boundary, role, and self-test requirements have not been independently evaluated. CMVP is on the roadmap; no application has been submitted to NIST as of this date.

7.2.41 test-vector replay on the newest NIST and C2SP files (2026-09-24)

For 7.2.41 we replayed NIST's newest ACVP files (release v1.1.0.43) with QNSQY's ACVP test harness. Every NIST file the harness reads is byte-identical to that release. Like the sweep above, the harness tests the cryptography libraries at the versions QNSQY 7.2.41 links. Only the FIPS 203 key-check vectors go through QNSQY's own code. This run does not test QNSQY's own file format or key storage. The Wycheproof and OpenSSL checks below exercise QNSQY's own signing and key-exchange functions.

NIST ACVP vectors passed

19,769

0 failed. 3,018 are post-quantum (ML-KEM, ML-DSA, SLH-DSA). 11,302 more were skipped because they cover options QNSQY does not implement; each skip is logged with its reason.

Wycheproof vectors run

4,884

0 failed, on the current C2SP files. The new ML-DSA signing and ML-KEM suites run through QNSQY's own signing and key-exchange code, in both QNSQY code bases.

Defects found and fixed

2

(1) A malformed ML-DSA private key made the signing code panic instead of returning an error; 7.2.41 checks the key first. (2) A malformed LMS key or signature reached a library parser that panics; the product already caught the panic and returned an error, and 7.2.41 now rejects such input before the library sees it.

NIST releaseACVP-Server v1.1.0.43, commit 975de31eb83d87039ec88934fdc47d8c312b892d
QNSQY buildv7.2.41, commit ee3c5c6b
Vectors attempted31,071 in 55 ACVP directories (36 directories had no skips)
OpenSSL interoperabilityML-KEM, ML-DSA and six SLH-DSA sets exchanged with OpenSSL 3.5, an independent implementation, in both directions: 12 of 12 agree.
Fuzzing33 targets for 2 minutes each with AddressSanitizer, a short campaign. After the LMS fix, both signature fuzz targets were re-run: 0 crashes.
Long fuzz campaign33 targets for 15 minutes each, 1,012,281,408 executions, 0 crashes (commit 1001b06b, which includes the LMS fix)
Raw logacvp-7.2.41-v1.1.0.43.log (one line per vector)
Reproduce itStandalone harness v1.1 (Section 1) reproduces this result; measured first run 9 minutes 26 seconds

This is NOT a certification.

Test-vector replay is evidence about the code, not a validation. QNSQY is not FIPS 140 validated and has not been tested by a CMVP laboratory.

Speed on real hardware (7.2.41, measured 2026-09-25)

We timed the exact shipped 7.2.41 Linux binary, taken from the released .deb, on one laptop-class machine. Each figure is the median of three runs of the complete command as a user runs it, including program start, the sandbox and the online licence check. Every encrypted file was then decrypted and compared byte for byte with its original, at 1 MB, 100 MB and 1 GB in both modes below: all identical.

Encrypt, 1 GB file

184 MB/s

Default mode: ML-KEM-768 with X25519, AES-256-GCM. Decrypt: 215 MB/s.

Encrypt and sign, 1 GB file

175 MB/s

Pure ML-KEM-1024 and a pure ML-DSA-87 signature, AES-256-GCM. Decrypt and verify: 194 MB/s.

Hash, 1 GB file

927 MB/s

BLAKE3. SHA3-256: 335 MB/s. Signing a 1 GB file with ML-DSA-87 takes 1.2 s; verifying it, 1.2 s.

Fixed cost per command

about 0.9 s

Program start, sandbox setup and the online licence check. It dominates small files: a 1 MB file takes 0.9 to 1.4 s end to end, and 100 MB encrypts at 64 MB/s. Password mode with Argon2id (default preset): about 1.2 s per 1 MB file.

QNSQY buildv7.2.41 Linux binary, SHA-256 ed8756a5a1b53e6e5bb3f50a914f54a6378d8d84eb61696bacc2a8a1e1c7052f
MachineAMD Ryzen 7 7735HS (8 cores, 16 threads, AES-NI, AVX2, SHA-NI), 28 GB RAM, Samsung NVMe SSD, btrfs, Fedora 44, kernel 7.1
MethodRandom files of 1 MB, 100 MB and 1 GB; wall-clock time of the full command; median of 3 runs; round-trip byte comparison afterwards
Raw databench-7.2.41.csv (every run) and bench-7.2.41-host.txt (machine and round-trip results)

One machine is not a lab benchmark: storage speed decides large-file times, and Windows has not been measured yet. For your own hardware, the pilot times every operation on a sample of your files and projects the total from the inventory.

Assurance summary

Cryptographic assurance is not a single score. QNSQY's rests on nine separate, published evidence streams plus its current third-party-certification status. The matrix below states, for each stream, the property it establishes, the measured result, and the prevailing industry benchmark. The ACVP and protocol-proof results are independently reproducible from the published artifacts; the remaining streams are evidenced by the raw logs and summaries in the numbered sections (the Kani model checking by its summary in Section 4.7).

Property What it establishes Result Industry benchmark
Algorithm conformance (upstream crates) Primitive outputs match NIST's published ACVP vectors byte-for-byte. 19,769 / 19,769 vectors, 0 fail (7.2.41 run, 2026-09-24, ACVP-Server v1.1.0.43; 11,302 skipped with logged reasons). Pass NIST CAVP/ACVP algorithm validation, replayed against the shipping crates. Full CMVP not pursued.
Own-code conformance QNSQY's own key handling, parameter validation and API surface produce NIST's expected outputs, not just the libraries underneath. 231 / 231 tests in 22 own-code suites, 0 fail (7.2.41 vector sweep, 2026-09-24); vectors that cannot be driven through the API are itemised with a reason in the corpus ledger published for v7.2.38. Pass Vector replay through the product's own entry points. Uncommon: most vendors stop at library-level replay.
Negative / adversarial testing Tampered ciphertext, malleable signatures, and malformed keys are rejected. 4,884 / 4,884 Wycheproof vectors, 0 fail (7.2.41 run, current C2SP files). Pass Google Project Wycheproof, executed on every build.
Formal verification Protocol security properties proven in a symbolic / computational model, and stated properties of Rust code and models checked for every input within set bounds, not only tested. 6 machine-checked protocol proofs: secrecy, unforgeability, anti-tamper, anti-rollback, forward secrecy, AEAD integrity. Proven 185 Kani harnesses verified (120 product crate, 65 core crate). Verified ProVerif / Tamarin / CryptoVerif; Kani bounded model checking (per property and within bounds, not a whole-program proof). Uncommon among commercial products; two further protocol properties (post-compromise security, IND-CPA length-hiding) and one general Kani chunk-ceiling proof remain open and are disclosed.
Side-channel resistance No secret-dependent timing variation in the constant-time primitives. No leak detected in the four constant-time comparison helpers (dudect), measured on a shared developer machine; the PQC primitives themselves were not measured, and dudect can falsify but not prove constant-time. Indicative Constant-time implementation plus statistical timing measurement (dudect / ctgrind). Hardware-isolated re-run pending for formal sign-off.
Fuzzing / fault tolerance No crash, hang, OOM, or memory error on hostile input (decryption-time DoS resistance). 0 crashes across 1,012,281,408 executions, 33 targets at 15 minutes each on the 7.2.41 code (commit 1001b06b); the v7.2.38 campaign (32 harnesses at one hour each) was also clean in product code. One panic inside a third-party crate (hbs-lms) was caught by the product via catch_unwind, is disclosed in full, and 7.2.41 now rejects that input before the crate sees it. Not CI-gated; the polyglot, deniable-container and remote-manifest parsers have no target yet. Pass (covered parsers) Coverage-guided fuzzing; continuous fuzzing (OSS-Fuzz) on the roadmap.
Memory safety Memory-corruption vulnerability classes precluded; remaining low-level code audited. Rust, all 189 unsafe blocks audited; miri clean on the pure-Rust safe-math core. The audit surfaced low-level soundness / UB defects; the priority shipping-path items (ML-KEM aliasing-UB, integrity read-extent) are now remediated and compile-verified, the remainder tracked. Strong Memory-safe language + undefined-behavior checkers (miri) + per-block unsafe audit. C/C++ tooling addresses only part of this class.
SAST & supply chain Source-pattern analysis, secret scanning, and dependency-advisory monitoring. Semgrep: 0 high/critical; CodeQL (billing-API TS, 94 files): 0 error / 0 warning (22 note-level). But the cargo-deny advisory gate currently fails non-zero: the unmaintained pqcrypto (HQC, FN-DSA/Falcon, LMS) and pre-1.0 RC crates (ml-dsa, slh-dsa, signature) that provide PQC algorithms do ship in the binary; only the npm dev-tooling advisories are build-only. SAST clean; supply-chain advisories open SAST (Semgrep / CodeQL) plus continuous dependency and secret auditing.
Release verification The shipped build passes its full regression, acceptance and application-security surface before release. 2,038 tests / 62 suites, 0 fail; a 1,392-operation CLI acceptance run; 701 passing billing-API tests including suites mapped to OWASP ASVS 5.0.0 and other published standards (8 known gaps disclosed as todo). All v7.2.38, build 868cc4e0. Pass (self-administered) Release-gate test matrix plus control-mapped application-security suites. Self-administered; independent audit not yet engaged.
Independent certification Accredited third-party validation of the module and the organization. None held. No FIPS 140-3 / CMVP, SOC 2, or ISO 27001. On roadmap NIST CMVP (module); SOC 2 / ISO 27001 (organization). Not yet initiated.

Rows one through nine are each backed by published artifacts on this page; the NIST ACVP results and the protocol proofs are additionally re-runnable by any third party from a standalone harness and runnable prover models, while the others are evidenced by their raw logs and summaries (they run against QNSQY's closed source; the Kani harnesses are evidenced by their summary in Section 4.7). The tenth, independent certification, is the control QNSQY does not yet hold; it is stated here alongside the strongest results rather than omitted. The numbered sections below provide the full method and raw logs for each stream, with re-run instructions for the two reproducible streams.

Scope of "Pass"

"Pass" denotes that the test executed and every result was correct against the exact code QNSQY ships, and is independently reproducible. It does not denote accredited-lab or government sign-off. Test-vector and formal results establish cryptographic correctness; certification establishes that an accredited body has evaluated the complete module and its processes. QNSQY has substantial evidence of the former and does not yet hold the latter.

1. Reproducibility

The procedure below reproduces the 7.2.41 result line on NIST's ACVP-Server release v1.1.0.43: 19,769 / 0 / 11,302 / 31,071 (pass / fail / skip / total attempted) in 55 ACVP directories, with 3,018 of the passes post-quantum. It takes five steps: download the harness, fetch NIST's vectors, build, run, count.

Measured first run, 25 September 2026: 9 minutes 26 seconds for steps 1 to 5. We followed the archive's README step by step with an empty Cargo cache and a fresh clone of NIST's vectors, on an AMD Ryzen 7 7735HS laptop processor (8 cores, 16 threads, 28 GB RAM) running Fedora 44 and Rust stable 1.92.0, with the working folder on an NTFS partition mounted through FUSE. Fetching the vectors took 1 minute 45 seconds (a 480 MiB download), the build 23 seconds (81 crates downloaded from crates.io and compiled; the other 3 crates in Cargo.lock are not needed for this build), and the replay 7 minutes 19 seconds. Checking and counting took under a second. Installing Rust is not included, and for this run the archive in step 1 was copied from our build folder because it was not yet published. The download time depends on the network, and the replay runs its tests in parallel on all cores, so a machine with fewer cores takes longer. Result: 19,769 passed, 0 failed, 11,302 skipped, 55 directories. The run used about 1.4 GiB of disk.

The harness is published as a self-contained archive: qnsqy-acvp-harness-v1.1.tar.gz (SHA-256, about 33 KB). It contains the 12 loader modules, the shared Report helper, a Cargo.toml pinned to the crate versions QNSQY 7.2.41 ships, a Cargo.lock that pins all 84 crates to the versions and checksums in QNSQY 7.2.41's own lockfile, and a README. It depends only on public crates from crates.io and contains no QNSQY product code. The earlier archive, v1.0 (SHA-256), pins the QNSQY 7.2.20 crate versions and reproduces the 2026-06-03 sweep; it stays available for that record.

What it tests: the open-source libraries QNSQY ships (ml-kem 0.2.3, ml-dsa 0.1.1, slh-dsa 0.2.0-rc.1, sha2, sha3, sha1, hmac, hkdf, aes-gcm, ed25519-dalek, x25519-dalek), not QNSQY's own code. One difference from QNSQY's internal run: the ml-kem crate has no FIPS 203 key check, so the 120 encapsulation-key and decapsulation-key check vectors run through a short check carried in the harness itself; in QNSQY's internal run they go through QNSQY's own validator. The harness's 50 X25519 self-consistency checks are not NIST vectors and are not counted.

Step 1. Download and check the harness

bash
$ mkdir acvp-repro
$ cd acvp-repro
$ curl -fLO https://quantumsequrity.com/validation-artifacts/qnsqy-acvp-harness-v1.1.tar.gz
$ curl -fLO https://quantumsequrity.com/validation-artifacts/qnsqy-acvp-harness-v1.1.tar.gz.sha256
$ sha256sum -c qnsqy-acvp-harness-v1.1.tar.gz.sha256
$ tar xzf qnsqy-acvp-harness-v1.1.tar.gz

Step 2. Fetch the NIST vectors at the pinned commit

bash
# Shallow, sparse clone: only gen-val/json-files is checked out (691 MiB of JSON, plus a 480 MiB pack).
$ git init acvp-server
$ cd acvp-server
$ git remote add origin https://github.com/usnistgov/ACVP-Server.git
$ git config core.sparseCheckout true
$ echo "gen-val/json-files/" > .git/info/sparse-checkout
$ git fetch --depth 1 origin 975de31eb83d87039ec88934fdc47d8c312b892d
$ git checkout FETCH_HEAD
$ cd ..

Step 3. Build

bash
# --locked makes Cargo use the bundled Cargo.lock exactly.
$ cd qnsqy-acvp-harness
$ cargo build --release --tests --locked

Step 4. Run the replay

bash
$ export QNSQY_ACVP_DIR="$PWD/../acvp-server/gen-val/json-files"
$ BIN=$(find target/release/deps -maxdepth 1 -type f -name 'acvp_official-*' ! -name '*.d')
$ ACVP_LOG_FILE=../acvp-vectors.log "$BIN" --nocapture 2>&1 | tee ../acvp-run.log
$ cd ..

# The test run must finish with:
test result: ok. 57 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in ...

Step 5. Count the vectors

bash
$ awk '$3 ~ /^#/ { n[$1]++; d[$2] = 1 } END { for (k in d) dirs++; printf "pass %d  fail %d  skip %d  directories %d\n", n["PASS:"], n["FAIL:"], n["SKIP:"], dirs }' acvp-vectors.log
pass 19769  fail 0  skip 11302  directories 55
$ grep -c 'self-consistency' acvp-vectors.log
50

The first count is the NIST result. The second is the X25519 self-consistency count, which the first leaves out. acvp-vectors.log has one line per vector with its verdict and, for every skip, the reason; acvp-run.log has one ACVP_REPORT line per directory. The commands are for a Linux shell with git, curl, tar and sha256sum, Rust 1.85 or newer from rustup, and a C linker; plan for at least 2 GB of free disk.

Three crates in the build are pre-releases: slh-dsa 0.2.0-rc.1, pkcs8 0.11.0-rc.11 and kem 0.3.0-pre.0. Cargo still downloads a yanked version when Cargo.lock names it, so the bundled lockfile keeps the build reproducible as long as crates.io keeps the files.

A divergent result indicates one of: a different ACVP-Server commit, a changed crate (build with --locked), or a defect. Discrepancies should be reported to [email protected]. A matching result is test-vector evidence about these libraries, not NIST certification or FIPS 140 validation.

2. Per-Algorithm Results

Fifty-five ACVP algorithm directories were attempted in the 2026-09-24 run for 7.2.41 (ACVP-Server v1.1.0.43). Thirty-six are at 100% coverage of the NIST vectors they contain. The remainder contain variant flavors we do not implement, plus one upstream crate limit (AES-GCM tags shorter than 96 bits). No directory contains a failing vector.

Of the 19,769 passing vectors, the majority are HMAC (12,375). The post-quantum subset (ML-KEM + ML-DSA + SLH-DSA) accounts for 3,018 vectors, approximately 15.3% of the passing total. Machine-readable per-directory totals: acvp-summary-7.2.41.json. The earlier sweep on ACVP-Server v1.1.0.42 (50 directories, 33 at 100%, 18,703 passed) remains in acvp-summary.json / .csv.

By cryptographic family

Family Spec Pass Skip Notes
HMAC FIPS 198-1, RFC 4231 12,375 0 All 22 directories (SHA-1, SHA-2 x6, SHA-3 x4 in both -1.0 and -2.0 schemas) at 100%. 100% covered
SHA-2 FIPS 180-4 2,947 2,203 SHA-2-256 / 512 / 512-256 -1.0 at 100% (AFT + MCT-alternate + LDT up to 8 GiB). 100% covered
SHA-3 FIPS 202 538 3,554 SHA3-{224,256,384,512} byte-aligned AFT + MCT-standard + LDT.
SHAKE FIPS 202 756 3,316 SHAKE-128-FIPS202 at 100% (269/269). Skips are bit-oriented inputs or outputs, plus 2 Monte Carlo variable-output tests. SHAKE-128-FIPS202 100%
ML-KEM FIPS 203 435 0 keyGen, encapDecap and encapDecap tr1 (a new NIST revision) all at 100%, including the FIPS 203 §7.2/§7.3 key checks, which run through a key check outside the ml-kem crate because ml-kem 0.2.3 has none. The earlier sweep skipped 60 of them. 100% covered
ML-DSA FIPS 204 1,335 0 keyGen, sigGen, sigGen tr1 (a new NIST revision, seed and expanded key formats) and sigVer all at 100% on ml-dsa 0.1.1. The 45 externalMu and randomized vectors the earlier sweep skipped (ml-dsa 0.1.0-rc.7) now run and pass. 100% covered
SLH-DSA FIPS 205 1,248 0 All 12 parameter sets, every pure/preHash, deterministic/randomized, external/internal combination. 100% covered
Ed25519 FIPS 186-5, RFC 8032 54 148 Pure Ed25519 keyGen, keyVer, sigGen and sigVer pass, including NIST's new Ed25519 keyGen (3) and sigGen (42) sets. The 148 skips are Ed448 (101) and Ed25519ph (47), which QNSQY does not use.
X25519 RFC 7748 51 51 X25519 keyGen (10), keyVer (16) and shared-secret computation (25) pass. The 51 skips are Curve448 (X448), which QNSQY does not implement. 50 X25519 self-consistency pair checks also pass and are not counted as NIST vectors.
AES-GCM SP 800-38D 30 30 NIST §5.2.1.2-compliant 96/104/112/120/128-bit tag cases pass. 30 sub-floor tag-length vectors rejected by aes-gcm 0.10 at type level.
HKDF (extract+expand) RFC 5869 0 2,000 The 2,000 vectors are SP 800-56C TwoStep KDA-HKDF, a different KDF construction that QNSQY does not use. QNSQY's RFC 5869 HKDF is covered by the KAT suite (Section 4.1) and by Wycheproof HKDF vectors instead.
Total 55 ACVP directories 19,769 11,302 36 of 55 directories at 100%. Full per-vector log: acvp-7.2.41-v1.1.0.43.log.

All 55 directories: filter & sort

Interactive view of every ACVP directory in the 7.2.41 run (data from acvp-summary-7.2.41.json). Columns are sortable; results can be filtered by directory name or status. For per-vector detail (tcId + expected/got), see the Raw Sweep Log.

Directory Total Pass Fail Skip Coverage
Loading 55 directories…

The 36 directories at 100% NIST coverage

Every vector in each of these directories matches NIST's expected output:

  • HMAC (22 dirs): HMAC-SHA-1, HMAC-SHA-2-{224,256,384,512,512/224,512/256}, HMAC-SHA3-{224,256,384,512} in both -1.0 and -2.0 ACVP schemas. 12,375 vectors total.
  • ML-DSA keyGen + sigGen + sigGen tr1 + sigVer: 75 + 360 + 720 + 180 vectors across all three parameter sets.
  • ML-KEM keyGen + encapDecap + encapDecap tr1: 75 + 165 + 195 vectors across all three parameter sets (512, 768, 1024), key checks included.
  • SLH-DSA-keyGen + sigGen + sigVer: 1,248 vectors across all 12 parameter sets and every signatureInterface flavor.
  • SHA-2-256 -1.0, SHA-2-512 -1.0, SHA-2-512/256 -1.0: 2,575 vectors. AFT, MCT-alternate, and LDT up to 8 GiB.
  • SHAKE-128-FIPS202: 269 byte-aligned single-output vectors.

The remaining 19 directories contain at least one variant we do not implement (for AES-GCM, a tag length the upstream crate rejects). They are not failures; they are deliberate scope decisions or an upstream-crate limit. Section 3 documents every skip.

3. Skip Catalogue (11,302 Vectors in the 7.2.41 Run)

Every skip is logged with its algorithm directory and a documented reason. In the 7.2.41 run (ACVP-Server v1.1.0.43) the 11,302 skips fall under seven logged reasons: 9,071 bit-oriented hash inputs or outputs, 2,000 SP 800-56C TwoStep KDA-HKDF encodings, 101 Ed448, 51 Curve448, 47 Ed25519ph, 30 AES-GCM tags shorter than 96 bits and 2 SHAKE Monte Carlo variable-output tests. The ML-KEM key checks and the ML-DSA externalMu and randomized vectors skipped in the earlier sweep now run and pass, as do 16 X25519 keyVer vectors. The subsections below describe each category as written for the earlier sweep on ACVP-Server v1.1.0.42 (11,259 skips); the counts in their headings are from that sweep. Each category is justified by a scope decision or an upstream-crate API constraint, listed in descending order of vector count.

3.1 Bit-oriented hash inputs (9,071 vectors)

NIST ACVP defines hash inputs at bit granularity (msgLen not a multiple of 8). The Rust sha2 and sha3 crates accept byte-aligned input only. We did not build a sub-byte feeder because QNSQY never hashes non-octet-aligned messages: every API boundary (CLI, GUI, MCP) takes whole bytes. Vectors where msgLen % 8 == 0 all pass. Affected directories: SHA-2 / SHA-3 / SHAKE bit-oriented variants. Status: out of scope for the byte-aligned API.

3.2 SP 800-56C TwoStep KDA-HKDF (2,000 vectors)

NIST's TwoStep KDF uses a different fixedInfo encoding than RFC 5869 HKDF. QNSQY uses the RFC 5869 construction, which is covered by the KAT suite (Section 4.1) and by Wycheproof HKDF vectors instead. TwoStep is unused. Status: unused construction.

3.3 ML-KEM EncapsKeyCheck / DecapsKeyCheck (60 vectors)

FIPS 203 §7 defines ML-KEM-EncapsKeyCheck and ML-KEM-DecapsKeyCheck for key validation. The ml-kem 0.2.3 crate does not expose these as standalone functions. The crate's own kem.rs:58 carries the comment "Should we verify that the provided `h` value is valid?", acknowledging the gap. Status: upstream crate API gap. We are tracking RustCrypto/KEMs for a fix; we will close this when the crate adds it.

3.4 ML-DSA externalMu + randomized (45 vectors)

ml-dsa 0.1.0-rc.7 exposes raw_sign_mu(mu, rnd) as pub(crate), unreachable from outside the crate. We pass externalMu deterministic via the public path; the randomized variant requires either a public API or an upstream patch. Status: upstream crate API gap. Tracking RustCrypto/signatures.

3.5 AES-GCM tagLen below 96 bits (30 vectors)

aes-gcm 0.10 enforces SP 800-38D §5.2.1.2 minimum tag floor (96 bits) at the type level. NIST publishes vectors at 32, 64, 96, 104, 112, 120, 128 bits; the four sub-96-bit tag lengths are rejected by the crate. QNSQY uses 128-bit tags exclusively. NIST §5.2.1.2-compliant tag-length cases all pass. Status: legacy IPsec/IKE configurations only. Not used by QNSQY.

3.6 XECDH-keyVer cross-protocol (32 vectors)

XECDH-keyVer verifies behavior across X25519/X448 boundaries. QNSQY uses X25519 only. Self-consistency RFC 7748 vectors (XECDH-SSC) all pass. Status: out of scope for X25519-only deployment.

3.7 Ed25519ph + Ed448 (19 vectors)

Pure Ed25519 (RFC 8032 with empty context) passes its ACVP vectors. Ed25519ph (pre-hashed Ed25519) and Ed448 are not used by QNSQY. Status: unused variants.

3.8 SHAKE MCT variable-output (2 vectors)

ACVP defines a Monte Carlo Test for SHAKE with variable output lengths drawn from a state machine. We implement single-output SHAKE, which is what QNSQY uses, at 100% (SHAKE-128-FIPS202 269/269). The 2 MCT variable-output vectors are not implemented in the harness. Status: harness scope, not a correctness gap.

3.9 AES-192 (varies)

QNSQY uses AES-256 only. Any vector group with keyLen=192 is skipped. Status: scope.

In the earlier sweep the categories add up to 11,259 (9,071 bit-oriented + 2,000 TwoStep HKDF + 60 ML-KEM key-checks + 45 ML-DSA externalMu-randomized + 32 XECDH-keyVer + 30 AES-GCM sub-96-bit tag + 19 Ed25519ph/Ed448 + 2 SHAKE MCT). Every skip line in acvp-7.2.41-v1.1.0.43.log (7.2.41) and acvp-RUN-final.log (earlier sweep) is grep-able by the substring SKIP: followed by the directory and reason.

4. Other Validation We Run

ACVP is one evidence stream. Independent of the NIST replay, QNSQY runs several other validation programs against every release: a curated test suite, install smoke tests, fuzzing, an own-code vector replay, release verification with application-security suites, formal proofs, timing side-channel measurement, memory-safety checks, and static + supply-chain scanning.

4.1 Curated KAT suite (403 tests)

QNSQY also runs a curated Known Answer Test suite internally before every release; in the 7.2.41 vector sweep (2026-09-24) it passed 403 tests across 19 algorithm modules with 0 failures and 1 ignored (an LMS ACVP signature-verification test that the hbs-lms 0.1.1 API cannot run). It complements the ACVP replay above by covering algorithms not in the NIST ACVP catalog (HQC, Falcon, BLAKE3, XChaCha20, Argon2id, Shamir Secret Sharing) alongside official vectors for ML-KEM, ML-DSA, SLH-DSA, LMS, SHA-2, SHA-3, Ed25519, X25519, HMAC, HKDF and AES-GCM, plus determinism, avalanche and stress tests per module.

Coverage honesty: 17 of the 19 KAT modules drive the upstream crates directly, the same scope as the ACVP replay; 2 (HQC and Shamir) drive QNSQY's own code. A broken dependency is still our problem, so we run and publish all of it, but the evidence about QNSQY's own implementation is the own-code replay in 4.5, not this suite. The KAT suite lives in the proprietary source; the ACVP harness in Section 1 is the shareable stream.

4.2 Install + functional smoke test (15 platforms)

Every release is installed from its real package (.deb / .rpm / .exe) and run through an 11-test Free-tier suite (password encrypt+decrypt, SHA round-trip, ML-DSA-44 keygen/sign/verify, ML-KEM-512 recipient round-trip, BLAKE3) plus an 8-test Business-tier suite (FN-DSA-1024, HQC-256, LMS-SHA256-H10W2, SLH-DSA-128s, ML-KEM-1024).

PlatformInstallFree 11-testBusiness 8-test
Ubuntu 22.04, 24.04, 24.10, 25.04, 25.10.deb11/11 PASS8/8 PASS
Debian 12, Debian 13 trixie.deb11/11 PASS8/8 PASS
Fedora 40, 41, 42, 43, 44.rpm11/11 PASS8/8 PASS
AlmaLinux 10.rpm11/11 PASSn/a
Windows 10 + 11 (Wine win10/win11).exe11/11 PASSn/a

Not supported (glibc 2.34 or older): Debian 11, Rocky 9, AlmaLinux 9. macOS: build pipeline pending.

4.3 Fuzzing (random + hostile input)

Coverage-guided fuzzing exercises parser and crypto code paths with random and adversarially mutated inputs; any crash, hang, or memory error is treated as a finding. QNSQY maintains 44 cargo-fuzz harnesses (33 in QNSQY, 11 in qs-chat) covering the .qs header and chunk decoders, the recipient-slot parser, AEAD, KEM, the audit-log chain, the steganography and time-lock extractors, and the qs-chat message/voice parsers; the harnesses live in QNSQY's proprietary source tree, so the published evidence for this stream is the campaign result log, not an external re-run. Coverage is not yet complete: the polyglot, deniable-container and remote-manifest parsers do not yet have fuzz targets, and the suite is not yet wired into CI as a merge gate.

The most recent long campaign (2026-09-24, on the 7.2.41 code at commit 1001b06b) ran all 33 targets for 15 minutes each: 1,012,281,408 executions with 0 crashes. A short pass earlier that day (33 targets, 2 minutes each, with AddressSanitizer) counted one panic inside hbs-lms 0.1.1 on malformed LMS input; the shipped lms_verify already caught it and returned an error, 7.2.41 now rejects such input before the library sees it, and both signature targets re-run on the fixed code found 0 crashes.

The previous long campaign (2026-08-04, against v7.2.38 build 868cc4e0) ran all 32 core harnesses for one hour each, eight concurrent, seeded from the accumulated corpus: 2,786,827,494 executions with zero crashes in product code. Per-target highlights: the verify path at 435.6M executions, the recipient-key parser at 383.0M, the steganography extractor at 308.4M, the threshold-parameter parser at 303.8M, the time-lock header at 240.8M, the chunk parser at 27.9M, the encrypted-header decoder at 23.7M. The corpus grew from 23 MB to 75 MB over the campaign, so the coverage carried into it compounds on the next run.

The campaign surfaced exactly one crash, and we report it rather than filter it: a four-byte input panics inside the third-party hbs-lms 0.1.1 crate (src/util/helper.rs:6, a slice range check), not inside QNSQY code. It cannot occur in the shipped product: lms_verify wraps that call in catch_unwind and the release profile sets panic = "unwind", so the panic is caught and returned as an error. The fuzzing harness builds with an abort handler that fires before the guard can run, which is why the fuzzer observes it and the product does not. We verified this against the shipped binary: LMS signatures corrupted at three different offsets, plus a hard truncation, all returned a non-zero exit with no crash, no abort and no memory fault. We run these campaigns before releases; wiring them into a public continuous-fuzzing service (OSS-Fuzz) is on the roadmap. The full campaign log is published at fuzz-campaign-v7.2.38.log (SHA-256). The previous campaign, run against v7.2.20 on 2026-06-13 at 180 s per target, is retained unchanged at fuzz-campaign.log so the figures quoted in that release of this page remain verifiable.

4.4 Internal security audit history

QNSQY undergoes multi-agent internal security audits on every major release. We do not publish per-finding detail to avoid telegraphing partially mitigated weaknesses, but we publish the cadence: internal audit rounds since 2026-03 have covered crypto core, billing API, payment API, CLI, and infrastructure on a rolling basis. Findings are tracked internally and remediated prior to release. Independent third-party audit is on the roadmap and not yet engaged.

4.5 Own-code vector replay (NIST vectors through QNSQY's API)

The ACVP sweep at the top of this page drives NIST's vectors into the Rust crates QNSQY ships. That is a real and necessary check, but it is worth being precise about what it shows: it is evidence that those libraries are correct. It says nothing about the code QNSQY wrote around them: the key wrapping, the parameter validation, the format binding, the API surface an attacker actually reaches. A vendor can pass every ACVP vector and still get its own integration wrong.

So we replay NIST vectors a second time, through QNSQY's own entry points instead of the crate's. In the 7.2.41 vector sweep (2026-09-24) the 22 own-code suites passed 231 tests with 0 failures, covering ML-KEM keygen/encap/decap, ML-DSA keygen/siggen/sigver (with and without context), SLH-DSA keygen/siggen/sigver across all twelve parameter sets, LMS sigver, X25519 keygen and shared-secret computation, pre-hash mode, key validation, and the hash and HMAC corpora. The Wycheproof ML-KEM and ML-DSA sets also run through the key-exchange and signing code of both QNSQY code bases. Most corpora drive the qnsqy_core library API, one of QNSQY's two code bases, rather than the shipped binary's own copy of that code; a dual-crate parity test, which passed in the same sweep, checks that the two stay in step. The hash corpus is driven through the compiled qnsqy CLI binary itself, which exercises argument parsing and chunked reads on top of the hasher.

Where deterministic replay requires fixing the randomness, seeded interfaces (generate_keypair_seeded, encapsulate_seeded, generate_signing_keypair_seeded, sign_data_seeded) exist for exactly this purpose and are compiled out of shipping builds; a dedicated test suite runs with default features and proves the gate holds, including that no shipping feature reaches the seeded code and that production key generation still draws from the system RNG. Verification-side suites (sigver, key validation) and X25519 public-key derivation consume no randomness and run through the ordinary public API.

Where a vector cannot be driven through our API we exclude it and record the reason in the corpus file rather than quietly dropping it. The exclusions fall into three families: bit-oriented hash inputs and outputs (messages or XOF output lengths that are not a whole number of bytes, which a byte-oriented API cannot express), LMS modes QNSQY does not ship (SHAKE variants and M24 parameter sets), and Curve448 (not implemented). NIST's signatureInterface=internal vectors are not excluded: they replay through the same gated, non-shipping entry points described above, and the corpus ledger cross-references them explicitly rather than double-counting them as excluded. Each exclusion is a documented design boundary, not a gap we are hiding.

One subset deserves a specific note, because it runs without any test-only feature flag at all: FIPS 204's deterministic ML-DSA variant fixes the per-signature randomness to zero, which is exactly what QNSQY's shipping sign_data and sign_data_with_context do, so those vectors replay straight through production code in a default build. Coverage that runs by default is worth more than coverage behind a flag no build sets.

Artifacts: the per-corpus vector counts and the full exclusion ledger of the v7.2.38 sweep are published at own-code-vectors-v7.2.38.txt (SHA-256). Artifacts published for the previous release (v7.2.20, sweep dated 2026-06-03) are retained verbatim under /validation-artifacts/archive/2026-06-13/ rather than overwritten, so any figure this page has ever quoted stays checkable.

4.6 Release verification (automated suites, CLI acceptance, application security)

Every release ships only after a verification sweep against the exact release build; for v7.2.38 that is build 868cc4e0, binary SHA-256 c7e22265953fbf87b3e110374e28fb7025701a82a4f10b6038c4ef306906f3dc, tested as the installed package, not from the build tree. Three layers, counted separately:

  • Automated suites: 2,038 tests across 62 suites, 0 failures. Of the 62 suites, 51 exercise QNSQY's own code, 4 replay official vectors against the upstream crates only (the ACVP and three Wycheproof harnesses), and 7 are self-contained consistency checks of constants and replicated logic. We publish the split rather than one blended number, for the same reason Section 4.5 exists. Two runs are excluded from the headline count, a duplicate library run and one suite invoked with the wrong feature flag; both exclusions lower the total, and the artifact states them so the arithmetic can be checked.
  • CLI acceptance: a 1,392-operation end-user run against the installed package, covering all 54 commands, all 66 subcommands, and all 115 long command-line flags with recorded exit codes and evidence per operation. Eight flag probes whose first invocations were malformed by the harness were re-run corrected and recorded additively; the two state-destroying commands (logout, reset-state) were exercised against an isolated profile so the live session was never at risk.
  • Application security (billing API): 24 test files, 701 passing tests, 8 marked todo. QNSQY's cryptography runs locally; the one networked service is the billing and account API, so it carries its own suite, including control-mapped files: OWASP ASVS 5.0.0 across six files and 288 tests (Level 1 core 95; L2/L3 authentication, session and authorization 48; configuration and cryptography 46; web and logging 46; formerly-open gaps now closed 39; N/A-condition guards 14), NIST SP 800-53 Rev 5 (31), NIST SP 800-63B (25), PCI-DSS v4.0 (21), HIPAA Security Rule technical safeguards (30), GDPR (7), SOC 2 Trust Services Criteria CC6/CC7 (32), and CNSA 2.0 / FIPS algorithm mapping (28). The 8 todo entries are known, tracked gaps stated in the suite itself rather than deleted. Scope: these cover the billing Worker; the payment processor has its own separate suite, not counted in these numbers.

Control-mapped tests are NOT compliance certification.

The ASVS, SP 800-53, SP 800-63B, PCI-DSS, HIPAA, GDPR, SOC 2 and CNSA suites are self-administered tests of our own code against published control descriptions. They are not audits, they were not performed by an assessor, and they confer no certification; QNSQY's certification status is exactly as stated in Section 5. They exist so the controls are continuously tested rather than asserted.

Artifacts: per-suite results, the exclusion arithmetic, and the billing-API summary are published at test-suites-v7.2.38.txt (SHA-256).

4.7 Formal verification (protocol proofs and Kani model checking)

Testing demonstrates correct behavior on the inputs exercised; symbolic and computational verification establish security properties over the entire input space under a defined attacker model. QNSQY's security-critical protocols were modeled in symbolic (ProVerif, Tamarin) and computational (CryptoVerif) provers under Dolev-Yao and game-based adversaries respectively. These are proofs about the protocol abstractions (hand-written models), not about the shipping Rust implementation; there is no automated model-to-code link. Six properties came back proven (no attack exists):

  • Your account key stays secret and a subscription token cannot be forged (billing channel). Proven
  • When you share a file with several people, an outsider with none of their keys learns nothing (multi-recipient). Proven
  • A malicious cloud-backup server cannot tamper with or swap your backup undetected. Proven
  • That same server cannot roll you back to an older backup to undo your changes (anti-rollback). Proven
  • In secure chat, past messages stay safe even if a long-term key is later stolen (forward secrecy). Proven
  • The encryption layer rejects forged ciphertext (AEAD integrity, proven computationally). Proven

Properties were verified with ProVerif 2.05 (4), Tamarin 1.12.0 (1), and CryptoVerif (1, integrity). Two properties remain open and are not claimed as proven: (1) Post-compromise security of the chat ratchet. A ProVerif model (ratchet_pcs.pv) does close a self-healing query, but only under an assumption that does not match the shipping protocol: it signs every new ratchet public key with the parties' long-term identity keys, whereas qs-chat (like Signal's Double Ratchet) leaves ratchet public keys unsigned and authenticates them through the symmetric key chain. Identity-key signing is strictly stronger than chain-key authentication, so that model proves an easier variant, not the deployed ratchet; the Tamarin model of the property did not converge. We therefore list PCS as open. (2) IND-CPA confidentiality of the symmetric cipher: the CryptoVerif secrecy query did not resolve, a known limitation of the symmetric-encryption model that hides content but not plaintext length (AEAD integrity, INT-CTXT, is proven). Both are tracked, and the runnable models, including the non-faithful PCS model, are published so the work can be checked and extended.

Reproducibility: the proof models and raw prover output are published as qnsqy-formal-proofs-v1.tar.gz (SHA-256), with the individual .pv / .spthy / .cv files and a README under /validation-artifacts/formal/. They contain only protocol abstractions and prover results; no QNSQY source, file-format internals, or findings are included.

Bounded model checking of the Rust code (Kani). The protocol proofs above are about hand-written models. Kani, a bounded model checker for Rust, works on Rust source instead: each harness states one property, such as no panic or overflow in size and offset arithmetic, a comparison that matches its reference, or an input check that accepts only the exact valid layout, and Kani proves it for every input within the bounds the harness sets. In the run of 2026-09-24 (Kani 0.67), 185 harnesses were verified: 120 in the product crate and 65 in the core crate. The five 64-bit multiply and divide proofs in each crate needed the kissat and z3 solvers. Some harnesses call QNSQY's own functions directly (checked arithmetic, chunk layout, constant-time comparison, Argon2 parameter parsing, tier parsing, and the LMS and ML-DSA input checks); others check self-contained models of tier, file-format, nonce, key-handling and memory-locking rules rather than the shipping functions. The first runs also exposed defects in some harnesses themselves (claims that were false or too loose, and loop bounds too small to finish), none in product code; those harnesses were corrected and re-verified.

Open, not claimed: one general chunk-ceiling proof (every chunk size the header accepts, present in both crates) ran three hours under each of z3 and kissat without a result. It is excluded from the default run and not counted above. A narrower version covering every power-of-two chunk size from 16 KiB to 64 MiB, which includes every chunk size the encryptor writes, is verified in both crates. The harnesses run against QNSQY's closed source and the raw Kani logs are not published, so this result rests on this summary, not on a third-party re-run.

4.8 Side-channel resistance (timing)

If a secret-dependent operation, such as comparing an authentication tag or a hash, exhibits secret-dependent execution time, an adversary measuring that time can recover the secret incrementally. The defense is constant-time code whose execution time is independent of the secret data. QNSQY's secret comparisons use the audited subtle crate, and we measured the running binary with dudect, a statistical timing-leak detector. All four constant-time functions (compare, compare-fixed, is-zero, select) showed no detectable timing leak (max |t|-statistic 1.5–2.3, well under the conventional dudect leak threshold of ~10). This was measured on a shared developer machine; a formal sign-off would re-run it on dedicated hardware with CPU frequency scaling disabled, which is the standard final step. The raw bench log is published at dudect-sidechannel.log.

4.9 Memory safety

The single biggest source of security vulnerabilities across the industry (roughly 70% of CVEs at major vendors) is memory-corruption bugs: buffer overflows, use-after-free, and similar. The most effective defense is a memory-safe language. QNSQY is written in Rust, which makes that entire class impossible in normal ("safe") code. The places that must use low-level unsafe blocks (for the OS sandbox and the C cryptography libraries) were audited one by one: all 189 blocks. The Rust undefined-behavior checker (miri) ran cleanly over the pure-Rust safe-math / overflow-protection module (11 tests; the 291 tests that call into C cryptography are outside miri's reach and were not covered). To cover what miri cannot reach, an AddressSanitizer build exercised the real cryptographic FFI: 13,248 NIST ACVP vectors across 32 algorithm modules (ML-KEM, ML-DSA, SLH-DSA, AES-GCM, EdDSA, SHA-2/3) executed with zero AddressSanitizer errors and zero failures (the run was time-capped before the remaining modules).

The unsafe-block audit identified low-level soundness/UB defects, 10 higher-risk and 26 medium-risk items, including an aliasing-UB pattern in the ML-KEM shared-secret zeroization, a 128-byte over-read extent in the binary-integrity self-check, and a repr(transparent)-assumption issue in the (not-yet-enabled) HSM path. None has been demonstrated as a working memory-corruption exploit on the shipping Linux build, and the more serious out-of-bounds cases are confined to the HSM feature that is not yet enabled. As of 2026-06-15 the priority shipping-path items are remediated and compile-verified (the ML-KEM aliasing-UB and the integrity read-extent), the HSM forward handle conversion was rewritten to remove the repr assumption, and the remaining items (HSM reverse conversion, blocked by an upstream PKCS#11 API gap; error-path cleanup; a Windows protect-size case) stay tracked. This is not a claim of verified soundness across all unsafe blocks. A sanitized summary (severity counts, categories, and remediation status; exact locations and proof-of-concept inputs withheld) is published at memory-safety-summary.txt.

4.10 Static analysis & supply chain

Two more automated streams run continuously. Static analysis (Semgrep, with the Rust, TypeScript, secrets, and OWASP rule packs) scans the source for risky patterns; the latest run reported zero high- or critical-severity issues (292 informational results, the bulk being an inventory of the audited unsafe blocks); the severity summary is published at semgrep-summary.txt. CodeQL (GitHub's semantic code analyzer, security-and-quality query pack) was additionally run over the billing-API TypeScript (94 files): 0 error- and 0 warning-severity results, with 22 note-level (the lowest tier) advisories, namely ReDoS-class input-validation regexes (bounded by Cloudflare Workers' CPU and request-size limits) and three intentional SIEM audit-log lines; the summary is published at codeql-billing-api-summary.txt. The supply-chain and secret scanning runs on every build; the complete results are reported below:

  • Dependencies (cargo-audit / cargo-deny): 0 exploitable CVEs, but the advisory gate currently fails non-zero on 8 unmaintained + 2 unsound transitive crates, notably the archived-upstream pqcrypto-* bindings. Separately, the build still depends on pre-1.0 release-candidate ml-dsa / slh-dsa crates (no advisory against them, but not yet at a stable release). The full advisory list is published at dependency-advisories.txt.
  • npm dev-toolchain: npm audit reports 1 critical + 3 high advisories in build-time tooling (esbuild / vite / wrangler / undici) with no upstream fix. These are dev-only and not part of the shipped Rust binary; the shipped Rust binary and its scoped optionalDependency wrapper carry no affected runtime dependencies.
  • Secret scanning (gitleaks): runs automatically on every build of the source tree. By design the client holds no server-side secrets: every cryptographic operation runs locally, and the only key material the binary embeds is the public release-verification key.
  • SBOM: every release since 7.2.41 ships a CycloneDX software bill of materials listing each Rust crate in its dependency lock file, with versions and, for crates.io crates, SHA-256 hashes, covered by the signed release checksums. See Software Bill of Materials on the download page.

5. Limitations and What This Does Not Prove

The following items bound the scope of the evidence presented above.

QNSQY is NOT FIPS 140-3 / CMVP certified.

FIPS 140-3 validation requires NIST's Cryptographic Module Validation Program (CMVP). A NIST-accredited Cryptographic and Security Testing Lab (CSTL) writes a Security Policy, runs operational tests on the cryptographic boundary, and submits the module to NIST for review. CMVP typically takes 6 to 18 months and costs tens of thousands of dollars; there is no shortcut. The ACVP vector replay on this page is the algorithm-correctness piece a CMVP lab would consult and is not a substitute for that process. CMVP is on the QNSQY roadmap; no application has been submitted to NIST as of this date. QNSQY is not on the CMVP Validated Modules list.

QNSQY does not hold SOC 2, ISO 27001, or HITRUST.

These are organizational/operational compliance frameworks, separate from cryptographic algorithm validation. We do not claim them and have not pursued them as of 2026-08-05. SOC 2 is therefore an absent control as of this date; no audit is in progress. The self-administered control-mapped test suites in Section 4.6 do not change this status.

30 ACVP vectors are a real coverage gap, not a scope decision.

In the 7.2.41 run the only skips that are not scope decisions are 30 AES-GCM vectors with tags shorter than 96 bits: aes-gcm 0.10 enforces the SP 800-38D §5.2.1.2 minimum at the type level, so a conforming API cannot exercise them (QNSQY itself uses 128-bit tags). A CMVP reviewer would treat them as open items, not as scope. The earlier sweep (ACVP-Server v1.1.0.42) listed 135 such gaps; the other 105 now run and pass: the 60 ML-KEM encapsulation-key and decapsulation-key checks, through a FIPS 203 §7.2/§7.3 key check outside the ml-kem crate, which has none, and the 45 ML-DSA externalMu and randomized vectors, on ml-dsa 0.1.1.

No independent third-party audit yet.

The internal multi-agent audit cadence is internal and does not substitute for an independent firm. Engaging an external auditor is on the roadmap. When it lands, the audit summary will be published here.

Test vector correctness does not prove deployment correctness.

ACVP confirms the cryptographic primitives produce NIST's expected outputs. It does not prove the surrounding orchestration (key handling, file format, billing, MCP, GUI) is bug-free. The audit history at Section 4.4 covers that surface; the limitation is that it is internal.

Kani model checking is bounded and per property, not a proof of the whole program.

Each of the 185 verified Kani harnesses (Section 4.7) proves one stated property, for the function or model it covers, and only for inputs within the bounds it sets. Code outside those harnesses, inputs beyond the bounds, and properties nobody wrote down are not covered. Some harnesses check self-contained models rather than the shipping functions, and one general chunk-ceiling proof remains unproven and is not claimed.

6. References

NIST standards QNSQY implements

IETF specifications

Source links

QNSQY's product source is proprietary and not shared. The artifacts above (NIST vectors + standalone harness + raw log + summaries + report) let any auditor verify the algorithm-correctness claims without access to QNSQY's repository.

7. Contact

For security issues, vulnerability reports, or questions about the validation methodology:

GPG key for security correspondence: see /.well-known/security.txt. We aim to acknowledge security reports within 72 hours.

Independent reproduction

Measured first run: 9 minutes 26 seconds on an 8-core laptop processor, with an empty Cargo cache and a fresh clone of NIST's vectors; fewer cores or a slower network take longer. Five steps: download, fetch the vectors, build, run, count. The harness is self-contained, the NIST vector tree is public, and every crate version is pinned by the bundled Cargo.lock.