ZKAC/docs/PYTHON_API.md
2026-05-06 17:47:35 +02:00

5.1 KiB
Raw Blame History

ZKAC Python API Reference

Version 0.7.1. Cryptographic stack: BBS+ on BLS12-381 (credentials), X25519 + ChaCha20-Poly1305 (transport), Schnorr/Ristretto255 (identity), BLAKE2b (role IDs, signatures).

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) -> bytesrole_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_blindCredential.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 · Changelog / breaking releases