- 
                Notifications
    You must be signed in to change notification settings 
- Fork 28
Add SignerZKEmail and ZKEmailUtils #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
    
  
     Merged
                    Changes from all commits
      Commits
    
    
            Show all changes
          
          
            62 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      89cecfc
              
                Add ZKEmailSigner
              
              
                ernestognw bea0548
              
                Remove yarn.lock
              
              
                ernestognw b968068
              
                Update ZKEmailSigner.sol
              
              
                Amxx b99b9f8
              
                Add initializer
              
              
                ernestognw f5a2643
              
                Merge branch 'master' into feature/zk-email
              
              
                ernestognw 9577e06
              
                Run `forge upate lib/email-tx-builder` to bring recent changes
              
              
                ernestognw 813b226
              
                Add ZKEmailUtils and update ZKEmailSigner
              
              
                ernestognw ef5fe72
              
                Add BN256 curve reference
              
              
                ernestognw d9cba45
              
                Add .prettierignore to ignore lib linting
              
              
                ernestognw ccc43fa
              
                Exclude zk-email from pragma consistency checks
              
              
                ernestognw 24ed077
              
                Update contracts/utils/cryptography/ZKEmailSigner.sol
              
              
                Amxx 82850cb
              
                Update contracts/utils/cryptography/ZKEmailSigner.sol
              
              
                Amxx b6a3fdf
              
                Update ZKEmailSigner.sol
              
              
                Amxx 3dd1fb9
              
                Run `forge update`
              
              
                ernestognw 6bc3140
              
                Document ZKEmailSigner and ZKEmailUtils
              
              
                ernestognw 27dcc0d
              
                Rename to SignerZKEmail for consistency
              
              
                ernestognw 35b0bd6
              
                Document ZKEmailSigner and ZKEmailUtils
              
              
                ernestognw 900b668
              
                Update README to include SignerZKEmail and ZKEmailUtils documentation
              
              
                ernestognw e8fa099
              
                Simplify return type for ZKEmailUtils.isValidZKEmail
              
              
                Amxx 4b6426c
              
                Setup tests
              
              
                ernestognw 581123d
              
                Rename commandTemplate to templateId
              
              
                ernestognw 11b197f
              
                Address https://github.com/OpenZeppelin/openzeppelin-community-contra…
              
              
                Amxx 6d5f974
              
                Fix compilation
              
              
                ernestognw 3e9d0e3
              
                Refactor ZKEmailUtils
              
              
                ernestognw 72a4cfc
              
                Adjustment
              
              
                ernestognw 9742daa
              
                Refactor ZKEmailUtils
              
              
                ernestognw 34aa505
              
                Note _matchCase
              
              
                ernestognw fa8b58b
              
                Remove _commandMatch
              
              
                ernestognw 471e4de
              
                refactor
              
              
                Amxx aa7cdaa
              
                Readd refactored _commandMatch
              
              
                ernestognw 190f0b3
              
                Remove extra line
              
              
                ernestognw 202b59f
              
                Add missing logic to remove prefix using Bytes library
              
              
                ernestognw 8f0a057
              
                Fix compilation
              
              
                ernestognw ed5e027
              
                Pragma increase for mcopy support
              
              
                ernestognw 4ec7569
              
                Apply pragma to SignerZKEmail too
              
              
                ernestognw 8a202bd
              
                Fix pragma in mocks
              
              
                ernestognw d3e0ddf
              
                Add @JohnGuilding and @zkfriendly to CODEOWNERS
              
              
                ernestognw 6d4f9f6
              
                Try alternative syntax
              
              
                ernestognw 683f3fc
              
                Revert CODEOWNERS
              
              
                ernestognw c3275d2
              
                Address review suggestions
              
              
                ernestognw 1d428d4
              
                Add ZKEmailUtils tests
              
              
                ernestognw 521fbdd
              
                Improve coverage
              
              
                ernestognw 7842fa6
              
                Moar coverage
              
              
                ernestognw 6bb0c00
              
                Remove verifyEmail from signer
              
              
                ernestognw 8a5a283
              
                Merge branch 'master' into feature/zk-email
              
              
                ernestognw c039530
              
                Remove unnecessary imports
              
              
                ernestognw cd6f66f
              
                Reorder ZKEmailUtils checks
              
              
                ernestognw de69659
              
                Moar tests
              
              
                ernestognw e70f6d1
              
                Simplify ZKEmailUtils.t.sol
              
              
                ernestognw a6dcddd
              
                Update syntax in _commandMatch to test codecov
              
              
                ernestognw de157d8
              
                Improve fuzz tests
              
              
                ernestognw c9672d9
              
                Improve fuzz tests
              
              
                ernestognw 9ee4ccd
              
                Remove DKIM mock
              
              
                ernestognw f26d26b
              
                Add Hardhat tests
              
              
                ernestognw 799cf6c
              
                Fix codespell
              
              
                ernestognw f27f1a1
              
                Add AccountZKEmail.test.js
              
              
                ernestognw e1d6297
              
                Fix codespell
              
              
                ernestognw c924e97
              
                Merge branch 'master' into feature/zk-email
              
              
                ernestognw e7f44f2
              
                nit
              
              
                ernestognw 9fed941
              
                Reorder README.adoc
              
              
                ernestognw 0138787
              
                forge update
              
              
                ernestognw 9f1171e
              
                Merge branch 'master' into feature/zk-email
              
              
                ernestognw File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1 @@ | ||
