Skip to content

Commit

Permalink
Add UserOverrideableDKIMRegistry.sol.
Browse files Browse the repository at this point in the history
  • Loading branch information
wshino committed May 28, 2024
1 parent 4626ff5 commit ef097a5
Show file tree
Hide file tree
Showing 5 changed files with 396 additions and 1 deletion.
6 changes: 6 additions & 0 deletions packages/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
For a detailed overview of its functionalities, please refer to the source file: [DKIMRegistry.sol](./DKIMRegistry.sol)
</details>

## UserOverrideableDKIMRegistry.sol

`UserOverrideableDKIMRegistry.sol` is a Solidity contract within the `@zk-email/contracts` package. Basically the same as DKIMRegistry.sol above, but with the addition of `bool individual` argument to the calling function. Each user can set a publicKeyHash only for himself/herself.

[UserOverrideableDKIMRegistry.sol](./UserOverrideableDKIMRegistry.sol)

## StringUtils.sol

`StringUtils.sol` is a Solidity library that offers a range of string manipulation functions, including conversion between bytes and strings, and numerical string operations, for use across the `@zk-email/contracts` package.
Expand Down
129 changes: 129 additions & 0 deletions packages/contracts/UserOverrideableDKIMRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
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 UserOverrideableDKIMRegistry is IDKIMRegistry, Ownable {
constructor(address _owner) Ownable(_owner) {}

event DKIMPublicKeyHashRegistered(
string domainName,
bytes32 publicKeyHash,
address register
);
event DKIMPublicKeyHashRevoked(bytes32 publicKeyHash, address register);

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

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

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

function isDKIMPublicKeyHashValid(
string memory domainName,
bytes32 publicKeyHash
) public view returns (bool) {
if (
revokedDKIMPublicKeyHashes[publicKeyHash][address(0)] ||
revokedDKIMPublicKeyHashes[publicKeyHash][msg.sender]
) {
return false;
}

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

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

return false;
}

/**
* @notice Sets the DKIM public key hash for a given domain.
* @dev This function allows the owner to set a DKIM public key hash for all users, or an individual user to set it for themselves.
* @param domainName The domain name for which the DKIM public key hash is being set.
* @param publicKeyHash The hash of the DKIM public key to be set.
* @param individual A boolean indicating whether the hash is being set for an individual user (true) or for all users (false).
* @custom:require Only the owner can set the DKIM public key hash for all users when `individual` is false.
* @custom:require The public key hash must not be revoked.
* @custom:event DKIMPublicKeyHashRegistered Emitted when a DKIM public key hash is successfully set.
*/
function setDKIMPublicKeyHash(
string memory domainName,
bytes32 publicKeyHash,
bool individual
) public {
address register = msg.sender;
if (!individual) {
require(
msg.sender == owner(),
"only owner can set DKIM public key hash for all users"
);
register = address(0);
}
require(
!revokedDKIMPublicKeyHashes[publicKeyHash][register],
"cannot set revoked pubkey"
);

dkimPublicKeyHashes[domainName][publicKeyHash][register] = true;

emit DKIMPublicKeyHashRegistered(domainName, publicKeyHash, register);
}

function setDKIMPublicKeyHashes(
string memory domainName,
bytes32[] memory publicKeyHashes,
bool individual
) public {
for (uint256 i = 0; i < publicKeyHashes.length; i++) {
setDKIMPublicKeyHash(domainName, publicKeyHashes[i], individual);
}
}

/**
* @notice Revokes a DKIM public key hash.
* @dev This function allows the owner to revoke a DKIM public key hash for all users, or an individual user to revoke it for themselves.
* @param publicKeyHash The hash of the DKIM public key to be revoked.
* @param individual A boolean indicating whether the hash is being revoked for an individual user (true) or for all users (false).
* @custom:require Only the owner can revoke the DKIM public key hash for all users when `individual` is false.
* @custom:event DKIMPublicKeyHashRevoked Emitted when a DKIM public key hash is successfully revoked.
*/
function revokeDKIMPublicKeyHash(
bytes32 publicKeyHash,
bool individual
) public {
address register = msg.sender;
if (!individual) {
require(
msg.sender == owner(),
"only owner can revoke DKIM public key hash for all users"
);
register = address(0);
}
revokedDKIMPublicKeyHashes[publicKeyHash][register] = true;

emit DKIMPublicKeyHashRevoked(publicKeyHash, register);
}
}
2 changes: 1 addition & 1 deletion packages/contracts/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ src = './'
out = 'out'
allow_paths = ['../../node_modules']
libs = ['../../node_modules']
solc_version = '0.8.21'
solc_version = '0.8.23'
1 change: 1 addition & 0 deletions packages/contracts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"files": [
"DKIMRegistry.sol",
"UserOverrideableDKIMRegistry.sol",
"/utils",
"/interfaces"
],
Expand Down
Loading

0 comments on commit ef097a5

Please sign in to comment.