GitHub

Learn

Privacy

What identifier hashing actually protects, what it does not, and which guarantees are properties rather than promises.

This page states what identifier hashing protects and what it does not.

The three things kept apart

Most privacy failures in payment systems come from collapsing two of these into one.

LayerQuestionFailure if merged
AuthenticationIs this session the subject it claims to be?A signed-in user is treated as a verified phone number
IdentifiersDoes the subject demonstrably control this identifier?An unverified number is indexed and someone else becomes reachable at it
ConsentDid the subject agree to this disclosure, to this counterparty?Verified means findable, and nobody ever opted in

PATH keeps them as three separate records, and a disclosure requires all three.

What a directory lookup returns

A lookup answers a routing question and gets a routing answer.

ReturnedNever returned
Which member holds the keyThe account holder's name
That member's endpointTheir institution's customer record
What the destination acceptsTheir KYC tier or documents
Applicable limitsTheir balance or history
A signature and a commitmentAny other identifier of theirs

A lookup answers a routing question. It does not return a profile.

Whether the destination is the person the payer means is a separate question, the payee check: the holder verifies a name or shows it masked, when a payment is prepared. It answers is this Alice Martin? It never answers who is behind this key?

Identifier hashing: what it does

Identifiers are normalised, then hashed with a network-held secret (a pepper) using Argon2id. The directory stores hashes; it never stores the identifier.

What that protects: the database at rest. Identifiers are not stored in the clear.

What it does not protect: identifiers from the operator that computes the hash. The member sends the identifier; the operator hashes it. That is not zero knowledge.

Until oblivious hashing ships, the honest statement is: the hash protects the database, not the network's members from the network. No page on this site will say otherwise.

Why the pepper is not distributed

Members do not receive the hashing secret. Lookups are hashed by the network. Sharing that secret is not part of this design. See PIP-0002 for the construction that hashes without showing the identifier to the operator.

The construction that does fix it

Oblivious hashing. Without the mathematics:

Fig. 01 — Oblivious hashing
  1. 01BlindThe member blinds the identifierA random value of its own.
  2. 02SendIt sends the blinded valueTo the network.
  3. 03PepperThe network applies its pepperIt cannot see the identifier.
  4. 04UnblindThe member removes the blindingAnd holds the final hash.
The network sees nothing. The member never learns the pepper.

The network sees nothing; the member never learns the pepper. Both problems close together. It is a known construction, deployed elsewhere — it is how a browser checks whether your password appears in a breach without sending your password — and it costs one round trip and a few milliseconds.

It is on the roadmap with an explicit trigger: before a second member joins a network. While one member holds everything, the network only sees its own customers and the exposure is theoretical. The second member makes it real, and that member will be the one to ask.

What a person can do

Choose a level per identifier. private keeps an identifier out of the directory entirely, reachable only through an existing relationship. network is the default for an individual. public is opt-in and, realistically, for merchants.

Withdraw completely. Withdrawal applies at the subject level and covers every identifier of that subject.

Rotate an address. Opaque addresses can be rotated without changing the underlying identity. The old one is revoked rather than deleted, so a payer holding a saved destination is told it moved rather than that it never existed.

What operators must do

Never persist the clear identifier. It is used to compute the hash and gone in the same request: not in a table, not in application logs, not in the search log.

Look up at the moment of intent. Look a key up when a payment is being prepared, not when an address book is first imported.

Log searches, and keep the log short. With a declared retention, published rather than buried in a contract.

The load-bearing assumption

In the central configuration, the network could correlate. It holds the index, so it knows who each hash belongs to, and it sees each search. Crossing the two reconstructs a payment graph without ever seeing a payment: volumes between members, corridors, cycles.

The counterweights — short retention, a rulebook prohibition on commercial use, independent audit — are commitments, not properties. With a design where the network could not know, the question would not arise. Here it can, and undertakes not to.

That difference matters on exactly one day: when a competing institution decides whether to trust the operator. It makes the neutrality of whoever runs the network a load-bearing assumption of the model, and it is why the separation between the entity that writes the rules and the entity that operates the system is worth taking seriously long before anyone asks about it.


Next: Trust and signatures — why nearly everything is signed.

On this page