Comments (1)
Since SHA256 follows Merkle–Damgård construction, the words are chained through the compression function, goal is to max out the SHA256's compression function invocations that could be done within 30M gas.
The following approach is used:
- Allocate some words on memory.
- Call to precompile using the memory slice as input.
- Change the first word in memory.
- Go to step 2.
JUMPDEST
JUMPDEST
# return size and offset
PUSH1 0x20 PUSH0
# input size and offset
PUSH3 0x025120 PUSH0
# precompile address
PUSH1 2
GAS
STATICCALL
# above also writes to first mem word
# jump to PC = 1
JUMP
The above evm code 5b5b60205f620251205f60025afa56
is sent to the NULL
address which in this case keeps making SHA256 precompile calls until it runs into OOG. Even though this is a failed transaction, to prove it was indeed failed/OOG, zkEVM must perform SHA256 in the circuit.
Using evm-run, it is found that if we use hash length of 4746 words (0x025120
bytes) then it makes 525 successful unique SHA256 precompile calls (526 but last one that fails by OOG), this means 2,491,650 compressions.
$ evm-run 5b5b60205f620251205f60025afa56 --gasLimit 30000000 | grep "STATICCALL" | wc -l
526
This script is used to estimate that 4746 words x 525 calls maxes out sha256 usage within 30M gas (click to expand).
// gas cost for allocating num_words on EVM memory
function init_cost(num_words: number) {
let mem_cost = num_words * 3 + Math.floor(num_words ** 2 / 512);
let extra_gas = 1 + 2500; // jumpdest + first staticcall
return mem_cost + extra_gas;
}
// gas cost for executing SHA256 precompile
function exec_cost(num_words: number) {
let extra_gas = 24;
return 100 + 60 + num_words * 12 + extra_gas;
}
function find_num_batches(num_words: number, target_gas: number) {
target_gas -= init_cost(num_words);
let single_exec_cost = exec_cost(num_words);
// floor because last batch will fail
let num_batches = Math.floor(target_gas / single_exec_cost);
return num_batches;
}
function quantity(num_words: number, num_batches: number) {
return num_words * num_batches;
}
function find_maxima(target_gas: number) {
let best_case = {
num_words: 1,
num_batches: find_num_batches(1, target_gas),
get quantity() {
return quantity(this.num_words, this.num_batches);
},
};
let new_num_words = 1;
while (1) {
new_num_words++;
let new_num_batches = find_num_batches(new_num_words, target_gas);
let new_quantity = quantity(new_num_words, new_num_batches);
if (new_quantity > best_case.quantity) {
best_case.num_batches = new_num_batches;
best_case.num_words = new_num_words;
console.log("best case update", best_case);
}
// stop once done
if (new_num_batches === 0) {
return best_case;
}
}
return best_case;
}
console.log(find_maxima(30_000_000));
Similarly, it is found that for 300k gas maxes out to 24024 sha256 compression functions (27456 bytes memory x 29 precompile calls).
Using PR 756, it is found to take 897848 rows. That's
from zkevm-circuits.
Related Issues (20)
- Memory requirements for generating a full block proof HOT 4
- [Testool] Panic_attempt to subtract with overflow
- [testool] Potential improvement HOT 2
- [proof-chunk] implement uncompleted features in bus-mapping and refactor
- A Typo detection CI automation HOT 2
- nondeterministic circuit generation in integration test HOT 2
- EVM Circuit: block.table_assignment introduces non fixed entries in fixed columns
- Toward Dencun Upgrade
- Transaction Hash
- BLOBBASEFEE opcode
- beacon root in EVM
- Shard Blob Transactions
- Get bench results for average block VS keccak maxed out HOT 2
- is_zero can be implemented without witnessing the inverse HOT 1
- State circuit spec sync
- Running make tests HOT 1
- EIP-3074: AUTH and AUTHCALL opcodes
- MPT fails with mainnet test with block 18363441
- Stack trie witness generator - modified extension node
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from zkevm-circuits.