Date | Memo | Editor |
---|---|---|
2023-09-27 | update memory commitment methodology | @sungmingwu |
Apply ZK Proof on EVM execution correctness is the huge milestone for Ethereum. To prove EVM correctness, below categorize into 2 methods.
Write a separate zk circuit to model the EVM specs (yellow paper). Ideally, this make zk circuit agnostics to the implmenetation language, and so as client. However in reality, we usually stick to one execution client execution trace and convert to witness.
Method 1, to some sense, is what the PSE zkEVM currently adopt. This aggresive way somehow means write a new complex program to model EVM spec. Since program is write by human, audit effort is needed, and might not be easier to accomplish, since EVM state space is very complex, formal verification model is too complex and not achievable.
Besides, spec (EIPs) keep changing as new released
Here explore a different way to prove EVM execution, which is by proving Geth execution
correctness instead. To achieve that, the goal is compiling Geth (golang) into a small and stable Risc-ISA, then intepreted by a Risc-VM.
An assumption: Geth in golang will be compiled to RiscEth in exactly the same functionality. No manual writing DSL.
The new Risc-based program will be called RiscEth
.
Now the original problem reduce to another problem: prove the RiscEth
program correctness. A Risc-VM will be implemented to execute the RiscEth, along with a zkSNARK to attest the correctness of RiscEth
execution.
pic from https://medium.com/@sin7y/a-programmable-privacy-platform-for-ethereum-understanding-olas-design-principles-and-technical-8a47ff07e725 in paragraphzkDSL vs zkVM
Compare with zkDSL based circuit construction to attest EVM execution, which usually means need to write the constraints circuit in another DSL language, zkVM have its shiny pros, and of course come with few cons, which will be accounted for below.
Of course come with few challenges
For long execution trace. usually it is bounded by the nth root of unity choice. However, after state-of-the-art computational unbounded folding scheme methodology is proposed, this problem can be addressed and solved maybe…ENTIRELY!! Detail will be giving below.
The monorepo is under https://github.com/hero78119/zkGeth
Detail design of VM will be in another docs
GETH will refer cannon, geth in MIPS project. Thanks to the modulo codebase, we can patching GETH MPT part. Instead of load from leveldb
, we can replace it with hash pre-image Oracle
and read from memory directly. A memory commitment will be provided, with few pre-defined memory address filling with opcodes/MPT root/pre state root/new block/mpt proof, mpt leaf etc information.
Special note for MPT path + leaf + rlp: Oracle will read those in global memory with a counter. This just need a very simple design on golang Oracle. Those global memory will be provided memory commitment in runtime, and memory commitment can be built from geth Geth execution trace.
we choose RiscV64
We choose to implement RiscV64 ISA by a unique microopcode SUBtract and branch if Less-than or EQual to zero, abbrev as SUBLEQ
. It's turing complete OISC and has be study for years under the topic: One-Instruction-Set-Computer
OISC.
The SUBLEQ
instruction is a three-operand instruction, performing
a combined subtraction and branching operation
reg_a reg_b reg_c
Such simple microopcode can implement any computation, and so as Risc ISA. This microopcode can also be used as building block for formal verification if ISA, and circuit. More detail will be below.
all the opcode will be implemented in microopcode SUBLEQ following this project
Formal verification will be introduced follow this paper (best paper reward in #FDL2022)
Formal Verification of SUBLEQ Microcode implementing the RV32I ISA to assure microopcode procedure is implemented correctly.
So far, Nova IVC is one of the state-of-the-art fast IVC: prover no FFT/quotiant computation, and claimed to be smallest verifier circuit. For R1CS, the dominated just few vectors dot product (no sum) + multi-scalar multiplication. With Nova, we have strong condident to fold circuit into more granularity unit, and per opcode is nature choice.
Another killing feature of Nova folding is its unbounded computation, means there is no restriction on circuit hyper parameter setting, max length of execution trace from Nth root of unity, etc.
More detail on Nova refer to reading Towards a Nova-based ZK VM
To avoid build everything from scratch, there is a plan to fork an existing ZK Risc rust implmentation https://github.com/risc0/risc0 with below planned modification
SUBLEQ
microopcode as the unit.Supernova follow up works has been shift to Lurk-labs Nova fork Arecibo.
The IVC will be fold per opcode based. It's follow SuperNova non-uniform IVC.
Conceptual diagram
Per folding step circuits F_op(pc) in R1CS involving
Here, SuperNova non-uniform-IVC is adapted to reduce the folding steps. Another possible way is flatten all ISA into SUBLEQ
and just using uniform-ivc, however it will exponeitiate steps of folding. We still choose SuperNova as it preserve the space for exending instruction in the future.
Just keep in mind, we need a tool, i.e. formal verification, to verify the security/correctness of ISA, especially when we extended.
Follow Von_Neumann and RiscV, we will prepare program opcode/public inputs/register/memory into a rw (memory)commitment. For program opcode, memory commitment will be pre-process and populated during execution client release on CI. In the process of SNARK proof generation, prover/verifier need to merge pre-processed program commitment, initial register value, along with other public input related to eth block execution (storage root merkle proof..) into a single public input commitment. Commiment merge rely on the underlyine commitment scheme. We plan to adopt rw lookup tricks solution Lookup Argument in Nova tricks: permutation checking without re-ordering
Reference link
TBD
TBD
Folding Steps
Opcode efficiency
TBD
The most important for PoC is benchmark. Before benchmark, there might need 2 data
SUBLEQ
per opcodeThen we can estimate the time to prove one transaction by #avg execution trace/#folding per second.
Same method can be applied on block.
sha
example vs go build, result looks promisingMulti-client will be prompt to discussion, as in the future they might all need to interect with zkEVM.
See the Vitalik post Ethereum’s multi-client iteract with zkEVM
Below is a conceptual idea for Nova-baase RiscVM to support multi-client.