This EIP proposes a standard interface for registering and validating DomainKeys Identified Mail (DKIM) public key hashes on the Ethereum blockchain. The interface allows domain owners to register their DKIM public key hashes and enables third parties to verify the validity of these hashes.
The registry operates by storing hashes of both domain names and DKIM public keys, creating a mapping that enables on-chain verification of DKIM signatures. Domain owners register their DKIM public key hashes by extracting the public key from their DNS TXT records (as specified in RFC 6376), computing the hash, and submitting it to the registry. DKIM clients can then query the registry to verify that a given public key hash is authorized for a specific domain, enabling trustless email ownership verification for applications such as account abstraction and social recovery mechanisms.
Motivation
With the growing adoption of Account Abstraction ERC-4337 and the emergence of ZK Email Technology, there is a need for a standardized way to verify email ownership on-chain. This EIP provides a crucial building block for these technologies by enabling the verification of DKIM signatures through on-chain registries.
This standard enables several important use cases:
Account Abstraction: When combined with zkEmail, this registry enables email-based account abstraction. Users can prove ownership of their email address through DKIM signatures, allowing them to:
Create and manage smart contract wallets
Sign transactions using their email credentials
Implement social recovery mechanisms
Account Recovery: The registry facilitates secure account recovery mechanisms:
Users can recover their wallet access by on-chain proving email ownership
The process is trustless and secure due to the cryptographic nature of DKIM
Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
Interface
pragmasolidity^0.8.25;/// @title ERC-XXX DKIM Registry Interface
/// @dev See https://eips.ethereum.org/EIPS/eip-xxx
/// Note: the ERC-165 identifier for this interface is 0xdee3d600.
interfaceIDKIMRegistry{eventKeyHashRegistered(bytes32domainHash,bytes32keyHash);eventKeyHashRevoked(bytes32domainHash);functionisKeyHashValid(bytes32domainHash,bytes32keyHash)externalviewreturns(bool);}
Domain Hash
The domainHash parameter MUST be the hash of the lowercase domain name or subdomain name. For example:
For the domain “example.com” using keccak256:
domainHash=keccak256(bytes("example.com"))
For the subdomain “mail.example.com” using keccak256:
domainHash=keccak256(bytes("mail.example.com"))
The registry MUST treat each domain and subdomain as a distinct entity. This means that:
A key hash registered for “example.com” does not automatically apply to its subdomains
Each subdomain can have its own independent DKIM key hash registration
The full domain name (including subdomain if present) must be hashed as a single string
Key Hash
The keyHash parameter MUST be a cryptographic hash of the DKIM public key. The public key should be in the standard DKIM format as specified in RFC 6376.
Implementations MAY choose any cryptographically secure hash function for computing the key hash. Common choices include keccak256, Poseidon (for zk-friendly applications) or other hash functions.
DKIM Public Key Specification
The DKIM public key MUST follow the format specified in RFC 6376. Here are the key requirements:
Key Format:
The public key MUST be in the format specified in the DKIM DNS record (p=PUBLIC_KEY)
The key MUST be base64 encoded
The key MUST NOT include the PEM headers or any other formatting
The key MUST be the raw public key data as specified in the DKIM DNS record
Key Requirements:
The key MUST be a valid RSA public key
The key MUST be in the format as published in the domain’s DNS TXT record
The key MUST be the exact value from the p= parameter in the DKIM DNS record
The key MUST NOT include any whitespace or line breaks
Key Registration Process:
Obtain the DKIM public key from the domain’s DNS TXT record
Extract the value from the p= parameter
Calculate the hash of the raw public key using the implementation’s chosen hash function
Register the hash in the DKIM registry
Key Validation:
The registry MUST verify that the provided key hash corresponds to a valid DKIM public key
The key MUST be in the correct format as specified in RFC 6376
The key MUST be the exact value as published in the domain’s DNS record
Example with keccak256:
Given the following DKIM DNS record from RFC 6376:
The interface is designed to be simple and focused on the core functionality of DKIM public key hash registration and validation. The use of keccak256 hashing for both domain names and public keys ensures consistent and secure handling of the data.
The events allow for efficient tracking of key registrations and revocations, which is important for maintaining the integrity of the registry.
Backwards Compatibility
This EIP introduces a new interface and does not affect existing contracts or standards.
Reference Implementation
pragmasolidity^0.8.0;import"@openzeppelin/contracts/access/Ownable.sol";import"./interfaces/IDKIMRegistry.sol";contractDKIMRegistryisIDKIMRegistry,Ownable{constructor(address_owner)Ownable(_owner){}// Mapping from hashed domain name to DKIM public key hash to enabled
mapping(bytes32=>mapping(bytes32=>bool))private_keyHashes;/**
* @notice Checks if a DKIM key hash is valid for a given domain
* @param domainHash The hash of the domain name
* @param keyHash The hash of the DKIM public key
* @return bool True if the key hash is valid for the domain, false otherwise
*/functionisKeyHashValid(bytes32domainHash,bytes32keyHash)publicviewreturns(bool){return_keyHashes[domainHash][keyHash];}/**
* @notice Sets a DKIM key hash for a domain
* @param domainHash The hash of the domain name
* @param keyHash The hash of the DKIM public key to register
* @dev Only callable by the contract owner
* @dev Cannot set zero hash as a valid key hash
*/functionsetKeyHash(bytes32domainHash,bytes32keyHash)publiconlyOwner{require(keyHash!=bytes32(0),"cannot set zero hash");_keyHashes[domainHash][keyHash]=true;emitKeyHashRegistered(domainHash,keyHash);}/**
* @notice Sets multiple DKIM key hashes for a domain in a single transaction
* @param domainHash The hash of the domain name
* @param keyHashes Array of DKIM public key hashes to register
* @dev Only callable by the contract owner
* @dev Array must not be empty
* @dev Each key hash must not be zero
*/functionsetKeyHashes(bytes32domainHash,bytes32[]memorykeyHashes)publiconlyOwner{require(keyHashes.length>0,"empty array");for(uint256i=0;i<keyHashes.length;i++){setKeyHash(domainHash,keyHashes[i]);}}/**
* @notice Revokes a DKIM key hash for a domain
* @param domainHash The hash of the domain name
* @param keyHash The hash of the DKIM public key to revoke
* @dev Only callable by the contract owner
* @dev Sets the key hash mapping to false, effectively revoking it
*/functionrevokeKeyHash(bytes32domainHash,bytes32keyHash)publiconlyOwner{delete_keyHashes[domainHash][keyHash];emitKeyHashRevoked(domainHash);}}
Security Considerations
Domain owners must ensure they have control over their private keys and domain names.
The registry implementation should include proper access control mechanisms to prevent unauthorized registrations.
The registry should implement a mechanism to handle key rotation and revocation.
Implementations should consider rate limiting to prevent spam registrations.
Registries should select the domainHash and keyHash algorithms carefully. Upgrading the hash function must be thoughtfully planned.
Mike Fu (@fumeng00mike), Matthew Yu (@0xknon), Ernesto García (@ernestognw), "ERC-7969: DomainKeys Identified Mail (DKIM) Registry [DRAFT]," Ethereum Improvement Proposals, no. 7969, June 2025. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7969.