Skip to main content

Official Python SDK for the Qpher Post-Quantum Cryptography API — ML-KEM-768 (FIPS 203) encryption and ML-DSA-65 (FIPS 204) digital signatures. Alternative to liboqs.

Project description

Qpher Python SDK

Official Python SDK for the Qpher Post-Quantum Cryptography API.

Installation

pip install qpher

Requirements

  • Python 3.9+

Quick Start

from qpher import Qpher

# Initialize the client
client = Qpher(api_key="qph_live_your_api_key")

# Encrypt data using Kyber768 KEM
result = client.kem.encrypt(
    plaintext=b"Hello, Quantum World!",
    key_version=1,
)
print(f"Ciphertext: {result.ciphertext.hex()}")

# Decrypt data
decrypted = client.kem.decrypt(
    ciphertext=result.ciphertext,
    key_version=result.key_version,
)
print(f"Plaintext: {decrypted.plaintext}")

# Sign a message using Dilithium3
sig_result = client.signatures.sign(
    message=b"Invoice #12345",
    key_version=1,
)
print(f"Signature: {sig_result.signature.hex()}")

# Verify a signature
verify_result = client.signatures.verify(
    message=b"Invoice #12345",
    signature=sig_result.signature,
    key_version=sig_result.key_version,
)
print(f"Valid: {verify_result.valid}")

API Reference

Client Initialization

from qpher import Qpher

client = Qpher(
    api_key="qph_live_your_api_key",  # Required
    base_url="https://api.qpher.ai",  # Optional, default
    timeout=30,                        # Optional, seconds
    max_retries=3,                     # Optional
)

KEM Operations (Kyber768)

Encrypt

result = client.kem.encrypt(
    plaintext=b"secret data",
    key_version=1,
    mode="standard",      # Optional: "standard" or "deterministic"
    salt=b"...",          # Required if mode="deterministic" (min 32 bytes)
)
# result.ciphertext: bytes
# result.key_version: int
# result.algorithm: str ("Kyber768")
# result.request_id: str

Decrypt

result = client.kem.decrypt(
    ciphertext=encrypted_data,
    key_version=1,
)
# result.plaintext: bytes
# result.key_version: int
# result.algorithm: str
# result.request_id: str

Signature Operations (Dilithium3)

Sign

result = client.signatures.sign(
    message=b"document to sign",
    key_version=1,
)
# result.signature: bytes (3,293 bytes)
# result.key_version: int
# result.algorithm: str ("Dilithium3")
# result.request_id: str

Verify

result = client.signatures.verify(
    message=b"document to sign",
    signature=signature_bytes,
    key_version=1,
)
# result.valid: bool
# result.key_version: int
# result.algorithm: str
# result.request_id: str

Key Management

Generate Key

result = client.keys.generate(algorithm="Kyber768")
# result.key_version: int
# result.algorithm: str
# result.status: str ("active")
# result.public_key: bytes
# result.created_at: str

Rotate Key

result = client.keys.rotate(algorithm="Kyber768")
# result.key_version: int (new)
# result.old_key_version: int
# result.algorithm: str
# result.public_key: bytes

Get Active Key

key_info = client.keys.get_active(algorithm="Kyber768")
# key_info.key_version: int
# key_info.algorithm: str
# key_info.status: str
# key_info.public_key: bytes
# key_info.created_at: str

List Keys

result = client.keys.list(
    algorithm="Kyber768",  # Optional filter
    status="active",       # Optional filter: "active", "retired", "archived"
)
# result.keys: List[KeyInfo]
# result.total: int

Retire Key

result = client.keys.retire(algorithm="Kyber768", key_version=1)
# result.key_version: int
# result.status: str ("retired")

Error Handling

from qpher import (
    Qpher,
    QpherError,
    AuthenticationError,
    ValidationError,
    NotFoundError,
    RateLimitError,
)

try:
    result = client.kem.encrypt(plaintext=b"data", key_version=99)
except NotFoundError as e:
    print(f"Key not found: {e.message}")
    print(f"Error code: {e.error_code}")
    print(f"Request ID: {e.request_id}")
except RateLimitError as e:
    print("Rate limit exceeded, please retry later")
except AuthenticationError as e:
    print("Invalid API key")
except ValidationError as e:
    print(f"Invalid input: {e.message}")
except QpherError as e:
    print(f"API error: {e.message}")

Error Types

Exception HTTP Status Description
AuthenticationError 401 Invalid or missing API key
ValidationError 400 Invalid request parameters
ForbiddenError 403 Operation not allowed
NotFoundError 404 Resource not found
RateLimitError 429 Rate limit exceeded
ServerError 500+ Server-side errors
TimeoutError 504 Request timed out
ConnectionError 503 Connection failed

Supported Algorithms

Algorithm Type Security Level
Kyber768 (ML-KEM-768) KEM (Encryption) NIST Level 3
Dilithium3 (ML-DSA-65) Digital Signatures NIST Level 3
X-Wing (X25519 + ML-KEM-768) Hybrid KEM NIST Level 3
Composite ML-DSA (ECDSA P-256 + ML-DSA-65) Hybrid Signatures NIST Level 3

Hybrid Mode (Pro/Enterprise plans): Pass algorithm="X-Wing" for hybrid KEM or algorithm="Composite-ML-DSA" for hybrid signatures. Without the algorithm parameter, PQC-only algorithms are used (backward-compatible).

Hybrid mode combines PQC with classical cryptography for defense-in-depth: if a lattice cryptanalysis breakthrough weakens ML-KEM or ML-DSA, the classical component (X25519 / ECDSA) still protects your data.

License

MIT License - see LICENSE for details.

Links

Alternative to: liboqs, AWS KMS PQC, Google Cloud KMS PQC.

Project details


Download files

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

Source Distribution

qpher-1.2.0.tar.gz (33.4 kB view details)

Uploaded Source

Built Distribution

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

qpher-1.2.0-py3-none-any.whl (32.0 kB view details)

Uploaded Python 3

File details

Details for the file qpher-1.2.0.tar.gz.

File metadata

  • Download URL: qpher-1.2.0.tar.gz
  • Upload date:
  • Size: 33.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for qpher-1.2.0.tar.gz
Algorithm Hash digest
SHA256 aaec49f9c05c53204bae3b0e77b3030e6648e8ebfcc12cb759012d0fa8a75e78
MD5 0cdeea39e9f84c71264f899e4cf00a56
BLAKE2b-256 06f61b696a2e82acf1e3b2e1f1b1b9c0dfbdba5685b748bea1e28fb5d2a0d5bd

See more details on using hashes here.

File details

Details for the file qpher-1.2.0-py3-none-any.whl.

File metadata

  • Download URL: qpher-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 32.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for qpher-1.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c368a10efbb8db46a16a2c53d43903b663028d396d5f6a7903e7ef18c67fd233
MD5 e9055b321e9455d195c3aacfb8335337
BLAKE2b-256 1b90038df1ab852c1acfc5981244fa665d97bba559f461551a240014a23f070d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page