Skip to main content

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.

Python 3.10+ License: Apache 2.0 FIPS 203/204/205 CI Documentation PyPI arXiv


Why this library exists

Every PQC library today exposes algorithm primitives. None of them solve the production problem:

Gap Status in ecosystem This library
Hybrid KEM (X25519+ML-KEM) Only Cloudflare CIRCL (Go) ✓ Default mode
Cross-language key format Every library differs ✓ PEM/CBOR/JWK parity
Migration path for existing keys No library supports this Upgrader + state machine
Protocol helpers (TLS, JWT, X.509) Not implemented anywhere protocols module
CI audit gate (SARIF output) grep scripts qs-audit CLI
SBOM PQC-readiness enrichment None ✓ CycloneDX enrichment

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}")

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

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. ENV-2 benchmarks (Docker/WSL2, 3,000 iterations) show ML-KEM-768 decapsulate CoV ~3.9% — within the AES-256-GCM noise floor band of 2.1%, confirming timing stability in practice.

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:ARXIV_ID_PLACEHOLDER},
  year      = {2026},
  url       = {https://arxiv.org/abs/ARXIV_ID_PLACEHOLDER}
}

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:

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

quantum_safe_py-0.2.1.tar.gz (210.7 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

quantum_safe_py-0.2.1-cp312-cp312-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.12Windows x86-64

quantum_safe_py-0.2.1-cp312-cp312-manylinux_2_28_x86_64.whl (59.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.28+ x86-64

quantum_safe_py-0.2.1-cp312-cp312-macosx_14_0_arm64.whl (14.9 MB view details)

Uploaded CPython 3.12macOS 14.0+ ARM64

quantum_safe_py-0.2.1-cp311-cp311-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.11Windows x86-64

quantum_safe_py-0.2.1-cp311-cp311-manylinux_2_28_x86_64.whl (59.6 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.28+ x86-64

quantum_safe_py-0.2.1-cp311-cp311-macosx_14_0_arm64.whl (14.9 MB view details)

Uploaded CPython 3.11macOS 14.0+ ARM64

quantum_safe_py-0.2.1-cp310-cp310-win_amd64.whl (4.0 MB view details)

Uploaded CPython 3.10Windows x86-64

quantum_safe_py-0.2.1-cp310-cp310-manylinux_2_28_x86_64.whl (59.6 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.28+ x86-64

quantum_safe_py-0.2.1-cp310-cp310-macosx_14_0_arm64.whl (14.9 MB view details)

Uploaded CPython 3.10macOS 14.0+ ARM64

File details

Details for the file quantum_safe_py-0.2.1.tar.gz.

File metadata

  • Download URL: quantum_safe_py-0.2.1.tar.gz
  • Upload date:
  • Size: 210.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for quantum_safe_py-0.2.1.tar.gz
Algorithm Hash digest
SHA256 e153d8e795f9c5a3eadbdbc9000fd4ae3c09fe6786130d17990d72310a4ebd66
MD5 61dd4898122720b4cfd3317bb3037126
BLAKE2b-256 ccb768748fcabe77ed651578affc7bd661331e473206bc4afe791fbad172ed16

See more details on using hashes here.

File details

Details for the file quantum_safe_py-0.2.1-cp312-cp312-win_amd64.whl.

File metadata

File hashes

Hashes for quantum_safe_py-0.2.1-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 a1724657dcbf42dc0d6d32386ffca7ee4880840f52592e63232a3d4261f9540f
MD5 77e5e2ce0e6a6358f692aad039c585ad
BLAKE2b-256 619662a082d00318ba89e8fb8cfd6a9eb162c9799ab57c363898f5a6e8d9ed49

See more details on using hashes here.

File details

Details for the file quantum_safe_py-0.2.1-cp312-cp312-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for quantum_safe_py-0.2.1-cp312-cp312-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 109628534ad15146b72c4667ed548f6b6885d7288f42d08b1066b6317db8f96c
MD5 73a1891bdbd96fb020fff5c8e77c41e9
BLAKE2b-256 02c84c0c0936dab245531fb00f4b97ae904093159ec6fb0d5a10902c00f8fc4a

See more details on using hashes here.

File details

Details for the file quantum_safe_py-0.2.1-cp312-cp312-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for quantum_safe_py-0.2.1-cp312-cp312-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 c359142eea21d047b75663a8c7ca05f399173a09538b1603e0db9514d2d4d371
MD5 9145013c11ee95503a4c8c4486c9b6e2
BLAKE2b-256 c54bd7978dc265d2cbf1d7691379c3f36b55d2a7c1afbd9f506b3ab6e0a3f8dd

See more details on using hashes here.

File details

Details for the file quantum_safe_py-0.2.1-cp311-cp311-win_amd64.whl.

File metadata

File hashes

Hashes for quantum_safe_py-0.2.1-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 eaf3e88c03d6a593e0aecb81c9d2ef38f884b52bdbeb36c305ec1ae1f60e9aee
MD5 97e2161722f6c1fb702759f98f7fd95f
BLAKE2b-256 342f66db99e9eae9418345ebd92562adb82005e4f3f10aeb3ab66c044f1bf108

See more details on using hashes here.

File details

Details for the file quantum_safe_py-0.2.1-cp311-cp311-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for quantum_safe_py-0.2.1-cp311-cp311-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fd99a430c25fa89d70621f34f551aeae6b2e9a4ceeb099a0f79d59cb97a1d5f2
MD5 ef06a4bf7dd2845a53082251a64fb6a9
BLAKE2b-256 879a7d3aea8e544d16f74b6f76084643e5f0a2091c5f9a3951e7cced2c8d937d

See more details on using hashes here.

File details

Details for the file quantum_safe_py-0.2.1-cp311-cp311-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for quantum_safe_py-0.2.1-cp311-cp311-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 21c432ac59726e3a5cbcbaabb579ab86472c620af9ba27b3013be2e228211320
MD5 e7b691cf5575c57a01ba615529f2fee2
BLAKE2b-256 d178c6ec1f6505f02e0c74b293db5631daf8b402e5e65f55f8de09aaa03fef76

See more details on using hashes here.

File details

Details for the file quantum_safe_py-0.2.1-cp310-cp310-win_amd64.whl.

File metadata

File hashes

Hashes for quantum_safe_py-0.2.1-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 328ec96489d03b595c04bcbfd6bea1fce2cb0474db47f6bf7c0959b8c97d0ec0
MD5 30981c90e02528f808c9d3d71d9dd88c
BLAKE2b-256 00df41ee5b3fd694ef27cb79294485d78b506450e5f4a86c10b714fe022ff959

See more details on using hashes here.

File details

Details for the file quantum_safe_py-0.2.1-cp310-cp310-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for quantum_safe_py-0.2.1-cp310-cp310-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4f36aa86f0f4a35ecf801dd444fd7172ee7a673eb34d2d94bb089ddb7dfd73fe
MD5 7c3186963a6ef91cb7a7c7314100bce2
BLAKE2b-256 15e1b65e3bdd38c0b32fa5be711aa0c8b958ef12e5931a9fb1206931d9420b3c

See more details on using hashes here.

File details

Details for the file quantum_safe_py-0.2.1-cp310-cp310-macosx_14_0_arm64.whl.

File metadata

File hashes

Hashes for quantum_safe_py-0.2.1-cp310-cp310-macosx_14_0_arm64.whl
Algorithm Hash digest
SHA256 ae6d9d3966cd8fe3cea8e203edcac8b858ec9f9683a72c138bbac1bbf9e7330c
MD5 4fffb0b61196881d29c45ee64ccab50e
BLAKE2b-256 fd79c8db3557639868e1d78fea9425bf5d6fc62630af56972a7fd1b9a5645e40

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.2.1 This release

10 files

0.1.0

2 files

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