Carrot: new addresses
The new addressing and key scheme arriving together with FCMP++
Carrot (Cryptonote Address on Rerandomizable-RingCT-Output Transactions) is the address and one-time-output scheme for the FCMP++ era. It keeps the existing address format but introduces a more flexible key hierarchy (separate "see incoming", "see everything", "generate key images", "prove spend authority"), closes the Janus attack and speeds up scanning.
Why change what works
An FCMP++ output has the form O = x·G + y·T, and the old one-time address formulas don't account for that. Since things must change anyway, Carrot fixes long-standing CryptoNote annoyances:
- View-only wallets don't see spends. You had to import key images.
- The Janus attack on subaddresses: a sender could test whether two subaddresses are linked.
- The "burning bug": two outputs with the same one-time key could be sent, and the recipient could spend only one.
- Slow scanning — Ed25519 operations and a 1-byte view tag.
Key hierarchy
| Key | Grants |
|---|---|
k_vi — view-incoming | finding incoming payments (like the old view key) |
k_gi — generate-image | computing key images → seeing which outputs are spent |
s_vb — view-balance | seeing all incoming and outgoing, the exact balance; recognising your own change |
s_ga — generate-address | creating subaddresses (e.g. on a shop server) without the right to see payments |
k_ps — prove-spend | the only key really needed to spend; can live on a hardware wallet |
Compatibility with old wallets
An existing wallet maps onto Carrot like this: k_vi = a, k_gi = b, k_ps = 0. Then K_s = b·G = B, and old addresses stay the same — you can send to them and scan them. The new capabilities (a separate view-balance key, etc.) go to wallets created under the new scheme.
What else changes in outputs
- Key exchange on X25519 (a Montgomery curve instead of Edwards) — faster scanning.
- View tag — 3 bytes instead of 1: 65,536 times fewer false positives.
- Janus protection: an "anchor" is added to the output so the recipient can check the sender knew the full address rather than gluing it from parts of different subaddresses.
- Burning-bug protection: the one-time key is bound to the transaction's first key image, so two identical outputs can't exist.
- Internal (self-send) outputs: change is built via
s_vb, and a wallet with the view-balance key recognises it reliably.
The Carrot specification is published in the jeffro256/carrot repository, the FCMP++ specification in kayabaNerve's papers and the monero-oxide repository. This site paraphrases them; if they disagree, trust the specification.