ZKAC/docs/PYTHON_API.md
2026-05-06 16:35:09 +02:00

116 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# ZKAC Python API Reference
Version 0.7.0. Cryptographic stack: **BBS+** on BLS12-381 (credentials), **X25519** + **ChaCha20-Poly1305** (transport), **Schnorr/Ristretto255** (identity), **BLAKE2b** (role IDs, signatures).
```python
import zkac
```
## Constants
### `MAX_BBS_AUTH_PROOF_BYTES`
Upper bound on BBS+ proof size in an encrypted auth packet (256 KiB). Larger proofs are rejected.
## Transport identity (Ristretto255)
### `Keypair()`
Generates a new random keypair (long-term identity).
- `public_key() -> PublicKey` — raises `ValueError` if consumed by `Node(...)`
- `sign(msg: bytes) -> bytes` — 64-byte Schnorr signature over `msg`
### `PublicKey`
- `to_bytes() -> bytes` — 32 bytes
- `from_bytes(bytes) -> PublicKey`
- `verify(msg: bytes, signature: bytes) -> bool` — verify a 64-byte Schnorr signature
- Equality, hash, `repr` supported
## BBS+ credentials
### `role_id(name: str) -> bytes`
32-byte opaque role id from a human-readable name.
### `BbsIssuer()`
New random issuer. `from_secret_key(bytes)` restores from 32-byte secret.
- `public_key() -> BbsPublicKey`
- `secret_key_bytes() -> bytes` (confidential)
- `issue_blind(commitment_with_proof, role_id, epoch) -> bytes``role_id` must be 32 bytes
### `BbsPublicKey`
- `to_bytes() / from_bytes`
### `prepare_blind_request() -> BlindRequest`
- `commitment_with_proof()`, `member_secret()`, `prover_blind()` — all return `bytes`
### `Credential.finalize(blind_sig, member_secret, prover_blind, role_id, epoch, pk) -> Credential`
`role_id` and `prover_blind` must be 32 bytes.
- `present(nonce) -> bytes`
- `role_id() -> bytes`, `epoch() -> int`
## Server registry
### `RoleRegistry`
- `register_role(role_id, pk, epoch)``role_id` 32 bytes
- `set_epoch(role_id, epoch)`
- `verify_presentation(role_id, proof_bytes, nonce) -> bool`
- `has_role(role_id) -> bool`
## Node and session
### `PendingConnect`
Opaque handle returned from `connect()`; passed once into a `complete_*` method (then consumed).
### `Node(keypair)` — consumes `Keypair`
- `public_key() -> PublicKey`
- `connect() -> (PendingConnect, bytes)` — 32-byte init message
- `accept(init_msg) -> (Session, bytes)``init_msg` 32 bytes
- `prove_identity(session) -> bytes` — server produces encrypted identity proof (Schnorr signature over transcript)
- `complete_connect(pending, response_msg, identity_proof, expected_server_pk, credential) -> (Session, bytes)` — verifies server identity, then produces BBS+ auth packet (static `RoleRegistry`)
- `complete_connect_anon(pending, response_msg, identity_proof, expected_server_pk) -> Session` — server identity only; no BBS+ auth packet
- `complete_connect_managed(pending, response_msg, identity_proof, expected_server_pk, credential, registry_id) -> (Session, bytes)` — auth packet includes 32-byte registry id (client-managed registries)
- `verify_auth(session, encrypted_auth, registry) -> bytes` — returns 32-byte `role_id` for static `RoleRegistry`
- `verify_auth_managed(session, encrypted_auth, manager) -> (registry_id, role_id)` — for `RegistryManager`
### `Session`
- `transcript_hash() -> bytes` — use as `nonce` for `Credential.present`
- `encrypt(plaintext) -> bytes`
- `decrypt(packet) -> bytes`
## Managed registries (optional)
Server-side state for multiple registries and admin proofs lives in **`RegistryManager`**. Opaque **`RegistryState`** blobs are built and certified client-side, then **`registry_id(admin_issuer_pk)`** / **`admin_role_id()`** identify a registry and the fixed admin role. Methods on **`RegistryManager`** include `create` / `update` / `get` / `has_registry`, `verify_admin`, `verify_presentation(registry_id, role_id, …)`, and issuance-queue helpers (`queue_issuance_request`, `take_pending_requests`, `grant_credential`, `take_granted_credential`). **`RegistryState`** exposes `build`, `serialize` / `deserialize`, `registry_id`, `version`, `state_hash`, `certify`, and `verify_cert`.
## E2E issuance encryption (optional)
**`IssuanceKeypair`** (with `encrypt` / `decrypt` on ephemeral keys) and module helpers **`encrypt_for_admin`** / **`decrypt_from_admin`** support encrypting blind-commitment material to an admins issuance public key. See `src/python.rs` for exact parameters.
## Typical flow
1. Issuer creates `BbsIssuer()`; server `register_role(role_id, issuer.public_key(), epoch)` (static registry), or use **`RegistryManager`** + certified **`RegistryState`** for multi-tenant / managed flows.
2. Member: `prepare_blind_request` → issuer `issue_blind``Credential.finalize`.
3. **Out-of-band:** client obtains server's `PublicKey` (static config, pinning, etc.).
4. Client: `connect` → server `accept` → server `prove_identity` → client `complete_connect` or `complete_connect_managed` (verifies server identity + sends BBS+ auth) → server `verify_auth` or `verify_auth_managed`. Use `complete_connect_anon` when no credential auth is needed.
5. Use `Session.encrypt` / `decrypt` for data.
## Errors
Raises `ValueError` with descriptive messages for crypto failures, replay, identity verification, and bad inputs.
## Further reading
[Security model and assumptions](./SECURITY.md) · [Changelog / breaking releases](../CHANGELOG.md)