Tutorial 03 — End-to-End Proof via the REST APIs¶
Goal: Run a complete proof lifecycle (setup → prove → verify → download) against the CoSMeTIC Flask APIs using curl.
Prerequisites:
- The Docker stack is running (docker compose up -d) — see docker_deployment.md.
- curl and jq available on your machine.
This tutorial targets the KS API on port 5013. The same steps apply to the ACC (5012) and LRT (5014) APIs — just change the port and any API-specific fields (see api_reference.md).
Variables used in this tutorial¶
bash
HOST="localhost"
PORT="5013"
BASE="http://${HOST}:${PORT}"
Step 1 — Check the server is up¶
bash
curl -s "${BASE}/"
You should get a JSON response or a short status message confirming the API is running.
Step 2 — Run setup¶
Setup builds the Sparse Merkle Trees and compiles EZKL circuits. It only needs to run once per configuration.
```bash SETUP_JOB=$(curl -s -X POST "${BASE}/ks/setup" \ -H "Content-Type: application/json" \ -d '{ "ZKP_MODE": 1, "GEN_FULL_PROOF": 0, "SETUP_MRP": 1, "SETUP_LTR": 1, "ZKP_SCALER": 10, "TREE_HEIGHT": 8 }')
echo "${SETUP_JOB}" | jq .
SETUP_JOB_ID=$(echo "${SETUP_JOB}" | jq -r '.job_id') echo "Setup job ID: ${SETUP_JOB_ID}" ```
Step 3 — Poll until setup is done¶
bash
while true; do
STATUS=$(curl -s "${BASE}/jobs/${SETUP_JOB_ID}" | jq -r '.status')
echo "$(date '+%H:%M:%S') setup status: ${STATUS}"
if [[ "${STATUS}" == "done" || "${STATUS}" == "error" ]]; then break; fi
sleep 10
done
When status is done, setup is complete. If it is error, check the error field in the response.
Step 4 — Obtain a user_hash¶
The user_hash is the raw hash of a user's salted leaf value. In a real deployment this comes from your data pipeline. For testing, check the setup job result for example hashes, or use one logged by driver.py during a dry run.
```bash
Example — substitute with an actual hash from your data¶
USER_HASH="0xabc123..." ```
Step 5 — Submit a proof generation job¶
```bash PROVE_RESP=$(curl -s -X POST "${BASE}/prove-hash/" \ -H "Content-Type: application/json" \ -d "{ \"user_hash\": \"${USER_HASH}\" }")
echo "${PROVE_RESP}" | jq . PROOF_JOB_ID=$(echo "${PROVE_RESP}" | jq -r '.job_id') echo "Proof job ID: ${PROOF_JOB_ID}" ```
The KS API does not require
smt_list— boths1ands2SMTs are probed automatically. To pass a specific nonce (for reproducibility): add"nonce": [[0.0, 0.0, ..., 0.0]](17 values for KS).
Step 6 — Poll until proof generation is done¶
bash
while true; do
STATUS=$(curl -s "${BASE}/jobs/${PROOF_JOB_ID}" | jq -r '.status')
echo "$(date '+%H:%M:%S') proof status: ${STATUS}"
if [[ "${STATUS}" == "done" || "${STATUS}" == "error" ]]; then break; fi
sleep 10
done
Step 7 — Verify the proofs¶
bash
curl -s -X POST "${BASE}/verify-job/${PROOF_JOB_ID}" | jq .
Expected response:
json
{
"ok": true,
"user_hash": "0xabc123...",
"results": [
{"proof_file": "s1/ltr/test_0xabc123....pf", "verified": true},
{"proof_file": "s1/mrp/test_0xabc123..._0.pf", "verified": true},
...
]
}
Step 8 — Download the proof archive¶
bash
curl -OJ "${BASE}/jobs/${PROOF_JOB_ID}/download"
This downloads a .zip file containing all .pf proof files for the job, organized by SMT and proof type:
s1/ltr/test_<hash>.pf
s1/mrp/test_<hash>_<level>.pf
s2/ltr/test_<hash>.pf
s2/mrp/test_<hash>_<level>.pf
Step 9 (optional) — Download the abs-gap proof¶
The KS test also produces a precomputed abs-gap proof during setup:
bash
curl -OJ "${BASE}/abs-gap-proof"
Step 10 (optional) — Download verification artifacts¶
If you need to verify proofs offline, download the verification keys and settings:
```bash curl -X POST "${BASE}/fetch-vk" \ -H "Content-Type: application/json" \ -d '{"smt_list": ["s1", "s2"], "which": ["ltr", "mrp"]}' -OJ
curl -X POST "${BASE}/fetch-settings" \ -H "Content-Type: application/json" \ -d '{"smt_list": ["s1", "s2"], "which": ["ltr", "mrp"]}' -OJ ```
Step 11 — Clean up the job¶
bash
curl -X DELETE "${BASE}/jobs/${PROOF_JOB_ID}"
Adapting this tutorial for ACC or LRT¶
| Change | ACC (5012) |
LRT (5014) |
|---|---|---|
| Port | 5012 |
5014 |
| Setup endpoint | /acc/setup |
/lrt/setup |
smt_list in prove |
["length", "acc"] |
["full", "reduced"] |
| Nonce shape | (1, 3) |
(1, 11) |
Everything else (polling, verify, download) is identical.