q-armor-lib
The post-quantum protection core of QArmor: score a validator, scan an endpoint, catch a harvester.
Blockchain bridges have lost more than $2.8B to exploits: Ronin $625M, Wormhole $320M, Multichain $130M. Three causes repeat, and the third one has not happened yet: traffic captured today, decrypted the day a cryptographically relevant quantum computer exists. That is Harvest Now, Decrypt Later, and it is the attack whose damage is already done by the time anyone can detect it.
q-armor-lib is the library that measures the exposure. It is the detection
and scoring logic of QArmor, separated from the runtimes
that consume it (the protection proxy, the dashboard, the canary network and
the DVN worker), so that one implementation produces one answer.
Three lines, and a number that means something
pip install q-armor-lib
from q_armor_lib.tls_scanner import scan_tls_endpoint
r = scan_tls_endpoint("example.com")
print(r.key_exchange_group, r.vqs.score, r.vqs.tier)
x25519 80 RiskTier.DENY
An endpoint that negotiates x25519 is doing a classical key exchange:
everything on that wire is harvestable today and readable the day the quantum
computer arrives. VQS is exposure, so 0 is safe, 80 is not, and above 75
the tier is DENY.
What VQS actually decides
The score is not a badge. It is the validator's weight in weighted BFT consensus, so posture changes what a vote is worth:
| Tier | VQS (exposure) | Effective weight |
|---|---|---|
PERMIT |
under 25 | full |
STEP_UP |
25 to 75 | halved, until posture improves |
DENY |
over 75 | one tenth, and excluded from critical quorum |
Signing algorithm and session algorithm weigh 0.4 each, and the canary capture rate weighs 0.2. ECDSA, RSA and Ed25519 all score 100 exposure, because Shor breaks all three and pretending otherwise would only make the label lie.
Why this, and not a hardware programme
- No QKD hardware. ML-KEM-768 runs on the server you already have.
- Active HNDL detection, not only prevention. Canary tokens embedded in proofs turn a silent harvest into an event with a timestamp.
- Posture, not just stake. A validator with a large stake and classical keys is a large hole, and VQS is what prices it.
- One axis, one producer.
key_establishment_classis computed here and nowhere else, so the CLI, the proxy and the dashboard cannot disagree. - It says "unknown" when it does not know. The class is asserted only when the negotiated group was actually observed; a TLS version alone is a guess, and a guess is not evidence.
What is inside
| Module | What it does |
|---|---|
vqs_engine |
VQS, the Validator Quantum Score: scoring of cryptographic posture |
tls_scanner |
Scanning of TLS endpoints and certificates |
sector_scanner |
VQS aggregation at network and sector level |
cbom |
Cryptographic bill of materials built from what a scan observed |
quantum_scanner_client |
HTTP client of the external QuantumScanner (idenq.io), enriches scans with QES |
session.key_exchange |
ML-KEM-768 peer-to-peer session exchange between validators |
proofs.aggregator |
Proof aggregation with an ML-DSA-65 signature and canary embedding, weighted by VQS |
identity.canary_tokens |
Canary tokens for active detection of HNDL attacks |
control_plane |
Client of the QArmor control plane, shared by the CLI and the proxy |
It depends on q-armor-pqc (interim,
see its README) for ML-DSA-65; ML-KEM-768 arrives through that same package
from the iden-q-post-quantum emission.
The QArmor family
Five packages, one version, published together from a single tag.
| Package | What it is |
|---|---|
q-armor-lib |
This one: 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 |
Interim ML-DSA-65 primitive |
Installing inside the workspace
Within iden-q-quantum-armor it is installed editable from the root
requirements.txt, which asks for all five with -e in ONE pip command: the
exact pin to q-armor-pqc is satisfied by the editable requested in that same
command. Standalone, the two together for the same reason:
pip install -e packages/q-armor-pqc -e packages/q-armor-lib
Tests
The package's own tests live in tests/ of this directory
(test_vqs_engine.py, test_tls_scanner.py, test_session.py,
test_proofs.py, test_canary_tokens.py) and do not depend on the runtime,
only on q_armor_lib and q_armor_pqc. They run with pytest from the
repository root like the rest of the suite (there is no restrictive
testpaths in pytest.ini).
The tests that exercise how the runtime uses this library (the
/endpoint/scan endpoints, the dashboard, the DVN worker, keypair
persistence) stay in tests/ at the repository root: they are integration
tests, not tests of the library itself.
Extraction status
It is a self-contained Python package, published to PyPI with the rest of the
workspace from a tag (release.yml; CI builds and verifies it on every pull
request). The licence decision is taken: proprietary
(LicenseRef-Proprietary as the SPDX expression in pyproject.toml, the
owner's decision of 2026-09-02) and with LICENSE inside the wheel. What is
worth knowing when consuming it:
quantum_scanner_client.probe_domaintakes the QuantumScanner URL as a parameter and does not read global configuration: the runtime that calls it decides where that value comes from.
Next
The local daemon and the VQS dashboard are free. The collective canary network, real-time alerting and on-premise deployment are the paid tiers: 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
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file q_armor_lib-0.1.0-cp313-none-any.whl.
File metadata
- Download URL: q_armor_lib-0.1.0-cp313-none-any.whl
- Upload date:
- Size: 67.2 kB
- Tags: CPython 3.13
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71d61a6bcafdc825a317763d551cb0fc416d838891afb8b653a87ef9d8a881fe
|
|
| MD5 |
e791a674e1fb1a39f403167891dd112a
|
|
| BLAKE2b-256 |
518cd074abc3fdeb98031d7ff727398b413edd7e342106fadde623c0fe6b07f2
|
Provenance
The following attestation bundles were made for q_armor_lib-0.1.0-cp313-none-any.whl:
Publisher:
release.yml on iden-q/iden-q-quantum-armor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
q_armor_lib-0.1.0-cp313-none-any.whl -
Subject digest:
71d61a6bcafdc825a317763d551cb0fc416d838891afb8b653a87ef9d8a881fe - Sigstore transparency entry: 2703661473
- Sigstore integration time:
-
Permalink:
iden-q/iden-q-quantum-armor@4cb5e50bd7ac5f10b9f7607d5d14eb71fe74328d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/iden-q
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4cb5e50bd7ac5f10b9f7607d5d14eb71fe74328d -
Trigger Event:
push
-
Statement type:
File details
Details for the file q_armor_lib-0.1.0-cp312-none-any.whl.
File metadata
- Download URL: q_armor_lib-0.1.0-cp312-none-any.whl
- Upload date:
- Size: 66.8 kB
- Tags: CPython 3.12
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a49f0505e84fbb20c722dbe27b0df8b9f62daf88e1f937786b4a10b21ef16d22
|
|
| MD5 |
90371399aed5006bb2d68a692fa21f8c
|
|
| BLAKE2b-256 |
d1dcff8a87469a1413d7147f66f2e1bbeca1281ed5009536040e689cbff29852
|
Provenance
The following attestation bundles were made for q_armor_lib-0.1.0-cp312-none-any.whl:
Publisher:
release.yml on iden-q/iden-q-quantum-armor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
q_armor_lib-0.1.0-cp312-none-any.whl -
Subject digest:
a49f0505e84fbb20c722dbe27b0df8b9f62daf88e1f937786b4a10b21ef16d22 - Sigstore transparency entry: 2703661524
- Sigstore integration time:
-
Permalink:
iden-q/iden-q-quantum-armor@4cb5e50bd7ac5f10b9f7607d5d14eb71fe74328d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/iden-q
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4cb5e50bd7ac5f10b9f7607d5d14eb71fe74328d -
Trigger Event:
push
-
Statement type:
File details
Details for the file q_armor_lib-0.1.0-cp311-none-any.whl.
File metadata
- Download URL: q_armor_lib-0.1.0-cp311-none-any.whl
- Upload date:
- Size: 67.9 kB
- Tags: CPython 3.11
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aeefa1b3c74e3977590aa7e036d5811cec0a01e3d57f167fdb950fcf3103bf01
|
|
| MD5 |
86e53c66ab9913909c4b00635703be0e
|
|
| BLAKE2b-256 |
8375de84216221f05f93a939ba98a526dd967e36a240d03d96d42c357ffa4c22
|
Provenance
The following attestation bundles were made for q_armor_lib-0.1.0-cp311-none-any.whl:
Publisher:
release.yml on iden-q/iden-q-quantum-armor
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
q_armor_lib-0.1.0-cp311-none-any.whl -
Subject digest:
aeefa1b3c74e3977590aa7e036d5811cec0a01e3d57f167fdb950fcf3103bf01 - Sigstore transparency entry: 2703661496
- Sigstore integration time:
-
Permalink:
iden-q/iden-q-quantum-armor@4cb5e50bd7ac5f10b9f7607d5d14eb71fe74328d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/iden-q
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4cb5e50bd7ac5f10b9f7607d5d14eb71fe74328d -
Trigger Event:
push
-
Statement type: