Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions .github/workflows/verifier-equivalence.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: verifier-equivalence

on:
push:
branches: [main]
pull_request:
workflow_dispatch:

# Three independently written ZAP1 verifiers (Python verify_proof.py, Rust
# zap1-verify, and the TypeScript-family Node runner) each compute a canonical
# fingerprint over a frozen corpus. This job fails if they disagree, or if the
# live output drifts from the committed reference. See equivalence/README.md.
jobs:
equivalence:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5

- uses: dtolnay/rust-toolchain@stable

- uses: actions/setup-python@v6
with:
python-version: "3.12"

- uses: actions/setup-node@v5
with:
node-version: "24"

- name: Python verifier fingerprints
run: python3 equivalence/fingerprint.py > "$RUNNER_TEMP/fp-python.txt"

- name: Rust verifier fingerprints
run: |
cargo run --quiet --manifest-path equivalence/rust/Cargo.toml -- \
equivalence/corpus.json > "$RUNNER_TEMP/fp-rust.txt"

- name: TypeScript verifier fingerprints
run: node equivalence/typescript/fingerprint.mjs > "$RUNNER_TEMP/fp-typescript.txt"

- name: Cross-implementation equivalence (python vs rust)
run: diff -u "$RUNNER_TEMP/fp-python.txt" "$RUNNER_TEMP/fp-rust.txt"

- name: Cross-implementation equivalence (python vs typescript)
run: diff -u "$RUNNER_TEMP/fp-python.txt" "$RUNNER_TEMP/fp-typescript.txt"

- name: Frozen corpus (python vs committed reference)
run: diff -u equivalence/fingerprints.expected.txt "$RUNNER_TEMP/fp-python.txt"
2 changes: 1 addition & 1 deletion CROSSLINK_INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,4 @@ The `zap1-verify` crate walks the Merkle proof path from leaf to root and confir

## Timeline

The staking event types are implemented and available in the API now. They can be tested against the live stack at pay.frontiercompute.io. When Crosslink launches, validators can start attesting immediately - no protocol changes needed.
The staking event types are implemented and available in the API now. They can be tested against the live stack at api.frontiercompute.cash. When Crosslink launches, validators can start attesting immediately - no protocol changes needed.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ tokio-stream = "0.1"
zap1-verify = { path = "zap1-verify" }

# Universal memo decoder
zcash-memo-decode = "0.1.0"
zcash-memo-decode = "0.1.1"
rand_core = "0.6.4"
incrementalmerkletree = "0.8.2"
shardtree = "0.6.2"
Expand Down
2 changes: 2 additions & 0 deletions E2E_PROOF_20260327.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ First on-chain ownership attestation anchored on Zcash mainnet.

Root: `024e36515ea30efc15a0a7962dd8f677455938079430b9eab174f46a4328a07a`

Scheme: `ZAP1_LEGACY_DUPLICATE_ODD` (historical pre-count-binding anchor)

### Anchor Transaction
- Txid: `98e1d6a01614c464c237f982d9dc2138c5f8aa08342f67b867a18a4ce998af9a`
- Block: 3,286,631
Expand Down
19 changes: 12 additions & 7 deletions EVALUATOR_QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,30 @@ cd zap1
bash scripts/evaluate.sh
```

This runs the live validation path against the public stack and forwards to `scripts/check.sh`.
This runs the validation path and forwards to `scripts/check.sh`. The proof
verification step is offline-first; live API reads are used for current
status/freshness.

## What it proves

- the live API is reachable and reports `protocol: ZAP1`
- anchored roots and leaves exist on mainnet
- a live proof verifies
- bundled proof material verifies without trusting a server
- current live proof routing is checked when the deployment exposes it for the
latest leaf
- memo decode returns `zap1` for a known attestation
- explorer and simulator are reachable
- published crates are live
- local Rust checks run when the toolchain is available

## Manual surfaces

- Live protocol info: `https://pay.frontiercompute.io/protocol/info`
- Live stats: `https://pay.frontiercompute.io/stats`
- Anchor history: `https://pay.frontiercompute.io/anchor/history`
- Proof page: `https://pay.frontiercompute.io/verify/075b00df286038a7b3f6bb70054df61343e3481fba579591354a00214e9e019b`
- Proof JSON: `https://pay.frontiercompute.io/verify/075b00df286038a7b3f6bb70054df61343e3481fba579591354a00214e9e019b/proof.json`
- Live protocol info: `https://api.frontiercompute.cash/protocol/info`
- Live stats: `https://api.frontiercompute.cash/stats`
- Anchor status: `https://api.frontiercompute.cash/anchor/status`
- Anchor history: `https://api.frontiercompute.cash/anchor/history`
- Offline proof check: `python3 examples/verify_proof.py`
- Optional live freshness check: `python3 examples/verify_proof.py --live-status`
- Browser verifier: `https://frontiercompute.io/verify.html`

