Metadata-Version: 2.4
Name: cyclecore-pq
Version: 0.3.0
Summary: Python SDK for CycleCore PQ — Post-Quantum Cryptography as a Service
Author-email: CycleCore Technologies <hi@cyclecore.ai>
License-Expression: MIT
Project-URL: Homepage, https://cyclecore.ai/pq
Project-URL: Documentation, https://pq-api.cyclecore.ai/docs
Project-URL: Live Demo, https://pq-api.cyclecore.ai/try
Project-URL: API Reference, https://pq-api.cyclecore.ai/docs
Project-URL: PyPI, https://pypi.org/project/cyclecore-pq/
Keywords: post-quantum,cryptography,dilithium,kyber,pqc
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security :: Cryptography
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.24.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Dynamic: license-file

# CycleCore PQ — Python SDK

[![PyPI version](https://img.shields.io/pypi/v/cyclecore-pq)](https://pypi.org/project/cyclecore-pq/)
[![Python](https://img.shields.io/pypi/pyversions/cyclecore-pq)](https://pypi.org/project/cyclecore-pq/)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)

Post-quantum cryptography as a service. Dilithium3 signing, Kyber768 encryption, AES-256-GCM — one API call. NIST-standardized (FIPS 204, FIPS 203, FIPS 197).

**[Try it now](https://pq-api.cyclecore.ai/try)** — no signup, no install, no API key.

## Install

```bash
pip install cyclecore-pq
```

## Quick Start

```python
from cyclecore_pq import CycleCoreClient

client = CycleCoreClient("pq_live_YOUR_KEY")

# Sign a message with Dilithium3 (FIPS 204)
result = client.sign(b"hello world")
print(f"Signature: {result.signature[:40]}...")
print(f"Latency: {result.latency_us:.1f} us")

# Verify
verified = client.verify(b"hello world", result.signature_bytes)
print(f"Valid: {verified.valid}")  # True

# Encrypt with Kyber768 + AES-256-GCM (FIPS 203/197)
encrypted = client.encrypt(b"sensitive data")
decrypted = client.decrypt(encrypted.ciphertext_bytes)
print(decrypted.plaintext_bytes)  # b"sensitive data"
```

Get a free API key (1,000 ops/day): [Register](https://pq-api.cyclecore.ai/v1/auth/register)

## Zero-Exposure Signing (ZES)

Sign and verify without exposing plaintext to the API. Your data is hashed client-side with SHAKE-256 — the API only sees a 32-byte digest.

```python
from cyclecore_pq import CycleCoreClient, zes_sign, zes_verify

client = CycleCoreClient("pq_live_YOUR_KEY")

# API never sees your original data — only a SHAKE-256 hash
result = zes_sign(client, b"sensitive medical record")
print(f"Signature: {result.signature[:40]}...")

# Verify (also uses ZES — hashes before checking)
verified = zes_verify(client, b"sensitive medical record", result.signature_bytes)
print(f"Valid: {verified.valid}")  # True
```

**Batch signing** — send 32 bytes per item instead of full payloads:

```python
from cyclecore_pq import zes_sign_batch

records = [record.encode() for record in patient_records]
batch = zes_sign_batch(client, records)  # up to 1,000
```

**When to use ZES:**
- Regulated data (HIPAA, PCI, GDPR) — sign without sending PII to a third party
- Large documents — send 32 bytes instead of 10MB
- Zero-trust architectures — use CycleCore without trusting us with your content
- Blockchain/DeFi — sign transaction digests without exposing full tx data

ZES uses SHAKE-256 (recommended for Dilithium synergy). The double-hash chain (SHAKE-256 client, SHA-256 server, Dilithium3 sign) is cryptographically sound and does not weaken NIST security properties. See `examples/zes_privacy_signing.py` for full examples.

> **Note:** ZES applies to signing and verification only. Encryption requires actual plaintext.

## Async

```python
from cyclecore_pq import AsyncCycleCoreClient

async with AsyncCycleCoreClient("pq_live_YOUR_KEY") as client:
    result = await client.sign(b"hello world")
```

## Methods

| Method | Description |
|--------|-------------|
| `zes_sign(client, data)` | **Zero-Exposure Sign** — hash locally, sign the digest |
| `zes_verify(client, data, sig)` | **Zero-Exposure Verify** — hash locally, verify the digest |
| `zes_sign_batch(client, data_list)` | **Zero-Exposure Batch** — hash + sign up to 1,000 |
| `zes_digest(data)` | Compute SHAKE-256 digest for custom workflows |
| `sign(message)` | Sign with Dilithium3 |
| `verify(message, signature)` | Verify a signature |
| `encrypt(plaintext)` | Encrypt with Kyber768 + AES-256-GCM |
| `decrypt(ciphertext)` | Decrypt a ciphertext blob |
| `sign_batch(messages)` | Batch sign (up to 1,000) |
| `encrypt_batch(plaintexts)` | Batch encrypt (up to 1,000) |
| `handshake_init()` | Start PQ key exchange |
| `handshake_respond(...)` | Respond to key exchange |
| `handshake_finish(...)` | Complete key exchange |
| `attest(data)` | Add to attestation chain |
| `attest_verify(chain_id)` | Verify chain integrity |
| `attest_export(chain_id)` | Export chain for audit |
| `keys()` | Get your public keys |
| `rotate_keys()` | Rotate key pairs |
| `usage_stats()` | Usage statistics |
| `health()` | API health check |

## Errors

```python
from cyclecore_pq import AuthenticationError, RateLimitError, ValidationError

try:
    result = client.sign(b"hello")
except AuthenticationError:
    print("Invalid API key")
except RateLimitError:
    print("Rate limit exceeded")
except ValidationError:
    print("Bad request")
```

## Links

- [Live Demo](https://pq-api.cyclecore.ai/try) — try PQ crypto in your browser
- [API Docs](https://pq-api.cyclecore.ai/docs) — interactive Swagger UI
- [Homepage](https://cyclecore.ai/pq)
