Skip to main content

ADR-010: Anonymity Revoking System

StatusProposed
Date2026-03-13

Context

Every on-chain operation in the encrypted balances system (transfer, shield, unshield) includes an encrypted compliance payload — the transaction amount encrypted under a compliance public key held by the anonymity revoking authority. Sender and recipient BPKs are already public inputs in the EB account model; only the amount requires encryption for compliance purposes. In the future L3 (UTXO/notes) layer, where the transaction graph is also hidden, the encrypted compliance payload will need to include additional data beyond the amount.

To fulfil regulatory obligations, the system needs a way for authorized parties to decrypt these values and trace fund flows upon a legitimate request from a regulator. ADR-007 and ADR-008 explored dashboard-centric approaches but were rejected — they focused on AWS infrastructure and a single anonymity revoker role without addressing the organizational process, the separation of concerns between decision-making and mechanical decryption work, or the need for structured, auditable workflows that connect each decryption to a specific regulatory inquiry.

This ADR describes the anonymity revoking system from the perspective of data flow, roles, and component responsibilities. It does not cover the internal workings of the Guardian Committee (single guardian vs. threshold committee), which is material for a separate ADR.

Proposal

Roles

There are three roles in the system:

RoleDescription
RegulatorExternal party (e.g. a law enforcement or financial authority) who reaches out and requests deanonymization of specific transactions or accounts.
Compliance Officer (CO)An employee (there can be more than one) who handles communication with regulators and performs the mechanical work of deanonymization in coordination with the Guardian Committee. The CO's job is to reduce the workload on the GC by taking care of all non-critical tasks — formulating requests, collecting proofs, compiling results — so that the GC only needs to make key decisions.
Guardian Committee (GC)The body responsible for keeping the anonymity revoking key secure and making decisions on which requests from regulators are legitimate and should be executed. Initially likely a single guardian, later a threshold committee.

Overview

┌────────────┐                ┌──────────────────────┐                ┌─────────────────────┐
│ │ request to │ │ │ │
│ Regulator │───deanonymize─▶│ Compliance Officer │ │ Guardian Committee │
│ │◀──results──────│ (CO) │ │ (GC) │
│ │ │ │ │ │
└────────────┘ └──────────┬───────────┘ └──────────┬──────────┘
│ │
make_initial_request accept_initial_request
make_follow_up_request submit_decryption
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ │
│ Coordination Service │
│ (untrusted middleman, HTTP) │
│ │
│ ┌─────────┐ ┌──────────┐ ┌─────────────────────┐ │
│ │Requests │ │Signatures│ │Encrypted Decryptions│ │
│ └─────────┘ └──────────┘ └─────────────────────┘ │
│ │
│ Audit Log │
└─────────────────────────────────────────────────────────────┘

Software components

Apart from the software run locally by the Guardian Committee on sandboxed hardware (out of scope for this ADR), two components are involved:

  1. Coordination Service — a backend HTTP service that stores, encrypted, the interactions between Compliance Officers and the Guardian Committee. Its purpose is threefold: (a) persistent, secure storage for request and response data, (b) asynchronous communication between COs and the GC (since these parties are not always online simultaneously, peer-to-peer connections are impractical), and (c) a precise, auditable log of what happened and when.

  2. Anonymity Revoking Dashboard — a frontend application for Compliance Officers. A CO logs in and is presented with a dashboard of their anonymity revoking history, pending requests, and investigation state. All data displayed comes from the Coordination Service and is available upon the CO's authentication. It is stored encrypted on the Coordination Service.

The Coordination Service as an untrusted middleman

A key design property: the Coordination Service is an untrusted middleman. It facilitates connections between COs and the GC, keeps archive data available, and maintains a log — but it cannot compromise the system even if fully breached. All parties rely on public key infrastructure for encryption and for confirming the validity of requests. The Coordination Service cannot forge signatures, decrypt data, or alter requests without detection.

Coordination Service API

The Coordination Service exposes the following endpoints:

make_initial_request(details, reason)

Called by a CO to initiate a deanonymization case as a direct consequence of a regulator's claim. The request includes the details of what is being investigated (e.g. an account's BPK, a specific note, a date range) and the reason (the regulatory basis). The request is recorded in the Coordination Service database and presented to the GC for evaluation.

accept_initial_request(signature)

