Skip to content
Independent auditUnclaimed

QuantaCipher — post-quantum security review

xaexaex/quantacipher· QuantaChain / QuantaLabs

Application · Rust

Verdict

Sound fundamentals — accuracy and compliance fixes required

The cryptographic fundamentals are sound and we found no data-exposure path. The material issues are accuracy and compliance, not a break: QuantaCipher ships a pre-standard Kyber variant while advertising a different, standardised one, and several operational and supply-chain claims do not hold up. A single dependency migration resolves both the compliance gap and the one outstanding advisory.

The fix that matters most

Migrate the KEM from pqc_kyber to the maintained ml-kem crate, at the 1024 parameter set

This single change makes the FIPS 203 ML-KEM claim true, closes the Kyber-768-versus-1024 discrepancy, and removes the unmaintained dependency carrying the KyberSlash advisory. Three of the findings below collapse into one migration. It has since been made: quantacipher-core 0.3.5 depends on ml-kem and the published WASM measures ML-KEM-1024.

What it gets right

Stated first, because it is the larger part of the picture and because a review that lists only defects is a distorted account of the thing it reviewed.

  • Correct CSPRNG throughout

    KEM keygen and encapsulation use OsRng, nonces use the AEAD's OsRng, and in WASM that is Web Crypto getRandomValues. No weak randomness anywhere.

  • Sound KEM/DEM construction

    AES-256-GCM authenticated encryption, a fresh 96-bit random nonce per operation, and a fresh KEM shared secret per message, so key and nonce reuse are structurally impossible.

  • The local-only claim substantially holds

    The WASM engine has no network capability. Plaintext and private keys are never transmitted; only ciphertext leaves the runtime, plus the metadata noted in the findings.

  • Careful input validation

    Exact length checks on keys, ciphertext and nonce, and strict base64. The Python wheel even ships a CycloneDX SBOM, which is above average.

https://quantakrypto.com/audits/xaexaex/quantacipher

Request an audit

Maintain an open source cryptography project? Tell us where it lives and we will take a look.

GitHub repository
Your email

We review open source projects free of charge, report findings to maintainers privately first, and publish only with the fix alongside.

quantakrypto
Independent post-quantum audit
Public review · Open findings
https://quantakrypto.com/audits/xaexaex/quantacipher

Independent review · xaexaex/quantacipher

QuantaCipher — post-quantum security review

QuantaChain / QuantaLabs · Application · Rust · 6 findings

The short version

Sound fundamentals — accuracy and compliance fixes required

The cryptographic fundamentals are sound and we found no data-exposure path. The material issues are accuracy and compliance, not a break: QuantaCipher ships a pre-standard Kyber variant while advertising a different, standardised one, and several operational and supply-chain claims do not hold up. A single dependency migration resolves both the compliance gap and the one outstanding advisory.

What it gets right

Correct CSPRNG throughout

KEM keygen and encapsulation use OsRng, nonces use the AEAD's OsRng, and in WASM that is Web Crypto getRandomValues. No weak randomness anywhere.

Sound KEM/DEM construction

AES-256-GCM authenticated encryption, a fresh 96-bit random nonce per operation, and a fresh KEM shared secret per message, so key and nonce reuse are structurally impossible.

The local-only claim substantially holds

The WASM engine has no network capability. Plaintext and private keys are never transmitted; only ciphertext leaves the runtime, plus the metadata noted in the findings.

Careful input validation

Exact length checks on keys, ciphertext and nonce, and strict base64. The Python wheel even ships a CycloneDX SBOM, which is above average.

The fix that matters most

Migrate the KEM from pqc_kyber to the maintained ml-kem crate, at the 1024 parameter set

This single change makes the FIPS 203 ML-KEM claim true, closes the Kyber-768-versus-1024 discrepancy, and removes the unmaintained dependency carrying the KyberSlash advisory. Three of the findings below collapse into one migration. It has since been made: quantacipher-core 0.3.5 depends on ml-kem and the published WASM measures ML-KEM-1024.

Findings

F1 · Advertised algorithm does not match the shipped one

MediumAccuracy / ComplianceFixed

QuantaCipher advertises "NIST ML-KEM / FIPS 203 / Kyber-1024", but the shipped key sizes measure public key 1184 / secret key 2400 / ciphertext 1088 bytes — those are Kyber-768, and a pre-standard round-3 variant at that. It therefore fails FIPS 203 and will not interoperate with a real ML-KEM implementation. This is a correctness and compliance defect, not a data-exposure risk: the exchange itself is not broken.

