This repository has been archived by the owner on Mar 25, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from matter-labs/vb-keccak-precompile
keccak precompile
- Loading branch information
Showing
3 changed files
with
106 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// SPDX-License-Identifier: MIT OR Apache-2.0 | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
import './SystemContractHelper.sol'; | ||
|
||
/** | ||
* @author Matter Labs | ||
*/ | ||
contract Keccak256 { | ||
uint256 constant PERMANENT_ERGS_COST = 100; | ||
uint256 constant INTERNAL_KECCAK_ROUND_ERGS_COST = 100; | ||
uint256 constant MAX_PREIMAGE_BYTES_LENGTH = 1024; | ||
uint256 constant BLOCK_SIZE = 136; | ||
uint32 constant INPUT_OFFSET_IN_WORDS = 0; | ||
uint32 constant OUTPUT_OFFSET_IN_WORDS = 0; | ||
uint32 constant OUTPUT_LENGTH_IN_WORDS = 1; | ||
|
||
fallback() external { | ||
address codeAddress = SystemContractHelper.getCodeAddress(); | ||
// Check that we are NOT in delegatecall | ||
require(codeAddress == address(this)); | ||
|
||
uint256 bytesSize; | ||
|
||
assembly { | ||
bytesSize := calldatasize() | ||
} | ||
|
||
require(bytesSize <= MAX_PREIMAGE_BYTES_LENGTH); | ||
|
||
uint256 padLen = BLOCK_SIZE - bytesSize % BLOCK_SIZE; | ||
uint256 paddedByteSize = bytesSize + padLen; | ||
assert(paddedByteSize % BLOCK_SIZE == 0); // can deleted later one | ||
uint64 numRounds = uint64(paddedByteSize / BLOCK_SIZE); | ||
|
||
// manual memory copy and management, as we do not care about Solidity allocations | ||
uint32 inputLengthInWords = uint32(paddedByteSize / 32); | ||
if (paddedByteSize % 32 != 0) { | ||
unchecked { | ||
inputLengthInWords += 1; | ||
} | ||
} | ||
|
||
|
||
assembly { | ||
calldatacopy(0x00, 0x00, bytesSize) | ||
} | ||
|
||
if (padLen == 1) { | ||
// write 0x81 at the end | ||
assembly { | ||
mstore(add(bytesSize, 1), 0x8100000000000000000000000000000000000000000000000000000000000000) // we do not care about what is after | ||
} | ||
} else { | ||
assembly { | ||
mstore(add(bytesSize, 1), 0x0100000000000000000000000000000000000000000000000000000000000000) | ||
mstore(sub(paddedByteSize, 1), 0x8000000000000000000000000000000000000000000000000000000000000000) | ||
} | ||
} | ||
|
||
uint256 precompileParams = SystemContractHelper.packPrecompileParams( | ||
INPUT_OFFSET_IN_WORDS, | ||
inputLengthInWords, | ||
OUTPUT_OFFSET_IN_WORDS, | ||
OUTPUT_LENGTH_IN_WORDS, | ||
numRounds | ||
); | ||
|
||
uint256 ergsToPay = PERMANENT_ERGS_COST + INTERNAL_KECCAK_ROUND_ERGS_COST * uint256(numRounds); | ||
bool success = SystemContractHelper.precompileCall(precompileParams, uint32(ergsToPay)); | ||
require(success); | ||
|
||
assembly { | ||
return(0, 32) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.