Only the latest minor release line receives security fixes. Older lines are not patched.
Please report security vulnerabilities to security@theqrl.org.
Do not open public issues for security vulnerabilities. We follow coordinated disclosure: please give us reasonable time to investigate and ship a fix before any public disclosure.
@theqrl/qrl-cryptography is a thin TypeScript layer over audited primitives. The supplied modules are:
| Module | Primitive | Underlying implementation |
|---|---|---|
keccak |
Keccak-256, SHA-3, SHAKE | @noble/hashes |
argon2id |
Argon2id KDF | @noble/hashes |
random |
CSPRNG | @noble/hashes/crypto |
aes |
AES-256-GCM | WebCrypto / Node crypto |
ml_dsa87 |
ML-DSA-87 (FIPS 204) | @theqrl/mldsa87 |
Bugs in the underlying implementations should be reported upstream; this policy covers the wrapper code, parameter handling, encoding, and packaging.
- The IV (12 bytes) must be unique per (key, plaintext) pair. Reusing an IV with the same key destroys confidentiality and authenticity.
- Callers must source IVs from a CSPRNG (e.g.
random.getRandomBytes). The library does not generate them for you. - AES-GCM has a hard limit of ~2³² messages per key before nonce-collision probability becomes non-negligible — rotate keys for high-volume use.
- Defaults must be tuned for the target environment. The library accepts caller-supplied
t(iterations),m(memory),p(parallelism), and salt; weak parameters produce weak hashes. - Salts must be ≥16 bytes and unique per password; reusing salts undermines the KDF.
- Backed by WebCrypto in browsers and Node's
cryptoin Node. In environments where neither is available, calls will throw — the library does not silently fall back to a weaker PRNG.
- These are unkeyed hashes, not MACs. Do not use them for authentication without HMAC or a keyed construction.
- Post-quantum digital signature scheme (FIPS 204), NIST Level 5.
- Public key 2,592 bytes, secret key 4,896 bytes, signature 4,627 bytes.
- Secret-key material must be kept in protected memory. The library does not zeroize buffers — callers handling long-lived keys should manage that themselves.
- Signing is deterministic by default; if callers expose hedged signing, the entropy source must be a CSPRNG.
- ML-DSA-87 is implemented in
@theqrl/mldsa87; constant-time guarantees are inherited from that package. - AES-256-GCM is delegated to WebCrypto/Node
crypto, which use platform-provided constant-time implementations on supported hardware (AES-NI / ARMv8 Crypto Extensions). On platforms lacking hardware AES, software fallbacks may not be constant-time. - The wrapper code in this package contains no secret-dependent branches or table lookups, but auditors should verify before deploying in side-channel-sensitive environments.
Each release ships:
- npm provenance (
npm publish --provenance) attesting the GitHub Actions build - SBOMs in SPDX and CycloneDX format, attached to the GitHub release
- SHA-256 / SHA-512 checksums of
package.json,package-lock.json, and source files - GitHub build provenance attestations (
actions/attest-build-provenance) for checksums and SBOMs - SLSA Level 3 provenance (
slsa-framework/slsa-github-generator) attached to the release asprovenance.intoto.jsonl
To verify a release, see the artefacts on the corresponding GitHub release page and use gh attestation verify or slsa-verifier.
- Report received → acknowledgement within 72 hours
- Triage and reproduction → within 7 days
- Fix developed and reviewed → typically within 30 days for high/critical
- Coordinated release with reporter
- Public advisory via GitHub Security Advisories