# Essences in the Email Wallet Protocol ## 1. Introduction At Progcrypto in November 2023, we launched Email Wallet, a contract wallet using ZK Email. As far as I know, this is the first wallet protocol in which the UX is complete with sending and receiving emails. Specifically, a user can 1) transfer tokens simply by sending emails, 2) specify the recipient by the email address without the recipient's Ethereum address or any actions from the recipient, and 3) call any smart contracts called extensions on-chain by changing the message in the subject. When designing the Email Wallet protocol, we aimed to remove dependencies on customized web frontends, browser extensions, and installed applications, to minimize the hurdles for non-crypto users to start using Ethereum. You can learn the basis of the Email Wallet protocol [here](https://zkemail.gitbook.io/zk-email/email-wallet). Despite such a beginner-friendly UX, it guarantees security and privacy for long-term use as follows: - **No trust in relayers for safety and liveness.** Although users need to rely on a permissionless entity called relayer that generates proofs of their emails and posts them to the Email Wallet contracts to execute transactions on-chain, our protocol **does not** rely on any relayers to guarantee safety and liveness. In other words, **no** relayer can steal the users' funds in Email Wallet or call smart contracts as users, and **at least one honest** relayer is enough for users to avoid censorship of their email-based transactions. Users only need to trust their email domain servers such as Gmail. - **Privacy protection of a link from an email address to an ethereum address against passive third parties.** If a user's relayer is honest for privacy or hosted by the user itself, on-chain data **does not** reveal the link from the user's email address to the corresponding ethereum address to passive third parties who only observe on-chain data without making transactions. Therefore, the only way for an adversary to break that privacy is to send tokens to a target recipient's email address using Email Wallet and observes how the tokens moves on-chain, costing the adversary some gas fees for each target. - **Sandbox security of extensions**. An ability of third-party extensions to control the user's wallet is limited to prevent malicious extensions from exploiting the user's funds without explicit permissions. In this article, I describe the challenges our team faced to achieve both the friendly UX and the security and privacy protection, and our path to solving them. <!-- - Email Wallet is a contract wallet that allows users to create Ethereum transactions just by sending an email. - (Some basic introductions of the email wallet.) - I first proposed the concept of Email Wallet in [this article](https://mirror.xyz/privacy-scaling-explorations.eth/mmkG4uB2PR_peGucULAa7zHag-jz1Y5biZH8W6K2LYM). - Later, we developed the first demo of Email Wallet using the Halo2 email verification circuit and presented it at ICBC2023. - However, this demo had many issues related to privacy, security, and development experience. --> ## 2. Conversion from Email Address to Ethereum Address One of the major challenges in the Email Wallet protocol is the conversion from a user's email address to its corresponding Ethereum address. If the Ethereum address is derived only from the email address with CREATE2, anyone can derive the Ethereum address of a specific email address, posing a privacy issue. To ensure privacy, a private salt known only to the user and the relayer is required. The salt is also useful to enable the user to transport the user's current account to different relayers for liveness without moving assets on-chain, if the user's current relayer goes offline or censors the user's transactions. Initially, we considered using the data from the user's first email sent or received for the Email Wallet as the private salt. Specifically, [BarryWhiteHat](https://github.com/barryWhiteHat) and [Aayush Guputa](https://aayushg.com/) proposed to use the signature and the message ID, respectively. However, we did not adopt them for the following reasons: 1. Some email client such as Gmail do not allow email senders to download the digital signatures attached by the email server. Therefore, the sender cannot transport the account by sharing the salt to different relayers. 2. The message ID does not necessarily have sufficient entropy. In that case, an adversary can predict the specific Email Wallet user's Ethereum address with reasonable computational costs. Instead of using data in the email, we next considered a method where either the user or the relayer generates a new random salt called account key. If it is generated by the relayer, they shares it with the user by sending an email containing it. Note that it is **not a private key** to spend the user's funds; thus while the relayer knows the account key, they **cannot** violate the safety of the account. Our contract, however, cannot directly verify if a malicious relayer has sent this email to the user. This is because if the relayer uses the self-hosted email domain, they can attach a digital signature and generate a proof of the expected email without actually sending it. Therefore, our contract verifies that the account key is available to the user. Specifically, the user sends an email containing the account key to the relayer. The relayer then sends our contracts a proof to claim that the CREATE2 salt of the user's wallet address, a commitment to the email address and the account key called account key commitment, and some other data in the public inputs are derived from the sender's email address and the account key in the user's email. Once the proof is verified, the wallet of which Ethereum address is derived from the CREATE2 salt is initialized on-chain as the user's accessible account. There are two ways for users to send emails with their account keys: 1. If the user generates their own account key using a frontend on a site such as [emailwallet.org](https://emailwallet.org/), they directly sends the relayer an email containing the account key in the email header. Note that the dependencies on that frontend is trivial because the user can use any frontends with the same functionality, and the frontend stores no data for each user. 2. In the other case, i.e., the relayer generates the account key, they first sends the user an email containing the account key in a field of the email header in which the value is inherited in the reply (e.g., subject line). The user then replies to this email. In both cases, the user's email will contain the account key. Therefore, the proof of this email will pass our contract's verification. In this way, our contract can ensure that the user who initializes the account can access to the account key to derive the Ethereum address and transport the account for liveness, while keeping the privacy of the link from the email address to the Ethereum address. ## 3. Token Transfer to Recipients Not Yet Starting Email Wallet A next hard issue that confronted us was how to determine a recipient's Ethereum address when the user tries to send tokens to the recipient who has not yet started Email Wallet, i.e., having no initialized account. The simpliest solution is that the sender's relayer generates the recipient's account key and transfers the tokens to the Ethereum address derived from that key. However, if the recipient receives tokens from multiple senders under different relayers, it worsens the recipient's UX because the recipient needs to manage multiple accounts provided by each relayer. You may think that the sender's relayer can adopt an existing Ethereum address if another relayer already creates the same recipient's account. Unfortunately, this idea makes a new attack vector that a malicious relayer can break the atomicity of the transaction. That is, if the recipient's relayer does not share the generated account key with the relayer, the transferred tokens are not available to the recipient as the recipient cannot transport the account without the account key when it is being censored, but the sender cannot retrieve the transferred tokens in such a case. We removed that attack vector by introducing expiration date. If the recipient does not complete the account initialization, i.e., sending an email containing the account key, within the expiration date, the sender can retrieve the transferred tokens. It ensures the atomicity because the transfer will be definitely expired when the recipient's relayer does not share the account key. It additionally provides another benefit that the user can retrieve tokens when the recipient's email address is actually not used. However, the sender's relayer cannot remove risks that the token transfer fails due to the malicious behavior by the recipient's relayer, which is still a bad UX. We finally found a solution like a Columbus' egg: the sender's relayer does not need to decide the recipient's Ethereum address. Specifically, the sender's tokens are transferred to our contract and locked with a commitment to the recipient's email address called email address commitment. If the recipient already initializes an account under a certain relayer, that relayer can claim the locked tokens and transfer them to the recipient's wallet by proving that the email address commitment and the account key commitment for the recipient's account use the same email address. To create this proof, the recipient's relayer needs to know a randomness of the email address commitment. Therefore, the sender's relayer shares the randomness with other relayers that say they have created an account for the recipient's email address. During this process, private set intersection (PSI) ensures that the email address is available only to two communicating relayers. These mechanisms enables the recipient to collect tokens sent from multiple users under different relayers to one wallet. ## 4. Reasonable Limitations to Extensions When designing a specification of extension contracts, we had to solve tradeoffs among the following properties: - Sandbox security against malicious extensions. - Better privacy by using a different sender's ID for each extension. - Interoperability among extensions. Depending on which properties are important, the sender’s ID that the extension can receive and the way to specify the tokens to be withdrawn from the sender's wallet will be different. Our first design was that the sender’s ID is unique to each sender and the called extension, and the withdrawn tokens are specified as a list of the token amount and name pairs. For example, an Uniswap extension withdraws tokens defined in the subject from the sender's wallet, calls Uniswap to exchange them with output tokens, and deposits the exchanged tokens to the sender's wallet. In the case of a NFT wallet extension, the extension contract deploys a NFT wallet for the given sender's ID, and contols it as its owner according to an instruction in the subject. It provides a good sandbox security because the states of the extension contracts are independent. Besides, if the future version of the Email Wallet manage the users' funds as UTXOs in a private pool, where the tokens will be withdrawn from a private UTXOs pool shared by all users, it also ensures high privacy because a third party cannot determine if two transactions calling different extensions are issued from the same user as their sender's IDs are different. However, its interoperability among extensions is bad due to their high independence. For example, the NFT wallet extension cannot allow the other extensions to control NFTs in the sender's NFT wallet since the other extensions cannot get the sender's ID for the NFT extension. Another design for the opposite tradeoffs is that the sender's single wallet contract uses `delegatecall` to call the extension contract. It achieves the best interoperability because all extensions share the same states, but at the same time it means a lack of the sandbox security and the weakest privacy. Especially, a malicious extension can easily exploit all funds in the sender's wallet without explicit permissions. Our final design adopted in the curren protocol is the combination of the above designs as follows: 1. The sender's ID is unique to each sender but common among all extensions under the current single wallet model. Specifically, it is the same as the sender's wallet address now. 2. The funds are withdrawn from the sender's wallet to the extension contract according to the token amount and name in the subject. For example, to withdraw 100 ETH, the words of "100 ETH" must be written in the subject clearly. 3. The extension contract can request the sender's wallet contract to call a target contract address with arbitrary calldata provided by the extension. However, that request is rejected if the target contract is an ERC20 contract registered in our token registry contract. The second and third features are proposed by [Saleel](https://saleel.xyz/). These features ensure both the high sandbox security of the ERC20 tokens in the sender's wallet and the high interoperability among extensions. Specifically, the third feature allows to the extension contract to call external contracts under the context of the sender's wallet contract, i.e., `msg.sender` of the called extension contract is the wallet contract address. However, this functionally cannot violate the safety from the second feature as the extensions cannot request the wallet contract to call ERC20 contracts. If our future protocol adopts the private UTXO model, the above design can achieve the best-effort privacy for each application by defining the sender's ID as a hash of the account key and a public tag specified by the extension. The privacy level that each application can achieve is essentially limited by the required interoperability, specifically, consistency of the sender's ID. For example, the Uniswap extension does not require the sender to use the same ID. Therefore, it can use a unique public tag for each transaction, preventing the same ID from being used more than once for the best privacy. In contrast, the NFT wallet extension wants to maintain the highest interoperability by adopting the same ID for the same sender, so it specifies a trivial public tag such as zero that will be often used by many other extensions. We cannot achieve the best privacy and interoperability at the same time due to the difference of requirements among applications, hence our specification allows the extensions to control them. ## Credits and Acknowledgement Email Wallet was built by [Aayush](https://aayushg.com/), [Saleel](https://saleel.xyz/), [Rasul](https://curryrasul.com/), [Wataru](https://github.com/wshino), [Elo](https://github.com/Metachaser24), and me. Thank [BarryWhiteHat](https://github.com/barryWhiteHat), [Tyler](https://github.com/AtHeartEngineer), and [Vivek](https://github.com/RiverRuby) for proposals and feedbacks about the Email Wallet protocol. ## References - S. Suegami, “Rsa verification circuit in halo2 and its applications”, 2022. Available at https://mirror.xyz/privacy-scaling-explorations.eth/mmkG4uB2PR_peGucULAa7zHag-jz1Y5biZH8W6K2LYM - S. Suegami, & K. Shibano, "Contract Wallet Using Emails", arXiv e-prints, arXiv-2312, 2023. Available at https://arxiv.org/pdf/2312.04173.pdf - Saleel, "Building Email Wallet", 2023. Available at https://saleel.xyz/blog/email-wallet/ - Email Wallet team, "Email Wallet V1 Spec", 2023. Available at https://proofofemail.notion.site/Email-Wallet-V1-Spec-Latest-d29eeb4201654eb983576772c09c98cb?pvs=74 - Email Wallet website, https://emailwallet.org/