Privacy: what SubEtha hides — and what stays public
This is the canonical privacy page of this site: the single place that states
SubEtha’s privacy claim in full, with every caveat attached. Every other page
that touches privacy links here rather than restating the claim. The
normative sources are the product repository’s
README “Privacy” section
and
docs/OVERVIEW.md §4
at the pinned commit.
The claim, with its caveats
Section titled “The claim, with its caveats”What SubEtha hides. SubEtha hides the correspondence between payer and
provider: the 402’s payTo is a one-time burn address from which the receiver
cannot be derived, and the mint-side ZK proof keeps which-burn-was-spent a
private witness. A specific payer’s burn and a specific treasury’s mint
therefore cannot be linked on-chain — the payer is never shown the receiver,
and no sender↔receiver link remains on-chain.
That claim comes with five caveats, none of which may be dropped:
- Amounts are public. The burn is an ordinary-looking
IndexedTransfer; values are transparent on-chain. - The receiver is not hidden forever. The treasury address appears at mint time (in calldata and as the mint destination); what is hidden is the correspondence, not the recipient.
- Small anonymity sets are weak. With few payments, timing and amount coincidences can suggest which burn fed which mint; unlinkability only becomes strong when many payments mix.
- Batching narrows the guesswork. The batch path mints one total in one transaction, so amount/timing coincidences leave more room to guess the grouping than N single mints would — while burn addresses remain fresh per payment and burns still do not link to each other.
- Payer-side visibility is unchanged by mode. Permit mode versus self-transfer neither weakens unlinkability nor creates it.
Why the burn and the mint don’t link
Section titled “Why the burn and the mint don’t link”The mechanism behind the claim, from the pinned sources:
- The burn address is derived as
burnAddress = truncate160(Poseidon("burn", recipientFr, secret))withrecipientFr = SHA256(chainId ‖ recipient ‖ tweak). Thesecretandtweakexist only on the deriving side; thesecretnever appears on-chain, and it is what breaks the link. - On-chain, the burn is recorded as an event of the same shape as an ordinary
transfer:
IndexedTransfer(payer → burnAddress). The burn address is an opaque hash; an observer who does not know the secret cannot work back to the treasury from it. Derivation inputs change per payment, so burn addresses do not link to each other either. - The mint-time ZK proof’s public signals are
[transferRoot, recipient(hash), totalValue]— which burn was spent is a private witness. The verifier call’s calldata carries the receiver information used to check the recipient hash, but nothing that points at a burn.
The payer–provider correspondence model, precisely
Section titled “The payer–provider correspondence model, precisely”What is hidden is a correspondence, against a specific observer:
- Hidden from on-chain observers: which payer’s burn funded which provider’s mint. No payer → treasury transfer ever exists on-chain.
- Hidden from the payer: the provider’s real payout destination. The 402 carries only the one-time burn address; the payer is never shown the treasury.
- Not hidden from the facilitator. The facilitator derives every burn address and processes every payment, so it sees the full correspondence at all times. The claim is about the public ledger, not about the parties operating the flow. The same goes for the provider, which knows who called its API.
What the system does not hide
Section titled “What the system does not hide”None of the following is concealed, and no page on this site may imply otherwise:
- Amounts. The burn is an ordinary-looking transfer; values are transparent on-chain. Anyone can see how much a given address burned.
- The payer’s own activity.
IndexedTransfer(payer → burnAddress)names the payer. An observer sees that this payer burned this amount at this time — what it cannot see is to whom that payment corresponds. - The treasury at mint time. The treasury address appears in the mint calldata and as the mint destination. Hidden is the correspondence to any burn, not the recipient’s existence or its revenue address.
- Timing. Burns and mints are timestamped public events; with few payments in flight, timing and amount coincidences narrow the guesswork (caveats 3 and 4 above).
- The HTTP layer. SubEtha changes nothing about HTTP: the provider sees the payer’s requests exactly as any web server sees its clients (network address, headers, timing). Transport-level concealment is out of scope and not claimed.
Scope of the claim
Section titled “Scope of the claim”The unlinkability property is independent of the gasless choice — permit mode versus self-transfer neither weakens nor strengthens it. It is also conditional on volume: with few payments the anonymity set is small and the claim is correspondingly weak. This is a structural property of a low-traffic PoC, stated here once and linked from everywhere else.
Who must trust whom — including the facilitator’s privileged position — is Trust & Limits; the settlement machinery referenced above is Accepted vs finalized.