qday-time-machine
Find the cryptography a quantum computer will break, see when it breaks, and get the post-quantum fix.
A large quantum computer running Shor's algorithm will break the RSA and elliptic-curve cryptography behind today's
logins, payments and signatures, and attackers can record encrypted traffic now to decrypt it later. qday tells
you which of your systems break first, in what year, and whether the data you send today is already at risk,
then gives you the replacement.
Documentation · Demo video, with a technical deep-dive · Source, dashboard and hardware results
Features
- Scan websites (certificate, issuing CA, key-exchange group, cipher) and source code in eight languages
(Python, JavaScript, TypeScript, Java, Go, Kotlin, Rust and config files) for quantum-vulnerable cryptography.
Detects the hybrid post-quantum TLS group
X25519MLKEM768. - Inventory everything as a CycloneDX 1.6 cryptography bill of materials (CBOM).
- Forecast a break year for each algorithm by comparing published attack costs (logical qubits and gate counts) with IBM's fault-tolerant quantum roadmap.
- Prioritise with Mosca's inequality: critical, high, medium or safe, with the reason and the replacement.
- Gate CI:
--fail-on criticalexits with code 1, so a pull request that adds RSA or ECDSA fails. - Prove it: scaled-down Shor (factors 15 and 21) and Grover attacks in Qiskit, on simulators or real IBM quantum computers.
- Migrate: a working hybrid X25519 + ML-KEM-768 handshake (NIST FIPS 203) and ML-DSA-65 signatures (FIPS 204).
Install
pip install qday-time-machine
Python 3.11 or newer. Install the OpenSSL 3.x command-line tool too, so website scans can report the negotiated key-exchange group.
Quick start
Scan a code base:
$ qday scan --path ./src
critical RSA-2048 payments.py:8 breaks 2037 fix: ML-KEM-768 (encryption) / ML-DSA-65 (signatures)
critical MD5 payments.py:18 breaks - fix: SHA-256
high ECDSA-P-256 server.js:3 breaks 2042 fix: ML-DSA-65
medium AES-128 payments.py:10 breaks - fix: AES-256
Scan a website and a folder together, and export a CBOM:
qday scan --host example.com --path ./src
qday cbom --host example.com --path ./src -o cbom.json
Ask when an algorithm breaks:
$ qday forecast RSA-2048
{ "logical_qubits": 1399, "toffoli": 6500000000.0, "first_break_year": 2037, ... }
Run the attacks and the post-quantum handshake:
qday shor --N 15 --a 7 # factors 15 = 3 x 5 on the Qiskit Aer simulator
qday grover --bits 3 --secret 6 # recovers the secret key
qday pqc # hybrid X25519 + ML-KEM-768 key exchange
qday shor --backend ibm_kingston # on real IBM hardware (needs an IBM Quantum API key)
Commands
| Command | What it does |
|---|---|
qday scan |
Findings with risk level, break year and the fix. Options: --host (repeatable), --path, --fail-on {medium,high,critical}, --json, --scenario {trend,roadmap}, --shelf-life, --migration |
qday cbom |
CycloneDX 1.6 CBOM: --host, --path, -o FILE |
qday forecast ALGORITHM |
What an attack needs and the first break year, e.g. RSA-2048, ECDSA-P-256 |
qday shor |
Shor's order finding: --N {15,21}, --a, --backend |
qday grover |
Grover key search: --bits {3,4}, --secret, --backend |
qday pqc |
Hybrid post-quantum handshake |
Exit codes: 0 ok, 1 a finding at or above --fail-on, 2 invalid input or every target failed.
Use it in CI
# .github/workflows/quantum-safe.yml
- run: pip install qday-time-machine
- run: qday scan --path . --fail-on critical
Python API
from qday.scanner.code import scan_code
from qday.forecast.risk import assess_all
from qday.scanner.cbom import build_cbom
assets = scan_code("./src")["assets"]
for finding in assess_all(assets, migration_years=3, shelf_life=10):
print(finding["risk"], finding["algorithm"], finding["break_year"], finding["replacement"])
cbom = build_cbom(assets, target="my-service") # a CycloneDX 1.6 dict
How the forecast works
A break year is the first year IBM's roadmap provides both the logical qubits and the operations a published
attack needs: Gidney 2025 for RSA-2048 (1,399 logical qubits, 6.5 × 10⁹ Toffoli gates) and Roetteler et al. 2017
for elliptic curves. Risk follows Mosca's inequality: if data must stay secret for x years and migrating takes
y, it is already at risk when x + y exceeds the years left before the break. After 2033 the default trend
scenario is an explicit extrapolation; --scenario roadmap uses IBM's published roadmap only.
Validated on IBM quantum hardware
The attacks were run on ibm_fez, ibm_kingston and ibm_marrakesh: 45 / 45 validation tests passed, and Shor passed 24 / 24 tests with pass rules fixed in code before the runs. From those runs we measured an error of about 3 × 10⁻³ per two-qubit gate on the best qubits, which means breaking RSA-2048 on today's hardware would take about 4 million physical qubits rather than the published estimate's under 1 million. Full results and job IDs.
Limitations
The Shor and Grover attacks break toy instances (N = 15 and 21, 3–4-bit keys), not real keys. Break years rest on published estimates and IBM's stated roadmap. The code scanner is pattern-based: findings are leads to review, not proof that the code path is reachable. Only scan systems you own or are authorised to test.
About
Built by Team Straw Hat Pirates (Raunak Kumar Gupta, Krish Jain) for the VTU-QFF Hackathon, Qiskit Fall Fest 2026. Uses Qiskit, Qiskit Aer, Qiskit IBM Runtime, quantum-debugger, cryptography, kyber-py and dilithium-py. MIT licensed.
Metadata
Release files for qday-time-machine 1.0.1
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 | Actions |
|---|---|---|---|---|
| qday_time_machine-1.0.1.tar.gz | 88.0 kB | Without provenance | Details for qday_time_machine-1.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| qday_time_machine-1.0.1-py3-none-any.whl | Python 3 | none | any | Details for qday_time_machine-1.0.1-py3-none-any.whl |
Total release size: 137.1 kB
Release files / qday_time_machine-1.0.1.tar.gz
| Download URL | qday_time_machine-1.0.1.tar.gz |
|---|---|
| Size | 88.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4e9569764b3d14d69698f30d32496fafc27e018e7bfb1124d5bd745a801e022a
|
|
BLAKE2b-256 checksum How to use checksums |
d27ee6c7e94b164b2d8c848a5435feb4cfcefe07439a05c45a8bedd21c0de7b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / qday_time_machine-1.0.1-py3-none-any.whl
| Download URL | qday_time_machine-1.0.1-py3-none-any.whl |
|---|---|
| Size | 49.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
54ce27cdbdb7b51a025b80ba54a10cf28b5cb384bf28155d4b3a751338c3474a
|
|
BLAKE2b-256 checksum How to use checksums |
467b63ec481cbd386b2ee18aa542efbd0e3578078ea08d85c1f1348cbc7c410a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Security for qday-time-machine 1.0.1
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.