github.com/ethereum-optimism/optimism@v1.7.2/packages/contracts-bedrock/src/cannon/PreimageKeyLib.sol (about) 1 // SPDX-License-Identifier: MIT 2 pragma solidity 0.8.15; 3 4 /// @title PreimageKeyLib 5 /// @notice Shared utilities for localizing local keys in the preimage oracle. 6 library PreimageKeyLib { 7 /// @notice Generates a context-specific local key for the given local data identifier. 8 /// @dev See `localize` for a description of the localization operation. 9 /// @param _ident The identifier of the local data. [0, 32) bytes in size. 10 /// @param _localContext The local context for the key. 11 /// @return key_ The context-specific local key. 12 function localizeIdent(uint256 _ident, bytes32 _localContext) internal view returns (bytes32 key_) { 13 assembly { 14 // Set the type byte in the given identifier to `1` (Local). We only care about 15 // the [1, 32) bytes in this value. 16 key_ := or(shl(248, 1), and(_ident, not(shl(248, 0xFF)))) 17 } 18 // Localize the key with the given local context. 19 key_ = localize(key_, _localContext); 20 } 21 22 /// @notice Localizes a given local data key for the caller's context. 23 /// @dev The localization operation is defined as: 24 /// localize(k) = H(k .. sender .. local_context) & ~(0xFF << 248) | (0x01 << 248) 25 /// where H is the Keccak-256 hash function. 26 /// @param _key The local data key to localize. 27 /// @param _localContext The local context for the key. 28 /// @return localizedKey_ The localized local data key. 29 function localize(bytes32 _key, bytes32 _localContext) internal view returns (bytes32 localizedKey_) { 30 assembly { 31 // Grab the current free memory pointer to restore later. 32 let ptr := mload(0x40) 33 // Store the local data key and caller next to each other in memory for hashing. 34 mstore(0, _key) 35 mstore(0x20, caller()) 36 mstore(0x40, _localContext) 37 // Localize the key with the above `localize` operation. 38 localizedKey_ := or(and(keccak256(0, 0x60), not(shl(248, 0xFF))), shl(248, 1)) 39 // Restore the free memory pointer. 40 mstore(0x40, ptr) 41 } 42 } 43 44 /// @notice Computes and returns the key for a global keccak pre-image. 45 /// @param _preimage The pre-image. 46 /// @return key_ The pre-image key. 47 function keccak256PreimageKey(bytes memory _preimage) internal pure returns (bytes32 key_) { 48 assembly { 49 // Grab the size of the `_preimage` 50 let size := mload(_preimage) 51 52 // Compute the pre-image keccak256 hash (aka the pre-image key) 53 let h := keccak256(add(_preimage, 0x20), size) 54 55 // Mask out prefix byte, replace with type 2 byte 56 key_ := or(and(h, not(shl(248, 0xFF))), shl(248, 2)) 57 } 58 } 59 }