Evidence, measured rather than inferred

Runtime execution of the published quantacipher-wasm 0.3.0 returned key sizes that are an exact Kyber-768 match, contradicting the product's own documented sizes. Root cause: pqc_kyber 0.7.1 with no kyber1024 feature, so KYBER_K defaults to 3. Separately, pqc_kyber 0.7.1 implements round-3 CRYSTALS-Kyber, last released in 2023, which is not FIPS 203 ML-KEM and is neither KAT- nor wire-compatible with it.

actual  pk=1184  sk=2400  ct=1088   -> Kyber-768
docs    pk=1568  sk=3168  ct=1568   -> Kyber-1024 (claimed)

Impact

Two true statements at once: the delivered security level is NIST Level 3, not the Level 5 advertised, and the algorithm is pre-standard Kyber rather than ML-KEM. For buyers who need FIPS 203 or CNSA 2.0 compliance, or interoperability with a real ML-KEM implementation, the product did not meet its claim. Data-exposure risk: none, Kyber-768 is unbroken.

Fix

Either advertise the parameter set actually shipped, or move to a standardised ML-KEM implementation (see the single recommended fix below). Re-measured on the published quantacipher-wasm 0.4.4: public key 1568 / secret key 3168 bytes, which are the FIPS 203 ML-KEM-1024 sizes, and the build identifies itself as 3.0.0-dual-mode-mlkem-fips203. The shipped parameter set now matches the advertised one.

Release: quantacipher-wasm 0.4.4: https://www.npmjs.com/package/quantacipher-wasm/v/0.4.4
Release: quantacipher-core 0.3.5: https://crates.io/crates/quantacipher-core/0.3.5

F2 · Unmaintained pqc_kyber crate carries the KyberSlash advisory

MediumSecurity hygieneFixed

The dependency pqc_kyber is unmaintained and is subject to KyberSlash (RUSTSEC-2023-0079, CVSS 7.4) with no fix available. Practical exploitability is low in QuantaCipher's local-only usage model — the timing side-channel needs an adversary positioned to measure decapsulation — but shipping an unmaintained crate with an open advisory is not acceptable for a security product.

Evidence, measured rather than inferred

cargo audit against the published dependency graph flagged RUSTSEC-2023-0079 in pqc_kyber 0.7.1. The crate's last release was in 2023 and no fixed version exists.

Impact

KyberSlash is a timing side channel in the key-recovery class, CVSS 7.4. Exploitability in a local-only usage model is low, since an attacker needs to be positioned to measure decapsulation. Shipping an unmaintained crate with an open advisory and no upgrade path is still not acceptable in a security product.

Fix

Migrate off pqc_kyber to a maintained implementation (see the single recommended fix below).

Release: quantacipher-core 0.3.5: https://crates.io/crates/quantacipher-core/0.3.5
Dependency manifest: https://crates.io/api/v1/crates/quantacipher-core/0.3.5/dependencies

F3 · Source provenance is unverifiable

MediumSupply-chainOpen

The declared source repository github.com/xaexaex/quantacipher returns 404, there is no build provenance for the published artifacts, and the package pulls a wildcard-versioned quantacipher-wasm dependency. A consumer cannot reproduce the build or pin a reviewed version.

Evidence, measured rather than inferred

The repository declared in package metadata, github.com/xaexaex/quantacipher, returned 404 across every published channel. No build provenance or signed attestation accompanies the npm, PyPI or crates.io releases.

Impact

Nobody outside the vendor can rebuild the artifacts and confirm they correspond to any source. For a product whose value proposition is that you do not have to trust the network, being unable to verify what you installed is the weakest link. The full source already ships in the PyPI sdist, so publishing the repository would close this at little cost.

Fix

Publish the source, pin exact dependency versions, and attach build provenance (e.g. SLSA / signed releases).

F4 · Gateway metadata sent unencrypted, contradicting the zero-trust claim

MediumClaim accuracyOpen

QuantaCipher markets a zero-trust posture, but gateway metadata is transmitted unencrypted. The claim and the observed behaviour disagree; the metadata channel is not protected to the standard the product advertises.

Evidence, measured rather than inferred

The gateway call posts ciphertext and metadata as sibling fields in the same JSON body. The vendor's own HIPAA example passes userId and record type in that metadata.

Impact

The zero-trust claim is that the operator learns nothing. Whoever runs the gateway learns who is talking, about what kind of record, and when. The payload is protected and the pattern of use is not, and for the health-record example given in the docs the pattern is often the sensitive part.

Fix