Called by the GC after deciding to accept a request. Making this decision may involve interactions beyond the digital infrastructure — discussions with the CO, the regulator, legal review, etc. To accept, the GC produces a signature (single signature or multisig, depending on the committee's form) over a hash of a specific payload that includes the request details. The signature is recorded in the Coordination Service database.

make_follow_up_request(sig, details, proof)

Called by a CO when they want to decrypt a specific transaction as part of an investigation initiated via a previously signed initial_request. The CO includes:

  • sig — the GC's signature from accept_initial_request, proving this follow-up is tied to an approved investigation.
  • details — the specific transaction or note to be decrypted.
  • proof — a proof that the requested item is related to the initial request, and hence is a legitimate follow-up (details depend on the investigation type; see examples below).

The Coordination Service saves the request and presents it to the GC.

submit_decryption(decrypted_tx)

Called by the GC upon seeing a valid follow-up request (valid sig and proof). The GC uploads the decrypted data — specifically, the appropriate secret from the transaction, encrypted with the requesting CO's public key so that only that CO can read it. The data is stored in the Coordination Service database and can be downloaded by the CO.

View functions

A general category of read endpoints for displaying information in the respective interfaces — pending requests, investigation history, request status, etc.

Audit trail

Every action on the Coordination Service is logged and persisted in the database: which transactions were decrypted, when, by whom, under which initial request, and for what stated reason. This supports auditability when needed — for instance, to demonstrate to an oversight body that decryptions were performed only with proper authorization.

Two-phase request model

A critical design feature is the separation between initial requests and follow-up requests:

  • The initial request is the point that requires manual work and manual acceptance by the Guardian Committee. This is where the GC exercises judgement about the legitimacy and proportionality of the regulator's claim.
  • Once the initial request is signed, follow-up requests can be handled automatically by the Guardian Committee's software. The automation simply checks the validity of the proof and, if valid, performs the decryption. No further human decision-making is needed.

This design avoids overwhelming the Guardian Committee with many individual decryption requests. They confirm one general investigation, and each legitimate follow-up within that investigation is processed automatically.

Example 1: Account balance history

A regulator points at an account (identified by its BPK) and asks for the history of transfers up to a certain date.

  1. The CO calls make_initial_request with a request conceptually of the form History(user_BPK, date).
  2. The request is saved to the Coordination Service.
  3. The GC sees the pending request, evaluates its legitimacy, and — if accepted — creates a signature and calls accept_initial_request.
  4. The CO retrieves all transfers to and from user_BPK up to date from on-chain data (BPKs are public in the EB account model). For each transfer, the CO calls make_follow_up_request including the GC's signature, the transaction details, and a proof. In this case the proof can be empty or trivial, because the GC can independently verify that each requested transaction involves user_BPK and falls within the specified date range.
  5. The GC's software processes these follow-up requests automatically: it verifies that each transaction matches the criteria in the signed initial request and submits the decrypted amounts via submit_decryption.
  6. The CO collects all decrypted values, reconstructs the complete balance history of the account, and provides it to the regulator.

Example 2: Tracing a note through the UTXO pool

A regulator points at a deposit into the L3 (UTXO) system and asks for the trace — where the funds went through the privacy pool.

  1. The CO calls make_initial_request with a request conceptually of the form TrackNote(note_details).
  2. The GC accepts via a signature, as in Example 1.
  3. The CO requests decryption of the initial note (call it note A). The proof can be empty here, since note A is literally what the GC signed in the initial request.
  4. Once the CO learns the hidden details of note A, they identify any successor notes created when A was spent. Suppose note B was created from note A. The CO calls make_follow_up_request for note B, providing a zk-SNARK proving that B was created from the note referenced in the initial request (A → B).
  5. If note B was subsequently spent to create note C, the CO requests decryption of C with a proof consisting of a chain of two proofs: A → B and B → C, demonstrating a connected path from the originally tracked note to the one being requested.
  6. This process continues recursively — follow-up requests can involve arbitrarily long proof chains, and can also trace backwards (from a note to its predecessors), limited only by the availability of appropriate zk-SNARKs.
  7. The investigation typically ends at a boundary between the private (L3) and public (L1/L2) world. The CO learns the path and the exit point of the funds and reports back to the regulator.

How the automation works on the GC side

For follow-up requests, the GC's software:

  1. Verifies the signature (sig) matches a valid, accepted initial request.
  2. Validates the proof (proof) — either by checking that the transaction matches criteria the GC can verify independently (Example 1) or by verifying a zk-SNARK proof chain (Example 2).
  3. If valid, performs the decryption, encrypts the result under the CO's public key, and uploads it via submit_decryption.

This automation means the GC does not need to be actively monitoring requests after signing the initial approval — the software handles the mechanical decryption work. How the manual check happens and how the automation is implemented are internal details of the Guardian Committee, to be discussed in a separate ADR.

Consequences

What becomes easier:

  • Regulators' requests are handled through a structured, auditable workflow rather than ad-hoc decryption operations. Every decryption is tied to a specific, approved investigation.
  • The Guardian Committee's workload is minimized: they only need to evaluate and sign initial requests. All subsequent mechanical work (collecting transactions, generating proofs, requesting follow-ups) is handled by Compliance Officers, and all subsequent decryptions are automated.
  • The Coordination Service being untrusted simplifies its security requirements — it does not need hardware enclaves or special key management. Compromise of the Coordination Service cannot leak decrypted data or forge approvals.
  • The system supports complex, multi-step investigations (e.g. tracing funds through an entire UTXO chain) without requiring the GC to approve each individual step.

What becomes harder:

  • The system requires zk-SNARK circuits for proving relationships between notes in follow-up requests (Example 2). These circuits need to be designed, implemented, and audited.
  • The Coordination Service must be built and operated as a persistent backend with authentication, encrypted storage, and reliable availability for asynchronous communication.
  • Compliance Officers need tooling to interact with on-chain data, construct proofs, and manage investigations — this is more complex than the simple "paste a hash, click decrypt" flow of the rejected ADR-007/008 dashboards.

What stays the same:

  • On-chain contracts and circuits are unchanged — they already emit encrypted compliance payloads with sender/recipient BPKs as public inputs.
  • The underlying cryptographic scheme is unchanged.
  • End-user privacy properties are unaffected — users do not interact with the anonymity revoking system, and their transactions remain private unless a specific, approved investigation targets them.