## Supporting docs
Expand Down
15 changes: 11 additions & 4 deletions EVIDENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,21 @@ ZAP1 validation check
pass protocol/info returns ZAP1
pass mainnet anchors > 0
pass mainnet leaves > 0
pass live proof verifies
pass offline proof bundle verifies
pass memo decode returns zap1
pass explorer reachable
pass simulator reachable
skip explorer reachable (optional web surface HTTP 000000)
skip simulator reachable (optional web surface HTTP 000000)
pass zap1-verify on crates.io
pass events feed returns data
pass current live proof endpoint verifies
pass zcash-memo-decode on crates.io
pass cargo test passes
pass ZIP-1243 conformance vectors
pass live API schema check
pass cargo metadata locked
pass zap1-verify tests pass
pass zcash-memo-decode tests pass

14 pass, 0 fail
```

## Repository State
Expand Down
22 changes: 13 additions & 9 deletions ONCHAIN_PROTOCOL.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Mainnet proof reference:
- first anchor txid: `98e1d6a01614c464c237f982d9dc2138c5f8aa08342f67b867a18a4ce998af9a`
- block height: `3,286,631`
- anchored root: `024e36515ea30efc15a0a7962dd8f677455938079430b9eab174f46a4328a07a`
- scheme: `ZAP1_LEGACY_DUPLICATE_ODD` (historical anchor; current roots use count-bound commitments)

## 2. Memo Protocol

Expand Down Expand Up @@ -53,7 +54,7 @@ Transaction types:
| `0x06` | `SHIELD_RENEWAL` | `hash(wallet_hash || year)` | Active |
| `0x07` | `TRANSFER` | `hash(old_wallet || new_wallet || serial_number)` | Active |
| `0x08` | `EXIT` | `hash(wallet_hash || serial_number || timestamp)` | Active |
| `0x09` | `MERKLE_ROOT` | raw 32-byte Merkle root | Active |
| `0x09` | `MERKLE_ROOT` | raw 32-byte Merkle root commitment | Active |
| `0x0A` | `STAKING_DEPOSIT` | `hash(wallet_hash || amount_zat_be || validator_id)` | Reserved for Crosslink |
| `0x0B` | `STAKING_WITHDRAW` | `hash(wallet_hash || amount_zat_be)` | Reserved for Crosslink |
| `0x0C` | `STAKING_REWARD` | `hash(wallet_hash || epoch_be || reward_zat_be)` | Reserved for Crosslink |
Expand All @@ -79,7 +80,7 @@ HOSTING_PAYMENT = BLAKE2b_32(0x05 || len(serial_number) || serial_number || m
SHIELD_RENEWAL = BLAKE2b_32(0x06 || len(wallet_hash) || wallet_hash || year_be)
TRANSFER = BLAKE2b_32(0x07 || len(old_wallet) || old_wallet || len(new_wallet) || new_wallet || len(serial_number) || serial_number)
EXIT = BLAKE2b_32(0x08 || len(wallet_hash) || wallet_hash || len(serial_number) || serial_number || timestamp_be)
MERKLE_ROOT = current_root
MERKLE_ROOT = current count-bound Merkle root commitment
STAKING_DEPOSIT = BLAKE2b_32(0x0A || wallet_hash || amount_zat_be || validator_id)
STAKING_WITHDRAW = BLAKE2b_32(0x0B || wallet_hash || amount_zat_be)
STAKING_REWARD = BLAKE2b_32(0x0C || wallet_hash || epoch_be || reward_zat_be)
Expand All @@ -105,16 +106,19 @@ Rules:
- the tree only grows; leaves are never deleted or rewritten
- parent nodes are computed as `BLAKE2b_32(left || right)`
- node hashing uses the personalization `NordicShield_MRK`
- if a layer has an odd leaf count, the final node is duplicated
- the current root is recomputed after each insertion
- if a layer has an odd node count, the final node carries up unchanged
- the raw tree root is committed as `BLAKE2b_32(0x01 || leaf_count_be_u64 || raw_tree_root)`
- root commitment hashing uses the personalization `NordicShield_RTK`
- the current committed root is recomputed after each insertion
- root history is preserved so older proofs remain tied to a specific anchor
- historical anchors produced before count binding used odd-node duplication and are verified only under `ZAP1_LEGACY_DUPLICATE_ODD`

Persistence model:

- `merkle_leaves`: leaf hash, event type, wallet hash, serial number, created time
- `merkle_roots`: root hash, leaf count, anchor txid, anchor height, created time

An inclusion proof consists of the leaf hash, ordered sibling hashes, sibling positions, the derived root, and the anchor transaction reference for that root.
An inclusion proof consists of the leaf hash, ordered sibling hashes, sibling positions, leaf count, the derived root commitment, and the anchor transaction reference for that root.

## 5. On-Chain Anchoring

Expand All @@ -123,7 +127,7 @@ The current Merkle root is periodically committed to Zcash in a shielded transac
Anchor rules:

- memo type is always `0x09`
- payload is the 32-byte current Merkle root
- payload is the 32-byte current Merkle root commitment
- send path uses `zingo-cli`
- anchor cadence is every 10 events or every 24 hours, whichever comes first
- the resulting txid and mined block height are recorded with the root
Expand All @@ -142,11 +146,11 @@ The txid is part of the proof bundle. A verifier checks the memo in the mined tr

Participant verification flow:

1. Open `pay.frontiercompute.io/verify/{leaf_hash}`.
1. Open `api.frontiercompute.cash/verify/{leaf_hash}`.
2. Read the displayed leaf hash, Merkle proof path, root, anchor txid, and block height.
3. Recompute the event leaf from the participant wallet hash and, where applicable, the serial number.
4. Walk the proof path to recompute the root.
5. Confirm the derived root equals the displayed root.
4. Walk the proof path to recompute the raw tree root.
5. Commit `leaf_count` and the raw tree root with `NordicShield_RTK`, then confirm the derived root commitment equals the displayed root.
6. Open the anchor txid in a Zcash explorer or with local node tooling.
7. Confirm the memo contains the matching `ZAP1:09` root commitment.
8. Confirm the transaction is mined at the stated block height on Zcash mainnet.
Expand Down
54 changes: 31 additions & 23 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ bash scripts/check.sh

Open:

`https://pay.frontiercompute.io/protocol/info`
`https://api.frontiercompute.cash/protocol/info`

