UNPKG

o1js-email-verify

Version:

Implemented using [o1js](https://github.com/o1-labs/o1js), this project is a reimplementation of [zk-email](https://github.com/zkemail/zk-email-verify), leveraging the Mina proving system [Kimchi](https://o1-labs.github.io/proof-systems/specs/kimchi.html#

118 lines (72 loc) 6.65 kB
# How zk-email works zk-email as a "technique" is the process of verifying the DKIM signature of an email to verify the authenticity of the email body, then running this verified body in a custom regex circuit that searches for spefific text patterns required for the application. The proof generated by the circuit can then be used to convince a smart contract to execute some action. ## Understanding the email chain #### Email Servers Emails need email servers to be running to allow for sending and receiving of emails. As this is a cumbersome task for an individual to do it (even though its totally possible), users often use a paid service like gmail or proton mail to handle this task. This means that emails used by such users are signed by the "gmail.com" domain.Large corporations however, that need to send large number of automated emails might host their own email servers that sign emails with their own custom domains (eg. x.com) The email server is sitting on a specific ip which the domain resolves to. How do we know which ip address for which domain? Enter DNS Registry. #### Email client Users interact with the server using a client which can be a desktop client (eg. thunderbird) or a web client (eg. gmail) #### DNS Registry The domain to public key mapping is stored in the DNS records of the domain. The DNS records are like the internet phonebook and copies of this database are stored in many DNS servers. #### DKIM Signature Most emails today are signed by the domain that sent it using a public key infrastructure (a public and private key pair) like [RSA](https://cryptobook.nakov.com/digital-signatures/rsa-signatures) for example. Email mailboxes use the email signature to verify the identity of email senders to detect phishing and scam attempts and that the original message has not been tampered with in transit. ![alt text](email-infra.png) ## What we want from Emails? There are two main functions we need to perform: **Check email authenticity** We do this by checking the DKIM signature that comes with an email. We want to be 100% sure the email has not been tampered with and we want to be sure that the public key that signed it is in fact the domain public key registered in DNS registry. **Check specific content** If we are sure that the email body is authentic, then we can use it as input to a regex circuit that can look for specific character sequences in it in verifiable code (i.e onchain). These two checks are sufficient to unlock some features in a smart contract, with the trust assumption that the email server that sent the email is secure. ## Verifying DKIM Signatures DKIM (DomainKeys Identified Mail) signatures are not a spefific type of cryptographic signature (like ecdsa, rsa, schnor..etc) but its a formatting and rules for handling email signatures generally. The standard for DKIM signatures is formalized in an internet standard [RFC 6337](https://datatracker.ietf.org/doc/html/rfc6376). This standard is maintained by the IETF (Internet Engineering Task Force, a non profit entity). The standard specifies which parts of the emails are signed and how data is formatted. An example of dkim signature found in the header of an email: ``` DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=androidloves.me; s=2019022801; t=1584218937; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=aeLbTnlUQQv2UFEWKHeiL5Q0NjOwj4ktNSInk8rN/P0=; b=eJPHovlwH6mU2kj8rEYF2us6TJwQg0/T7NbJ6A1zHNbVJ5UJjyMOfn+tN3R/oSsBcSDsHT xGysZJIRPeXEEcAOPNqUV4PcybFf/5cQDVpKZtY7kj/SdapzeFKCPT+uTYGQp1VMUtWfc1 SddyAZSw8lHcvkTqWhJKrCU0EoVAsik= ``` v: version of the DKIM key record a: The algorithm used for hashing (sha256) and signing (RSA) c: message canocicalization: how is message formatted before signing d: domain used for the DNS lookup s: Selector for the public key t: signature timestamp h: header fields used as message in signature bh: body hash of body in base64 encoded b: base64 encoded signature Presented with a signature above, we can verify it using these steps: 1. Check the signature algorithm and get the public Key for the domain from a DNS server: query any DNS server to obtain the public key of a domain using s and d. It returns a p value for public key that looks like this: ``` "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCcaywJn59dbp7TbRiDsVloBdCsgl9wAEvHo9WCDSNRqDJjkF1Fjy44Q4emckHP/Tv7hJdIlBtV8hEw5zGD+/kKkhnlx04BSYqXuxed1nOq6FDjNTIR6TmHetMfVU1IcO7ewyJZp5/2uM64JmTDh2u3ed4+JR7jqFE2e/ZqBTM1iQIDAQAB" ``` 2. Construct the exact header message that is signed. Exact header format is specified in the parameter h. 3. Hash the header message from 2. 4. Format using pkcs1.5 encoding [see here](https://datatracker.ietf.org/doc/html/rfc3447#section-9.2) 5. verify the rsa signature using the signature b, public key p and the hashed header obtained from step 4. Note: We know its RSA signing algorithm because of a. Another check that is usually performed as an extra measure is the body hash check which is field bh in the header that should correspond to the body b. To perform this check: 6. Calculate the hash of the body from b 7. compare the hash with the base64 decoded value bh from the DKIM-signature header of the email These steps are summarized in the following diagram: ![alt text](DKIM-process.png) ![alt text](../zkEmail-architecture.png) ## Regex Circuits - Background of zkregex and why its desirable - For more thorough explanation, explre the README of the regex repo: - Downside: if html format changes, then well have redeploy again Explain the reveal and out where we use it in the library? core: for headers, body checks app specific: it might be worth hosting regex libraries. Please submit PRs. explain how they integrate together ## Trust assumptions of emails If these two checks pass for our given application, then we can be sure this email was sent from that email server. Of course, the trust assumption is the email server. We cannot be sure the email server of x.com has not been hijacked by an internal employee to forge an email. (This is like saying someone got access to the king's stamp in 18th century and forged a letter). Hence there is an underlying assumption that we trust these servers for our given application. How much trust and on which domain servers will be application specific. ## References - https://zkemail.gitbook.io/zk-email/ - https://blog.aayushg.com/zkemail/ - https://github.com/zkemail