Read this first
Three reviews are now listed at quantakrypto.com/audits. noble-post-quantum, a widely used pure-JavaScript implementation of all three standards: six findings, all fixed by the maintainer, one still waiting on a release. The Dart NDK: five findings, the most serious of them a GPL-3.0-only crate linked into an MIT SDK, all fixed and merged. QuantaCipher, an encryption product: four of six defects fixed, two still open. Every finding marked fixed links to the pull request, commit or published release that closed it, because a security claim nobody can check is not worth publishing.
An audit page is easy to write and hard to trust. Anyone can publish a list of things they say they found, grade the project, and add a badge. The reader has no way to tell a careful review from a marketing exercise, and by the time the findings are fixed the page usually still says what it said on the day it went up.
So we built the three pages around one rule: nothing may be described as fixed unless it links to the thing that fixed it. Not a note saying the maintainer confirmed it. A merged pull request, a commit, or a published artifact a reader can fetch. It is enforced by a test that reads the published data and fails the build if any finding claims a remediation it cannot cite, and a finding whose status nobody has recorded reads as open rather than resolved.
noble-post-quantum: six findings, five of them shipped
@noble/post-quantum implements ML-KEM, ML-DSA and SLH-DSA in pure JavaScript and is one of the most widely used post-quantum implementations in the ecosystem. The primitives held up: no key recovery, no forgery, no plaintext disclosure.
The most serious finding is not a break, it is an availability bug. Falcon's sampler mutated two of its arguments in place, and at the top sampling level those arguments are the sampler's own persistent state, so after the first rejection they held the wrong values and signing could loop forever. The code already copied a third argument defensively, with a comment explaining exactly why. The other two had no such protection.
- A hybrid decapsulation path left expanded child secret keys in memory when a child KEM threw, reachable from an attacker-supplied ciphertext.
- K-PKE decryption wiped three buffers but not the polynomial holding the decrypted message, one threshold away from the plaintext.
- An SLH-DSA conformance test used `return` where its two ML-DSA siblings use `continue`, so the first vector below the security level ended the entire suite while it still reported success.
- Two documentation defects, including a README promising a non-aliased copy from an API whose own source comment says it returns a view into the caller's buffer.
All six were fixed by the maintainer, four in a pull request merged within two hours of the report and two more the same day. The page does not say resolved, because the Falcon fix is on main and npm still serves 0.7.0. It says fixed, awaiting release, which is a different fact and the one a reader installing the package today actually needs.
The Dart NDK: a licence problem, not a cryptography problem
The most serious finding in relaystr/ndk has nothing to do with cryptography. The SDK ships under MIT and depended on a GPL-3.0-only crate, compiled unconditionally into every dependent application whether or not that application touched post-quantum code at all. Statically linking GPL-3.0-only code makes the combined binary a derivative work, which obliges every downstream application to distribute under GPL-3.0.
Alongside it, the quantum-secure signer implemented the pre-standard round-3 CRYSTALS submission rather than FIPS 204. NIST changed the algorithm during standardisation, so the keys and signatures it produced could not be verified by any standards-compliant implementation. Two memory-safety defects in the Rust FFI and one key-recoverability gap turned up in the same code.
All five are fixed and merged upstream, in pull request 712 and the hybrid encryption work stacked on it.
QuantaCipher: what a partly remediated audit looks like
The third review is the interesting one to publish, because it is not finished. QuantaCipher advertised NIST ML-KEM and FIPS 203 while shipping a pre-standard round-3 Kyber variant at the wrong parameter set, and its runtime reported an algorithm string that did not match what it was doing. It also depended on an unmaintained crate carrying an unfixed timing advisory.
Since then they migrated. We did not take that on report: we measured it. The published WASM build now returns a public key of 1568 bytes and a secret key of 3168 bytes, which are the FIPS 203 ML-KEM-1024 sizes, and reports an algorithm string that agrees with them. The core's dependency manifest no longer carries the unmaintained crate. The SDK's default gateway resolves and now refuses plain HTTP outside localhost.
Two findings stay open, and they stay open for the same reason the others closed: we can check one and not the other. The source repository is still not public, so build provenance remains unverifiable, and metadata is still posted alongside the ciphertext in the clear. The page says four of six, with links on the four.
Why publish the merge rather than the verdict
Every one of these reviews was sent to the maintainer privately first, and every page went up after they had a chance to act. That is ordinary disclosure practice. The part worth arguing for is what happens next.
A grade ages badly. A link does not. If we say a zeroization gap was closed and point at the commit, a reader can open the diff and decide for themselves whether it was, this year or in five years, with or without us. It also means the honest answer to a partly fixed audit is available: we can say four of six and show which four, instead of choosing between an unfair red and a premature green.
The pages carry the kind of code reviewed, the language, the current status of every finding, and the people who signed the review. If you maintain something in this space and want a second set of eyes on it, talk to us.