Skip to main content

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:

  1. 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.
  2. A hybrid helper module. Drops pqc_hybrid.py into the project's package: X25519 + ML-KEM-768 key encapsulation and Ed25519 + ML-DSA-65 signatures, built on cryptography>=48. Nothing is wired in automatically, because both peers of a protocol have to move together.
  3. 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 apply and run, such as with(gen) { initialize(n) }: the generator's size stays unknown.
  • BouncyCastle's ECMQV key agreement is not mapped.
  • ssh.ParsePrivateKey and ssh.ParseRawPrivateKey are not reported, because the key type is not visible at the call. ssh.NewSignerFromKey is 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)

Source distribution for pqcpilot 0.1.0
File Size Uploaded Provenance
pqcpilot-0.1.0.tar.gz 95.9 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pqcpilot 0.1.0
File Interpreter ABI Platform
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 log

Release 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 log

Security 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.

Select from 2 files

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 log

A 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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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