Technical › FCMP++

Carrot: new addresses

The new addressing and key scheme arriving together with FCMP++

In short

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

s_master k_psprove spend authority s_vbview everything (balance) k_gigenerate key images k_viview incoming s_gagenerate addresses K_s = k_gi·G + k_ps·T
New Carrot wallets. The public spend key uses two generators — hence FCMP++'s O = x·G + y·T form.
KeyGrants
k_vi — view-incomingfinding incoming payments (like the old view key)
k_gi — generate-imagecomputing key images → seeing which outputs are spent
s_vb — view-balanceseeing all incoming and outgoing, the exact balance; recognising your own change
s_ga — generate-addresscreating subaddresses (e.g. on a shop server) without the right to see payments
k_ps — prove-spendthe 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.
Primary sources

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.