Open ainsleys opened 4 years ago
The concept of a "secret briefcase" is very interesting! I think it can be implemented as a custom account, where plugin will manage all shielded addresses on user's behalf.
Hi @ainsleys, thanks again for this writeup! I agree that a lot of the problems you describe have to be solved at the wallet layer. Some we've thought about before, some are new to us. For MetaMask's part, I believe that the plugin system can definitely play a role.
Since you mentioned Tornado, and since I know he has opinions, I'm going to try to summon @rstormsf to this issue.
On to your questions:
- Is there a way to automate the process of generating the correct # of fresh wallets with derived keys for a desired mix amount?
Yes, but it gets complicated. We can freely generate as many Ethereum accounts as we want. However, from your description, we don't want these accounts to be correlatable with any of the user's other accounts. That being the case, they probably shouldn't be "normal," SLIP44 accounts, as the user may have generated and used those accounts in the past, or may generate and use them in the future.
We have a number of proposals for app keys---including this, completely protocol-agnostic one by @Bunjin ---where we can try to standardize some new HD path that the user ought to never have used and won't use again. Whatever we do, it's unlikely to be compliant with existing HD standards per the BIP process, since AFAIK the owners of those repos generally don't merge new stuff (see discussion here).
- How can users make a single payment that draws from multiple addresses?
- Can a UI abstraction handle multiple transactions but abstract the process from the user (i.e., we accept the fees associated with multiple transactions, but at least the UX is similar to the effort involved in sending a single transaction).
AFAIK, there's no way to accomplish this in a single transaction, but we could definitely create a UI abstraction to make it pleasant for the user to accomplish, without confirm every single transaction. That abstraction does not yet exist, though. I'd like to invite our designers to check out our main plugin designer, @rachelcope, to check out your Figma and thoughts UI/UX abstractions!
Also, cc: @danfinlay
@rekmarks I think that a privacy wallet should differentiate between public accounts and private accounts. Private accounts should never have any incoming transactions(except the first one), only outgoing. We are working on Tornado.cash v3 where we are going to try to solve those problems. Once we understand a few basic UI flows, we will help everyone out there to show how we think privacy wallet should look like.
At this point, I don't really think it's worth to try to integrate tornado.cash into any other wallet because we believe it's not complete solution and lacks a bunch of functionalities such as join
and split
for private notes.
Regarding other privacy solutions on Ethereum, if they can provide fully functioning service on mainnet with long history of transactions + volume + security audits of their work, then it's time to think about integrations.
Thanks for the comments, @rekmarks and for your response as well @rstormsf . I understand your position, and look forward to hearing what you all come up with.
I also agree w/ @rstormsf 's concept of private accounts. Putting rails like described on private accounts is probably the best way to help users act safely here. Is a custom account something that could handle this? Another idea is to have two "recipient" addresses-- a contract account which is a kind of smart wallet, and an owner account which deploys that contract immediately upon receipt (or something, just thinking out loud).
Do you know what the correlatability of these SLIP44 accounts is exactly, from an observer perspective? I'm also afraid I didn't follow this:
the user may have generated and used those accounts in the past, or may generate and use them in the future.
Isn't this an issue in general for generating accounts on behalf of the user? why isn't it a problem in other applications?
Would love to hear @rachelcope 's thoughts on abstractions.
I'd also like to thank @rstormsf for providing his thoughts.
Regarding your privacy-related questions @ainsleys, I'll try to account for my understanding. I apologize in advance if I'm explaining things that you already know.
AFAIK, all major Ethereum wallets that manage Externally Owned Accounts (EOAs) use the same BIP/SLIP standard to generate private keys for the user. The public key is derived from the private key, and the address is derived from the public key. For more details and links to BIPs/SLIP44, see this thread.
In broad strokes, Ethereum private keys are generated by running a cryptographic algorithm on the user's seed phrase and a number (call it the account_index
or address_index
) that starts at 0
. When you generate a new account, your wallet increments this number and re-runs the algorithm. This means that e.g. your Account 5
should be the same in MetaMask as in any other wallet.
Do you know what the correlatability of these SLIP44 accounts is exactly, from an observer perspective?
Now, assuming the seed phrase is secret, there's no way for an observer to tell if any two addresses came from the same seed phrase without more information. Unfortunately, that information is abundant and comes in two flavors: on-chain and website usage data.
Isn't this an issue in general for generating accounts on behalf of the user? why isn't it a problem in other applications?
It is a general issue, but only to the extent that the user cares. Privacy is not the point of most existing Ethereum applications, and most people don't seem to care if they can be identified as the owner of e.g. a rare CryptoKitty. Most EOA wallets leave prevent account correlations as an exercise to the user. At MetaMask, we implemented EIP 1102 to make it possible for the privacy-concerned user to obviate one way in which dapps can correlate accounts, but IMO, most users would do best to assume that nothing they do on Ethereum is private.
Does that answer your questions?
Thanks @rekmarks for the deeper clarification-- with Salad, users should never send ether directly from coinbase to a "recipient address", or between addresses they own. This would as you say link the addresses. Instead, ether would go from one owned address to a pool and then on to another owned address. Someone observing the chain would not be able to distinguish this easily, because the funds are pooled with other user funds in a deposit contract.
I'm trying to understand whether there's some additional linkability/correlatability issue that arises with generating the addresses with "normal SLIP 44" accounts that would not exist if we pursued something like the app keys.
I think this is a slightly different challenge from app/website fingerprinting, which we should also consider.
I think this is a slightly different challenge from app/website fingerprinting, which we should also consider.
I agree, I was just mentioning that for completeness!
with Salad, users should never send ether directly from coinbase to a "recipient address", or between addresses they own.
The problem with using SLIP44 accounts is that, when the user's Salad wallet generates those accounts, the user may have generated and used them in the past, and may generate and use them in the future.
You can of course stop accounts used in the past from being used by Salad by checking their history onchain, but there is nothing stopping another wallet from using those accounts for god knows what in the future. This doesn't even have to be far in the future; the user could be on multiple wallets, and start transacting between accounts that their Salad wallet thinks are uncorrelated, even as funds are in the mixer.
If done right, app keys get around this problem because the accounts you'd get by using them would be used for Salad and Salad only. We can think of app keys as claiming a part of the address namespace that neither the user nor anyone else has interacted with before, or will interact with outside the context of using Salad.
there is nothing stopping another wallet from using those accounts for god knows what in the future.
Ah, I understand. Thanks a lot for the clarification, I appreciate it. Yes, I agree-- if it is possible to do this with app keys, that would be very useful. It may be sufficient in early versions to explain to users the situation, and advise them to use caution if they are using multiple wallets with the same seed phrase.
I swear I was going to include that key line in the original overlong response, but I forgot about it while writing the preamble :p
The app key proposals we have going should work out of the box for everyone when implemented. If any of y'all want to chime in on them, especially the protocol-agnostic one I mentioned in my first comment above, that'd be greatly appreciated!
@rekmarks
there is even a bigger problem: RPC endpoints.
When you change Account 1 to Account 2, you are querying eth_balance
, nonce, etc on both of them to the same RPC endpoint, so the RPC owner can conclude that you are the owner of both of these accounts since the request originating from the same IP at the same time.
In metamask's case: infura. It knows waay too much about owners. Once they share their data with analytics - it's game over.
@rstormsf, I agree that not mentioning RPC endpoints is an oversight on my part. In any discussion about "who knows things about your Ethereum activity," we cannot leave out the RPC endpoint and in our case Infura.
We (Enigma) have been working on Salad, a decentralized mixing-service, as well as looking into the usability and functions of other mixers. In this process we have found significant usability issues that arise regardless of the technical approach to mixing (including centralized mixers, ad-hoc mixing behavior (such as sending to and from exchanges), zero-knowledge proof mixers and TEE-based mixers like Salad.)
These usability issues seem most suited to be addressed on the wallet side, as they mainly pertain to the generation of wallets, wallet key management, and the classification and observation of accounts. Fundamentally, when mixing tokens, users usually end up with more addresses than they started with.
Note: These are all R&D questions for us. In some cases there may be existing EIP work that addresses them, or alternative solutions we’re not aware of. We hope to collaborate both with wallet creators such as Metamask as well as other mixing services on finding solutions that will benefit users the most. We hope this issue helps kick off a conversation. We know there are a lot of points in here, and happy to re-structure these as individual issues moving forward or however makes sense
Terminology Receiving address / destination address: the address a user specifies that they want funds delivered to after mixing Fresh address: a newly-generated address with no transaction history Mixing service: Salad, Tornado Cash, Wasabi: a service that enables users to combine their tokens with other users and obtain a degree of transactional anonymity. Self-mix: When a user mixes her own tokens and sends them to another address she controls. This is in contrast to a mix-and-send where a user mixes tokens as part of a normal transaction to another user or app.
Creating the right number of “fresh wallets” Whether a service relies on fixed-amount mixing (i.e., denominations of 1 eth) or variable amount mixing (as we see with Wasabi), users will likely end up with more addresses to manage than they start with. For example, to mix 6 ETH, you may participate in 6 1-ETH mixes and then have 6 wallets, each with 1 ETH in them. Currently, the user needs to generate the required number of wallets herself, and use these destination addresses with the mixing application.
Send from multiple In this issue a user has successfully mixed his or her coins to fresh recipient addresses, but now has say 6-10 addresses with 0.1 ETH in them (users ideally use “fresh” addresses with no prior transactions). How can she make a payment without needing to send 10 transactions, which is burdensome on the user in cost and time? Is there a way to accomplish ‘send from multiple’ that is less expensive? Note: Re-linking addresses by using multiple in one payment also has privacy considerations that should be explored, but this UX issue will persist even if that can be mitigated.
How can users make a single payment that draws from multiple addresses?
Can a UI abstraction handle multiple transactions but abstract the process from the user (i.e., we accept the fees associated with multiple transactions, but at least the UX is similar to the effort involved in sending a single transaction).
Representing tokens in mixed addresses / account abstraction This issue touches on what metaphor / abstraction is useful for users sending and receiving with accounts that have received funds from mixers.
Wireframes / Concepts
Here are some very early-stage figma wireframes we’ve been working with as we think through some of the usability issues. These are WIP, and explore two concepts:
Other issues that came up as we worked with these concept wireframes: