// Contract: KeyMap
// Target function: function mapKey(bytes calldata _pubKey) external returns(address _address)
pragma solidity ^0.6.0;

/**
 * @title KeyMap
 * @author https://github.com/d1ll0n
 * This contracts maps addresses to public keys.
 * Public keys for Secp256k1 are always 64 bytes.
 * To save gas, this contract stores them as an array of two bytes32 words.
 */
contract KeyMap {
  mapping(address => bytes32[2]) private mappedKeys;

  /**
   * @dev mapKey
   * Calculates the address for a public key, then saves the mapping from address to public key.
   * @notice This overload reduces the calldata cost of submission.
   * @param slice0 - first 32 bytes of the public key
   * @param slice1 - second 32 bytes of the public key
   * @return _address - calculated address
   */
  function mapKey(bytes32 slice0, bytes32 slice1) external returns(address _address) {
    assembly {
      let ptr := mload(0x40)
      calldatacopy(ptr, 0x04, 0x40)
      let mask := 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff
      _address := and(mask, keccak256(ptr, 0x40))
      calldatacopy(ptr, calldatasize(), 0x40)
    }
    mappedKeys[_address][0] = slice0;
    mappedKeys[_address][1] = slice1;
  }