o1js-email-verify
v0.0.1
Published
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#
Downloads
4
Maintainers
Readme
ZK Email O1JS
Implemented using o1js, this project is a reimplementation of zk-email, leveraging the Mina proving system Kimchi.
ZK Email is an application that allows for anonymous verification of email signatures while masking specific data. It enables verification of emails to/from specific domains or subsets of domains, as well as verification based on specific text in the email body. Our core SDK comes with libraries to assist with circuit generation as well as utility templates for general zk applications.
The zk-email-o1js package serves as a toolkit for zkapp developers looking to integrate email verification functionality into their o1js/Mina applications.
Motivation
ZK Email in o1js serves as a wrapper around the existing project zk-email-verify, aimed at integrating the concept of Programmable Provenance into the Mina blockchain.
Programmable Provenance is the holy grail of web2-web3 integration, and it’s what zk-email enables.
The implementation of zk-email in o1js is a step towards achieving Mina's mission of becoming the Proof of Everything.
For a more in-depth understanding of the motivation and purpose behind ZK Email, please read Aayush's thoughts on ZK Email.
Primitives Overview
The ZK Email Verifier in o1js is built upon several key packages that have been developed and published to empower developers within the Mina ecosystem to build their applications.
ZK Regex Circuit Compiler
The ZK Regex Compiler is not a module but rather a tool that generates o1js regex circuits as strings in the terminal, which can be copied and pasted into other o1js projects.
While not a direct dependency of the zk-email-verify project, the ZK Regex Compiler utilizes specialized regex circuits to extract the
body hash
from email headers, enabling the binding of separate inputs (header and body bytes) within theemailVerify
circuit.The ZK Regex Compiler is essential for extending the utility of ZK Email verification to develop various real-world applications such as ZKP2P or Proof of Twitter. It achieves this by facilitating the extraction or validation of specific substrings from email bodies and verifying information in email headers like authority or sender details.
For detailed usage instructions on the o1js ZK Regex Compiler, please refer to the zk-regex-o1js documentation.
RSA65537 Signature Verification
This is a core primitive used by the main ZK Email Verify provable function to verify the DKIM signature of an email.
The primitive is published as an npm package called o1js-rsa, making it accessible for other Mina developers to utilize.
Base64 Encoding/Decoding
The body hash retrieved from email headers is crucial for proving the integrity of the input body. Since the body hash in headers is base64 encoded, it's necessary to base64 encode the computed SHA256 digest of the body for a consistent and compliant integrity check.
Initially published separately as o1js-base64, these functionalities have been merged into the main o1js package since v1.3.0. The
base64Encode
andbase64Decode
functions can now be directly accessed as methods within the provableBytes
class. However, developers can refer to the package README for detailed guidance on using these primitives effectively.
Dynamic & Partial SHA256
Dynamic SHA256 is pivotal for verifying messages uniformly using the same verifier circuit, allowing hashing of messages up to a maximum length. This dynamic capability enhances email verification, although it imposes limits on the size of bytes in email headers and bodies. Otherwise, differing sizes would necessitate compiling distinct circuits for each email, preemptively setting the size.
Partial SHA256 is an adaptation of dynamicSHA256. It initializes with a
precomputedHash
as the initial hash value instead of the default specified by SHA2 standards. The remaining blocks are hashed within the SNARK, mirroring dynamic hash functionality.Partial SHA256 serves as a significant optimization for proving the integrity of email body hashes.
For detailed usage instructions and performance insights on dynamic & partial SHA256, please consult the dynamic-sha256 package documentation.
How to use the package
The o1js-email-verify
includes two essential functions:
generateEmailVerifierInputs
: This helper function generates necessary inputs for the email verifier circuit from raw email content.emailVerify
: This provable function verifies an email, optionally checking the integrity of the email body if it matches the one in the header.
How to install
npm install o1js-email-verify
How to import
import { generateEmailVerifierInputs, emailVerify } from 'o1js-email-verify';
How to generate inputs for Email Verification
When generating inputs for the provable emailVerify
function, follow these guidelines:
Start by specifying the
filePath
of the raw EML file.Optionally, adjust the size limits for the headers and body:
maxHeaderLength
: Default is 1024 bytes.maxRemainingBodyLength
: Default is 1536 bytes.- Ensure these sizes are multiples of 64 and sufficiently large to accommodate your inputs.
The input generator returns an object that must be destructured for use with the
emailVerify
function:- See the tester function example for guidance.
Customize the
bodyHashCheck
boolean parameter to indicate whether to verify the body hash (true
) or not (false
).Any deviation from these input requirements may cause the email verifier circuit to fail. The
emailVerify
provable function includes robust security checks to detect and handle errors effectively.
Using ZK Email Verification in Real-World Applications
Existing Projects Utilizing ZK Email on Ethereum
- ZKP2P: Decentralized Venmo <> USDC Bridge
- Email Wallet: Send transactions via email or act as a Safe multisig signer!
- Email Account Recovery: Use emails as guardians for any smart wallet or multisig.
- Nozee: Anonymous Proofs of Email Domain via JWTs
- Proof of Twitter: Verify your Twitter username on-chain using zk proofs.
Developing zkApps with ZK Email
Currently, there isn't a robust demo of a zkapp using the ZK Email Verification infrastructure. Here is a general approach to developing such applications:
- Generate Inputs and Verify Email: Follow the instructions in the input generation guide.
- Call
emailVerify
in a zkApp Method: Use this function to prove the authenticity of the email and its body. - Optional: Use ZK-Regex for Sender Authority: Implement a zk-regex circuit to assert the authority of specific senders (e.g., Twitter, GitHub, Venmo).
- Extract Data from Email Body: Use a tailored zk-regex circuit to scrape specific data from the email body, such as a Twitter handle or invitation ID etc.
Troubleshooting
Please note that the input generator function is a wrapper around the helpers from the zkemail library, particularly the DKIM parser class, to generate the inputs required for the email verifier circuit.
The decision to use the original zk-email library helpers for input generation ensures that we benefit from code audits and maintain compatibility with other zk-email applications in the future.
For any bugs or errors, you can refer to the FAQ or open an issue in the original zk-email-verify repository.
How to build
npm run build
How to run tests
npm run test
npm run testw # watch mode
How to run coverage
npm run coverage
How to quickly verify an eml
Download your email EML file, change the filePath
in the tester file, and run:
npm run tester
How to benchmark
npm run zkProgram
Preview
verifyEmailNoBodyCheck summary: {
'Total rows': 109111,
Generic: 41907,
EndoMulScalar: 30840,
RangeCheck0: 2488,
Xor16: 22512,
Zero: 11265,
Poseidon: 99
}
verifyEmailBodyCheck1024 summary: {
'Total rows': 340298,
Generic: 206040,
EndoMulScalar: 64102,
RangeCheck0: 2488,
Xor16: 45040,
Zero: 22529,
Poseidon: 99
}
verifyEmailBodyCheck1536 summary: {
'Total rows': 386506,
Generic: 221528,
EndoMulScalar: 77926,
RangeCheck0: 2488,
Xor16: 56304,
Zero: 28161,
Poseidon: 99
}
Comparison of Email Verifier Circuit
| Function | O1JS Kimchi Constraints | Circom R1CS Constraints | | --------------------- | ----------------------------------------- | ----------------------------------------- | | SHA256 header hashing | 92,675 constraints for a 1024-byte input | 506,670 constraints for a 1024-byte input | | RSA65537 | 12,401 constraints | 149,251 constraints | | SHA256 body hashing | 139,074 rows for a 1536-byte input | 760,142 rows for a 1536-byte input | | base64Encode | 1,697 constraints for a 32-byte input | 1,697 constraints for a 32-byte input | | bodyHashRegex | 86,453 rows for a 1024-byte input | 617,597 rows for a 1024-byte input | | | 145,586 rows if selectSubarray is counted | |
Further Development Directions
- Compute and integrate domain check regex function.
- Ensure RFC compliance for the email verification standard for DKIM.
- Develop a universal DKIM registry for the Mina ecosystem with an incentivized oracle network of DNS servers.
- Explore handling very large emails using kimchi's recursion capabilities.
- Experiment with wallet integrations.
Acknowledgments
- Thanks to the zk-email team for their pioneering efforts, comprehensive library, detailed documentation, and quick responses to our questions on the Telegram group.
- Gratitude to the Mina Foundation for funding the zkIgnite series.