# ZKAC Python API Reference Version 0.4.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` - `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 ### `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 - `verify_auth(session, encrypted_auth, registry) -> bytes` — returns 32-byte `role_id` ### `Session` - `transcript_hash() -> bytes` — use as `nonce` for `Credential.present` - `encrypt(plaintext) -> bytes` - `decrypt(packet) -> bytes` ## Typical flow 1. Issuer creates `BbsIssuer()`; server `register_role(role_id, issuer.public_key(), epoch)`. 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` (verifies server identity + sends BBS+ auth) → server `verify_auth`. 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)