trezor-firmware
trezor-firmware copied to clipboard
Address and account labeling
Feature request
It would be nice to allow users to assign names to outgoing addresses, multisig XPUBs and to their accounts and passphrases, so that the name could be shown on the device screen and the user wouldn't have to carefully check the address or XPUB every time. This labeling should also be integrated with the account and passphrase labeling in the Suite.
For example:
- Suite sends a new message
SetAccountLabel. Trezor shows "Do you want to label Bitcoin account 3 as Savings?" If yes, Trezor encrypts and authenticates this information and returns a data blob to the Suite or in case of TT, optionally stores the data on the SD card. - Next time, when you accompany
address_nwith alabelfield set to the matching blob, Trezor can decrypt it and show: "Sending 0.07 BTC from Savings (account 3)"
Proposed solution
The data is stored as a Merkle tree, where the leaves are name-value pairs such that each name is in plaintext and each value is encrypted separately (doesn't necessarily need to be authenticated). The leaves are sorted by name and the names are unique. Trezor has a dedicated counter, which is incremented every time a label is added, changed or removed. The data structure is authenticated by MACing the Merkle hash of the tree together with the current counter value using a SLIP-21 derived key known only to Trezor. This MAC and counter value are stored together with the tree.
If Trezor is presented with data that uses a lower counter value than the one in the internal storage, then an error is returned. If the counter is the same and the MAC is valid, then the data is accepted. If the counter value is higher than the one in the storage and the MAC is valid, then the data is accepted and the internal counter is increased to match the counter value, because the device is either a recovered Trezor with a lower counter value or the user has multiple devices with the same seed.
Rationale:
- The counter is required to ensure that after a label is changed or removed, the old value is revoked.
- The Merkle tree structure allows for better scalability in terms of the amount of data that needs to be communicated with Trezor when verifying the MAC.
- The leaves shoud be sorted so that it is possible to easily prove that a name is not present in the tree. This is also needed to ensure name uniqueness when adding a new name to the tree.
Storage
- The labels could be stored encrypted in Google Drive or DropBox, so that they can be synced across different computers and devices used by the user.
- In case of the TT, labels could be stored on the SD card as an alternative to internal storage. If the number of labels is small, they could be stored in the internal storage of the device. However, this is problematic for syncing the labels between multiple devices loaded with the same seed.
Access rights
- The labels could be encrypted and authenticated by a SLIP-21 symmetric key. Reading and changing the labels in Suite could only be done with Trezor present, Suite would need to ask Trezor to decrypt each one, but it would be allowed to cache the labels.
- There could be a separate encryption key and authentication key. The encryption key would be shared by Suite and Trezor, so that suite could decrypt the data. The authentication key would be known only to Trezor. In order to change labels, you would need Trezor to be plugged in and the user would have to confirm the change, but in order to read them you wouldn't need Trezor. Presumably the key would be constant, which means that access to reading the labels cannot be revoked, but that's probably not a major problem, because you can always revoke access to the cloud storage.
Questions
- Are there any other things that we would like to use this for in addition to accounts, passphrases, outgoing addresses and multisig XPUBs?
- The value in the name-value pair should be encrypted, but can the name always be considered public information? The proposed solution assumes that it can be considered public, or at least encrypted by a key known to the Suite.
- What are the implications for plausible deniability when it comes to passphrase use?
- Do we need to worry about merging these data blobs? For example, the user has two devices with the same seed, updates a label on one computer with one device and a label on another with another device but the two computers don't have the blobs synced and later they find they are different but have the same counter. I think that could be accommodated, but not sure how complicated it is.
Use of counter might be problematic with multiple passphrases: consider account #3 under passphrase A or passphrase B, and the user wants to set label in both cases. Either the passphrases have separate label trees, in which case the update under passphrase A bumps the tree and invalidates the label under passphrase B Or there is a common tree, in which case the passphrase info must become part of the name somehow.
On a quick look the latter could work: say, e.g., that the name is in fact a hash of the account path and a key derived from the current (passphrased) seed. Suite can learn the correspondence implicitly via SetAccountLabel or explicitly via GetAccountKey?
It seems to me it is quite a lot of engineering for what we achieve by this. We will discuss it in Product (and I'll invite you if possible)
It seems to me it is quite a lot of engineering for what we achieve by this. We will discuss it in Product (and I'll invite you if possible)
If it were just the account labeling, then I would agree. But labeling addresses and XPUBs would be pretty useful. Also, we don't need to use the Merkle tree solution if we think that the amount of data stored this way will be small.
Conclusions from yesterday's meeting with @slush0 and the product team:
The main conclusion is that we would like a three-layered approach which builds on the existing solution:
- Label encryption. This is already solved by SLIP-0015 and implemented in mywallet and Suite.
- Label authentication. This should be the subject of the current issue. The user will need to confirm new labels on the Trezor screen, which will result in Trezor returning an authentication tag. Suite will store that in the cloud alongside the existing data. When displaying a request on the Trezor which includes a labelled address/account/xpub, Suite will provide the label and authentication tag to Trezor as part of the request and Trezor will verify the tag before displaying the label. The main difference to the existing solution is that the authentication keys will never leave the Trezor device as opposed to the encryption keys, which are given to mywallet/Suite upon request.
- Rollback protection (including the ability to prove that an address/account/xpub does not have any label assigned). We believe this will find wider use and should be solved separately at a later time.
To answer the questions above:
- Are there any other things that we would like to use this for in addition to accounts, outgoing addresses and multisig XPUBs?
Only other thing that came to mind is labeling hidden wallets.
- The value in the name-value pair should be encrypted, but can the name always be considered public information? The proposed solution assumes that it can be considered public, or at least encrypted by a key known to the Suite.
Yes, we can work under the assumption that the information is fully open to the Suite, but encrypted when stored in the cloud.
- What are the implications for plausible deniability when it comes to passphrase use?
The cryptographic keys used to encrypt or authenticate the data should be derived from the seed and passphrase. This approach is in line with the current labeling solution described in SLIP-0015. This way even if an attacker gains access to the ciphertext or authentication tag, the user can plausibly deny the existence of the seed, claiming that the seed used to create the ciphertext was for testing purposes and has long been destroyed, when in fact the seed is loaded in the user's Trezor. If the keys were derived from the seed without including the passphrase in the derivation process, then given a loaded Trezor, an attacker could prove the existence of any passphrases which were used to create labels. As @matejcik explained above, the use of the counter in this case is problematic and the solution will require further thought, because apparently this means separate trees for each passphrase.
- Do we need to worry about merging these data blobs? For example, the user has two devices with the same seed, updates a label on one computer with one device and a label on another with another device but the two computers don't have the blobs synced and later they find they are different but have the same counter. I think that could be accommodated, but not sure how complicated it is.
Yes, merging or syncing labels is something we should concern ourselves with.
We removing priority and labeling this R&D, @matejzak and @andrewkozlik please discuss priority together.