Skip to content

Commit d0bda8e

Browse files
aphelionzclaude
andcommitted
docs(zeronym): the mixnet is deployed; verifiability is not
Sixteen commits landed on main while the book was being edited, and four of them reversed what the previous commit had just documented as true. Both Nym attested-deploy blockers are closed. The hub publishes its address at GET /nym-address instead of writing it to a log no enclave exposes, and its identity now survives a client rebuild; both sides pin entry gateways, the real lever, since the throughput constraint was gateway backpressure rather than any credential limit. An attested shim and hub pair has run the transport on the PUBLIC mixnet since 2026-08-14, so the status table moves Nym to Deployed and every "built, not deployed" marker across the other seven chapters follows. But verifiability now lags capability, and the book says so plainly rather than leading with the deploy. Both published hashes are stale against tip of main and both reproduce jobs report DOES NOT REPRODUCE (runs 31816057371, 31816060394). Those jobs run on pull requests and manual dispatch, never on push, so the last five direct-to-main commits outran them; the old "checked in CI on every change" claim was simply wrong. Worse, the live pair's provenance does not check out: the shim's cites a source commit that is not public, and the hub's quotes a hash its own cited commit does not produce. The enclaves are attested and running and an auditor cannot yet tie either back to a public commit, so the book now declines to call the system independently verifiable until that closes. Also corrected: submit is dispatch-only, so the shim answers the wallet before the hub has acknowledged receipt, which widens the false-success edge trust.md already documented (lookups still await, deliberately); the clearnet POST / submit path is closed unless ZIH_HTTP_SUBMIT re-opens it, falling through to a 404 so a scanner cannot fingerprint it; the Caution control-plane relay is now flag-gated; the orchard skew is shim-and-hub agreeing on 0.15.5 against zebra's 0.15.3, and the old remedy no longer describes what would close it; and both config blocks gain the five new env vars. New material the book had no home for: the hub's two read-only endpoints and the deliberate decision that neither exposes queue depth or batch size, which served live would be an anonymity-set oracle. The 2026-08-11 mainnet run is explicitly marked as predating the mixnet and using the clearnet hop. No migration has been observed crossing Nym in production, and the book does not imply one has. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 2779498 commit d0bda8e

8 files changed

Lines changed: 72 additions & 39 deletions

File tree

zeronym/book/src/architecture.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Two new pieces of attested software plus a transport put an **attested, verifiab
88

99
- **zero-indexer-shim (ZIS)**: a lightweight, attested router each operator deploys behind its existing public URL (for example `zec.rocks:443`). To every wallet it looks exactly like the indexer already there, so wallets need no reconfiguration. It forwards almost all traffic untouched to the operator's backing indexer, and isolates two things: transactions that **touch Orchard** (diverted to the hub) and `GetTransaction` (answered by the hub, so a wallet's lookup for its own migration never reaches the operator). Everything else passes straight through instantly; the backend still sees those contents, but arriving from the shim, not the wallet's IP. The shim is **stateless**, holding nothing about what it diverted, which is exactly why every `GetTransaction` must go to the hub.
1010
- **zero-indexer-hub (ZIH)**: a central, attested service, designed to run as two or more instances with failover. It does two jobs. It **batches**: an Orchard-touching transaction is encrypted to a key the local operator cannot access, routed to a hub, batched with those from every other shim, and co-published on a strict block cadence after a short delay, so an observer holding "IP X connected at time T" cannot time-match it to the transaction when it appears on-chain. And it **answers lookups**: a `GetTransaction` is served from the hub's queue while the migration is unflushed (height 0, mempool), otherwise from the hub's own indexer.
11-
- **Nym, embedded in both binaries** (built, not deployed): each side links `nym-sdk` and runs its own mixnet client **in-process**, inside the enclave, so there are no proxy sidecars and no untrusted process on the path. It runs only between shim and hub, never wallet-to-shim. The transport is proven end to end over a local mixnet but is not yet deployable in an attested enclave, so the deployed hop is still plain TLS to a pinned address ([roadmap](./roadmap.md) has the status and the two blockers).
11+
- **Nym, embedded in both binaries** (deployed): each side links `nym-sdk` and runs its own mixnet client **in-process**, inside the enclave, so there are no proxy sidecars and no untrusted process on the path. It runs only between shim and hub, never wallet-to-shim. An attested pair has run it on the public mixnet since 2026-08-14; the clearnet dial remains in the code but is off at the hub by default ([roadmap](./roadmap.md) has the status table).
1212
- **The operator's backing indexer**: the unmodified lightwalletd or Zaino the operator already runs, on its internal address. To it the shim is a single ordinary gRPC client. It serves block sync, address queries, and pass-through broadcasts in cleartext, exactly as today; a diverted Orchard-touching transaction and a wallet's `GetTransaction` never reach it.
1313
- **The hub's indexer**: a CompactTxStreamer (lightwalletd or Zaino), distinct from any operator's, that the hub connects out to over TLS to read the chain tip, publish each flushed batch, and answer a `GetTransaction` its queue does not hold. Neither enclave runs a validator of its own. (In a single-operator deployment the two indexer roles can collapse onto one instance, which removes the lookup privacy but not the batching.)
1414

@@ -94,7 +94,7 @@ flowchart TB
9494
HFLUSH ==>|"SendTransaction (batched, shuffled)"| FN
9595
FN -->|"P2P relay"| ZNET
9696
HFLUSH -.->|"tip (GetLightdInfo) + lookup fallthrough"| FN
97-
HDEC -.->|"AckV1 (64 bytes, SURB return)"| SHUB
97+
HDEC -.->|"AckV1 (SURB return; not awaited)"| SHUB
9898
SHUB -.->|"failover (dedup by payload hash)"| HUB2
9999
SHUB -.->|"last resort near expiry: direct broadcast over Nym"| NYM
100100
HUB2 -.-> FN
@@ -123,10 +123,10 @@ flowchart TB
123123

124124
**Reading it:** *migration* is the code's label for the diverted class ([the shim](./components.md) has the predicate). Thin arrows = the **pass-through path** (queries other than `GetTransaction`, and non-migration txs), which go to the operator's unmodified backing indexer as **plaintext the operator can read**, exactly as today. Thick arrows = the paths that **bypass the operator**: the migration broadcast, encrypted end to end, and the hub-served `GetTransaction`. Green = attested enclave processes, the only things that ever see migration cleartext, and note that this now includes each side's mixnet client, which is linked in-process rather than run as a sidecar; red = the untrusted host and the operator's own indexer, which never sees the migration path at all; gray = external networks; blue = the drop-in wallet.
125125

126-
**Three nested encryption layers are designed for the migration (shim to hub) path**, so that only the two attested enclaves ever see cleartext. **The deployed hop today is a single layer, plain TLS**, terminated by the platform's in-enclave proxy.
126+
**Three nested encryption layers are designed for the migration (shim to hub) path**, so that only the two attested enclaves ever see cleartext. **The deployed hop today has the outer layer only**: Sphinx across the mixnet, with the wallet's own TLS terminated by the platform's in-enclave proxy before it.
127127
1. **Inner** (designed): the tx is encrypted to the **hub key** at the classifier, so it survives a compromised host.
128128
2. **Middle** (designed): **STEVE** (AES-256-GCM) terminates inside the hub enclave.
129-
3. **Outer** (built, not deployed): **Nym** Sphinx across the 5-hop mixnet.
129+
3. **Outer** (deployed): **Nym** Sphinx across the 5-hop mixnet.
130130

131131
---
132132

0 commit comments

Comments
 (0)