| lib | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| // SPDX-License-Identifier: MIT | ||
|  | ||
| pragma solidity ^0.8.24; | ||
|  | ||
| import {Account} from "../../account/Account.sol"; | ||
| import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; | ||
| import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; | ||
| import {ERC7739, EIP712} from "../../utils/cryptography/ERC7739.sol"; | ||
| import {ERC7821} from "../../account/extensions/ERC7821.sol"; | ||
| import {SignerZKEmail} from "../../utils/cryptography/SignerZKEmail.sol"; | ||
| import {IDKIMRegistry} from "@zk-email/contracts/DKIMRegistry.sol"; | ||
| import {IVerifier} from "@zk-email/email-tx-builder/interfaces/IVerifier.sol"; | ||
|  | ||
| contract AccountZKEmailMock is Account, SignerZKEmail, ERC7739, ERC7821, ERC721Holder, ERC1155Holder { | ||
| constructor( | ||
| bytes32 accountSalt_, | ||
| IDKIMRegistry registry_, | ||
| IVerifier verifier_, | ||
| uint256 templateId_ | ||
| ) EIP712("AccountZKEmailMock", "1") { | ||
| _setAccountSalt(accountSalt_); | ||
| _setDKIMRegistry(registry_); | ||
| _setVerifier(verifier_); | ||
| _setTemplateId(templateId_); | ||
| } | ||
|  | ||
| /// @inheritdoc ERC7821 | ||
| function _erc7821AuthorizedExecutor( | ||
| address caller, | ||
| bytes32 mode, | ||
| bytes calldata executionData | ||
| ) internal view virtual override returns (bool) { | ||
| return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData); | ||
| } | ||
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| // contracts/MyAccountZKEmail.sol | ||
| // SPDX-License-Identifier: MIT | ||
|  | ||
| pragma solidity ^0.8.24; | ||
|  | ||
| import {Account} from "../../../account/Account.sol"; | ||
| import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; | ||
| import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; | ||
| import {ERC1155Holder} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol"; | ||
| import {ERC7739} from "../../../utils/cryptography/ERC7739.sol"; | ||
| import {ERC7821} from "../../../account/extensions/ERC7821.sol"; | ||
| import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; | ||
| import {SignerZKEmail} from "../../../utils/cryptography/SignerZKEmail.sol"; | ||
| import {IDKIMRegistry} from "@zk-email/contracts/DKIMRegistry.sol"; | ||
| import {IVerifier} from "@zk-email/email-tx-builder/interfaces/IVerifier.sol"; | ||
|  | ||
| contract MyAccountZKEmail is Account, SignerZKEmail, ERC7739, ERC7821, ERC721Holder, ERC1155Holder, Initializable { | ||
| constructor() EIP712("MyAccountZKEmail", "1") {} | ||
|  | ||
| function initialize( | ||
| bytes32 accountSalt_, | ||
| IDKIMRegistry registry_, | ||
| IVerifier verifier_, | ||
| uint256 templateId_ | ||
| ) public initializer { | ||
| _setAccountSalt(accountSalt_); | ||
| _setDKIMRegistry(registry_); | ||
| _setVerifier(verifier_); | ||
| _setTemplateId(templateId_); | ||
| } | ||
|  | ||
| /// @dev Allows the entry point as an authorized executor. | ||
| function _erc7821AuthorizedExecutor( | ||
| address caller, | ||
| bytes32 mode, | ||
| bytes calldata executionData | ||
| ) internal view virtual override returns (bool) { | ||
| return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData); | ||
| } | ||
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
        
          
  
    
      
          
            16 changes: 16 additions & 0 deletions
          
          16 
        
  contracts/mocks/utils/cryptography/ZKEmailVerifierMock.sol
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| // SPDX-License-Identifier: MIT | ||
|  | ||
| pragma solidity ^0.8.20; | ||
|  | ||
| import {IVerifier, EmailProof} from "@zk-email/email-tx-builder/interfaces/IVerifier.sol"; | ||
|  | ||
| contract ZKEmailVerifierMock is IVerifier { | ||
| function commandBytes() external pure returns (uint256) { | ||
| // Same as in https://github.com/zkemail/email-tx-builder/blob/1452943807a5fdc732e1113c34792c76cf7dd031/packages/contracts/src/utils/Verifier.sol#L15 | ||
| return 605; | ||
| } | ||
|  | ||
| function verifyEmailProof(EmailProof memory proof) external pure returns (bool) { | ||
| return proof.proof.length > 0 && bytes1(proof.proof[0]) == 0x01; // boolean true | ||
| } | ||
| } | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| // SPDX-License-Identifier: MIT | ||
|  | ||
| pragma solidity ^0.8.24; | ||
|  | ||
| import {IDKIMRegistry} from "@zk-email/contracts/DKIMRegistry.sol"; | ||
| import {IVerifier} from "@zk-email/email-tx-builder/interfaces/IVerifier.sol"; | ||
| import {EmailAuthMsg} from "@zk-email/email-tx-builder/interfaces/IEmailTypes.sol"; | ||
| import {AbstractSigner} from "./AbstractSigner.sol"; | ||
| import {ZKEmailUtils} from "./ZKEmailUtils.sol"; | ||
|  | ||
| /** | ||
| * @dev Implementation of {AbstractSigner} using https://docs.zk.email[ZKEmail] signatures. | ||
| * | ||
| * ZKEmail enables secure authentication and authorization through email messages, leveraging | ||
| * DKIM signatures from a {DKIMRegistry} and zero-knowledge proofs enabled by a {verifier} | ||
| * contract that ensures email authenticity without revealing sensitive information. The DKIM | ||
| * registry is trusted to correctly update DKIM keys, but users can override this behaviour and | ||
| * set their own keys. This contract implements the core functionality for validating email-based | ||
| * signatures in smart contracts. | ||
| * | ||
| * Developers must set the following components during contract initialization: | ||
| * | ||
| * * {accountSalt} - A unique identifier derived from the user's email address and account code. | ||
| * * {DKIMRegistry} - An instance of the DKIM registry contract for domain verification. | ||
| * * {verifier} - An instance of the Verifier contract for zero-knowledge proof validation. | ||
| * * {templateId} - The template ID of the sign hash command, defining the expected format. | ||
| * | ||
| * Example of usage: | ||
| * | ||
| * ```solidity | ||
| * contract MyAccountZKEmail is Account, SignerZKEmail, Initializable { | ||
| * constructor(bytes32 accountSalt, IDKIMRegistry registry, IVerifier verifier, uint256 templateId) { | ||
| * // Will revert if the signer is already initialized | ||
| * _setAccountSalt(accountSalt); | ||
| * _setDKIMRegistry(registry); | ||
| * _setVerifier(verifier); | ||
| * _setTemplateId(templateId); | ||
| * } | ||
| * } | ||
| * ``` | ||
| * | ||
| * IMPORTANT: Avoiding to call {_setAccountSalt}, {_setDKIMRegistry}, {_setVerifier} and {_setTemplateId} | ||
| * either during construction (if used standalone) or during initialization (if used as a clone) may | ||
| * leave the signer either front-runnable or unusable. | ||
| */ | ||
| abstract contract SignerZKEmail is AbstractSigner { | ||
| using ZKEmailUtils for EmailAuthMsg; | ||
|  | ||
| bytes32 private _accountSalt; | ||
| IDKIMRegistry private _registry; | ||
| IVerifier private _verifier; | ||
| uint256 private _templateId; | ||
|  | ||
| /// @dev Proof verification error. | ||
| error InvalidEmailProof(ZKEmailUtils.EmailProofError err); | ||
|  | ||
| /** | ||
| * @dev Unique identifier for owner of this contract defined as a hash of an email address and an account code. | ||
| * | ||
| * An account code is a random integer in a finite scalar field of https://neuromancer.sk/std/bn/bn254[BN254] curve. | ||
| * It is a private randomness to derive a CREATE2 salt of the user's Ethereum address | ||
| * from the email address, i.e., userEtherAddr := CREATE2(hash(userEmailAddr, accountCode)). | ||
| * | ||
| * The account salt is used for: | ||
| * | ||
| * * Privacy: Enables email address privacy on-chain so long as the randomly generated account code is not revealed | ||
| * to an adversary. | ||
| * * Security: Provides a unique identifier that cannot be easily guessed or brute-forced, as it's derived | ||
| * from both the email address and a random account code. | ||
| * * Deterministic Address Generation: Enables the creation of deterministic addresses based on email addresses, | ||
| * allowing users to recover their accounts using only their email. | ||
| */ | ||
| function accountSalt() public view virtual returns (bytes32) { | ||
| return _accountSalt; | ||
| } | ||
|  | ||
| /// @dev An instance of the DKIM registry contract. | ||
| /// See https://docs.zk.email/architecture/dkim-verification[DKIM Verification]. | ||
| // solhint-disable-next-line func-name-mixedcase | ||
| function DKIMRegistry() public view virtual returns (IDKIMRegistry) { | ||
| return _registry; | ||
| } | ||
|  | ||
| /// @dev An instance of the Verifier contract. | ||
| /// See https://docs.zk.email/architecture/zk-proofs#how-zk-email-uses-zero-knowledge-proofs[ZK Proofs]. | ||
| function verifier() public view virtual returns (IVerifier) { | ||
| return _verifier; | ||
| } | ||
|  | ||
| /// @dev The command template of the sign hash command. | ||
| function templateId() public view virtual returns (uint256) { | ||
| return _templateId; | ||
| } | ||
|  | ||
| /// @dev Set the {accountSalt}. | ||
| function _setAccountSalt(bytes32 accountSalt_) internal virtual { | ||
| _accountSalt = accountSalt_; | ||
| } | ||
|  | ||
| /// @dev Set the {DKIMRegistry} contract address. | ||
| function _setDKIMRegistry(IDKIMRegistry registry_) internal virtual { | ||
| _registry = registry_; | ||
| } | ||
|  | ||
| /// @dev Set the {verifier} contract address. | ||
| function _setVerifier(IVerifier verifier_) internal virtual { | ||
| _verifier = verifier_; | ||
| } | ||
|  | ||
| /// @dev Set the command's {templateId}. | ||
| function _setTemplateId(uint256 templateId_) internal virtual { | ||
| _templateId = templateId_; | ||
| } | ||
|  | ||
| /** | ||
| * @dev See {AbstractSigner-_rawSignatureValidation}. Validates a raw signature by: | ||
| * | ||
| * 1. Decoding the email authentication message from the signature | ||
| * 2. Verifying the hash matches the command parameters | ||
| * 3. Checking the template ID matches | ||
| * 4. Validating the account salt | ||
| * 5. Verifying the email proof | ||
| */ | ||
| function _rawSignatureValidation( | ||
| bytes32 hash, | ||
| bytes calldata signature | ||
| ) internal view virtual override returns (bool) { | ||
| // Check if the signature is long enough to contain the EmailAuthMsg | ||
| // The minimum length is 512 bytes (initial part + pointer offsets) | ||
| // - `templateId` is a uint256 (32 bytes). | ||
| // - `commandParams` is a dynamic array of bytes32 (32 bytes offset). | ||
| // - `skippedCommandPrefixSize` is a uint256 (32 bytes). | ||
| // - `proof` is a struct with the following fields (32 bytes offset): | ||
| // - `domainName` is a dynamic string (32 bytes offset). | ||
| // - `publicKeyHash` is a bytes32 (32 bytes). | ||
| // - `timestamp` is a uint256 (32 bytes). | ||
| // - `maskedCommand` is a dynamic string (32 bytes offset). | ||
| // - `emailNullifier` is a bytes32 (32 bytes). | ||
| // - `accountSalt` is a bytes32 (32 bytes). | ||
| // - `isCodeExist` is a boolean, so its length is 1 byte padded to 32 bytes. | ||
| // - `proof` is a dynamic bytes (32 bytes offset). | ||
| // There are 128 bytes for the EmailAuthMsg type and 256 bytes for the proof. | ||
| // Considering all dynamic elements are empty (i.e. `commandParams` = [], `domainName` = "", `maskedCommand` = "", `proof` = []), | ||
| // then we have 128 bytes for the EmailAuthMsg type, 256 bytes for the proof and 4 * 32 for the length of the dynamic elements. | ||
| // So the minimum length is 128 + 256 + 4 * 32 = 512 bytes. | ||
| if (signature.length < 512) return false; | ||
| EmailAuthMsg memory emailAuthMsg = abi.decode(signature, (EmailAuthMsg)); | ||
| return (abi.decode(emailAuthMsg.commandParams[0], (bytes32)) == hash && | ||
| emailAuthMsg.templateId == templateId() && | ||
| emailAuthMsg.proof.accountSalt == accountSalt() && | ||
| emailAuthMsg.isValidZKEmail(DKIMRegistry(), verifier()) == ZKEmailUtils.EmailProofError.NoError); | ||
| } | ||
| } | ||
      
      Oops, something went wrong.
        
    
  
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Uh oh!
There was an error while loading. Please reload this page.