Skip to content

Commit

Permalink
fix: optimise PasskeyBinder
Browse files Browse the repository at this point in the history
  • Loading branch information
zkJoaquin committed Sep 27, 2024
1 parent 07fb30d commit fa0991b
Showing 1 changed file with 12 additions and 39 deletions.
51 changes: 12 additions & 39 deletions system-contracts/contracts/PasskeyBinder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,24 @@ contract PasskeyBinder is IPasskeyBinder {
uint256 y;
}

// Deprecated
struct AuthorizedKey {
address owner;
P256PublicKey publicKey;
}

mapping(address account => EnumerableSet.Bytes32Set credentialIdHashSet) private accountToCredentialIdHashSet;
mapping(bytes32 credentialIdHash => AuthorizedKey) private authorizedKeys; // Deprecated
mapping(bytes32 credentialIdHash => P256PublicKey) private authorizedPublicKeys;
mapping(bytes32 keyIdHash => AuthorizedKey) private authorizedKeys;

/// @dev Event emitted when a P256 key is added
event AddedP256PublicKey(bytes32 indexed credentialIdHash, address indexed owner, uint256 x, uint256 y);
/// @dev Event emitted when a P256 key is removed
event RemovedP256PublicKey(bytes32 indexed credentialIdHash, address indexed owner);
/// @dev Event emitted when a P256 key is deprecated
event DeprecatedP256PublicKey(bytes32 indexed credentialIdHash);
/// @dev Error emitted when a P256 key is not on the curve
error KeyNotOnCurve(uint256 x, uint256 y);
/// @dev Error emitted when an empty credential id hash is attempted to be added
error InvalidCredentialIdHash();
/// @dev Error emitted when a P256 key is not stored and attempted to be removed
error KeyDoesNotExist(bytes32 credentialIdHash);
/// @dev Error emitted when a P256 key is not owned by the caller
error DoesNotOwner(bytes32 credentialIdHash);
error DoesNotOwnershipOfRights(bytes32 credentialIdHash);
/// @dev Error emitted when a P256 key is attempted to be add by not EOA
error DoesNotEOA();

Expand All @@ -65,9 +59,10 @@ contract PasskeyBinder is IPasskeyBinder {

if (_credentialIdHash == bytes32(0)) revert InvalidCredentialIdHash();

P256PublicKey memory publicKey = authorizedPublicKeys[_credentialIdHash];
if (publicKey.x == 0 && publicKey.y == 0) {
authorizedPublicKeys[_credentialIdHash] = P256PublicKey({x: _x, y: _y});
bytes32 keyIdHash = keccak256(abi.encodePacked(_credentialIdHash, sender));
address authorizedKeyOwner = authorizedKeys[keyIdHash].owner;
if (authorizedKeyOwner == address(0)) {
authorizedKeys[keyIdHash] = AuthorizedKey(sender, P256PublicKey(_x, _y));
}

accountToCredentialIdHashSet[sender].add(_credentialIdHash);
Expand All @@ -81,35 +76,12 @@ contract PasskeyBinder is IPasskeyBinder {
*/
function removeP256PublicKey(bytes32 _credentialIdHash) external {
address sender = msg.sender;
EnumerableSet.Bytes32Set storage credentialIdHashSet = accountToCredentialIdHashSet[sender];

bool isOwner = credentialIdHashSet.contains(_credentialIdHash);
if (!isOwner) revert DoesNotOwner(_credentialIdHash);

accountToCredentialIdHashSet[sender].remove(_credentialIdHash);
bool success = accountToCredentialIdHashSet[sender].remove(_credentialIdHash);
if (!success) revert DoesNotOwnershipOfRights(_credentialIdHash);

emit RemovedP256PublicKey(_credentialIdHash, sender);
}

/**
* @notice Deprecate owner-specified P256 public key
* @param _credentialIdHash The ID Hash of the credential to deprecate
*/
function deprecateP256PublicKey(bytes32 _credentialIdHash) external {
address sender = msg.sender;
EnumerableSet.Bytes32Set storage credentialIdHashSet = accountToCredentialIdHashSet[sender];

bool isOwner = credentialIdHashSet.contains(_credentialIdHash);
if (!isOwner) revert DoesNotOwner(_credentialIdHash);
P256PublicKey memory publicKey = authorizedPublicKeys[_credentialIdHash];
if (publicKey.x == 0 && publicKey.y == 0) revert KeyDoesNotExist(_credentialIdHash);

delete authorizedPublicKeys[_credentialIdHash];
accountToCredentialIdHashSet[sender].remove(_credentialIdHash);

emit DeprecatedP256PublicKey(_credentialIdHash);
}

/**
* @notice Returns authorized key infos by credential id hash
* @param _account The account to get the authorized key
Expand All @@ -122,10 +94,11 @@ contract PasskeyBinder is IPasskeyBinder {
bytes32 _credentialIdHash
) external view returns (uint256 x, uint256 y) {
EnumerableSet.Bytes32Set storage credentialIdHashSet = accountToCredentialIdHashSet[_account];
P256PublicKey memory publicKey = authorizedPublicKeys[_credentialIdHash];
bool isOwner = credentialIdHashSet.contains(_credentialIdHash);
bool ownershipOfRight = credentialIdHashSet.contains(_credentialIdHash);

if (isOwner) {
if (ownershipOfRight) {
bytes32 keyIdHash = keccak256(abi.encodePacked(_credentialIdHash, _account));
P256PublicKey memory publicKey = authorizedKeys[keyIdHash].publicKey;
x = publicKey.x;
y = publicKey.y;
} else {
Expand Down

0 comments on commit fa0991b

Please sign in to comment.