This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 0.3.2 instead.
Reason given by maintainers: Signature prefix forgery, see GHSA-wqv6-gm9x-69x8
quantum-safe
Production-grade post-quantum cryptography for Python. Hybrid KEM, hybrid signatures, migration tooling, protocol helpers, and a CI-ready audit scanner — all in one library.
Why this library exists
We audited nine PQC libraries against nine dimensions anchored to CNSA 2.0,
CMVP, the TNO CADI market survey, and the IETF hybrid draft — not to our own
design, so the audit can (and does) score this library below others on some
dimensions. Full methodology, per-dimension sources, and a re-auditable
verification procedure: docs/production_readiness_rubric.md.
| Gap (September 2026 audit, 7 libraries with verified evidence) | Ecosystem | This library |
|---|---|---|
| Cryptographic discovery/inventory | 0 of 7 provide it | ✓ CycloneDX CBOM (qs-audit cbom) |
| Stateful hash-based signing (LMS/XMSS) | 1 of 7 (Bouncy Castle: both) | Partial — LMS only, optional [lms] extra |
| Conformance evidence vs. NIST vectors | 1 of 5 holds a real CMVP cert (Bouncy Castle) | 225/225 ACVP known-answer cases — not a CMVP validation |
| Hybrid KEM combiner | 3 of 6 have one (up from 1 of 9 nine months ago) | ✓ Default mode |
| CNSA 2.0 parameter sets by default | n/a (raw primitives, no opinion) | Partial — defaults are ML-KEM-768/ML-DSA-65, below CNSA 2.0; qs-audit cnsa2 reports or cnsa2.enforce() blocks it |
| Migration path for existing keys | 1 of 7 partial | ✓ Upgrader + state machine |
| Protocol helpers (TLS, JWT, X.509) | 3 of 7 (partial-to-full) | ✓ protocols module |
We are not the strongest library on every axis — Bouncy Castle holds an actual CMVP FIPS 140-3 certificate and supports both LMS and XMSS, ahead of us on both. We report that rather than the version of this table that would look better.
Quick start
from quantum_safe import HybridKEM, HybridSign
# Key exchange — hybrid X25519 + ML-KEM-768 (NIST transition-period standard)
kem = HybridKEM()
kp = kem.generate_keypair()
ct, shared_secret = kem.encapsulate(kp.public)
ss2 = kem.decapsulate(kp.secret, ct)
assert shared_secret == ss2
# Digital signatures — hybrid Ed25519 + ML-DSA-65
signer = HybridSign()
kp = signer.generate_keypair()
sm = signer.sign(b"important document", kp.secret, context=b"myapp-v1")
signer.verify(sm, kp.public) # raises VerificationError if invalid
Installation
Core (classical crypto only, no PQC backend required)
pip install quantum-safe-py
The core package works without liboqs. Key generation, serialization, hybrid construction, Envelope, JWT, TLS helpers, scanner, auditor, and SBOM enrichment all work with the classical (X25519/Ed25519) components.
With liboqs backend (full ML-KEM / ML-DSA support)
pip install 'quantum-safe-py[liboqs]'
liboqs-python itself (the dependency behind this extra) does not ship a
prebuilt liboqs binary — on its own, the first import oqs downloads and
compiles liboqs from source, needing git, CMake, and a C compiler.
Our own released wheels work around that: for common platforms — Linux
x86_64, Windows x64, and macOS arm64 (14+) — we compile liboqs ourselves as
part of the release process and bundle the binary directly into the wheel
(see hatch_build.py). On those platforms, pip install 'quantum-safe-py[liboqs]' just works, no compiler needed. Outside them
(32-bit, other architectures, Intel Mac, macOS <14), liboqs-python falls back
to its normal build-from-source path, so you'll still need git/CMake/a C
compiler there.
Verify installation:
python -c "from quantum_safe.backends import list_available_backends; print(list_available_backends())"
# → {'rustcrypto': False, 'liboqs': True, 'noble': False}
Development install
git clone https://github.com/AnimeshShaw/quantum-safe-py
cd quantum-safe-py
pip install -e '.[dev]'
pre-commit install
Core concepts
Hybrid mode is the default
During the NIST transition period, every security standard (NIST, CISA, BSI, NCSC) recommends hybrid classical + PQC. This library makes hybrid the default so you have to explicitly opt out, not in.
# Default: X25519 + ML-KEM-768 (hybrid)
kem = HybridKEM()
# Override to pure PQC (not recommended for new deployments)
kem = KEM("ML-KEM-768")
# Override to a different hybrid combination
kem = HybridKEM(classical="X25519", pqc="ML-KEM-1024")
Typed outputs prevent accidents
Raw bytes are never returned from key operations. Every output is a distinct type:
kp: KeyPair # contains .public (PublicKey) and .secret (SecretKey)
ct: HybridCipherText # ciphertext — pass to decapsulate()
ss: SharedSecret # 32 bytes — call ss.derive_key() to get AES keys
sm: SignedMessage # message + signature + metadata — self-contained
This prevents the class of bug where you accidentally pass a SharedSecret
as a CipherText.
Keys know their format
Every key carries its algorithm name, migration state, and supports multiple serialization formats:
pub = kp.public
print(pub.algorithm) # "X25519+ML-KEM-768"
print(pub.migration_state) # MigrationState.HYBRID_TRANSITION
print(pub.fingerprint()) # "3a7f1c2e..." (sha256 hex)
# Serialize
pem = pub.to_pem() # PEM string with qs-version and qs-algo headers
cbor = pub.to_cbor() # CBOR bytes (compact, binary)
jwk = pub.to_jwk() # JSON Web Key dict
# Round-trip (Python ↔ TypeScript ↔ Rust — same format)
pub2 = PublicKey.from_pem(pem)
pub3 = PublicKey.from_cbor(cbor)
pub4 = PublicKey.from_jwk(jwk)
Key encapsulation (KEM)
from quantum_safe import HybridKEM
from quantum_safe.protocols import Envelope
# Option 1: Low-level (you manage the shared secret)
kem = HybridKEM()
kp = kem.generate_keypair()
ct, ss = kem.encapsulate(kp.public)
ss2 = kem.decapsulate(kp.secret, ct)
# Derive AES keys from shared secret
enc_key = ss.derive_key(32, info=b"myapp-encryption-v1")
mac_key = ss.derive_key(32, info=b"myapp-mac-v1")
# Option 2: High-level (recommended for most use cases)
# Envelope = KEM + AES-256-GCM, fully self-describing
sealed = Envelope.seal(b"plaintext", kp.public)
plain = Envelope.open(sealed, kp.secret)
# Serialize for network transport
wire = sealed.to_bytes() # or .to_hex()
sealed = SealedMessage.from_bytes(wire) # or .from_hex()
# With authenticated metadata (visible but authenticated)
sealed = Envelope.seal(b"payload", pub, aad=b"recipient-id:user-42")
Digital signatures
from quantum_safe import HybridSign, Sign
from quantum_safe.types import SignedMessage
# Hybrid (Ed25519 + ML-DSA-65) — recommended
signer = HybridSign()
kp = signer.generate_keypair()
sm = signer.sign(b"document", kp.secret, context=b"myapp-v2-docs")
signer.verify(sm, kp.public) # raises VerificationError if invalid
# Hedged mode is on by default — two signings of the same message differ
sm1 = signer.sign(b"same", kp.secret)
sm2 = signer.sign(b"same", kp.secret)
assert sm1.signature != sm2.signature # different random prefix each time
# Store and retrieve a signed message
cbor_bytes = sm.to_cbor()
sm2 = SignedMessage.from_cbor(cbor_bytes)
# Include signer fingerprint for key lookup
sm = signer.sign_with_fingerprint(b"doc", kp)
print(sm.signer_fingerprint) # "3a7f1c2e..."
Protocol helpers
Encrypted envelopes
See Key Encapsulation section above.
JWT (PQC-aware)
from quantum_safe.protocols.jwt import JWTSigner, JWTVerifier
# Sign
signer = JWTSigner(keypair, issuer="auth.myapp.com")
token = signer.sign({"sub": "user123", "role": "admin"})
# Verify
verifier = JWTVerifier(keypair.public, issuer="auth.myapp.com")
claims = verifier.verify(token)
# raises VerificationError on invalid, expired, or wrong issuer
TLS hybrid key exchange
import ssl
from quantum_safe.protocols.tls import configure_hybrid_context, HybridTLSConfig
ctx = ssl.create_default_context()
configure_hybrid_context(ctx, HybridTLSConfig(
kem_algorithm="X25519+ML-KEM-768",
fallback_classical=True, # include X25519 as fallback
))
# ctx now prefers X25519MLKEM768 when the OQS provider is available
Hybrid X.509 certificates
from quantum_safe.protocols.x509 import HybridCertificateBuilder, generate_classical_keypair_for_cert
classical_key = generate_classical_keypair_for_cert("Ed25519")
hybrid_kp = HybridSign().generate_keypair()
builder = HybridCertificateBuilder(
subject_cn="service.internal",
classical_private_key=classical_key,
pqc_keypair=hybrid_kp,
dns_names=["api.service.internal"],
validity_days=365,
)
cert_pem, cosig_bundle = builder.build()
Migration tooling
Scan a codebase for classical crypto
from quantum_safe.migrate import Scanner
report = Scanner.scan_directory("./src")
print(report.summary())
# Scanned 42 files in './src': 2 CRITICAL, 5 HIGH, 3 MEDIUM
for finding in report.high + report.critical:
print(f"{finding.file}:{finding.line} [{finding.rule_id}] {finding.message}")
print(f" Fix: {finding.fix_hint}")
# Exit 1 in CI if blocking findings exist
if report.has_blocking_findings:
sys.exit(1)
Upgrade an existing key to hybrid
from quantum_safe.migrate import Upgrader
result = Upgrader.upgrade_kem_key(
classical_secret_bytes=x25519_private_bytes, # your existing X25519 key
classical_public_bytes=x25519_public_bytes,
classical_algorithm="X25519",
target_pqc="ML-KEM-768",
)
# result.new_keypair contains X25519 + ML-KEM-768
# Old senders using X25519-only can still encrypt to the new public key
print(result.notes)
Track migration progress
from quantum_safe.migrate import MigrationStateManager
from quantum_safe.types import MigrationState
store = {} # replace with Redis / DynamoDB / Postgres
mgr = MigrationStateManager(store)
mgr.transition(
key_id="user-123",
from_state=MigrationState.CLASSICAL_ONLY,
to_state=MigrationState.HYBRID_TRANSITION,
algorithm="X25519+ML-KEM-768",
actor="key-rotation-v2",
)
print(mgr.migration_progress())
# {'classical_only': 0, 'hybrid_transition': 1, ...}
Audit and compliance
CI audit gate
from quantum_safe.audit import Auditor, AuditPolicy
# Returns 0 (pass) or 1 (fail) — use directly in CI
exit_code = Auditor.ci_gate(
"./src",
policy=AuditPolicy(allow_classical_only=False, hybrid_required=True),
output_sarif="audit.sarif", # GitHub Code Scanning
output_json="audit.json",
)
sys.exit(exit_code)
NIST compliance report
from quantum_safe.audit import NISTComplianceChecker
from quantum_safe.migrate import Scanner
scan = Scanner.scan_directory("./src")
report = NISTComplianceChecker.check(scan, target="./src")
print(report.to_json())
# Maps findings to FIPS 203, FIPS 204, FIPS 205, SP 800-208, CISA checklist
CycloneDX SBOM enrichment
from quantum_safe.audit import SBOMEnricher
with open("sbom.json") as f:
sbom = json.load(f)
enriched, assessments = SBOMEnricher.enrich(sbom)
# Each component gets quantum-safe:pqc-readiness: READY|PARTIAL|NOT_READY|UNKNOWN
not_ready = [a for a in assessments if a.readiness.value == "NOT_READY"]
for a in not_ready:
print(f"NOT READY: {a.name} {a.version} → {a.action}")
CycloneDX Cryptographic Bill of Materials (CBOM)
Every audited library in our September 2026 survey scored None on
automated cryptographic discovery — this is the actual gap, not the hybrid-KEM
one an older library snapshot suggested. qs-audit cbom closes it: a
CycloneDX 1.6 cryptographic-asset inventory, one component per detected
classical algorithm (file:line, quantum-vulnerability flag) plus the
post-quantum algorithms available to migrate to.
qs-audit cbom ./src --output cbom.json
This is an inventory, not a compliance verdict — pair it with qs-audit cnsa2
below, and note that neither is a FIPS 140-3 validation.
CNSA 2.0 parameter-set compliance
CNSA 2.0 mandates specific parameter sets — ML-KEM-1024, ML-DSA-87 — not just "uses post-quantum algorithms". This library's own defaults (ML-KEM-768, ML-DSA-65) are below that suite. We report this against ourselves rather than let it stay implicit:
from quantum_safe.compliance import cnsa2
report = cnsa2.report(kem="X25519+ML-KEM-768", signature="Ed25519+ML-DSA-65")
print(report.render())
# [FAIL] Key establishment ... requires ML-KEM-1024
# [FAIL] Signatures ... requires ML-DSA-87
# OVERALL: NOT compliant
kem = cnsa2.hybrid_kem() # X25519 + ML-KEM-1024, compliant
signer = cnsa2.hybrid_sign() # Ed25519 + ML-DSA-87, compliant
Or from the CLI: qs-audit cnsa2 (defaults to checking this library's own
defaults — which fail, on purpose, so you see it immediately).
ACVP conformance evidence
225 of 225 runnable ACVP known-answer cases, run against NIST's own
published test vectors — ML-KEM keyGen (75/75, exact ek+dk), ML-KEM
encapsulation (75/75), ML-KEM decapsulation (30/30, including
implicit-rejection cases), ML-DSA sigVer (45/45, both acceptance and
rejection). No other Python PQC library publishes this.
This is conformance evidence, not a CAVP or CMVP validation — validation is performed by an accredited laboratory and produces a certificate; nothing here does. Bouncy Castle is the one library in our audit holding an actual CMVP FIPS 140-3 certificate, and we say so rather than blur the distinction.
python tests/conformance/acvp_kat.py --save results/acvp_kat.json
Full methodology, including exactly which ACVP test types remain unreachable
through a high-level API and why: results/BENCHMARKS.md.
CLI tools
qs-audit
# Scan for classical crypto — text output
qs-audit scan ./src
# SARIF output for GitHub Code Scanning
qs-audit scan ./src --format sarif --output audit.sarif
# JSON report with strict policy
qs-audit scan ./src --format json --preset-policy strict
# Fail CI if HIGH or above findings exist (default)
qs-audit scan ./src --fail-on high && echo "PASSED" || echo "FAILED"
# Enrich a CycloneDX SBOM
qs-audit sbom sbom.json --output sbom-pqc.json
# Quick requirements.txt check
qs-audit requirements requirements.txt
# NIST SP 800-208 compliance report
qs-audit compliance ./src --format json --output compliance.json
# CNSA 2.0 parameter-set check (defaults to checking this library's own defaults)
qs-audit cnsa2
# CycloneDX Cryptographic Bill of Materials
qs-audit cbom ./src --output cbom.json
qs-migrate
# Scan a codebase for classical crypto
qs-migrate scan ./src --format sarif --output migrate.sarif
# Check migration progress
qs-migrate status
Security notes
Memory safety
SecretKey and SharedSecret zero their memory on deletion using
ctypes.memset against the live bytearray buffer. A Python byte-loop
is subject to dead-store elimination by the optimizer; ctypes.memset
operates at the C level and cannot be elided.
Python's garbage collector still makes hard guarantees impossible, but this
approach minimises the window during which secret material is visible in
heap dumps. Callers that need to zero a copy immediately after use should
call SecretKey._raw_bytearray (returns a fresh bytearray) and zero it
with ctypes.memset in a try/finally block.
For high-security deployments, use an HSM or a secrets manager with key isolation.
Constant-time operations
We use hmac.compare_digest() for all secret comparisons. Hybrid signature
verification evaluates both sub-signatures unconditionally before combining
the result, preventing timing oracles that would reveal which component failed.
The underlying liboqs implementations are designed for constant-time operation.
Two distinct measurements back this, and it matters which one you're reading:
CoV (Coefficient of Variation, ~3.9% for ML-KEM-768 decapsulation in ENV-2,
within the AES-256-GCM noise floor) is computed with the secret held fixed, so
it shows timing stability under repetition — not secret independence.
A separate fixed-vs-random test with a random-vs-random control (needed to
rule out measurement artifacts — see docs/guides/benchmarks.rst) shows no
key-dependent timing in ML-KEM decapsulation, the implicit-rejection path, or
the hybrid combiner, across two environments. Neither is a formal
constant-time proof; dudect or ct-verif against the compiled backend
would be. See the companion timing-leakage paper for the full methodology.
Serialization safety
The _internal.serialization layer caps all incoming payloads at 10 MB
before parsing, guarding against memory-exhaustion via deeply nested or padded
CBOR / JSON structures. Deserialised key payloads with version < 1 are
rejected immediately to prevent version-rollback attacks.
Thread safety
MigrationStateManager.transition() holds a per-key threading.Lock across
the read-check-write critical section. For multi-process deployments (e.g.
multiple Gunicorn workers sharing a Redis store) you must additionally acquire
an external distributed lock (Redis SETNX, database row-level lock) on the
key_id before calling transition().
Hedged signing
HybridSign and Sign default to hedged mode: a 32-byte random prefix
is prepended before signing. This prevents fault-injection attacks that have
been demonstrated on lattice signatures in lab conditions. Opt out with
hedged=False only if you have a specific need for deterministic signatures.
Hybrid mode rationale
ML-KEM was standardized in 2024. Hybrid mode (X25519 + ML-KEM-768) means:
- If ML-KEM is broken, X25519 still protects you.
- If X25519 is broken by a quantum computer, ML-KEM still protects you.
- Both would need to fail simultaneously.
This is the position of NIST, CISA, BSI, NCSC, and every TLS library that has added PQC support.
Algorithm reference
| Algorithm | Type | NIST Level | Standard | Notes |
|---|---|---|---|---|
| ML-KEM-512 | KEM | 1 | FIPS 203 | Smallest. Use ML-KEM-768 for new deployments. |
| ML-KEM-768 | KEM | 3 | FIPS 203 | Recommended default. |
| ML-KEM-1024 | KEM | 5 | FIPS 203 | Maximum security. |
| ML-DSA-44 | Sign | 2 | FIPS 204 | Smallest ML-DSA. |
| ML-DSA-65 | Sign | 3 | FIPS 204 | Recommended default. |
| ML-DSA-87 | Sign | 5 | FIPS 204 | Maximum security. |
| SLH-DSA-SHAKE-128s | Sign | 1 | FIPS 205 | Hash-based. Very slow to sign. |
| SLH-DSA-SHAKE-128f | Sign | 1 | FIPS 205 | Hash-based. Larger sigs, faster sign. |
| X25519+ML-KEM-768 | Hybrid KEM | — | IETF draft | Default hybrid combination. |
| Ed25519+ML-DSA-65 | Hybrid Sign | — | IETF draft | Default hybrid combination. |
Development
Running tests
# Unit tests only (no liboqs needed)
python -m pytest tests/unit/ -v
# With liboqs installed
python -m pytest tests/ -v -m "not slow"
# Integration tests
python -m pytest tests/integration/ -v
# Skip liboqs-dependent tests
python -m pytest tests/ -v -m "not requires_liboqs"
Running benchmarks
The recommended environment is Docker (Linux kernel + from-source liboqs with AVX2):
# Build the benchmark image once (~3 min, compiles liboqs from source)
docker build -t quantum-safe-bench .
# Full KEM suite — CPU pinned, 3,000 iterations (recommended)
docker run --rm --cpuset-cpus="0,1" \
-v "$(pwd)/results:/app/results" quantum-safe-bench \
python -X utf8 tests/bench/bench_kem.py --with-pqc --iterations 3000 \
--save /app/results/bench_kem_$(date +%Y-%m-%d).json
# Signature suite — CPU pinned, 3,000 iterations
docker run --rm --cpuset-cpus="0,1" \
-v "$(pwd)/results:/app/results" quantum-safe-bench \
python -X utf8 tests/bench/bench_signatures.py --with-pqc --iterations 3000 \
--save /app/results/bench_sig_$(date +%Y-%m-%d).json
Native (Windows/Linux, no Docker):
python -X utf8 tests/bench/bench_kem.py --with-pqc --iterations 3000
python -X utf8 tests/bench/bench_signatures.py --with-pqc --iterations 3000
Benchmark results and methodology are in results/BENCHMARKS.md.
Headline numbers (ENV-2, Docker/WSL2, 2026-03-29): full hybrid KEM handshake ~243 µs,
throughput ~2,848 ops/s at 5,000 concurrent users.
The cov_pct (coefficient of variation) column is the timing side-channel proxy —
values near the AES-256-GCM baseline (~2.1%) indicate constant-time behaviour.
Statistical analysis
tests/bench/bench_stats.py provides research-grade statistical utilities
used to generate paper-quality numbers from raw benchmark samples:
from tests.bench.bench_stats import bootstrap_ci, welch_t_test, cohens_d, latex_table
lo, median, hi = bootstrap_ci(samples_us, confidence=0.95)
result = welch_t_test(classical_samples, hybrid_samples)
print(f"p={result.p_value:.4f}, d={cohens_d(classical_samples, hybrid_samples):.2f}")
Code quality
# Type checking
mypy src/quantum_safe --strict
# Linting
ruff check src/ tests/
# Formatting
black src/ tests/
Cite this work
If you use quantum-safe-py in research or build on the methodology, please cite the accompanying paper:
@article{shaw2026quantumsafe,
title = {quantum-safe: Bridging the Post-Quantum Production Gap with a
Hybrid-by-Default Python Cryptography Library},
author = {Shaw, Animesh},
journal = {arXiv preprint arXiv:2605.17061},
year = {2026},
note = {v2},
url = {https://arxiv.org/abs/2605.17061}
}
A machine-readable CITATION.cff is also provided for GitHub's "Cite this repository" button.
Contributing
See CONTRIBUTING.md.
License
Apache 2.0. See LICENSE.
Acknowledgements
Built on:
- Open Quantum Safe / liboqs — reference PQC implementations
- PyCA cryptography — classical primitives and X.509
- NIST PQC Standardization — FIPS 203/204/205
Metadata
Release files for quantum-safe-py 0.3.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 | |
|---|---|---|---|
| quantum_safe_py-0.3.0.tar.gz | 267.3 kB | Details |
Built distributions (wheels)
Total release size: 235.8 MB
Release files / quantum_safe_py-0.3.0.tar.gz
| Download URL | quantum_safe_py-0.3.0.tar.gz |
|---|---|
| Size | 267.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4c47019793735701e91b8558976546f780656b47e710fad2ab392d522bef34fa
|
|
BLAKE2b-256 checksum How to use checksums |
6e1d7a024d9fa1006d91a97485bbfef892db6aed00f2630fcf4c185f4f51429e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / quantum_safe_py-0.3.0-cp312-cp312-win_amd64.whl
| Download URL | quantum_safe_py-0.3.0-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
943156bb7a0b64f5c6cded35871bc086cf4755d13af049983bf4973d72fa33f6
|
|
BLAKE2b-256 checksum How to use checksums |
1fbb8cfe7b401982ffb71b827545aa259af05a7faf762ed39f2afd58fefffa86
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / quantum_safe_py-0.3.0-cp312-cp312-manylinux_2_28_x86_64.whl
| Download URL | quantum_safe_py-0.3.0-cp312-cp312-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 59.6 MB |
| Tags | CPython 3.12 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
58836b7addbae636ed25a352b8d06e2973f4cbde45d45ece5bcaea1f694758bc
|
|
BLAKE2b-256 checksum How to use checksums |
5ca124fc2ca831cc46820fddb5b35423522d492e582b9f360298676d694af4fe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / quantum_safe_py-0.3.0-cp312-cp312-macosx_14_0_arm64.whl
| Download URL | quantum_safe_py-0.3.0-cp312-cp312-macosx_14_0_arm64.whl |
|---|---|
| Size | 14.9 MB |
| Tags | CPython 3.12 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
afe44e7c872389a0b002061bac0174585347ea0c0b4dae35ebbe0dc4b74cd78a
|
|
BLAKE2b-256 checksum How to use checksums |
696ad2a3f187e57e8919881c9e9402f6c023878524482c3099e2e507207ebda3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / quantum_safe_py-0.3.0-cp311-cp311-win_amd64.whl
| Download URL | quantum_safe_py-0.3.0-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
71f1f6e6244c46bbd84ceb10e2a22b9024974fb4a332a2b895444d3f88b2c48c
|
|
BLAKE2b-256 checksum How to use checksums |
fedb95d217dccb99b582daea90c85647e7d7522247ca395795383a952ddb3862
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / quantum_safe_py-0.3.0-cp311-cp311-manylinux_2_28_x86_64.whl
| Download URL | quantum_safe_py-0.3.0-cp311-cp311-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 59.6 MB |
| Tags | CPython 3.11 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
7e2226f0a2bb153e2035baa4774557e2856d9c575cee91e4a1d389cf81f45950
|
|
BLAKE2b-256 checksum How to use checksums |
abda192da29f2aa3af62ecc3b68a5538e86413486bf82f3cff03e69a82124ec9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / quantum_safe_py-0.3.0-cp311-cp311-macosx_14_0_arm64.whl
| Download URL | quantum_safe_py-0.3.0-cp311-cp311-macosx_14_0_arm64.whl |
|---|---|
| Size | 14.9 MB |
| Tags | CPython 3.11 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
f1e5ba40fecf0dcb5ab1f2d89cd6434674534034251bd2318a318c978a76a728
|
|
BLAKE2b-256 checksum How to use checksums |
9f5befa1532e6c7553e43f20e21389263742f43f9196912a4416f1a989692ae0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / quantum_safe_py-0.3.0-cp310-cp310-win_amd64.whl
| Download URL | quantum_safe_py-0.3.0-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 4.1 MB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
6afaafe892aefa2d064ac11c96e13c17b129dc8924b8dcd0357c1ec95af533e1
|
|
BLAKE2b-256 checksum How to use checksums |
75640d5a33d06b68a6075d4ee5ac0dd20a977b0c842ff53e8528f7f1d3c221be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / quantum_safe_py-0.3.0-cp310-cp310-manylinux_2_28_x86_64.whl
| Download URL | quantum_safe_py-0.3.0-cp310-cp310-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 59.6 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
982f80ce7d7531f51c32a79a63c0318892b659fc2cbbdb167c335249f2bffa75
|
|
BLAKE2b-256 checksum How to use checksums |
d47cef1010cc7a898b227cc48dfa2378ba158168036206200e085e0e66a6961e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / quantum_safe_py-0.3.0-cp310-cp310-macosx_14_0_arm64.whl
| Download URL | quantum_safe_py-0.3.0-cp310-cp310-macosx_14_0_arm64.whl |
|---|---|
| Size | 14.9 MB |
| Tags | CPython 3.10 macOS 14.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
3ebc11e7dc4e7936f9e5a3b13ee409378d062e0c7bde2b17929f8a452e8d0beb
|
|
BLAKE2b-256 checksum How to use checksums |
add823e447e015f208500de9ed4ab07e7b7cf9ef816c22a5eb9e5e17cffe6b2c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|