Skip to content

Payment Codes and Memos

To spend a note you must know its secrets (amount, rho, r). When someone pays you, how do you learn them, if you were offline and no server is trusted to tell you? Cheshire’s answer is payment codes, in the spirit of BIP-47: everything is derived from your address and a little data on chain.

The requirement: Alice pays Bob by entering Bob’s address and an amount. Bob’s wallet need not be online, and no relay or server hands anything out on his behalf.

Your address is your payment code: chs1… on mainnet, tchs1… on test networks. It carries your note public key pk and an X25519 public key used only to find payments.

When Alice pays Bob for the first time:

  1. Alice’s wallet derives a secret e from her own seed and Bob’s address, so her seed can always derive it again.
  2. It publishes E = e·G once, in a handshake record: a 92-byte record right after the payment’s record.
  3. Alice and Bob now share a secret s: Alice from e and Bob’s X25519 key, Bob from his X25519 secret and E.

A first payment therefore publishes two records (about 58 vB) instead of one.

Payment number n from Alice to Bob (n = 0, 1, 2, …) uses note secrets derived from the shared secret and the counter:

(rho_n, r_n) = KDF(s, n)
K_n = H(pk_Bob, rho_n, r_n)
word = 2³⁰ + (amount + KDF(K_n, "amount")) mod 2²⁷ the memo word

The amount rides in the record’s one free word, padded with a value only someone who knows K_n can compute. So a payment costs zero extra bytes beyond its record.

Bob’s wallet, scanning the chain, tries every handshake with his key, derives each payment he could have received, and finds his notes. Alice’s wallet rebuilds what she sent the same way. Neither needs the other to be online.

Alice learns the note’s rho and r (as any payer chooses them). She still cannot spend it: that needs Bob’s sk.

Withdrawals and payments to yourself carry a random memo word. On Bitcoin they look like payments. (On the share chain a withdrawal’s payout is visible; see privacy.)

  • Handshakes are visible as handshakes. An observer can count first-time payments in a settlement, but not who they are between.
  • A wrong memo hides a payment. The payer can write a wrong memo, and then the payee finds no note. Nothing in the proof checks a memo’s correctness. Check each payment once it settles.
  • The handshake is X25519, which is not post-quantum. A future quantum computer that breaks a recorded handshake would learn that pair’s payment amounts and that the payments are linked, not how to spend them. A hybrid X25519 + ML-KEM-768 handshake is designed and prototyped (13 records per first payment, a re-pin to adopt). It is not wired in; the plan is an opt-in per payee before mainnet.
  • Payment indices must not repeat. Reusing an index with a different amount would leak the difference. After a recovery, the wallet resumes each payee one past the last payment it finds on chain, and refuses to pay a payee it has not resumed. Two devices holding the same seed and paying the same payee before either payment settles can still collide.
  • Prover pay uses its own one-time keys, not payment codes (paying the provers).