QUAC 100 Python SDK
Python bindings for the QUAC 100 Post-Quantum Cryptographic Accelerator.
Overview
The QUAC 100 Python SDK provides a Pythonic interface to the QUAC 100 hardware accelerator, enabling high-performance post-quantum cryptographic operations with an easy-to-use API.
Features
- ML-KEM (Kyber) - Post-quantum key encapsulation (ML-KEM-512/768/1024)
- ML-DSA (Dilithium) - Post-quantum digital signatures (ML-DSA-44/65/87)
- QRNG - Quantum random number generation
- Hardware-accelerated hashing - SHA-2, SHA-3, SHAKE, HMAC, HKDF
- HSM Key Storage - Secure key management with 256 key slots
- Type hints - Full type annotation support (PEP 561)
- Context managers - Automatic resource cleanup
- Cross-platform - Windows, Linux, macOS support
Requirements
- Python 3.8 or later
- QUAC 100 hardware or simulation mode
Platform Support
| Platform | Architecture | Status |
|---|---|---|
| Windows | x64 | ✅ Supported |
| Linux | x64 | ✅ Supported |
| macOS | x64/arm64 | ✅ Supported |
Installation
From PyPI (Recommended)
pip install quantacore-sdk
From Source
git clone https://github.com/dyber-pqc/quantacore-sdk.git
cd quantacore-sdk/bindings/python
pip install -e .
With Development Dependencies
pip install quantacore-sdk[dev]
Quick Start
import quantacore
# Initialize library
quantacore.initialize()
try:
# Open device
device = quantacore.open_first_device()
# ML-KEM key exchange
kem = device.kem()
with kem.generate_keypair(quantacore.KemAlgorithm.ML_KEM_768) as keypair:
# Sender: encapsulate
with kem.encapsulate(keypair.public_key) as encap:
ciphertext = encap.ciphertext
sender_secret = encap.shared_secret
# Recipient: decapsulate
recipient_secret = kem.decapsulate(keypair.secret_key, ciphertext)
assert sender_secret == recipient_secret
print(f"Shared secret: {quantacore.to_hex(sender_secret)}")
device.close()
finally:
quantacore.cleanup()
API Reference
Library Management
import quantacore
# Initialize with default flags
quantacore.initialize()
# Initialize with specific flags
quantacore.initialize(
quantacore.InitFlags.HARDWARE_ACCEL |
quantacore.InitFlags.FIPS_MODE
)
# Check initialization
if quantacore.is_initialized():
print("Library ready")
# Get version info
print(f"Version: {quantacore.get_version()}")
print(f"Build: {quantacore.get_build_info()}")
# Enumerate devices
devices = quantacore.enumerate_devices()
for dev in devices:
print(f"Device {dev.index}: {dev.model} ({dev.serial_number})")
# Open device
device = quantacore.open_first_device()
# or: device = quantacore.open_device(0)
# Clean up
quantacore.cleanup()
Device Operations
device = quantacore.open_first_device()
# Get device info
info = device.get_info()
print(f"Model: {info.model}")
print(f"Serial: {info.serial_number}")
print(f"Firmware: {info.firmware_version}")
print(f"Key Slots: {info.key_slots}")
# Get device status
status = device.get_status()
print(f"Temperature: {status.temperature}°C")
print(f"Entropy Level: {status.entropy_level}%")
print(f"Healthy: {status.is_healthy}")
# Run self-test
device.self_test()
# Reset device
device.reset()
# Close device
device.close()
Key Encapsulation (ML-KEM/Kyber)
kem = device.kem()
# Generate key pair
keypair = kem.generate_keypair(quantacore.KemAlgorithm.ML_KEM_768)
# Convenience methods: generate_keypair_512(), generate_keypair_768(), generate_keypair_1024()
print(f"Public key: {len(keypair.public_key)} bytes")
print(f"Secret key: {len(keypair.secret_key)} bytes")
# Encapsulate (sender)
encap = kem.encapsulate(keypair.public_key, quantacore.KemAlgorithm.ML_KEM_768)
ciphertext = encap.ciphertext # Send to recipient
shared_secret = encap.shared_secret # Use for encryption
# Decapsulate (recipient)
shared_secret = kem.decapsulate(
keypair.secret_key,
ciphertext,
quantacore.KemAlgorithm.ML_KEM_768
)
# Clean up sensitive data
keypair.close()
encap.close()
Digital Signatures (ML-DSA/Dilithium)
sign = device.sign()
# Generate signing key pair
keypair = sign.generate_keypair(quantacore.SignAlgorithm.ML_DSA_65)
# Convenience methods: generate_keypair_44(), generate_keypair_65(), generate_keypair_87()
# Sign a message
message = b"Important document"
signature = sign.sign(
keypair.secret_key,
message,
quantacore.SignAlgorithm.ML_DSA_65
)
print(f"Signature: {len(signature)} bytes")
# Verify signature
valid = sign.verify(
keypair.public_key,
message,
signature,
quantacore.SignAlgorithm.ML_DSA_65
)
print(f"Valid: {valid}")
# Verify and raise exception if invalid
try:
sign.verify_or_raise(keypair.public_key, message, signature)
except quantacore.VerificationError:
print("Signature verification failed!")
keypair.close()
Random Number Generation (QRNG)
random = device.random()
# Check entropy status
status = random.get_entropy_status()
print(f"Entropy level: {status.level}%")
print(f"Healthy: {status.is_healthy}")
# Generate random bytes
data = random.bytes(32)
# Fill buffer
buffer = bytearray(64)
random.next_bytes(buffer)
# Random integers
value = random.next_int() # 32-bit
value = random.next_int(100) # [0, 100)
value = random.randint(10, 20) # [10, 20]
# Random floats
f = random.next_float() # [0.0, 1.0)
f = random.uniform(10.0, 20.0) # [10.0, 20.0)
# Random boolean
b = random.next_bool()
# UUID
uuid_str = random.uuid() # String format
uuid_obj = random.next_uuid() # UUID object
# Choose from sequence
item = random.choice(['a', 'b', 'c'])
# Sample without replacement
sample = random.sample(range(100), 5)
# Shuffle in place
items = [1, 2, 3, 4, 5]
random.shuffle(items)
# Get shuffled copy
shuffled = random.shuffled([1, 2, 3, 4, 5])
Hashing
hash = device.hash()
# One-shot hashing
digest = hash.hash(quantacore.HashAlgorithm.SHA3_256, b"data")
# Convenience methods
digest = hash.sha256(b"data")
digest = hash.sha384(b"data")
digest = hash.sha512(b"data")
digest = hash.sha3_256(b"data")
digest = hash.sha3_512(b"data")
# String input
digest = hash.sha256("Hello, World!")
# SHAKE (variable output)
output = hash.shake128(b"data", output_length=64)
output = hash.shake256(b"data", output_length=128)
# Incremental hashing
with hash.create_context(quantacore.HashAlgorithm.SHA256) as ctx:
ctx.update(b"Part 1")
ctx.update(b"Part 2")
ctx.update("Part 3") # String also accepted
digest = ctx.digest()
# HMAC
mac = hash.hmac_sha256(key, data)
mac = hash.hmac_sha512(key, data)
mac = hash.hmac(quantacore.HashAlgorithm.SHA256, key, data)
# HKDF key derivation
derived_key = hash.hkdf(
quantacore.HashAlgorithm.SHA256,
ikm=input_key_material,
salt=b"salt",
info=b"context",
length=32
)
Utility Functions
from quantacore import to_hex, from_hex, to_base64, from_base64
from quantacore import secure_zero, secure_compare
# Hex encoding
hex_str = to_hex(b'\xde\xad\xbe\xef') # 'deadbeef'
data = from_hex('deadbeef') # b'\xde\xad\xbe\xef'
# Base64 encoding
b64 = to_base64(data)
data = from_base64(b64)
# URL-safe Base64
b64url = to_base64url(data)
data = from_base64url(b64url)
# Secure operations
secret = bytearray(b"sensitive")
secure_zero(secret) # Zero memory
# Constant-time comparison
if secure_compare(hash1, hash2):
print("Hashes match")
Exception Handling
try:
device = quantacore.open_first_device()
except quantacore.DeviceError as e:
print(f"Device error: {e}")
except quantacore.InitializationError as e:
print(f"Not initialized: {e}")
try:
sign.verify_or_raise(pk, msg, sig)
except quantacore.VerificationError:
print("Invalid signature")
except quantacore.CryptoError as e:
print(f"Crypto error: {e}")
except quantacore.QuacError as e:
print(f"Error [{e.error_code}]: {e.message}")
Error Codes
| Code | Name | Description |
|---|---|---|
| 0 | SUCCESS |
Operation completed |
| -4 | DEVICE_NOT_FOUND |
No device found |
| -6 | DEVICE_ERROR |
Device error |
| -13 | VERIFICATION_FAILED |
Signature invalid |
| -17 | NOT_INITIALIZED |
Library not initialized |
| -26 | INVALID_ALGORITHM |
Invalid algorithm |
| -27 | CRYPTO_ERROR |
Cryptographic error |
Context Managers
The SDK uses context managers for automatic resource cleanup:
# Recommended: use context managers
with quantacore.open_first_device() as device:
kem = device.kem()
with kem.generate_keypair() as kp:
with kem.encapsulate(kp.public_key) as encap:
# Use encap.shared_secret
pass
# encap automatically cleaned up
# keypair automatically cleaned up
# device automatically closed
Testing
# Install test dependencies
pip install quantacore-sdk[test]
# Run tests
pytest
# Run with coverage
pytest --cov=quantacore
# Run specific test
pytest tests/test_kem.py -v
Performance
Typical performance on QUAC 100 hardware:
| Operation | Performance |
|---|---|
| ML-KEM-768 KeyGen | ~1,000,000 ops/sec |
| ML-KEM-768 Encaps | ~1,700,000 ops/sec |
| ML-KEM-768 Decaps | ~8,000,000 ops/sec |
| ML-DSA-65 Sign | ~900,000 ops/sec |
| ML-DSA-65 Verify | ~4,000,000 ops/sec |
| SHA3-256 | ~500 MB/sec |
| QRNG | ~2,000 MB/sec |
Environment Variables
| Variable | Description |
|---|---|
QUAC100_LIBRARY_PATH |
Path to native library |
Troubleshooting
Library Not Found
OSError: Failed to load QUAC 100 native library
Solution: Set the library path:
export QUAC100_LIBRARY_PATH=/path/to/libquac100.so
Device Not Found
DeviceError: No QUAC 100 device found
Solution:
- Check device is connected
- Verify drivers are installed
- Run with elevated privileges if needed
Not Initialized
InitializationError: Library not initialized
Solution: Call quantacore.initialize() first.
Building from Source
# Clone repository
git clone https://github.com/dyber-pqc/quantacore-sdk.git
cd quantacore-sdk/bindings/python
# Create virtual environment
python -m venv venv
source venv/bin/activate # or venv\Scripts\activate on Windows
# Install in development mode
pip install -e .[dev]
# Run tests
pytest
# Build wheel
pip install build
python -m build
Publishing to PyPI
# Build
python -m build
# Upload to TestPyPI
twine upload --repository testpypi dist/*
# Upload to PyPI
twine upload dist/*
Project Structure
python/
├── pyproject.toml # Package configuration
├── setup.py # Legacy support
├── README.md # This file
├── quantacore/ # Main package
│ ├── __init__.py
│ ├── library.py # Library management
│ ├── device.py # Device class
│ ├── kem.py # Key encapsulation
│ ├── sign.py # Digital signatures
│ ├── hash.py # Hashing
│ ├── random.py # QRNG
│ ├── keys.py # Key storage
│ ├── types.py # Type definitions
│ ├── exceptions.py # Exceptions
│ ├── utils.py # Utilities
│ └── native/ # Native libraries
│ ├── windows-x64/
│ ├── linux-x64/
│ └── macos-x64/
└── tests/ # Test suite
├── test_library.py
├── test_kem.py
├── test_sign.py
└── test_utils.py
License
Copyright © 2025 Dyber, Inc. All Rights Reserved.
This software is proprietary and confidential.
Support
- Documentation: https://docs.dyber.org/quac100/python
- Issues: https://github.com/dyber-pqc/quantacore-sdk/issues
- Email: support@dyber.org
- Website: https://dyber.org
Release files for quantacore-sdk 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 | |
|---|---|---|---|
| quantacore_sdk-1.0.1.tar.gz | 45.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| quantacore_sdk-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 79.0 kB
Release files / quantacore_sdk-1.0.1.tar.gz
| Download URL | quantacore_sdk-1.0.1.tar.gz |
|---|---|
| Size | 45.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
452e9d89086b3cdab428ca285c986d021794fb83fe792a3aa6e7071777e375a8
|
|
BLAKE2b-256 checksum How to use checksums |
8524f45dd9a502e274368516f3671f03199c296e89ec8b23f713d2c31c8074c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.4
|
Release files / quantacore_sdk-1.0.1-py3-none-any.whl
| Download URL | quantacore_sdk-1.0.1-py3-none-any.whl |
|---|---|
| Size | 33.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a4fd12b00674643c1ccd53ebdc482fd6e18f6809fdf0310391bb182e92c5d3b3
|
|
BLAKE2b-256 checksum How to use checksums |
dea1dc20d48a0cfeafa179fa10e6a8852071cd0c7d7c2c460f868fcfce357e56
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.4
|