Encrypt the metadata channel end-to-end, or scope the zero-trust claim to what is actually protected.

F5 · Runtime returns a hardcoded algorithm label

LowAccuracyFixed

generate_keypair() returns a hardcoded algorithm: "Kyber-1024" string regardless of the parameters actually in use, so callers and telemetry are told the wrong algorithm at runtime. This compounds the advertised-vs-shipped mismatch above.

Evidence, measured rather than inferred

generate_keypair() returned a constant algorithm string in both the WASM build and the Python shared object, independent of the parameters actually compiled in.

Impact

Downstream policy engines, CBOM generators and attestation tooling record whatever the runtime tells them. A constant string means those records are wrong wherever the constant is wrong, and they are trusted precisely because they came from the runtime rather than from documentation.

Fix

Derive the reported algorithm from the implementation in use rather than a constant. generate_keypair() on 0.4.4 returns algorithm "ML-KEM-1024", which agrees with the measured key sizes. The label is no longer contradicted by the artifact.

Release: quantacipher-wasm 0.4.4: https://www.npmjs.com/package/quantacipher-wasm/v/0.4.4

F6 · Default endpoints do not resolve

LowOperationalFixed

The default gateway host api.quantacipher.com returns NXDOMAIN, and the Python SDK defaults to http://localhost. Out of the box the client points at endpoints that do not exist, so any default-configured deployment fails or silently talks to the wrong host.

Evidence, measured rather than inferred

The TypeScript SDK's default gateway, api.quantacipher.com, did not resolve in DNS. The Python SDK defaulted to http://localhost.

Impact

A deployment issue rather than a cryptographic one, but it blocks independent verification of the upstream path and means the documented default configuration does not work as shipped.

Fix

Ship working defaults, or fail closed with a clear configuration error when no endpoint is set. quantacipher-sdk 1.4.3 defaults to https://quantacipher.com/api/v1/ingest, which resolves, and rejects any non-HTTPS gateway except localhost. The dead api.quantacipher.com default is gone.

Release: quantacipher-sdk 1.4.3: https://www.npmjs.com/package/quantacipher-sdk/v/1.4.3

F7 · One migration resolves the compliance gap and the advisory together

InfoRecommended fixAdvisory

Migrating from pqc_kyber to the maintained ml-kem crate resolves both major threads at once: it moves QuantaCipher onto a standardised, FIPS 203-aligned ML-KEM implementation (closing the advertised-vs-shipped compliance gap) and off the unmaintained crate carrying the KyberSlash advisory. This is the single highest-leverage change.

Impact

Three findings, one migration. Worth reading as a single piece of work rather than a backlog.

Fix

Adopt the ml-kem crate for key encapsulation and re-run the parameter and interoperability checks.

Release: quantacipher-core 0.3.5: https://crates.io/crates/quantacipher-core/0.3.5

Automated scan (qScan v0.7.0)

PackageFiles scannedFindings
quantacipher-sdk3 (5 with minified)0
quantacipher-wasm60
quantacipher-core70
quantacipher (PyPI)160

Read this correctly. qScan detects classical, quantum-vulnerable cryptography: RSA, ECDH, ECDSA, legacy TLS. A post-quantum library correctly shows none, which is the expected result and not a clean bill of health for everything else. The findings in this review come from measurement, from dependency advisories, and from comparing claims against artifacts, all of which are complementary to what qScan does.

Merged upstream

  • Release: quantacipher-wasm 0.4.4: https://www.npmjs.com/package/quantacipher-wasm/v/0.4.4
  • Release: quantacipher-core 0.3.5: https://crates.io/crates/quantacipher-core/0.3.5
  • Dependency manifest: https://crates.io/api/v1/crates/quantacipher-core/0.3.5/dependencies
  • Release: quantacipher-sdk 1.4.3: https://www.npmjs.com/package/quantacipher-sdk/v/1.4.3

Scope & method

Artifacts reviewed

Method

Package checksums verified against registry metadata. qScan v0.7.0 on each package. Runtime execution of the published WASM to measure real key and ciphertext sizes. cargo audit and cargo tree across the dependency graph. Source read of the Rust core and the bindings. DNS and HTTP checks on the gateway and the repository. Two independent reviewers.

A point-in-time review of published artifacts. It does not cover the closed-source gateway service, the platform back end, or anything not shipped in the four packages above. Shared privately first, under a fix-first disclosure arrangement.

Reviewers

  • Krzysztof Cywiński
  • León Acosta
quantakrypto.com · [email protected]Independent audit · xaexaex/quantacipher