# ves-stark
Python bindings for the VES STARK proof system. Generate and verify zero-knowledge compliance proofs for VES events.
## Installation
```bash
pip install ves-stark
```
## Requirements
- Python >= 3.8
- Supported platforms: Linux (x64, arm64), macOS (x64, arm64), Windows (x64)
## Usage
### Generate a Compliance Proof
```python
import ves_stark
# Create a policy (AML threshold of 10,000)
policy = ves_stark.Policy.aml_threshold(10000)
# Compute the policy hash
policy_hash = ves_stark.compute_policy_hash("aml.threshold", {"threshold": 10000})
# Create public inputs
public_inputs = ves_stark.CompliancePublicInputs(
event_id="550e8400-e29b-41d4-a716-446655440000",
tenant_id="550e8400-e29b-41d4-a716-446655440001",
store_id="550e8400-e29b-41d4-a716-446655440002",
sequence_number=12345,
payload_kind=1,
payload_plain_hash="a" * 64, # 64-char lowercase hex
payload_cipher_hash="b" * 64,
event_signing_hash="c" * 64,
policy_id="aml.threshold",
policy_params={"threshold": 10000},
policy_hash=policy_hash
)
# Generate proof (amount must be < threshold for aml.threshold)
proof = ves_stark.prove(5000, public_inputs, policy)
print(f"Proof generated in {proof.proving_time_ms}ms")
print(f"Proof size: {proof.proof_size} bytes")
print(f"Proof hash: {proof.proof_hash}")
print(f"Witness commitment (hex): {proof.witness_commitment_hex}")
```
### Verify a Proof
```python
import ves_stark
public_inputs_bound = ves_stark.CompliancePublicInputs(
event_id=public_inputs.event_id,
tenant_id=public_inputs.tenant_id,
store_id=public_inputs.store_id,
sequence_number=public_inputs.sequence_number,
payload_kind=public_inputs.payload_kind,
payload_plain_hash=public_inputs.payload_plain_hash,
payload_cipher_hash=public_inputs.payload_cipher_hash,
event_signing_hash=public_inputs.event_signing_hash,
policy_id=public_inputs.policy_id,
policy_params=public_inputs.policy_params,
policy_hash=public_inputs.policy_hash,
witness_commitment=proof.witness_commitment_hex,
)
result = ves_stark.verify(
proof.proof_bytes,
public_inputs_bound,
proof.witness_commitment,
)
if result.valid:
print("Proof is valid!")
print(f"Verified in {result.verification_time_ms}ms")
print(f"Policy: {result.policy_id} (limit: {result.policy_limit})")
else:
print(f"Verification failed: {result.error}")
# VerificationResult is also truthy/falsy
if result:
print("Valid!")
```
`ves_stark.verify(...)` now binds the supplied witness commitment into the public inputs before
verification, so local verification is witness-bound by default.
For payload-to-amount binding, derive a canonical binding artifact and verify against it directly:
```python
amount_binding = ves_stark.create_payload_amount_binding(public_inputs, 5000)
bound_result = ves_stark.verify_with_amount_binding(
proof.proof_bytes,
public_inputs,
amount_binding,
)
```
## API Reference
### Classes
#### `Policy`
Represents a compliance policy.
```python
# Create AML threshold policy (proves amount < threshold)
policy = ves_stark.Policy.aml_threshold(10000)
# Create order total cap policy (proves amount <= cap)
policy = ves_stark.Policy.order_total_cap(50000)
# Create agent authorization policy (proves amount <= maxTotal)
policy = ves_stark.Policy.agent_authorization(20000, "11" * 32)
# Properties
policy.policy_id # "aml.threshold", "order_total.cap", or "agent.authorization.v1"
policy.limit # The threshold/cap/maxTotal value
```
#### `CompliancePublicInputs`
Public inputs for proof generation and verification.
```python
public_inputs = ves_stark.CompliancePublicInputs(
event_id="...", # UUID string
tenant_id="...", # UUID string
store_id="...", # UUID string
sequence_number=12345, # u64
payload_kind=1, # u32
payload_plain_hash="...", # 64-char lowercase hex
payload_cipher_hash="...",
event_signing_hash="...",
policy_id="aml.threshold",
policy_params={"threshold": 10000}, # dict
policy_hash="...", # 64-char lowercase hex
witness_commitment=None, # optional 64-char lowercase hex (witnessCommitment)
authorization_receipt_hash=None, # optional 64-char lowercase hex
amount_binding_hash=None, # optional 64-char lowercase hex
)
# All fields are readable and writable
public_inputs.sequence_number = 12346
```
#### `ComplianceProof`
Result of proof generation.
```python
proof.proof_bytes # bytes - raw proof data
proof.proof_hash # str - SHA-256 hash of proof
proof.proving_time_ms # int - generation time in ms
proof.proof_size # int - size in bytes
proof.witness_commitment # list[int] - 4-element commitment
proof.witness_commitment_hex # str - 64-char lowercase hex commitment
```
#### `VerificationResult`
Result of proof verification.
```python
result.valid # bool - whether proof is valid
result.verification_time_ms # int - verification time in ms
result.policy_limit # int - verified policy limit
# Supports boolean conversion
if result:
print("Valid!")
```
### Functions
#### `prove(amount, public_inputs, policy)`
Generate a STARK compliance proof.
```python
proof = ves_stark.prove(
amount=5000,
public_inputs=public_inputs,
policy=policy
)
```
**Parameters:**
- `amount` (int): The amount to prove compliance for
- `public_inputs` (CompliancePublicInputs): Event metadata and policy info
- `policy` (Policy): The policy to prove compliance against
**Returns:** `ComplianceProof`
**Raises:**
- `ValueError`: If inputs are invalid
- `RuntimeError`: If proof generation fails
#### `verify(proof_bytes, public_inputs, witness_commitment)`
Verify a STARK compliance proof.
```python
result = ves_stark.verify(
proof_bytes=proof.proof_bytes,
public_inputs=public_inputs,
witness_commitment=proof.witness_commitment
)
```
**Parameters:**
- `proof_bytes` (bytes): Raw proof bytes from `prove()`
- `public_inputs` (CompliancePublicInputs): Must match proving inputs and
include `witness_commitment` when using canonical bound verification
- `witness_commitment` (list[int]): 4-element list from proof
**Returns:** `VerificationResult`
**Raises:**
- `ValueError`: If arguments are malformed
#### `verify_agent_authorization(proof_bytes, public_inputs, witness_commitment, receipt)`
Verify an `agent.authorization.v1` proof against a canonical authorization receipt, deriving the
payload amount binding from `receipt["amount"]`.
#### `verify_with_amount_binding(proof_bytes, public_inputs, amount_binding)`
Verify a proof against a canonical payload-derived amount binding.
#### `verify_agent_authorization_with_amount_binding(proof_bytes, public_inputs, amount_binding, receipt)`
Verify an `agent.authorization.v1` proof against both a payload-derived amount binding and a
canonical authorization receipt. This is equivalent to `verify_agent_authorization(...)` when the
binding matches `receipt["amount"]`, but keeps the artifact explicit.
#### `create_payload_amount_binding(public_inputs, amount)`
Create a canonical payload amount binding artifact for the supplied public inputs and extracted
amount.
#### `compute_policy_hash(policy_id, policy_params)`
Compute the canonical policy hash.
```python
hash = ves_stark.compute_policy_hash("aml.threshold", {"threshold": 10000})
```
**Parameters:**
- `policy_id` (str): Policy identifier
- `policy_params` (dict): Policy parameters
**Returns:** `str` - 64-character lowercase hex hash
## Policy Types
| AML Threshold | `aml.threshold` | amount < threshold | Anti-money laundering compliance |
| Order Total Cap | `order_total.cap` | amount <= cap | Order value limits |
| Agent Authorization | `agent.authorization.v1` | amount <= maxTotal | Delegated commerce execution |
## Building from Source
Requires [maturin](https://github.com/PyO3/maturin):
```bash
# Create & activate a virtualenv (required for `maturin develop`)
python -m venv .venv
source .venv/bin/activate
# Install maturin
python -m pip install --upgrade pip maturin
# Build and install in development mode
cd crates/ves-stark-python
maturin develop --release
# Build release wheel
maturin build --release
```
## Performance
Typical performance on modern hardware:
- Proof generation: 500-2000ms
- Proof verification: 50-200ms
- Proof size: ~100-200 KB
## Example: Full Round-Trip
```python
import ves_stark
# Setup
policy = ves_stark.Policy.aml_threshold(10000)
policy_hash = ves_stark.compute_policy_hash("aml.threshold", {"threshold": 10000})
public_inputs = ves_stark.CompliancePublicInputs(
event_id="550e8400-e29b-41d4-a716-446655440000",
tenant_id="550e8400-e29b-41d4-a716-446655440001",
store_id="550e8400-e29b-41d4-a716-446655440002",
sequence_number=1,
payload_kind=1,
payload_plain_hash="0" * 64,
payload_cipher_hash="0" * 64,
event_signing_hash="0" * 64,
policy_id="aml.threshold",
policy_params={"threshold": 10000},
policy_hash=policy_hash
)
# Prove
amount = 5000 # Must be < 10000
proof = ves_stark.prove(amount, public_inputs, policy)
print(f"Generated {proof.proof_size} byte proof in {proof.proving_time_ms}ms")
# Verify
result = ves_stark.verify(proof.proof_bytes, public_inputs, proof.witness_commitment)
assert result.valid, f"Verification failed: {result.error}"
print(f"Verified in {result.verification_time_ms}ms")
```
## License
MIT