Skip to main content

q-armor-pqc

ML-DSA-65 (FIPS 204) for QArmor, and an interim package by design: it exists to be deleted.

PyPI Python Licence FIPS 204

A cryptographic primitive with two implementations has two behaviours, and you find out which one you were running during the incident. This package exists so that QArmor has exactly one, until the place it belongs can hold it.

iden-q-post-quantum is the L2 generator's emission (iqcgen) and the only place in the estate where a cryptographic primitive has one source and one KAT gate. It carries ML-KEM-768 and ML-DSA-44, in Python and in TypeScript. The DVN's on-chain attestations sign with ML-DSA-65 (SAD §6.4.2), and no language emits that primitive. Per ADR-22 it is a spec missing from the generator (SAD D-7), not a second library, and the generator is private. While that gate stays closed, this package is where ML-DSA-65 lives.

When the emission publishes ML-DSA-65, this package is deleted. It is not versioned in parallel, not migrated, not maintained: q_armor_lib and q_armor_chain change the import to the emission and packages/q-armor-pqc/ disappears from the workspace. It is published to PyPI only because q-armor-lib pins it, and a published library cannot depend on an editable.

Install

pip install q-armor-pqc            # ML-DSA-65 with a development Ed25519 fallback
pip install 'q-armor-pqc[pqc]'     # + liboqs-python: real ML-DSA-65

Read this before you deploy it. QARMOR_REQUIRE_PQC=1 demands liboqs and fails if it is absent. Without that variable, ML-DSA-65 falls back to Ed25519, which is classical, and says so with a RuntimeWarning at import. It is the only live exception to "NIST algorithms only" (CLAUDE.md), and it is stated rather than hidden. The KEM has no fallback.

What is here, and what is delegated

  • MLDSA65: liboqs, or Ed25519 in development. The only thing that justifies the package.
  • MLKEM768: delegates to the emission. ML-KEM-768 has not been implemented here since 2026-08-23: a second implementation over liboqs meant the same primitive on two backends, one inside the KAT gate and one outside (ADR-13, the SAD's S-6 scenario). The wrapper stays because encapsulate never returned the raw secret but HKDF-SHA3-256(ss), while the emission derives with HKDF-SHA256: changing the import alone would have changed the AES key, a cryptographic change dressed up as a refactor. The emission's keygen is deterministic from a seed, and the seed comes from secrets.
  • aead_encrypt / aead_decrypt: AES-256-GCM from cryptography.

The KEM's X25519 fallback is gone, and that went with the delegation: the emission is pure Python and a hard dependency, so the "liboqs is absent" case no longer exists for the KEM.

About the name

In this estate "crypto" means blockchain, not cryptography: quantum-armor-crypto is the DVN (SAD §4.2, §6.4, ADR-18). And q-crypto-* is the prefix of the L2 generator (q-crypto-gen) and of what it emits. This distribution's previous name, q-crypto-py, broke both rules and was also the one the SAD used for the Python emission; the directory packages/q-armor-crypto/ inverted ADR-18 in the tree itself. Both were renamed on 2026-09-02, before the first publication, so that name would never reach an index. pqc is what it contains; armor, who it belongs to.

A dependency on a private module, said out loud

pqc_engine imports iden_q_post_quantum._runtime, not the emission's public API. Checked against iden-q-post-quantum 1.2.0: what is public is seal/unseal (a hybrid X25519 and ML-KEM-768 envelope), encrypt/decrypt by passphrase, derive_recipient_keys and the ML-DSA-44 signature. There is no public raw KEM: mlkem768_keygen, encapsulate and decapsulate live only in _runtime. QArmor's session needs the raw KEM to derive its own key, so this dependency contradicts "consumers depend on published outputs" (ADR-22) and is recorded as what it is: a gap in the generator with the same shape as D-7, a missing public KEM API spec, to be closed upstream rather than wrapped here.

Tests

tests/ carries the package's own suite: that the KEM's AES key is HKDF-SHA3-256 of the emission's secret (and not the raw secret, nor HKDF-SHA256), that encapsulate and decapsulate converge, that a signature verifies only its own message, and that AES-GCM rejects a tampered tag.

What is still open is an ML-DSA-65 KAT against the FIPS 204 vectors: with QARMOR_REQUIRE_PQC undefined the signature runs over Ed25519, and a test that has only passed there has not seen ML-DSA-65. It is exercised as well from q-armor-lib's session and proofs tests, from the DVN worker's, and from api/.

The QArmor family

Five packages, one version, published together from a single tag.

Package What it is
q-armor-lib Detection, scoring and the control-plane client
q-armor-cli q-armor, the operator's command line
q-armor-proxy Enterprise runtime: protection proxy, firewall, SIEM webhook
q-armor-chain DVN worker and QArmorDVN.sol
q-armor-pqc This one, and it is interim

Next

idenq.io

Metadata

Release files for q-armor-pqc 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for q-armor-pqc 0.3.0
File Interpreter ABI Platform
q_armor_pqc-0.3.0-cp313-none-any.whl CPython 3.13 none any Details
q_armor_pqc-0.3.0-cp312-none-any.whl CPython 3.12 none any Details
q_armor_pqc-0.3.0-cp311-none-any.whl CPython 3.11 none any Details

Total release size: 34.0 kB

Release files / q_armor_pqc-0.3.0-cp313-none-any.whl

Download URL q_armor_pqc-0.3.0-cp313-none-any.whl
Size 11.3 kB
Tags CPython 3.13
SHA-256 checksum
How to use checksums
87b91dd4053cb87f82a6b0ab76743952090dbd488583f0aea585ab21311f5536
BLAKE2b-256 checksum
How to use checksums
0dd4362981da2cfd7d8060969ec0a22e8c1bb468b4e37eeb5d26dd6d2d9a454c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release files / q_armor_pqc-0.3.0-cp312-none-any.whl

Download URL q_armor_pqc-0.3.0-cp312-none-any.whl
Size 11.3 kB
Tags CPython 3.12
SHA-256 checksum
How to use checksums
b43c2328e51ed3eabd0cc90d9d767548215a2bed0598967d948967628bfd81f2
BLAKE2b-256 checksum
How to use checksums
bc4a04ae381f200591f29133ea06338c11f52470154d676dcde580fd62a3e21f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release files / q_armor_pqc-0.3.0-cp311-none-any.whl

Download URL q_armor_pqc-0.3.0-cp311-none-any.whl
Size 11.4 kB
Tags CPython 3.11
SHA-256 checksum
How to use checksums
5c31cbf71ce6c19918eab7288e00bca350020e9f106e55bcbc0ee25d4d29aa21
BLAKE2b-256 checksum
How to use checksums
806e1d1829aedee369359a3910b8cd18c9d0d98c290b1919153607e178f98ba0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.1

3 release files

This release

0.3.0 This release

3 release files

0.2.0

3 release files

0.1.2

3 release files

0.1.1

3 release files

0.1.0

3 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page