pqcpilot
Find quantum-vulnerable cryptography in your code, produce a CycloneDX Cryptographic Bill of Materials (CBOM), and get a readiness report mapped to the post-quantum deadlines that apply to you.
RSA, elliptic-curve cryptography (ECDSA, ECDH, EdDSA, X25519) and Diffie-Hellman can all be broken by a large quantum computer. Regulators now set dates to replace them:
- India: the DST Quantum-Safe Roadmap (May 2026) expects critical sectors, including banking and finance, to complete a cryptographic inventory by December 2027 and fully adopt PQC by December 2029, with vendor CBOMs from FY 2027-28.
- United States: NIST IR 8547 (draft) deprecates 112-bit algorithms such as RSA-2048 in 2030 and disallows all quantum-vulnerable public-key algorithms, including P-256, in 2035. CNSA 2.0 sets earlier dates for national security systems.
Install
pip install -e . # no required dependencies
pip install -e ".[certs]" # adds certificate and key parsing via pyca/cryptography
Use
pqcpilot scan path/to/repo # terminal summary
pqcpilot scan . --format cbom -o cbom.json # CycloneDX 1.6 CBOM
pqcpilot scan . --format markdown --profile india-cii -o pqc-report.md
pqcpilot scan . --skip-tests --fail-on critical # CI gate
Profiles: india-cii (default), india-enterprise, nist, cnsa2.
Fix
pqcpilot fix . # show the diff of safe fixes, change nothing
pqcpilot fix . --apply --pr-body pr.md # apply them and write a pull request body
pqcpilot init-ci # add a GitHub Actions workflow
fix does three things:
- Safe in-place fixes. Raises RSA and DH keys below 3072 bits, and replaces P-192 / P-224 and python-ecdsa's default NIST192p with P-256. These change parameters, not protocols, so the other end keeps working. Sizes pinned by a constant are left for the engineer.
- A hybrid helper module. Drops
pqc_hybrid.pyinto the project's package: X25519 + ML-KEM-768 key encapsulation and Ed25519 + ML-DSA-65 signatures, built oncryptography>=48. Nothing is wired in automatically, because both peers of a protocol have to move together. - A migration checklist. The PR body lists every remaining finding with what to change, grouped and ordered by urgency, plus the regulatory timeline.
Findings in tests, fixtures and examples are never rewritten: a test may use a small key on purpose to
check that it is rejected. They are listed in the checklist (--include-tests).
The workflow from init-ci scans on every push, publishes the CBOM, fails on critical findings in
production code, and once a week opens a pull request with the fixes and checklist.
Check live endpoints
pqcpilot tls www.example.com api.example.com:8443
pqcpilot tls --hosts-file endpoints.txt --format markdown -o tls-report.md
For each endpoint it sends a hand-built TLS 1.3 ClientHello that offers X25519MLKEM768 (the hybrid key exchange browsers use) and reports which group the server chose, whether it supports the hybrid at all, the TLS version, and the certificate's key. It works with any OpenSSL, because it does not rely on the local library knowing about ML-KEM. No handshake is completed and nothing is sent after the ServerHello. A server that is not quantum-safe is rated high, because recorded traffic can be decrypted later.
What it detects
| Source | Coverage |
|---|---|
| Python | pyca/cryptography, pycryptodome / pycryptodomex, python-rsa, python-ecdsa, paramiko, JWT algorithms (PyJWT, python-jose) |
| JavaScript / TypeScript | Node crypto, WebCrypto subtle, jsonwebtoken / jose alg values, node-forge, elliptic, tweetnacl |
| Java / Kotlin | JCA/JCE getInstance (KeyPairGenerator, Cipher, Signature, KeyAgreement, KeyFactory) with the key size or curve from initialize(...), BouncyCastle lightweight API, Nimbus / jjwt / java-jwt algorithms |
| Go | crypto/rsa, crypto/ecdsa, crypto/ecdh, crypto/ed25519, crypto/dsa, x/crypto/curve25519, x509 key parsing, golang-jwt, and tls.Config.CurvePreferences lists that disable Go's default X25519MLKEM768 |
| Files | PEM certificates and keys (parsed for real key size and curve), OpenSSH public keys |
Severity:
- Critical: weak even today (RSA under 2048 bits, DSA, P-192 / P-224, small DH groups).
- High: key exchange and encryption, exposed to harvest-now-decrypt-later.
- Medium: signatures, which break once a large quantum computer exists.
- Low: the classical half of a hybrid post-quantum scheme (the file also uses ML-KEM).
Findings in tests, fixtures and examples are tagged so reports can separate them from production code.
Limits
It reads source and files only. It does not see cryptography inside compiled dependencies, HSMs,
cloud KMS or live TLS endpoints yet. Keys loaded from files at runtime (load_pem_private_key) are
not reported because their algorithm is unknown until runtime.
The live endpoint check does not echo cookies. A server that answers with a stateless HelloRetryRequest asking only for a cookie is reported as not assessed, not rated.
Findings are tagged as tests, fixtures or examples from the path alone: a directory named test,
tests, spec, specs, __tests__, __mocks__, fixtures, testdata, tap, test-d, examples,
cookbook or demo, or a file named test_*, *.test.*, *.spec.* or *.test-d.*. A production
directory with one of those names is tagged the same way, and --skip-tests drops its findings.
Known misses in the Java, Kotlin and Go scanners:
- Go dot-imports of a JWT library (
import . "github.com/golang-jwt/jwt/v5"): the signing methods are unqualified, so they are not matched. Aliased and unaliased imports are. - Kotlin scope functions other than
applyandrun, such aswith(gen) { initialize(n) }: the generator's size stays unknown. - BouncyCastle's
ECMQVkey agreement is not mapped. ssh.ParsePrivateKeyandssh.ParseRawPrivateKeyare not reported, because the key type is not visible at the call.ssh.NewSignerFromKeyis RSA only for a key declared as an RSA key in the same function.
Development
pip install -e ".[dev]"
pytest
Metadata
Release files for pqcpilot 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pqcpilot-0.1.0.tar.gz | 95.9 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pqcpilot-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 161.2 kB
Release files / pqcpilot-0.1.0.tar.gz
| Download URL | pqcpilot-0.1.0.tar.gz |
|---|---|
| Size | 95.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3c0af2477ce990781ac940134c3f3e79f39861b268f6dca4e99597a8788480f6
|
|
BLAKE2b-256 checksum How to use checksums |
7edecf96afe5d658721910dbf46b963003d4a8a340d45270b30955d73c8c8b4b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Oct 26, 2026.
Transparency logRelease files / pqcpilot-0.1.0-py3-none-any.whl
| Download URL | pqcpilot-0.1.0-py3-none-any.whl |
|---|---|
| Size | 65.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4a8ce383eb14fff80816d9b9abc6e1b7ffd5ab334d36b249e9a428fa99327292
|
|
BLAKE2b-256 checksum How to use checksums |
0f6caab7765331a9489b831df0f3c740a4769689825f9af0edb64244347a98e0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 Oct 26, 2026.
Transparency logSecurity for pqcpilot 0.1.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pqcpilot-0.1.0.tar.gz
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 Oct 26, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.