> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pesapay.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> Split TLS capture across two enclaves, a native VOLE proof on the phone, and an attested verifier.

## Components

| Component | Runs on | Job |
| - | - | - |
| SDK | The user's phone (iOS, Android) | Login, capture client, prover, claim check |
| Front door and allocator | Cloud | Authenticates the app, assigns each session a K/T pair and a verifier, enforces quotas |
| TEE\_K | AMD SEV-SNP enclave | Holds the TLS keys, produces the keystream view, signs a receipt |
| TEE\_T | AMD SEV-SNP enclave on a second cloud | Checks record tags, holds the ciphertext view, signs a receipt |
| Verifier | AMD SEV-SNP enclave | Checks both receipts and the proof, signs the claim |
| Trust bundle | Signed document | Lists every enclave and verifier key a consumer may trust |

## Capture

The phone opens its own TCP socket to the provider. TLS 1.3 key establishment runs between the phone, TEE\_K and the provider, so the provider sees an ordinary TLS client on the user's network. The record keys are split: TEE\_K can make the keystream, TEE\_T can check the authentication tags, and the phone holds the request secrets. No single party can forge or read the reply alone.

When the reply is complete, each enclave **freezes** its view and signs a receipt that commits to it. The two receipts bind one session, one origin and one authorised request. A capture that fails before the freeze cannot be resumed, because resuming would reuse a secret; the user starts a new session.

The first profile supports TLS 1.3 with `TLS_AES_128_GCM_SHA256` and a bounded HTTP/1.1 read.

## Proving

The phone proves the policy in a native Rust circuit over VOLE-based zero knowledge (`mpz`), with no virtual machine. The circuit:

* opens both enclaves' committed views and reconstructs the plaintext records,
* parses the bounded reply and locates each field the policy reads,
* checks every predicate (for a payment: status, amount, currency, payee, payer, reference),
* computes the nullifier from the provider's transaction ID.

On ARM phones the prover uses the PMULL instruction for GF(2^128) field math.

## Verification

The verifier is a designated verifier: it takes part in the interactive proof. It runs in an attested SEV-SNP enclave, checks both capture receipts against the trust bundle, checks the proof, and derives the public inputs (policy, context) itself, never from the phone. Only then does it sign a claim with its per-epoch Ed25519 key.

## Cells

The fleet is organised in regional cells. Each cell is a set of K/T capture pairs on two clouds, verifiers on T's cloud, an allocator and a small session directory. The SDK times the cells the front door offers and uses the fastest, or the one for the user's region.

## Two modes

| Mode | Claim says | Used for |
| - | - | - |
| Proof mode | Predicates held for a record the phone proved, bound to a per-order context | Pesa payments |
| Attested mode | TEE\_K read declared endpoints and attests a dataset receipt | Fallback, and datasets too large to prove |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.