Skip to content
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

Add multiple keys to DKIMRegistry #130

Merged
merged 6 commits into from
Nov 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 62 additions & 13 deletions packages/contracts/DKIMRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,83 @@ import "./interfaces/IDKIMRegistry.sol";
/**
A Registry that store the hash(dkim_public_key) for each domain
The hash is calculated by taking Poseidon of DKIM key split into 9 chunks of 242 bits each
https://zkrepl.dev/?gist=43ce7dce2466c63812f6efec5b13aa73 can be used to generate the public key hash.
The same code is used in EmailVerifier.sol
Input is DKIM pub key split into 17 chunks of 121 bits. You can use `helpers` package to fetch/split DKIM keys
*/
contract DKIMRegistry is IDKIMRegistry, Ownable {
event DKIMPublicKeyHashRegistered(string domainName, bytes32 publicKeyHash);
event DKIMPublicKeyHashRevoked(bytes32 publicKeyHash);

// Mapping from domain name to DKIM public key hash
mapping(string => bytes32) public dkimPublicKeyHashes;
mapping(string => mapping(bytes32 => bool)) public dkimPublicKeyHashes;

// DKIM public that are revoked (eg: in case of private key compromise)
mapping(bytes32 => bool) public revokedDKIMPublicKeyHashes;

constructor() {
// Set values for popular domains
dkimPublicKeyHashes["gmail.com"] = bytes32(uint256(21238126716164910617487233347059218993958564577330259377744533585136010170208));
dkimPublicKeyHashes["hotmail.com"] = bytes32(uint256(2431254542644577945126644490189743659677343436440304264654087065353925216026));
dkimPublicKeyHashes["twitter.com"] = bytes32(uint256(5857406240302475676709141738935898448223932090884766940073913110146444539372));
dkimPublicKeyHashes["ethereum.org"] = bytes32(uint256(1064717399289379939765004128465682276424933518837235377976999291216925329691));
dkimPublicKeyHashes["skiff.com"] = bytes32(uint256(7901875575997183258695482461141301358756276811120772965768802311294654527542));
dkimPublicKeyHashes["gmail.com"][
bytes32(uint256(21238126716164910617487233347059218993958564577330259377744533585136010170208))
] = true;

dkimPublicKeyHashes["hotmail.com"][
bytes32(uint256(2431254542644577945126644490189743659677343436440304264654087065353925216026))
] = true;

dkimPublicKeyHashes["twitter.com"][
bytes32(uint256(5857406240302475676709141738935898448223932090884766940073913110146444539372))
] = true;

dkimPublicKeyHashes["ethereum.org"][
bytes32(uint256(1064717399289379939765004128465682276424933518837235377976999291216925329691))
] = true;

dkimPublicKeyHashes["skiff.com"][
bytes32(uint256(7901875575997183258695482461141301358756276811120772965768802311294654527542))
] = true;
}

function _stringEq(string memory a, string memory b) internal pure returns (bool) {
function _stringEq(
string memory a,
string memory b
) internal pure returns (bool) {
return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));
}

function getDKIMPublicKeyHash(
string memory domainName
) public view returns (bytes32) {
return dkimPublicKeyHashes[domainName];
function isDKIMPublicKeyHashValid(
string memory domainName,
bytes32 publicKeyHash
) public view returns (bool) {
if (revokedDKIMPublicKeyHashes[publicKeyHash]) {
return false;
}

if (dkimPublicKeyHashes[domainName][publicKeyHash]) {
return true;
}

return false;
}

function setDKIMPublicKeyHash(
string memory domainName,
bytes32 publicKeyHash
) public virtual onlyOwner {
dkimPublicKeyHashes[domainName] = publicKeyHash;
) public onlyOwner {
require(
!revokedDKIMPublicKeyHashes[publicKeyHash],
"cannot set revoked pubkey"
);

dkimPublicKeyHashes[domainName][publicKeyHash] = true;

emit DKIMPublicKeyHashRegistered(domainName, publicKeyHash);
}

function revokeDKIMPublicKeyHash(bytes32 publicKeyHash) public onlyOwner {
revokedDKIMPublicKeyHashes[publicKeyHash] = true;

emit DKIMPublicKeyHashRevoked(publicKeyHash);
}
}
7 changes: 4 additions & 3 deletions packages/contracts/interfaces/IDKIMRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
pragma solidity ^0.8.0;

interface IDKIMRegistry {
function getDKIMPublicKeyHash(
string memory domainName
) external view returns (bytes32);
function isDKIMPublicKeyHashValid(
string memory domainName,
bytes32 publicKeyHash
) external view returns (bool);
}
2 changes: 1 addition & 1 deletion packages/contracts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zk-email/contracts",
"version": "3.2.0",
"version": "4.0.2",
"scripts": {
"build": "forge build",
"publish": "yarn npm publish --access=public"
Expand Down
2 changes: 1 addition & 1 deletion packages/twitter-verifier-contracts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zk-email/twitter-verifier-contracts",
"version": "2.0.0",
"version": "2.0.1",
"scripts": {
"build": "forge compile",
"test": "forge test"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,7 @@ contract VerifiedTwitterEmail is ERC721Enumerable {

// Verify the DKIM public key hash stored on-chain matches the one used in circuit
bytes32 dkimPublicKeyHashInCircuit = bytes32(signals[pubKeyHashIndexInSignals]);
bytes32 dkimPublicKeyHashOnChain = dkimRegistry.getDKIMPublicKeyHash(domain);

require(dkimPublicKeyHashOnChain != bytes32(0), "dkim for domain not found");

require(dkimPublicKeyHashInCircuit == dkimPublicKeyHashOnChain, "invalid signature");
require(dkimRegistry.isDKIMPublicKeyHashValid(domain, dkimPublicKeyHashInCircuit), "invalid dkim signature");

// Veiry RSA and proof
require(
Expand Down