polyseed
polyseed copied to clipboard
feature bit for Carrot wallets
the upcoming Monero fork involves switching to the FCMP++ proof system. this brings some optional features that can be used only with a new addressing protocol. to this end, Carrot is planned to be made available with the next fork.
this extends the set of available Monero addressing protocols to two (legacy, Carrot). for the first time, Monero users (and potentially users of other blockchains adopting Carrot) will need to know not only their mnemonics, but also the addressing protocol they used, to recover funds. this will be a new source of confusion.
(some Bitcoin wallets offer a mitigation by scanning with addresses from multiple derivation paths. I assume this isn't a desirable primary mitigation in Monero, since it would increase enote scanning times for non-light wallets, a process already lengthy enough to be a big UX issue.)
this ambiguity is inevitable for any type of mnemonic generated before Carrot is finalized, and for any 25-word mnemonic (that scheme doesn't offer embedding feature data.)
Polyseed, however, has still-available feature bits. using one of these to indicate Carrot usage would let wallets choose the addressing protocol without user intervention, at least for Carrot polyseeds generated with an updated version of the Polyseed library (or throw an error if they didn't update their Polyseed library).
here's an outcome matrix, accounting for the facts that some wallets may adopt Carrot without updating their Polyseed library or offer legacy derivation for new wallets generated post-fork.
could the addressing protocol be chosen automatically and unambiguously when restoring from a given polyseed?
| Polyseed library left as is | Polyseed library updated; mnemonic has feature bit = 0 | Polyseed library updated; mnemonic has feature bit = 1 | |
|---|---|---|---|
| pre-fork birthday | no. (the user may want to use Carrot while keeping their existing polyseed.) | no. (the user may want to use Carrot while keeping their existing polyseed.) | yes. 🎉 (it's unambiguously Carrot. a niche, but it will be technically possible to generate Carrot addresses pre-fork.) |
| post-fork birthday | no. (the polyseed may have been generated by a wallet that allowed using the legacy addressing protocol for polyseeds generated post-fork.) | no. (the polyseed may have been generated by a wallet that allowed using the legacy addressing protocol for polyseeds generated post-fork.) | yes. 🎉 (it's unambiguously Carrot.) |
downsides:
- wallets will need to update their Polyseed library to be able to import polyseeds with the Carrot feature bit set to 1.
- this will use up one of the 5 feature bits. one is designated for encryptedness (although its usefulness is debated), the other for a future KDF upgrade. that would leave two more opportunities to upgrade Polyseed while still being 16 words long (the last feature bit could extend the standard with another word).
This may break the spirit of Polyseed's design choice to make seed phrases incompatible with other coins and features, but we could allow migrations to a Carrot key hierarchy seamlessly without modifying the seed phrase:
- Use the default salt to generate all the old addresses, private spend key, and private view key like normal.
- Modify one of the salt bits before calling the KDF to generate the Carrot master secret
- Using the Carrot master secret, derive all of the other account secrets according to this derivation tree, except for the private view-incoming key
- Generate new Carrot receive addresses and replace the old ones in your relevant UI, using the legacy-derived view key in address construction
- Update the subaddress map so that the values are not just subaddress indices, but also a flag for whether the address is legacy-derived or Carrot-derived
- Update hardware device interfaces to disambiguate between different derivations of addresses when getting addresses or signing transactions
The reason why we would want to update to a Carrot key hierarchy is to leverage these features. And the reason why we use the legacy view key instead of a new view key is so that we aren't doing double the scanning work we need to. And the reason why we would want the internal key migration to be seamless is for better UX and the security implications of forcing users to move seeds en masse. Note that the reference Monero Core seed derivation scheme doesn't allow for Carrot migrations since quantum computers can extract seed phrases from a Monero address, which nullifies the forward secrecy benefits of the new key hierarchy.