Confirms:

Expand All @@ -30,7 +30,7 @@ Confirms:

Open:

`https://pay.frontiercompute.io/stats`
`https://api.frontiercompute.cash/stats`

Confirms:

Expand All @@ -43,7 +43,7 @@ Confirms:

Open:

`https://pay.frontiercompute.io/anchor/history`
`https://api.frontiercompute.cash/anchor/history`

Human-readable view:

Expand All @@ -56,42 +56,50 @@ Confirms:
- block heights
- leaf-count growth over time

## 4. Live proof page
## 4. Offline proof verification

Open:
Run:

`https://pay.frontiercompute.io/verify/075b00df286038a7b3f6bb70054df61343e3481fba579591354a00214e9e019b`
```bash
python3 examples/verify_proof.py examples/proof_bundle_example.json
```

Confirms:

- leaf hash
- proof path
- root
- anchor txid
- block height
- bundled anchor reference, if present
- no hosted `/verify` endpoint is required

## 5. Server-side verification
## 5. Optional live proof fetch

Open:
If the live deployment exposes a proof bundle for a current leaf, fetch it
explicitly:

`https://pay.frontiercompute.io/verify/075b00df286038a7b3f6bb70054df61343e3481fba579591354a00214e9e019b/check`
```bash
LEAF=$(curl -sf https://api.frontiercompute.cash/events?limit=1 | python3 -c "import json,sys; print(json.load(sys.stdin)['events'][0]['leaf_hash'])")
python3 examples/verify_proof.py "$LEAF" --api-base https://api.frontiercompute.cash
```

Confirms:

- `valid: true`
- proof can be verified independently by the server
- verification is performed with `zap1-verify`
- current proof route is exposed for that leaf
- the fetched bundle still verifies offline after download

## 6. Proof bundle download
## 6. Optional on-chain memo check

Open:
With a local Zebra RPC, check the anchor transaction memo when the proof bundle
has a txid:

`https://pay.frontiercompute.io/verify/075b00df286038a7b3f6bb70054df61343e3481fba579591354a00214e9e019b/proof.json`
```bash
python3 examples/verify_onchain.py examples/proof_bundle_example.json --rpc http://127.0.0.1:8232
```

Confirms:

- bundle format is downloadable
- proof data can be reused outside the hosted site
- Merkle proof resolves to the claimed root
- anchor memo matches when the local chain reader can decrypt/extract it

## 7. Reference implementation

Expand Down Expand Up @@ -163,9 +171,9 @@ Confirms:
```bash
git clone https://github.com/Frontier-Compute/zap1.git
cd zap1
cargo run --bin zap1_ops -- --base-url https://pay.frontiercompute.io --json
cargo run --bin zap1_ops -- --base-url https://api.frontiercompute.cash --json
cargo run --bin zap1_schema -- --witness examples/schema_witness.json
cargo run --bin zaino_adapter -- --zaino-url http://127.0.0.1:8137 --api-url https://pay.frontiercompute.io
cargo run --bin zaino_adapter -- --zaino-url http://127.0.0.1:8137 --api-url https://api.frontiercompute.cash
```

Confirms:
Expand All @@ -179,8 +187,8 @@ Operator runbook: `https://github.com/Frontier-Compute/zap1/blob/main/docs/OPERA
## 13. Conformance kit

```bash
python3 conformance/check.py # 14 protocol checks
python3 conformance/check_api.py # 21 API schema checks
python3 conformance/check.py # protocol fixture checks
python3 conformance/check_api.py # live API schema checks
python3 scripts/check_compatibility.py # 6 hash vectors
```

Expand Down
Loading