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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

q_armor_pqc-0.1.1-cp313-none-any.whl (11.3 kB view details)

Uploaded CPython 3.13

q_armor_pqc-0.1.1-cp312-none-any.whl (11.2 kB view details)

Uploaded CPython 3.12

q_armor_pqc-0.1.1-cp311-none-any.whl (11.4 kB view details)

Uploaded CPython 3.11

File details

Details for the file q_armor_pqc-0.1.1-cp313-none-any.whl.

File metadata

  • Download URL: q_armor_pqc-0.1.1-cp313-none-any.whl
  • Upload date:
  • Size: 11.3 kB
  • Tags: CPython 3.13
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for q_armor_pqc-0.1.1-cp313-none-any.whl
Algorithm Hash digest
SHA256 e9a29468488e034177b17f6274c2bf4616b3acc5a0474b00d181dc32b8e896eb
MD5 4137c5e1554208b20dab88e44d3da664
BLAKE2b-256 9e0eb3317287f1f97b65025ab124eed2695317db0b73ee5763e3ee9822ff5b3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for q_armor_pqc-0.1.1-cp313-none-any.whl:

Publisher: release.yml on iden-q/iden-q-quantum-armor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file q_armor_pqc-0.1.1-cp312-none-any.whl.

File metadata

  • Download URL: q_armor_pqc-0.1.1-cp312-none-any.whl
  • Upload date:
  • Size: 11.2 kB
  • Tags: CPython 3.12
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for q_armor_pqc-0.1.1-cp312-none-any.whl
Algorithm Hash digest
SHA256 e1fbeb25cac3027873a050767ac9000965f58f06e4dea0e6f437701e5e2d7d1f
MD5 565c12e82a21f95d9d80080748ef25aa
BLAKE2b-256 a521a1aa7e0b1360e170244d0a7eb85de0a7605c4ebb8e0063dcf8ddfdb48582

See more details on using hashes here.

Provenance

The following attestation bundles were made for q_armor_pqc-0.1.1-cp312-none-any.whl:

Publisher: release.yml on iden-q/iden-q-quantum-armor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file q_armor_pqc-0.1.1-cp311-none-any.whl.

File metadata

  • Download URL: q_armor_pqc-0.1.1-cp311-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: CPython 3.11
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for q_armor_pqc-0.1.1-cp311-none-any.whl
Algorithm Hash digest
SHA256 41221650e7b4e30b74e3fb7b09c307ffa38c4ebe7ff75c965e0074f87fa0df99
MD5 62f2b5b2ced0f0f411618b0818443673
BLAKE2b-256 4ffd04b34c8359df97661b983a299d6b52c4042dedeef5a720962836bdec472c

See more details on using hashes here.

Provenance

The following attestation bundles were made for q_armor_pqc-0.1.1-cp311-none-any.whl:

Publisher: release.yml on iden-q/iden-q-quantum-armor

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.1.2

3 files

This release

0.1.1 This release

3 files

0.1.0

3 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