Skip to main content

Python bindings for the QUAC 100 Post-Quantum Cryptographic Accelerator

Project description

QUAC 100 Python SDK

PyPI version Python License Documentation

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:

  1. Check device is connected
  2. Verify drivers are installed
  3. 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

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

quantacore_sdk-1.0.0.tar.gz (40.9 kB view details)

Uploaded Source

Built Distribution

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

quantacore_sdk-1.0.0-py3-none-any.whl (33.2 kB view details)

Uploaded Python 3

File details

Details for the file quantacore_sdk-1.0.0.tar.gz.

File metadata

  • Download URL: quantacore_sdk-1.0.0.tar.gz
  • Upload date:
  • Size: 40.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for quantacore_sdk-1.0.0.tar.gz
Algorithm Hash digest
SHA256 2a8c6da0b278033990af5d93437d5c00aaf6eb8b28336f6a61f2cb28182abef0
MD5 c661a496ffe57f4bc6d0a00d6fb59e38
BLAKE2b-256 de6598bbf9803e8585ece5741da3f75cbf6a6628d2e1a046c9e75c51bfd70431

See more details on using hashes here.

File details

Details for the file quantacore_sdk-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: quantacore_sdk-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 33.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.4

File hashes

Hashes for quantacore_sdk-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a3c7d5bd9cec64f17dca4379a3b9cc1bb0bc4726191023f635ff86f6baf46ee4
MD5 816668159d8577fcf7866cfdca866d84
BLAKE2b-256 9405d1b3656d5712bec9309e3c3406706a408ab98a8dc2b2f570c5832d30d214

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