Skip to content

Commit 9742daa

Browse files
committed
Refactor ZKEmailUtils
1 parent 72a4cfc commit 9742daa

File tree

1 file changed

+33
-47
lines changed

1 file changed

+33
-47
lines changed

contracts/utils/cryptography/ZKEmailUtils.sol

Lines changed: 33 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ library ZKEmailUtils {
4242
enum Case {
4343
LOWERCASE, // Converts the command to hex lowercase.
4444
UPPERCASE, // Converts the command to hex uppercase.
45-
CHECKSUM // Computes a checksum of the command.
45+
CHECKSUM, // Computes a checksum of the command.
46+
ANY
4647
}
4748

4849
/// @dev Variant of {isValidZKEmail} that validates the `["signHash", "{uint}"]` command template.
@@ -64,8 +65,8 @@ library ZKEmailUtils {
6465
*
6566
* This function takes an email authentication message, a DKIM registry contract, and a verifier contract
6667
* as inputs. It performs several validation checks and returns a tuple containing a boolean success flag
67-
* and an {EmailProofError} if validation failed. See {validateDKIMAndCommandFormat} and {validateExpectedCommandAndProof}
68-
* for more details on the validation checks performed.
68+
* and an {EmailProofError} if validation failed. Returns {EmailProofError.NoError} if all validations pass,
69+
* or false with a specific {EmailProofError} indicating which validation check failed.
6970
*
7071
* NOTE: Attempts to validate the command for all possible string {Case} values.
7172
*/
@@ -75,12 +76,7 @@ library ZKEmailUtils {
7576
IVerifier verifier,
7677
string[] memory template
7778
) internal view returns (EmailProofError) {
78-
EmailProofError err = validateDKIMAndCommandFormat(emailAuthMsg, dkimregistry, verifier);
79-
if (err != EmailProofError.NoError) return err;
80-
for (uint256 i = 0; i < uint8(type(Case).max) && err != EmailProofError.NoError; i++) {
81-
err = validateExpectedCommandAndProof(emailAuthMsg, verifier, template, Case(i));
82-
}
83-
return err;
79+
return isValidZKEmail(emailAuthMsg, dkimregistry, verifier, template, Case.ANY);
8480
}
8581

8682
/// @dev Variant of {isValidZKEmail} that validates a template with a specific string {Case}.
@@ -90,56 +86,46 @@ library ZKEmailUtils {
9086
IVerifier verifier,
9187
string[] memory template,
9288
Case stringCase
93-
) internal view returns (EmailProofError) {
94-
EmailProofError err = validateDKIMAndCommandFormat(emailAuthMsg, dkimregistry, verifier);
95-
return
96-
err == EmailProofError.NoError
97-
? validateExpectedCommandAndProof(emailAuthMsg, verifier, template, stringCase)
98-
: err;
99-
}
100-
101-
/**
102-
* @dev Validates the email authentication message parameters.
103-
*
104-
* * Returns {EmailProofError.DKIMPublicKeyHash} if the DKIM public key hash is not valid according to the registry.
105-
* * Returns {EmailProofError.MaskedCommandLength} if the proof's `maskedCommand` exceeds the verifier's command bytes.
106-
* * Returns {EmailProofError.SkippedCommandPrefixSize} if the proof's `skippedCommandPrefix` exceeds the verifier's command bytes.
107-
*/
108-
function validateDKIMAndCommandFormat(
109-
EmailAuthMsg memory emailAuthMsg,
110-
IDKIMRegistry dkimregistry,
111-
IVerifier verifier
11289
) internal view returns (EmailProofError) {
11390
if (!dkimregistry.isDKIMPublicKeyHashValid(emailAuthMsg.proof.domainName, emailAuthMsg.proof.publicKeyHash)) {
11491
return EmailProofError.DKIMPublicKeyHash;
11592
} else if (bytes(emailAuthMsg.proof.maskedCommand).length > verifier.commandBytes()) {
11693
return EmailProofError.MaskedCommandLength;
11794
} else if (emailAuthMsg.skippedCommandPrefix >= verifier.commandBytes()) {
11895
return EmailProofError.SkippedCommandPrefixSize;
96+
} else if (!_commandMatch(emailAuthMsg, template, stringCase)) {
97+
return EmailProofError.MismatchedCommand;
98+
} else {
99+
return verifier.verifyEmailProof(emailAuthMsg.proof) ? EmailProofError.NoError : EmailProofError.EmailProof;
119100
}
120-
return EmailProofError.NoError;
121101
}
122102

123-
/**
124-
* @dev Validates the command and proof of the email authentication message.
125-
*
126-
* * Returns {EmailProofError.MismatchedCommand} if the command does not match the proof's command with {stringCase}.
127-
* * Returns {EmailProofError.EmailProof} if the email proof is invalid.
128-
*/
129-
function validateExpectedCommandAndProof(
103+
function _commandMatch(
130104
EmailAuthMsg memory emailAuthMsg,
131-
IVerifier verifier,
132105
string[] memory template,
133106
Case stringCase
134-
) internal view returns (EmailProofError) {
135-
string memory expectedCommand = CommandUtils.computeExpectedCommand(
136-
emailAuthMsg.commandParams,
137-
template,
138-
uint8(stringCase)
139-
);
140-
if (!expectedCommand.equal(emailAuthMsg.proof.maskedCommand)) {
141-
return EmailProofError.MismatchedCommand;
142-
}
143-
return verifier.verifyEmailProof(emailAuthMsg.proof) ? EmailProofError.NoError : EmailProofError.EmailProof;
107+
) private pure returns (bool) {
108+
return
109+
stringCase == Case.ANY
110+
? _matchAnyCase(emailAuthMsg, template)
111+
: _matchCase(emailAuthMsg, template, stringCase);
112+
}
113+
114+
function _matchAnyCase(EmailAuthMsg memory emailAuthMsg, string[] memory template) private pure returns (bool) {
115+
return
116+
_matchCase(emailAuthMsg, template, Case.LOWERCASE) ||
117+
_matchCase(emailAuthMsg, template, Case.UPPERCASE) ||
118+
_matchCase(emailAuthMsg, template, Case.CHECKSUM);
119+
}
120+
121+
function _matchCase(
122+
EmailAuthMsg memory emailAuthMsg,
123+
string[] memory template,
124+
Case stringCase
125+
) private pure returns (bool) {
126+
return
127+
CommandUtils.computeExpectedCommand(emailAuthMsg.commandParams, template, uint8(stringCase)).equal(
128+
emailAuthMsg.proof.maskedCommand
129+
);
144130
}
145131
}

0 commit comments

Comments
 (0)