Cashu — Chaumian Ecash for Bitcoin
- Cashu — Chaumian Ecash for Bitcoin
Cashu — Chaumian Ecash for Bitcoin
Free and open-source ecash protocol. Digital bearer tokens. Like physical cash, but on Bitcoin.
The Big Picture
┌──────────┐ ┌──────────┐
│ Mint │ issues tokens │ Wallet │ receives & spends
│ (Bob) │ ◄────────────────▶ │ (Alice) │
└──────────┘ redeems tokens └──────────┘
│ │
│ backed by on-chain BTC │ peer-to-peer
▼ ▼
┌──────────┐ ┌──────────┐
│ Bitcoin │ │ Carol │
│ UTXOs │ │ (friend) │
└──────────┘ └──────────┘
Key properties:
- No accounts: the mint has no user database
- Bearer tokens: posession = ownership
- Blind signatures: mint can’t link issuance to redemption
- Bitcoin-backed: tokens represent real BTC held by the mint
Blind Diffie-Hellman Key Exchange (BDHKE)
The core cryptographic primitive.
Actors
- Alice (User): holds ecash, generates secrets
- Carol (Receiver): receives tokens from Alice
- Bob (Mint): issues and redeems tokens
Protocol Flow
1. BOB PUBLISHES: K = kG (public key for a specific denomination)
2. ALICE MINTS:
a. Pick random secret x
b. Compute Y = hash_to_curve(x)
c. Pick random blinding factor r
d. Compute blinded message: B = Y + rG
e. Send B to Bob with payment
3. BOB SIGNS:
f. Receives payment
g. Computes blind signature: C' = k·B
h. Returns C' to Alice
4. ALICE UNBLINDS:
i. C = C' - r·K = k·B - r·(k·G) = k·(Y + rG) - r·k·G = k·Y
5. TOKEN CREATED: (x, C)
Alice can now send (x, C) to Carol
6. CAROL REDEEMS:
j. Sends (x, C) to Bob
k. Bob verifies: k·hash_to_curve(x) == C
l. Bob adds x to spent secrets list (prevent double-spend)
m. Bob sends BTC to Carol
Why Blinding Matters
Without blinding: Bob sees Y, remembers it, and when Y is redeemed, Bob links it to Alice.
With blinding: Bob sees B (blinded), has no idea what Y looks like. When Y is later redeemed as part of (x, C), Bob can’t link it to Alice’s minting session.
Privacy = unlinkability between issuance and redemption.
Denominations (Keysets)
Bob uses a different private key k_a for each supported amount a:
Keyset:
k_1 → $0.01 (1 sat)
k_2 → $0.02 (2 sat)
k_4 → $0.04 (4 sat)
k_8 → $0.08 (8 sat)
k_16 → $0.16 (16 sat)
k_32 → $0.32 (32 sat)
...powers of 2...
Why powers of 2?
- Unique decomposition: 1337 sats = 1+16+128+256+1024
- Maximizes anonymity sets: each denomination bucket has many users
- Tradeoff: More denominations = smaller buckets = less privacy
Decomposition Example
Amount: 1337 sats
Binary: 0b10100111001
Position 0: 1 → +1
Position 4: 1 → +16
Position 7: 1 → +128
Position 8: 1 → +256
Position 10: 1 → +1024
Tokens: [1, 16, 128, 256, 1024]
Token Lifecycle
[Alice BTC] → [Mint] → [Alice ecash tokens] → [Carol] → [Mint] → [Carol BTC]
1. Minting (Atomic Swap)
Alice sends BTC on-chain → Mint
Mint issues ecash tokens via BDHKE → Alice
OR (Lightning):
Alice pays LN invoice → Mint
Mint issues ecash tokens → Wallet
2. Sending (Peer-to-Peer)
Alice sends (x, C) tuple to Carol
Carol verifies with mint that token hasn't been spent
No on-chain transaction. No mint involvement.
3. Redeeming (Melt / Burn)
Carol sends (x, C) to Mint
Mint checks: k·hash_to_curve(x) == C AND x not in spent list
Mint sends BTC to Carol (on-chain or Lightning)
Mint adds x to spent list
4. Receiving (Fusion / Rotate)
Alice swaps her tokens for new, unlinkable tokens
Same mint, but now with fresh secrets and new blindings
Breaks any timing-based linkability
Spending Conditions (P2PK, HTLCs)
Cashu tokens can have programmable spending conditions:
P2PK (Pay-to-Public-Key)
Token locked to a specific pubkey.
Only the holder of the corresponding private key can redeem.
Like "endorsed checks" in ecash.
HTLCs (Hash Time-Locked Contracts)
Token locked with:
hashlock: reveal preimage R → spend
timelock: wait N blocks → refund
Enables trustless atomic swaps across mints.
Privacy Guarantees
| Observer | What They Can See |
|---|---|
| Mint | Denomination of each token, timing, nothing about sender/receiver link |
| Network observer | Encrypted traffic only |
| Recipient (Carol) | Token value, can verify with mint |
| Third party | Nothing |
Anonymity set: Each denomination bucket. Larger = more private.
NUT Specifications
NUTs = Notation, Utilization, Terminology — Cashu’s protocol specs.
| NUT | Title | Description |
|---|---|---|
| 00 | Base | Notation, endpoints, models |
| 01 | Mint Keyset | Keyset rotation |
| 02 | Keysets | Multiple keyset support |
| 03 | Swap | Token mint/melt |
| 04 | Mint Quotes | Quote-mint protocol (bolt11-based) |
| 05 | Melting | Token destruction for BTC |
| 06 | Mint Info | Mint metadata |
| 07 | Spending Conditions | P2PK, HTLCs |
| 08 | Overpaid Fees | Fee handling |
| 09 | Signatures | Message signatures |
| 10 | Spending | Token transfer |
| 11 | P2PK | Pay-to-Public-Key locked tokens |
| 12 | Offline | Offline ecash |
| 13 | Nostr | Nostr integration |
Cashu on Nostr (NIP-60)
Nostr integration brings ecash to the Nostr ecosystem:
| Kind | Purpose |
|---|---|
| 7374 | Reserved Cashu Wallet Tokens |
| 7375 | Cashu Wallet Tokens |
| 7376 | Cashu Wallet History |
Nutzaps (NIP-61): zap-style ecash payments on Nostr.
Apps & Ecosystem
| App | Platform | Type |
|---|---|---|
| Minibits | Android/iOS | Wallet |
| Cashu.me | PWA (Web) | Wallet |
| Nutstash | PWA (Web) | Wallet |
| Macadamia | iOS | Wallet |
| eNuts | PWA | Wallet |
| Boardwalk | Web | Mint management |
Libraries
| Language | Library |
|---|---|
| Python | cashubtc/cashu |
| TypeScript | cashubtc/cashu-ts |
| Rust | cashubtc/cdk |
Tradeoffs
| Aspect | Cashu | Lightning | On-Chain |
|---|---|---|---|
| Speed | Instant | Instant | ~10 min |
| Privacy | Excellent (unlinkable) | Good (onion routing) | Poor (public ledger) |
| Trust | Mint (custodial) | Non-custodial | Trustless |
| Scalability | Unlimited | Limited by channels | 7 tx/s |
| Fees | ~Free | <1 sat | Variable |
| Complexity | Low | High | Low |
Key Insight
Cashu brings physical cash properties to digital Bitcoin payments: instant finality, bearer ownership, and strong privacy — at the cost of trusting a mint with custody. Perfect for small/medium payments where privacy matters more than absolute trustlessness.
Write a comment