Title: Long_term_L1_execution_layer_proposal__replace_the
Category: Magicians

Author: vbuterin
Date: 2025-04-20T11:20:02.729Z

This post proposes a radical idea for the future of the Ethereum execution layer, one that is equally as ambitious as the beam chain effort is for the consensus layer. It aims to greatly improve the efficiency of the Ethereum execution layer, resolving one of the primary scaling bottlenecks, and can also greatly improve the execution layer’s simplicity - in fact, it is perhaps the only way to do so.
The idea: replace the EVM with RISC-V as the virtual machine language that smart contracts are written in.
Important clarifications:

The concepts of accounts, cross-contract calls, storage, etc would stay exactly the same. These abstractions work fine and developers are used to them. Opcodes like SLOAD, SSTORE, BALANCE, CALL, etc, would become RISC-V syscalls.
In such a world, smart contracts could be written in Rust, but I expect most developers would keep writing smart contracts in Solidity (or Vyper), which would adapt to add RISC-V as a backend. This is because smart contracts written in Rust are actually quite ugly, and Solidity and Vyper are much more readable. Potentially, devex would change very little and developers might barely notice the change at all.
Old-style EVM contracts will continue to work and will be fully two-way interoperable with new-style RISC-V contracts. There are a couple ways to do this, which I will get into later in this post.

One precedent for this is the Nervos CKB VM, which is basically RISC-V.
Why do this?
In the short term, the main bottlenecks to Ethereum L1 scalability are addressed with upcoming EIPs like block-level access lists, delayed execution and distributed history storage plus EIP-4444. In the medium term, we address further issues with statelessness and ZK-EVMs. In the long term, the primary limiting factors on Ethereum L1 scaling become:

Stability of data availability sampling and history storage protocols
Desire to keep block production a competitive market
ZK-EVM proving capabilities

I will argue that replacing the ZK-EVM with RISC-V solves a key bottleneck in (2) and (3).
This is a table of the number of cycles that the Succinct ZK-EVM uses to prove different parts of the EVM execution layer:
download (6)800×359 154 KB
There are four parts that take up a significant amount of time: deserialize_inputs, initialize_witness_db, state_root_computation and block_execution.
initialize_witness_db and state_root_computation both have to do with the state tree, and deserialize_inputs refers to the process of converting block and witness data into an internal representation; hence, realistically over 50% of it is proportional to witness sizes.
These parts can be heavily optimized by replacing the current keccak 16-ary Merkle patricia tree with a binary tree that uses a prover-friendly hash function. If we use Poseidon, we can prove 2 million hashes per second on a laptop (compared to ~15,000 hash/sec for keccak). There are also many options other than Poseidon. All in all, there are opportunities to massively reduce these components. As a bonus, we can get rid of accrue_logs_bloom by, well, getting rid of the bloom.
This leaves block_execution, which makes up roughly half of prover cycles spent today. If we want to 100x total prover efficiency, there’s no getting around the fact that we need to at least 50x EVM prover efficiency. One thing that we could do is to try to create implementations of the EVM that are much more efficient in terms of prover cycles. The other thing that we can do is to notice that ZK-EVM provers today already work by proving over implementations of the EVM compiled down to RISC-V, and give smart contract developers access to that RISC-V VM directly.
Some numbers (see here) suggest that in limited cases, this could give efficiency gains over 100x:


download (7)800×476 154 KB

4a3981f5-7c49-4631-9c7c-3216b4c62466583×528 33.4 KB


In practice, I expect that the remaining prover time will become dominated by what today are precompiles. If we make RISC-V the primary VM, then the gas schedule will reflect proving times, and so there will be economic pressure to stop using more expensive precompiles; but even still the gains won’t be quite this impressive, but we have good reason to believe they will be very significant.
(Incidentally, the roughly 50/50 split between “EVM” and “other stuff” also appears in regular EVM execution, and we intuitively expect that the gains from removing EVM as “the middleman” should be similarly large)
Implementation details
There are a number of ways to implement this kind of proposal. The least disruptive is to support two VMs, and allow contracts to be written in either one. Both types of contracts would have access to the same types of facilities: persistent storage (SLOAD and SSTORE), the ability to hold ETH balances, the ability to make and receive calls, etc. EVM and RISC-V contracts would be free to call into each other; a the RISC-V perspective calling an EVM contract would appear from its perspective to be doing a syscall with some special parameters; the EVM contract receiving the message would interpret it as being a CALL.
A more radical approach from a protocol perspective is to convert existing EVM contracts into contracts that call an EVM interpreter contract written in RISC-V that runs their existing EVM code. That is, if an EVM contract has code C, and the EVM interpreter lives at address X, then the contract is replaced with top-level logic that, when called from outside with call params D, calls X with (C, D), and then waits for the return value and forwards it. If the EVM interpreter itself calls the contract, asking to run a CALL or SLOAD/SSTORE, then the contract does so.
An intermediate route is to do the second option, but create an explicit protocol feature for it - basically, enshrine the concept of a “virtual machine interpreter”, and require its logic to be written in RISC-V. The EVM would be the first one, but there could be others (eg. Move might be a candidate).
A key benefit of the second and third proposal is that they greatly simplify the execution layer spec - indeed, this type of idea may be the only practical way to do that, given the great difficulty of even incremental simplifications like removing SELFDESTRUCT. Tinygrad has the hard rule of never going above 10000 lines of code; an optimal blockchain base layer should be able to fit well within those margins and go even smaller. The beam chain effort holds great promise for greatly simplifying the consensus layer of Ethereum. But for the execution layer to see similar gains, this kind of radical change may be the only viable path.

Author: benaadams
Date: 2025-04-20T14:03:07.366Z

A difficulty of going as low level as a cpu architecture for the VM means it’s difficult to optimize back up
So at the moment the UInt256 operations in the Evm are usually implemented with Avx2 or Avx512 (equivalent on Arm); operating with 256bit or 512bit registers.
If that was decomposed to RISC-V 64bit or worse 32bit instructions; that then becomes a extremely hard problem to recognise the patterns and then recompose back to 256bit operations when the RISC-V code is then run on AMDx64 or ARM64 that most blockbuilders and validators will be running (as there is currently no high performance RISC-V hardware).
C/C++ compilers; which spend a long time compiling, have a hard time doing auto-vectorisation in this way; and they only auto-vectorize simple repetitive structures, they don’t recognise entire algorithms and convert them to a totally different form (which is normally the case with using specific CPU SIMD instructions effectively).
The risk here is that zk-proving may get better, but blockbuiling and execution will deteriorate significantly?

Author: pcaversaccio
Date: 2025-04-20T14:31:13.315Z

Hmm, so if I understood correctly, the basic idea is that proving basic RISC-V instructions (simple adds, moves, comparisons) might be much quicker & easier for ZK systems than proving the complex EVM execution step. Generally, that makes sense I think. But what about all the other stuff needed to actually run smart contracts? Like, I’m thinking about standard RISC-V features like integer multiplication and especially division, or more complex bit manipulation instructions. And crucially, what about the special syscalls needed to interact with Ethereum’s state, like reading/writing storage (SLOAD/SSTORE) or making calls? How hard are those specific things to prove in ZK? Is there a risk that even if the basic instruction proving gets faster, these necessary extras (especially things like division, or maybe even floating-point or vector math if they were ever added) could become the new major bottlenecks, essentially the new hotspots that dominate the proving time?

Author: AdamCochran
Date: 2025-04-20T14:53:57.049Z

I think the simplicity argument makes a lot of sense.
But, taking a step back, I think it raises the question of what is Ethereum’s priority purpose right now?
L1 execution, simplicity, decentralization, or L2 enablement?
This would be great for L1 execution, but that lowers the value add of L2s, competing against ourselves, and doesn’t add much value to that roadmap in exchange for a huge technical lift.
It seems like there are a lot of other ambitious pie in the sky efforts that could either improve drastically the execution for L2s or have more moderate boosts for both L1 & L2


Blob‑only data model + mandatory danksharding


Recursive‑proof aggregation precompile (“VERIFY_RECURSIVE” / “AGGREGATE_SNARKS” – folds N rollup proofs into one SNARK so the slot verifies a single proof)


Unified prime‑field crypto stack & BLS signatures (Adopt a single curve—e.g., BLS12‑381—for user sigs, KZG commitments, and SNARK verifiers. + Poseidon/Rescue hash precompile in the same field.)


Stateless KZG / IPA commitment root (Replace the Merkle Patricia/Verkle tree with a polynomial commitment of the full state vector)


Enshrined global message bus (native inbox/outbox for all L2s)


Sequencer‑level PBS (proposer‑builder separation at the rollup block level)


BLS aggregate‑signature mempool (Mempool nodes accept only bundles where thousands of user or rollup signatures are pre‑aggregated into one BLS sig)


Where as RISC-V move seems to 50x - 100x L1 execution, but very little benefit for the L2 model.
TL;DR:
-agree it seems like a good idea for the L1 that solves points 2 and 3 of the L1 bottlenecks.
-but is this the set of priorities we want to solve for, especially given the scale of technical cost here?
That I don’t have the answer for, but thought it was worth raising the question!

Author: levs57
Date: 2025-04-20T15:26:16.568Z

Please don’t.
Hi.
This is not a good plan, largely based on wrong priors about proof systems and their performance.
Checking the assumptions
As far as I understand the argumentation, main arguments are (1) scalability and (2) maintainability.
At first, I would like to address maintainability.
Realistically, all RISC-V zk-VMs use precompiles to perform the computationally intense operations. List of SP1 precompiles can be found here: docs.succinct.xyz/docs/sp1/writing-programs/precompiles , you can see that it includes pretty much every relevant “computational” opcode from EVM.
Therefore, any change to cryptographic primitives of the base layer will require writing and auditing circuits for these precompiles. This is a severe restriction.
It is correct, indeed, that maintenance of “out-of-EVM” part of the execution client plausibly becomes relatively easy if performance is good enough. I am not exactly sure if it is good enough, either, but this part is low-confidence:

Indeed, state tree computation can be done much faster by using a friendly precompile, such as Poseidon.
It is less clear that you can deal with deserialization in an elegant and maintainable way.
Also, I think there are some nasty details such as gas metering and various checks, they are probably in “block evaluation time” but realistically they are better quantified as “out-of-EVM” part (and these are mostly subject to maintenance pressure).

Second, scalability
To reiterate, there is no way RISC-V works without precompiles for EVM payload. It does not.
So the statement

In practice, I expect that the remaining prover time will become dominated by what today are precompiles.

is while technically correct, is unnecessarily optimistic. It assumes there won’t be precompiles. In fact (in this future world), there will be exactly the same set of precompiles as computation-heavy opcodes that we have in EVM (signatures, hashes, possibly large modular operations).
To address Fibonacci example, it is hard to judge without digging into extremely low-level details, but at least large parts of these advantages are:

Interpretation vs execution overhead.
Loops unrolling (decreases control flow on RISC-V part, not sure if done by solidity but even if done singular opcodes still perform a lot of control flow / memory accesses due to interpretation overhead).
Using smaller data type.

What I want to point out here, is that to get advantages 1 & 2, you must kill interpretation overhead. That seems aligned with RISC-V idea, but this is not the RISC-V as we currently speak of it, rather it is something resembling (?) RISC-V capable of various things.
So, there is a bit of a problem


To get plausible advantages to maintainability, you have to have RISC-V (with precompiles) that your EVM compiles to. Which is, basically, current status.


To get plausible advantages to scalability, you need to have entirely different beast - something (plausibly resembling RISC-V) that has the concept of a “contract”, aware of the various restrictions of Ethereum runtime, and is able to run contracts as executables, without interpretation overhead.


I am assuming, now, that you mean 2 (because it seems that the rest of the post suggests so). I urge you to realize that everything outside of this environment will be written on whatever thing RISC-V zkVMs are currently written in, with implications for maintenance.
Some caveats


It is possible to compile the bytecode from high-level EVM opcodes. Compiler then is in charge of ensuring that the resulting program maintains invariants such as absence of stack overflow. I would like to see it demonstrated in normal EVM. SNARK of correct compilation then can be supplied together with contract deploying instruction.


It is possible to construct a formal proof that some invariants are preserved. This approach (instead of virtualization) is used in some browser contexts, as far as I remember. By making a SNARK of this formal proof, you can also achieve similar result.


Simplest option is biting the bullet and…


Constructing a minimal “blockchain-y” MMU
I think this is probably implicit in your post, but let me clarify once again. What you actually need if you want to get rid of virtualization overhead is execution of compiled code. That means that you need to somehow prevent the contract (which is now executable!) from writing to the kernel (off-EVM implementation?) memory, at the very least.
So, naturally, we need some kind of MMU. Arguably, approach with pages (used in normal computers) is largely unnecessary, as the “physical” memory space is almost unlimited. This MMU, ideally, should be minimal (as it lives on the same level of abstraction as the architecture itself); though possibly some features (say, atomicity of transactions) could be moved to this level.
Provable EVM then becomes a kernel program running in this architecture.
RISC-V might be not the best choice for the task
Interestingly enough, under all these conditions it might turn out that the actual ISA that is optimal for this task is not RISC-V, but, rather, something similar to EOF-EVM.
The reason for that is that “small” opcodes create, in fact, an extremely large amount of RAM accesses, which are hard to prove using current methods.
Similarly, to minimize branching overhead, in our recent paper Morgana (eprint/2025/065) we show how to prove the code with static jumps (similar to EOF) with precompile-level performance.
My recommendation is, instead, constructing a proof-friendly architecture with minimal MMU allowing to run contracts as separate executables; I don’t think it should be RISC-V; rather a separate ISA - ideally, aware of limitations dictated by SNARK protocols. Even ISA resembling some subset of opcodes of EVM will likely be better (+ as we are aware, the precompiles will be with us whether we want it or not, so RISC-V doesn’t give any simplification here).

Author: levs57
Date: 2025-04-20T15:37:22.002Z

(not sure how to edit posts here, so just write some additional thoughts)

LLVM has a lot of compiler bugs. Solidity, in comparison, has excellent track record. This is largely thanks to much simpler pipeline.
None of RISC-V vms are production ready, and their complexity is significant. Their teams might falsely claim otherwise, but, for example, SP1 recommends their customers to use a trusted prover. It came in handy when we have recently uncovered a soundness bug allowing to prove arbitrary statements.
@pcaversaccio this is correct intuition. The likely bottleneck is stack management (due to larger granularity of instructions), and, potentially, jumps. That being said, of course going from interpretation to execution will have huge advantages anyway, but this requires to figure out things written in my previous post.
@AdamCochran strongest possible support of enshrined aggregation of stateless computations.

Author: SirSpudlington
Date: 2025-04-20T16:59:15.417Z

I agree with @benaadams here, The EVM as a whole is very much U256 based, so abstracting down to riscv would decrease overall execution performance. From my limited STARK knowledge, I know that the AIR can be built more easily over register-based instruction sets.
The immediate first solution I think of is using a language like Cairo, or a pseudo-cpu architecture similar to risc-v but designed for emulation, e.g 256 bit registers. These solutions are somewhat adhoc and may present overt complexity when actually being implemented, but they may serve as an alternative POV.

Author: underflow
Date: 2025-04-20T19:36:17.679Z

Would agree here with @levs57, virtualization can be an intermediate step, but this will not achieve the optimal scenario (by far). Compilation to a better ISA than RISC-V will likely be needed (ala TinyRAM) given that RISC-V was never designed for verifiable computation, and then, also include a proof of correct compilation (this part may or may not be too hard, depending on trust assumptions and how far up into the compiler stack we want to prove).
Even in the case of virtualization, one would require formal proofs that (1) the virtualized RISC-V EVM code is correctly implemented (i.e., it follows the EVM specs), (2) the RISC-V circuits themselves correctly follow the RISC-V specs, (3) a formal proof that the RISC-V circuits, I/O, memory-checking mechanisms (for RAM and registers), and bootloading mechanisms (for program initialization) satisfy both completeness and soundness so no invalid proof will be accepted, and lastly (4) a formal proof that the verifier itself is indeed sound, building on top of (3).
However, part of the challenge of building these formal proofs include that the circuits and proof systems are ever changing in the current landscape, so before investing deeply into doing this, one would want to fix a zkVM architecture – but by the time this effort is completed, such an architecture may now be deemed outdated.

Author: underflow
Date: 2025-04-20T19:51:01.628Z

[additional thoughts]
Having said the above, I do think the original proposal is worth seriously pursuing – that in fact, we’re doing at Nexus, however reaching true scalability and maintenance will be a hard and long task, and one will eventually need to indeed (1) provide a better ISA than RISC-V, (for the Nexus RISC-V zkVM, we’ve explored this direction, in the lines of a simple “Universal Turing Machine” designed, particularly, for verifiable computation, but this in experimental stages), and (2) provide proofs of correct compilation, which require carefully specifying and mapping the invariants.

Author: malik672
Date: 2025-04-20T20:20:42.911Z

This is not true in anyway and short sighted, a register based system will be way faster than a stack based one bseides there’s literally no difference, you can emulate U256 via limbs(that’s how it’s mostly done anyway)

Author: malik672
Date: 2025-04-20T20:26:40.946Z

Those one are like the easiest, I urge you to read the risc-v specs just for the 32 bits: https://www2.eecs.berkeley.edu/Pubs/TechRpts/2016/EECS-2016-118.pdf
for syscalls we can just ECALLS(which are already already control by design)

Author: malik672
Date: 2025-04-20T20:29:22.883Z

MTER :  make the EVM RISC

Author: SirSpudlington
Date: 2025-04-20T20:33:51.496Z

I was not stating that stack-based architectures are faster, they’re are not (in most cases), merely that it would be inefficient to use serveral cycles to compare and add 8 different U256 limbs, and that either an extention or modification to the risc-v architecture to have U256 registers may be better for optimisation.
I edited the above post for clarification.

Author: GCdePaula
Date: 2025-04-20T20:42:19.557Z

Yes, please  



 vbuterin:

replace the EVM with RISC-V


What ISA exactly in the RISC-V family were you considering?



 vbuterin:

One precedent for this is the Nervos CKB VM, which is basically RISC-V.


Another one, more mature, is the Cartesi Machine, which is proper RISC-V. Specifically rv64gc — it even boots Linux and runs Doom!




 AdamCochran:

but very little benefit for the L2 model.


If the L2s also become RISC-V, keeping L1 compatibility, wouldn’t they see (in their execution environment) a similar speedup?




 levs57:

run contracts as executables, without interpretation overhead.


I really don’t get this part, can you give more details?



 levs57:

LLVM has a lot of compiler bugs.


The scale at which LLVM and GGC are used is ridiculously higher than the Solidity compiler. I believe this is one of the most important metrics for security. Personally, I’d bet on LLVM and GCC. If that’s not enough, there’s always CompCert, which also targets RISC-V.



 levs57:

None of RISC-V vms are production ready


Perhaps true for zkVMs, but not true for non-zkVMs.

Author: vbuterin
Date: 2025-04-20T20:58:17.563Z

levs57:


None of RISC-V vms are production ready, and their complexity is significant. Their teams might falsely claim otherwise, but, for example, SP1 recommends their customers to use a trusted prover. It came in handy when we have recently uncovered a soundness bug allowing to prove arbitrary statements.



Sure, but this is a limitation on the existing EVM too. ZK-EVMs today are written as ZK RISC-V plus an EVM implementation in RISC-V. And this trend seems to be solidifying more and more over time. So exposing RISC-V to the user directly cuts out the middleman.

I urge you to realize that everything outside of this environment will be written on whatever thing RISC-V zkVMs are currently written in, with implications for maintenance.

Today, the parts other than VM execution are written in (or rather, compiled down to) RISC-V.

The EVM as a whole is very much U256 based, so abstracting down to riscv would decrease overall execution performance

The important point here is that most of the usage of the EVM is not u256 based. The great majority of values that the stack deals with are u32 or u64, balances are u128. And so the HLL code that devs write can be compiled down to something that uses the smaller-sized RISC-V instructions and gets the benefits of doing so directly.

Author: SirSpudlington
Date: 2025-04-20T21:23:52.576Z

vbuterin:

The important point here is that most of the usage of the EVM is not u256 based. The great majority of values that the stack deals with are u32 or u64, balances are u128.


Now that I think about it a bit more, having a 32-bit ISA allow for easier proving via fields like goldilocks, so it would probably be a better trade off having easier proving at the cost of VM cpu cycles.

Author: pkieltyka
Date: 2025-04-20T23:01:31.500Z

I know it’s a stretch, but what about considering EVM+/Stylus by the Offchain Labs team as the future L1 execution layer? It offers full EVM bytecode compatibility that runs in a WASM VM, and allows any WASM-targetable language like Rust, with significant performance improvements, while maintaining full interoperability with EVM bytecode contracts at runtime. Feels likejj the easiest upgrade path while maintaining compatibility.

Author: eigmax
Date: 2025-04-21T01:02:41.843Z

[repost to fix an ambiguity]

If we use Poseidon, we can prove 2 million hashes per second on a laptop (compared to ~15,000 hash/sec for keccak). this is an issue of the MPT, but nothing to do with any ISA (EVM bytecode, RISCV or MIPS). Strongly agree with supporting the zk-friendly hash function and make it possible to align the prover’s cost with the gas used.
notice that ZK-EVM provers today already work by proving over implementations of the EVM compiled down to RISC-V, and give smart contract developers access to that RISC-V VM directly.. On ethproofs, please notice that ZKM is MIPS based, and ZKM’s cycles is far way less than others. This is due to keccak sponge precompile and MIPS ISA.
Should EF maintain its own RISCV instruction set, compiler and other toolchains? like static analyzer, linter, etc. Or reuse LLVM? Since it claims a RISCV VM, if I compile a CPP program into RISCV, should I be able to use this library in the VM interpreter? we have an example here to demo how to use a CPP static library in zkMIPS (unfortunately links is not allowed to be included here). I say this cause if we are saying supporting RISCV, we are supporting a general purpose backend of any compiler that has supported.
If RISCV becomes mass adopted by all miners for snarkifying everything, this means block producer can generate the proof of the block, and all other validators just verify the proof instead of re-executing the block. Will overall computing power for prove-and-verify be less than mine-and-validate and when?

Author: MASDXI
Date: 2025-04-21T04:53:23.916Z

If EVM transitions to RISC-V VM, I think it’s similar to the concept of the revive to run Solidity on PolkaVM which is RISC-V VM.

Author: elevenarms
Date: 2025-04-21T05:23:38.671Z

@vbuterin this is an awesome idea.
Realizing the full potential of a global distributed computer is fundamentally constrained by Layer 1 transaction throughput. While L2 solutions are vital, enhancing core L1 performance remains crucial for broader adoption and further success.
A key advantage of RISC-V is its defined extensibility. We should investigate defining a set of custom RISC-V instructions specifically designed to accelerate core, performance-critical EVM opcodes.
RISC-V’s open nature permits specialized hardware implementations (ASICs, FPGAs) beyond generic CPU execution. This offers a path to significant L1 TPS improvements by accelerating core EVM logic directly in silicon, potentially orders of magnitude faster than current software interpretation or JIT approaches.
Verifiability & Security: The modularity and clean design of RISC-V lend themselves more readily to formal verification methods compared to complex legacy ISAs. A formally verified RISC-V core executing EVM logic could provide much stronger guarantees about runtime behavior, crucial for securing high-value smart contracts.
It would be great for the community to Initiate focused research tracks and working groups to:

Benchmark existing EVM implementations against potential RISC-V software models. @MASDXI - revive/PolkaVM looks great - it currently only targets RV32EM which is worth discussion.
Identify high-impact EVM operations suitable for custom RISC-V instruction acceleration.
Develop proof-of-concept RISC-V models (FPGA/emulation) with custom EVM extensions.
Engage with the RISC-V community on standardization potential for blockchain-specific extensions.
Evaluate the formal verification advantages and challenges.

RISC-V, potentially enhanced with custom EVM-centric instructions, offers a compelling path towards a more performant, secure, and scalable Layer 1

Author: dilrong
Date: 2025-04-21T08:34:59.791Z

Vitalik Buterin claims that replacing the Ethereum Virtual Machine (EVM) with RISC-V could improve zero-knowledge (ZK) proof efficiency by 50 to 100 times. However, is RISC-V truly superior? The EVM has been a stable, battle-tested environment for approximately nine years, while RISC-V lacks substantial real-world experience in blockchain execution contexts. Although PolkaVM has adopted RISC-V, I believe it has not been adequately validated, as it has yet to be thoroughly proven on a mainnet.
The EVM is specifically optimized for smart contract execution, whereas RISC-V, designed as a general-purpose architecture, may lack tailored optimizations for blockchain use cases. While RISC-V’s versatility allows the use of programming languages from other blockchains, Vitalik himself noted that improvements leveraging existing Solidity are preferable. Transitioning the entire ecosystem to a new architecture is a daunting challenge.
Implementing RISC-V in software inevitably leads to performance degradation. Using an emulator for software-based execution raises doubts about its ability to process tasks efficiently. On the other hand, adopting RISC-V hardware would entail significant transition costs. I believe that ZK-EVMs already provide sufficient efficiency for current needs. When considering the costs of development, the effort required for transition, and the potential for unforeseen errors, replacing the EVM with RISC-V does not seem like a compelling approach.
While transitioning to RISC-V may offer potential benefits, I argue that improving ZK-EVMs and optimizing the existing EVM are more practical and stable alternatives.

Author: LukaszRozmej
Date: 2025-04-21T10:24:08.717Z

But… why? And this is genuine question that I don’t understand and need more context about.
The supposed answer is performance. But this until proven might be just a false promise. And if you are getting 100x-1000x improvements in benchmarks, you are clearly doing something wrong and the overhead should be avoidable at least to some extent.
There are multiple projects that try compiling EVM bytecode to native code (Revmc, Nethermind IL-EVM ect.), why not to build a compiler to risc-v that would give us the speedups we need while not needing a complete paradigm change?
The potential problem with that is that classic EVM bytecode is hard to introspect and thus hard to compile, but we have a solution just around the corner - EOF, which should make things much simpler.
Having abstract EVM that is easy to compile to other things, while laser focused on domain problems is probably better than using general purpose architecture. This is the foundation of Java, .Net or LLVM and works well for them, and with some effort it is not a performance bottleneck (for example check Nethermind client performance which is build on .Net).
Also no idea about the hardware that is coming, especially zk-circuts, but my bet is that RISC-V general purpose CPU’s will have a hard time catching up to x86 and ARM.

Author: kongtaoxing
Date: 2025-04-21T12:55:54.153Z

This proposal is preaty radical — but I believe it will carry the seeds of a renaissance for Ethereum. Native RISC-V execution could supercharge performance, enable more efficient ZK proofs, and better align with future hardware acceleration.
That said, several concerns give me pause:

The complexity of implementation could introduce new vulnerabilities and slow down core development.
A RISC-V shift raises the bar for low-level developers, potentially increasing the learning curve and reducing accessibility.
Without adoption from other EVM chains, we risk fragmenting the broader ecosystem.
Backward compatibility with the vast existing contract base may be difficult to guarantee.
And finally, coordinating such a transformation through governance and a potential hard fork is no small feat.

Author: koute
Date: 2025-04-21T15:16:05.660Z

elevenarms:

Benchmark existing EVM implementations against potential RISC-V software models. @MASDXI - revive/PolkaVM looks great - it currently only targets RV32EM which is worth discussion.


Hi. I’m the guy responsible for PolkaVM. Since I see some misinformation flying around here and there let me chime in with some details as to what PolkaVM is and how it works.
PolkaVM currently supports riscv64emac with the Zbb extension, but unlike most (all?) other RISC-V VMs it doesn’t run RISC-V binaries as-is (it’s not actually a RISC-V VM!). Offline we ingest normal RISC-V ELF binaries that you build using a normal compiler, and we translate them into a more constrained and efficient custom bytecode that’s designed for use in a VM (and not native hardware, like RISC-V is). The idea is to remove as much complexity out of the VM itself (which needs to run on-chain), put as much of that complexity as possible into offline tooling (which can run off-chain), and improve security by removing unnecessary features (e.g. in vanilla RISC-V you can jump to any address; in PolkaVM bytecode the code address space is fully virtualized, you can’t jump everywhere, and the bytecode isn’t even loaded into memory that’s accessible by the program).
Performance-wise we get very close to bare metal performance[1]; it’s as fast as wasmtime (which is the state-of-art WASM VM), but it guarantees O(n) recompilation and recompiles programs into native code hundreds times faster. To put this into perspective, it is faster to recompile a program from scratch starting with raw PolkaVM bytecode into the native code than it is to cache the recompilation artifacts and look them up based on their hash (in other words, recompiling the program is faster than calculating its hash), and this is without sacrificing runtime execution performance.
We mainly use RISC-V not because it’s a particularly good bytecode for a VM (it actually isn’t that great), but because it’s simple, well supported and it’s relatively easy to translate to something else, so we can get the best of both worlds - great software compatibility (you can use existing compilers and programming languages, e.g. the other day I ported Quake to PolkaVM[2][3]), but you also get the benefits of a custom, optimized bytecode (blazing fast compilation speed, near-native performance, simplicity and customizability).
Anyway, if you have any questions feel free to ask me anything.

Links: (New account so I’m not allowed to post links, so just replace “github” with github dot com)
[1] - github/paritytech/polkavm/blob/master/BENCHMARKS.md
[2] - github/paritytech/polkaports/tree/master/apps/quake
[3] - github/paritytech/polkavm/tree/master/examples/quake

Author: edubart
Date: 2025-04-21T18:38:44.230Z

Hi, I am one of the core developers of Cartesi’s VM. As someone actively working in a RISC-V VM for blockchain applications – the Cartesi Machine[1], which @GCdePaula kindly mentioned – I wanted to share some perspective supporting the exploration of RISC-V for Ethereum’s execution layer.
One of the biggest advantages I see in adopting RISC-V is the immediate access to mature tooling and ecosystems. Instead of building a completely bespoke environment, using RISC-V allows developers (and the core protocol) to tap into decades of work on compilers like GCC and LLVM, debuggers, libraries, and even full operating systems like Linux. This significantly lowers the barrier for developers and potentially reduces the risk associated with compiler bugs compared to newer, less battle-tested toolchains. It aligns well with the goal of potentially allowing contracts written in languages like Rust or even C++ to target Ethereum, compiled via standard backends. For those who question bugs in LLVM or GCC, strengthening security guarantees by using formally verified compilers such as CompCert[2] that are capable of targeting RISC-V today is a possibility. Thinking big, maybe even running applications on top of formally verified RISC-V operating system kernels such as seL4[3] on VMs covering RISC-V privileged ISA specification (such as the one I work on) could be a possibility for more complex applications demanding to run inside an operating system environment.
The performance concerns raised by some are valid but addressable. From my experience, RISC-V doesn’t inherently sacrifice execution performance when implemented properly. While u256 operations naturally decompose to multiple instructions, in practice in a well optimized RISC-V VM the cost of doing so for most situations should not impact performance that much. Furthermore, optimization techniques at the VM level could significantly mitigate these costs, as the RISC-V ISA is extensible enough to add custom blockchain-specific extensions that could optimize common cryptographic operations (e.g., Keccak256).
I think basing the future execution layer on a standardized, open, and well-supported ISA like RISC-V provides a solid foundation. It offers a path towards leveraging existing software ecosystems, potentially simplifying the developer experience, and benefiting from future hardware advancements in the RISC-V space.
While the road is complex, I believe the potential benefits for scalability, tooling maturity, and long-term maintainability make RISC-V a direction very much worth pursuing for the future of blockchain execution environments. Many existing RISC-V VMs in the blockchain space today demonstrate that robust, production-ready RISC-V implementations can exist. Specifically, I think the Cartesi Machine showcases the power of leveraging a standard, open ISA. It’s a stable, high-performance RISC-V emulator implementing the standard RV64GC ISA capable of running the entire Linux software stack and unmodified RV64GC ELF binaries. Crucially, it’s fully deterministic, right down to floating-point operations. For those curious wanting to grasp what it’s capable of running, I recommend experimenting with my WebCM[4] experiment, a serverless terminal that runs a virtual Linux directly in the browser by emulating a RISC-V machine powered by the Cartesi Machine emulator compiled to WebAssembly.
Now, the L1 proposal focuses on ZK-proofs, whereas Cartesi currently enables on-chain verification via interactive fraud proofs, leveraging deterministic execution, and state Merkle proofs. While the verification mechanism differs, Cartesi confirms that building a verifiable and deterministic execution environment on top of RISC-V is viable and worthwhile.
Of course, integrating RISC-V directly into L1 with ZK-proving presents unique and significant challenges, particularly around gas metering, defining the precise syscalls for state interaction, and optimizing ZK circuits for RISC-V instructions. Performance in the specific context of ZK-proving also needs deep investigation. Fortunately, there are many RISC-V zkVMs projects already doing research and development on those points.
Regarding implementation strategy, I believe serious consideration should be given to the “radical approach” of defining a protocol that enshrines the concept of a virtual machine interpreter compiled down to RISC-V. This approach would create a path where Ethereum’s core RISC-V VM could remain minimal and simple, while still being flexible enough to accommodate different VM interpreters beyond the EVM, giving developers more freedom in their virtual machine development.
In short, I believe leveraging a standard like RISC-V offers tremendous advantages in tooling, developer familiarity, flexibility, and even the potential for long-term hardware acceleration. My work experience with the Cartesi Machine reinforces the idea that RISC-V is a powerful and viable foundation for the next generation of verifiable blockchain computation, and it’s exciting to see it being seriously considered for Ethereum’s core execution layer.
–
[1] - /github.com/cartesi/machine-emulator
[2] - /compcert.org
[3] - /sel4.systems
[4] - /edubart.github.io/webcm
Links: New accounts are not allowed to include links, prefix them with https:/.

Author: clarus
Date: 2025-04-21T20:39:19.117Z

Hi, can Yul be a good choice for a zk-friendly ISA?
It does not make a hypothesis about how variables are allocated. They could be stack-based (like in EVM), register-based (like in RISC-V), or even memory-based (like in Valida zkVM). The execution layer could provide a (proven) compilation pass from Yul to its assembly language.
In addition, it is relatively standard, being the intermediate language of the Solidity compiler.

Author: elistark
Date: 2025-04-22T05:52:08.546Z

I’m working on a longer reply, but have a question @vbuterin : I see how this could potentially help goal 3 (ZK-EVM proving capabilities), but how does it address goal 2 (Desire to keep block production a competitive market)?

Author: mayorpepe
Date: 2025-04-22T06:24:06.371Z

Fantastic points here Adam! I think overall your comments make a lot sense and I think understanding what we’re trying to optimize for primarily helps us understand which trade offs we want to make and I agree about the tension between optimizing for L1 but canabalizes gains from L2

Author: andreolf
Date: 2025-04-22T06:36:20.718Z

vbuterin:

The idea: replace the EVM with RISC-V as the virtual machine language that smart contracts are written in.


thinking about this more and wondering how difficult would it be to maintain backwards compatibility between EVM and RISC-V contracts at scale?



 vbuterin:

which is [basically RISC-V].


also on this could be opt-in at first, with the RISC-V VM gradually becoming dominant as tooling matures?

Author: elistark
Date: 2025-04-22T06:53:28.320Z

Not sure what the priorities are. Notice that you really want all the cryptography to move to 32-bit PQ secure stuff, like over M31 or babybear. Going down the KZG+ECC stuff will lead to things that are quantum susceptible, and ~100x slower than STARK friendly crypto.

Author: elistark
Date: 2025-04-22T06:55:24.489Z

#1 priority to get more proving scale is to embrace 32-bit logic and 32-bit primes, like M31 and babybear. If you do this, you’ll get things that are probably compatible with fastest STARK proof generation (in addition to being PQ secure)

Author: xermicus
Date: 2025-04-22T07:45:07.400Z

vbuterin:

The important point here is that most of the usage of the EVM is not u256 based. The great majority of values that the stack deals with are u32 or u64, balances are u128. And so the HLL code that devs write can be compiled down to something that uses the smaller-sized RISC-V instructions and gets the benefits of doing so directly.


Hi, I’m the maintainer of the previously mentioned revive Solidity compiler. Your are spot on. Exactly this is the reason for a lot of unnecessary overhead contracts written in Solidity or any other language compiled to the EVM are exposed to.
Adding to that, the big endian nature of the EVM requiring a lot of byte swaps on those u256 values makes things even worse. A big endian VM with 256 bit word size as the only type is by nature unable to compete with lets say PolkaVM or SVM (n.b. a more efficient bytecode would generally also imply more efficient execution proving of said bytecode). I really want to stress your point here.

Author: AlexandreBelling
Date: 2025-04-22T10:20:37.872Z

I like the idea of exploring changes in the EVM to make it more provable.
As for the performances, I understand implicitly the proposal as splitting the EVM in two parts. The first part is a kernel controlling the “sensitive” operations (e.g. handling the state accesses, creating the execution contexts for every calls and subcalls, doing the reverts etc…) and the second part is a free RISC5 interpreter that can be used by the contracts. I am confident it would allow massive saving for use-cases like Fibonacci, doing heavy integer arithmetic and almost no kernel calls. But for actual workload, most of the gas spending is done by doing cryptography operations and storage access. I am also concerned that switching a lot between kernel and user mode may have a non-negligible cost. So, even in a world where every contract has migrated to the RISC5 version of the EVM, the prover runtime savings I see would be well under the objective of 50x.
For similar reasons, I wouldn’t suggest moving to more ZK-friendly ISAs because they would not address the above problem and would also come with the issues of young developer ecosystems.  If the target of 100x is important, it would have to be combined with an effective way to optimize the precompiles and the kernel operations and this will require more aggressive solutions. Direct arithmetization, combined with in-depth proof-system engineering (for the precompiles), is a more promising way to get there. This is the path we have been taking at Linea and unlike many, we have no plan to switch to a pure RISC-V approach.
And even then, all the benefits would be negated if the retro-compatibility entails maintaining the old EVM beside the RISC5 one. If the actual driver and primary goal of the proposal is to move away from the current EVM while maintaining ZK-friendliness, then it is understandable. But then, I also have concerns/questions with the proposed approaches.

Side-by-side environments: I worry about these temporary solutions that end up lasting forever and adding a lot complexity to the overall system.
Transpiling on the fly the legacy bytecode. This will require figuring out a transpilation algorithm that guarantees that the contracts always behave in the same way after transpilation. It’s not very clear to me how this would work; would it just expand the “EVM” handling of every opcode into RISC5 code?
Multiple execution environments: If we want this to unfold in a way that does not worsen the Eth fragmentation and maintain prover-friendliness, it means we will have to work out a standard way to allow contracts to call each other through different execution environments. For the provers, this corresponds to emulating multiple VMs. I can see how this could make developing on Ethereum more attractive but it also means that the prover complexity will increase even more.

To conclude, I stress that formal verification of zk-EVMs is years away from being L1-ready. I fully appreciate all the steady progress that is being and has been made in the RISC5 ecosystem toward formally verifying the arithmetization of RISC5. However, I think the speed of the progress (vs direct arithmetization) is mainly due to the simplicity of the RISC5 VM, and I’d add that the FV analysis of a RISC5 approach also needs to cover FV-ing the compiler suites. This part is a completely different beast. Taking this into account, contrary to the current popular belief, I don’t think direct arithmetization is that much worse off than RISC5 for FV.
Multiprovers and L2 fallback mechanisms are currently the only short-to-medium-term solution to have fully production-ready ZK systems on-chain.

Author: clarus
Date: 2025-04-22T11:16:02.939Z

Thanks for stressing out that a large part of the execution time is in cryptography, and that formally verifying RISC-V VM is not comparable to formally verifying zkEVM, as the compiler is missing, and this is the most complex part!
That being said, I am fairly confident we will have a complete and formally verified stack in Rocq/Coq with an EVM interpreter on RISC-V, down to the Rust implementation of the circuits, by the end of the year thanks to a joint work. It would use the CompCert project internally to compile an optimized EVM implementation in Rocq to RISC-V, and then we would verify the Rust code of the circuits with “coq-of-rust” (I would personally like to see ZK optimized ISA, from an engineering perspective).

Author: SirSpudlington
Date: 2025-04-22T11:47:45.565Z

If we did go about this, would it be in a separate GitHub repo like eWASM or would it be a sequence of EIPs like EOF?

Author: ericsson49
Date: 2025-04-22T16:13:36.500Z

If the goal is prover efficiency than RISC-V is a sub-optimal choice.
Cost profiles for a direct execution and for proving such execution are different.
Of course, if the direct execution requires less steps, it’s beneficial from the prover perspective too.
However, provers actually prove execution of a trace checking program, not execution of the original program per se.
One such problem is register file. RISCs are register-based ISAs, which is clearly beneficial for direct execution. However, it’s a problem from trace checking perspective, since one needs to maintain register file consistency somehow (e.g. by copying unchanged register values from row to row). And one has to prove load/store operations which moves data from memory to registers and back. Such memory hierarchy is critical for achieving high CPU speed, but it’s a serious source of redundancy from trace checking perspective - and thus degrades prover time. Compare with ZK-optimized ISAs like Cairo or Valida, which have only two or three registers and operate with memory directly.
In that respect, it’s not actually clear whether RISC-V is a really better ISA than EVM from prover (trace checking) perspective. EVM is stack based, so its register file is small.
EVM operates with 256bit numbers, which can be a problem, if much smaller values dominates. However, a prover has an access to an actual execution trace, so it can choose a lighter weight implementation option for small values (e.g. a byte decomposition of a 32bit value can occupy less rows than a byte decomposition of a 256bit value).

Author: ericsson49
Date: 2025-04-22T16:40:09.932Z

Another aspect is smart contract Formal Verification costs. EVM is more a limited ISA than RISC-V, so F/V will be more complicated, in general. RISC-V smart contracts will generally have more loops and more memory operations, both of which pose problems from F/V.
E.g. one study (/www.cs.utexas.edu/~isil/solis.pdf) indicates that roughly one fifth of EVM smart-constracts has one or more loop. Since EVM operates with 256bit values, in RISC-V code more loops will be necessary. Even if loops are unrolled, this will result in much bigger SMT queries.
RISC-V has a richer memory model and there should be more memory operations (e.g. EVM has 1024 256bit stack, vs 16-32 32/64 bit registers). So, aliasing (two syntactically distinct expressions pointing to the same memory location) will be a more severe problem. Which in turn affects static analyses like Call Graph reconstruction, point-to analysis and similar.
I expect that formal reasoning about RISC-V smart-contracts in presence of loops/aliasing will be much more challenging compared to EVM smart-contracts.

Author: torfoes
Date: 2025-04-22T20:13:26.117Z

If the base protocol only needs to know “There’s a RISC‑V CPU and a merkleized key‑value store,” a lot of historical EVM quirks disappear. A smaller surface means fewer consensus bugs.
Plus, we inherit battle‑tested compiler stacks like GCC, LLVM, and the Rust toolchain, all with thousands of contributors and years of scrutiny. Relying on these well‑audited compilers means stronger optimization, richer debugging, and formal‑verification tooling right out of the box. Leaner core, proven toolchain, cheaper ZK proofs, faster syncs.

Author: codygunton
Date: 2025-04-23T00:41:24.272Z

It’s certainly desirable to give the zkVMs something in a more ready format. I want to raise the possibility of going a bit deeper and specifying implementations of the EVM opcodes in an enshrined circuit IR (call it TheIR in for the moment) which could then be consumed directly by the provers.
Objection 1: Provers differ so much that it’s not possible to do this with out giving preference to some particular architecture.
Response 1: The same objection could be raised about enshrining RISC-V. It is the most common target choice but not the only one (see ://x.com/eth_proofs/status/1912604603394502802/photo/1).
Objection 2: But zkVM progress has been spectacular. Won’t constraining the cryptographic backends by providing something too low level / opinionated stifle progress?
Response 2: Agree that this is a serious concern, but we can’t draw conclusions without a deeper viability study. On that note, many different groups have thought about circuit IRs. In particular, as part of the zkEVM Formal Verification Project (://verified-zkevm.org/), Veridise is working on such an IR called LLZK (see ://medium.com/veridise/veridise-secures-ethereum-foundation-grant-to-develop-llzk-a-new-intermediate-representation-ir-224c0e71f4d5). This could be TheIR if it’s designed well enough (broader community involvement would of course be a requirement here).
Objection 3: But then won’t the zkVMs have to implement circuits for TheIR opcodes?
Response 3: We’re talking about long timescales for any of this. “Have to”? Possibly they will have to the long long run if there is widespread abandonment of EVM interpretation by zkVMs. In the medium (many-year) term, if we can tolerate storing EVM bytecode alongside TheIR bytecode (I don’t know how viable this is), then zkVMs could experiment with both approaches and even incrementally upgrade. In this world, I would regard the switch to consuming TheIR as the change to upgrade the proving system to a format would likely unlock both efficiency gains and the possibility to use security tooling built around TheIR.
Objection 4: But so much energy has gone into supporting RISC-V—why not just go with that?
Response 4: Objections have been raised in previous comments about how RISC-V is too low-level for clean usage in large integer arithmetic cryptography. zkVMs chose generality on the basis of bringing SNARKs to the world generally, and that’s a great feature for those products, but IMO that’s shouldn’t be a factor in the long term.
I’m not strongly advocating for this, just raising it as worthy of discussion and learn any flaws that might be obvious to others 
I want to close by saying that any change, whether the RISC-V proposal or the one I’m suggesting, is a very-long term proposition should not IMO be blocking to unlocking scaling and usability improvements in the short term.

Author: xxuejie
Date: 2025-04-23T04:22:22.659Z

Hey there, I’m the original designer and current maintainer of Nervos CKB-VM. I’m not gonna directly debate which VM is better, but instead just want to sure our journey building a RISC-V based blockchain VMs in the past 7 years.
NOTE: in this post I will talk about IR(intermediate reprentation) and instruction set interchangably. IR is typically used for software virtual machines(VMs), while instruction set is more used to refer a CPU’s instruction set. However in this very post, I use IR and instruction set to refer to the same thing.

The choice of CKB-VM, in Nervos’ thoughts, simply came from first principle thinking: all we want is a simple, secure and fast sandbox that is also as thin as possible on commodity CPUs. A CPU instruction set turns out to be the best fit here, and RISC-V stands out amongst other choices: x64 is far too heavyweight(believe it or now, when we first tried RISC-V, there is someone building blockchain VMs using x64!), arm might or might not have a licensing issues. There are certainly other open source RISC CPU cores, but it did seem to us that RISC-V is the one that attracts the most attentions, which will mean more people working on the toolchain. To us it will be a huge advantage.

Personally, I could never understand the argument that “RISC-V is for hardware implementations, while xxx is for software implementations”. If one really digs down to the IR level, the core RISC-V instructions are not so unlike instructions found in WASM, JVM, or even qemu TCG IR ( /www.qemu.org/docs/master/devel/tcg-ops.html). Yes the RISC-V CSR instructions ( /five-embeddev.com/riscv-user-isa-manual/Priv-v1.12/csr.html) might be slightly weird in a software based VM but there are 2 solutions: 1) you can simply choose not to implement them, CKB-VM does this, I know for a fact that some RISC-V VMs also do this. This choice has served us well for years; 2) other teams such as Cartesi have implemented all the CSR instructions without blockers. It is a solvable problem.
Now it is also a good time to share an anecdote lost in history: many consider WASM to be a choice as a blockchain VM, mainly because WASM is designed for software implementations(let’s ignore for a second if this makes any sense). Did you know that before WASM was born, there is a subset of JavaScript named asm.js that was popular for a while? So Alon Zakai first built emscripten, which translates C/C++ code to JavaScript so native code can be used in modern browsers. On the quest to make emscripten more performant, it has been discovered that if JavaScript is written in a particular style ( /kripken.github.io/mloc_emscripten_talk/#/14), the JavaScript code would map to native CPU instructions directly. And this is really the point of asm.js: having a set of pseudo-instructions that can map to native CPU instructions, but still utilizing JavaScript sandbox environment in a browser. Gradually, asm.js evolved into WASM, and somehow grows to be much bigger than asm.js’s original vision(IMHO right now WASM looks more like a clean, freshly designed JVM than asm.js these days). But let’s not forget asm.js’s original goal here: people yearn for a software IR that can map to native CPU instructions deterministically, than a JIT that does it 90% of the time. If RISC-V fulfills such goal, I would see it a perfect fit for a software VM.


Many here would be quite surprised that a considerable amount of EVM contracts would actually run much faster when reimplemented in a RISC-V VM. The fundamental reason, is that the majority variables do not need to be declared as 256-bit long. Even though at solidity level one does have values with shorter bits, but at EVM level, they will all be translated to 256-bit long values. I do remember reading somewhere that the original hope was that compiler technologies would catch up to solve this issue, but the unfortunate reality is that compilers never came up close, and might never come up. A similar story is v8: JavaScript shares similar design with EVM, in that JavaScript only has 64-bit double values. V8 spent a whole lot of efforts optimizing JavaScript code, lowering as many values to 32-bit integer value as possible, and the result is still not good enough: WASM was born because people want deterministic 32-bit operations that map to clean CPU instructions in the browser. Now the question is: do we want to repeat the same story in EVM? Do we finally accept that a real, close-to-CPU redesign is required, only when EVM grows to be a 2-million-lines-or-more code base like v8?

The problem with having only 256-bit values, does not simply end with performance. I do remember it has been raised many times that a reimplementation of any simple cryptographic algorithm would consume too much gas than one can afford. As a result, many EIPs have been proposed to add almost any cryptographic algorithm to Ethereum as precompiles. I do remember it took 4 years or so to finally have blake2b in Ethereum, many others, including secp256r1 are still in pending state. The fundamental issue here, IMHO, has to do with 256-bit values. Since any EVM operations work on 256-bit values, the gas charged for a mathematical operation(e.g., add/sub/mul) will have to consider the runtime cost of 256-bit values. However, most cryptrographics algorithms nowadays are not only implemented, but designed against 64-bit CPUs, making it quite wasteful to implement them on EVM with only 256-bit value types to spare.
This discussion above, really comes back to the recurring theme of designing Nervos CKB-VM: we want a simple, secure and fast instruction set that can map perfectly to native CPU instructions. It enables us to ship Nervos CKB-VM free from any precompiles up till this point(April 2025). I personally consider it my biggest achievement in the past 7 years, to help build a blockchain VM that is free from any precompiles, and as long as I’m working on Nervos CKB-VM, I will continue to fight to keep it this way. Yes I do realize that many other RISC-V VMs introduce precompiles like EVM does, but my wish is that if Nervos CKB-VM can prove that a precompile-free VM is possible, there will be others that follow in this design. And really if Ethereum embraces RISC-V, I do personally recommend that Ethereum can also design its own RISC-V VM in a precompile-free design.
With the precompile discussion, I do have a suggestion here: when we discuss EVM vs RISC-V, I do recommend that we make it one step further, to either compare the pros and cons of them either with precompiles included in both, or with precompiles missing in both. Let’s not compare EVM with precompiles to RISC-V without precompiles or the other ways around, to me it is not a proper comparison.


A real CPU instruction set is typically the final target of a compiler, leading to the common myth that a higher level IR might embrace optimizations easier than a lower level IR. However, both our reasoning and real experience throughout the years, have proved this to be false:

RISC-V does have employed a macro-op fusion ( /arxiv.org/abs/1607.02318) technique, where multiple instructions in a sequence can be merged into a single operation by high performance implementations for speedups. Modern compilers have widely employed this technique to emit instructions in macro-op fusion styles when suitable. One huge benefit of macro-op fusion, is that the semantics won’t change at all even if an implementation does not implement macro-op fusion, so compilers can act in an aggresive way. In Nervos CKB-VM we have employed macro-op fusions resulting in a very good performance bumps.
For cases where 256-bit integers are really needed, RISC-V have V extension ( /github.com/riscvarchive/riscv-v-spec) and P extention ( /github.com/riscv/riscv-p-spec) designed for this case. V extension provides support for big vector operations up to 1024 bit integers(I do have to mention that V extension support for 256-bit and bigger integers is only reserved for now, but all the encoding specs are there, you can already implement them). P extension provides SIMD support much like AVX operations. The choice between V and P will vary by cases, but the point is with either V or P extensions, you can have a RISC-V based smart contract implementing 256-bit cryptographic algorithms using V or P extensions, then translate them in your RISC-V VMs to highly optimized x64/aarch64/insert-other-CPUs-here instructions. We have experimented ( /github.com/xxuejie/rvv-prototype/tree/rvv-crypto) this path before, with the introduction of RISC-V V extension, a properly implemented RISC-V smart contract without precompiles, and a highly optimized interpreter VM, we can boost the performance of alt_bn128 operations( /eips.ethereum.org/EIPS/eip-197) to wihin 10x of EVM’s performance with precompile implementations. Note that this result was obtained with an interpreter VM using only x64’s basic instructions. Assuming a JIT or AOT RISC-V implementation, or the introduction of AVX instructions, we might have a real comparible performance to EVM using RISC-V VM without precompiles.
Many have a common myth that Nervos CKB-VM is a pure interpreter VM, hence it will be slow and cannot be compared to other high performant VMs. Nothing could be further from the truth. At layer 1, simplicity is a major goal of Nervos’ design. So when the highly optimized interpreter based VM provides enough performance for Nervos CKB, we are happy sticking to an interpreter based design. However, thoughout the years, we have implemented a pure Rust interpreter based VM, an assembly optimized interpreter VM(this is also what is deployed in layer 1 Nervos CKB), a native dynasm-based AOT VM ( /github.com/nervosnetwork/ckb-vm-aot), and an LLVM-based closed-to-native AOT VM. Our latest advancement in optimizing performance can be found in this post ( /xuejie.space/2022_09_08_a_journey_to_the_limit/), in which you can find that in certain cases we are getting much faster and closer-to-native performance compared to other VMs, including WASM VMs. As of today, the term Nervos CKB-VM really represents an umbrella of VMs, all implementing Nervos CKB’s RISC-V flavor(rv64imc_zba_zbb_zbc_zbs with macro-op fusions, we use flavors, not specs, because Nervos CKB-VM strictly contronts to RISC-V ISA, it’s just we have picked particular RISC-V extensions to implement). For difference scenarios, such as a layer 2 implementation, a much faster Nervos CKB-VM branch can definitely be employed for close-to-native performance, where no precompiles are needed.


I see discussions about EVM-on-RISCV here, I do want to mention that we have once taken the evmone ( /github.com/ethereum/evmone) implementation, ported it over to RISC-V, then used it to build an Ethereum-style layer-2 ( /github.com/godwokenrises/godwoken/tree/develop/gwos-evm) on Nervos CKB. I do want to mention that this is an earlier attempt in this space, and it definitely had its own set of quirks, but I do want to mention it as an example that at Nervos we do take this no-precompiles approves quite seriously. We have also built a similar path for WASM ( /xuejie.space/2020_03_03_introduction_to_ckb_script_programming_performant_wasm/), where compilcated WASM smart contracts can be translated to RISC-V as well.
Some have misbeliefs that cycle(think of it just like gas but in the CPU world everyone talks about cycles) calculations will be impossible for RISC-V. This is also false. We have implemented proper cycle calculations ( /github.com/nervosnetwork/rfcs/blob/master/rfcs/0014-vm-cycle-limits/0014-vm-cycle-limits.md) across the whole umbrella of Nervos CKB-VM implementations, including interpeter based VMs and AOT based VMs. It has never been a problem for us to keep cycle consumptions at every step, and error out when a particular smart contracts run out of cycles. In fact, even for a hardware based RISC-V core, we don’t believe cycle consumptions will be a problem. Performance counters( /www.intel.com/content/www/us/en/developer/articles/tool/performance-counter-monitor.html) have long existed in modern CPUs, even the cycles calculated for a particular blockchain are quite different from the internal cycles of a particular RISC-V CPU die, one can definitely implement such blockchain cycles as a CPU performance counter, and have a real CPU die emit those cycles matching blockchain consensus.

That is already a long post so I will stop here, but free free to reply or contact me if you are interested in more about Nervos CKB-VM. And I do want to repeat it one last time: at Nervos, we want a simple, secure and fast VM that is as thin as possible on modern CPUs, enabling us to build our smart contracts with no precompiles. To the best of our knowledge, RISC-V was the best solution 7 years ago, it is still the best solution we see in the foreseeable future. And if people call out that RISC-V is a hardware solution, so be it, we have implemented via pure software and it continues to serve our purposes perfectly, in this sense, we are happy with what we have, and will continue move forward with this path.

Author: xxuejie
Date: 2025-04-23T04:41:54.754Z

One more bullet on ZK:
First of all, this is just my personal opinion on zero knowledge, my colleagues might have different views on ZK.
There 2 different use cases for RISC-V related to zero knowledge:

The virtual machine / IR used to express a program that will be proved by ZK
The underlying platform where ZK verifiers will run upon

A simple but inaccurate analogy, would be that there is a VM on top of ZK algorithms(bullet 1), and there is a VM beneath ZK algorithms(bullet 2). They should be discussed separately.
With a stricly-no-precompile design, Nervos CKB-VM perfectly fits bullet 2 here: you can compile a ZK verifier code down to RISC-V code, and run the ZK verifier on Nervos CKB-VM. In this sense, Nervos CKB will be flexible to support any arbitrary ZK solutions. In other words, I consider Nervos CKB-VM to be a decent choice as a VM beneath ZK algorithms.
Bullet 1 will be a separate use case, I’m not so familiar with zero knowledge proof internals to weigh in if RISC-V will be a proper solution. I suspect if certain properties of ZK algorithms, might rule the choices for VMs on top of ZK algorithms.
I might be wrong but I have a feeling that @vbuterin might be talking about bullet 2 here, or a proper VM beneath ZK algorithms, so maybe we don’t have to discussion if RISC-V is fit for ZK-proving?

Author: gcolvin
Date: 2025-04-23T05:01:14.087Z

Why would this have any more chance of success than switching to Wasm did?

Author: grosu
Date: 2025-04-23T15:54:51.025Z

RISC-V may look appealing now, but like all languages, it will be out of fashion (and performance) before we know it.  All languages worth their salt evolve fast initially, then migrate into another, better language.
Why limit to one language and not have them all? See how Ethereum could look like, where you plug-and-play new languages in minutes: https://youtu.be/dP3QraNv6tI?si=H9Jdi9BwOJeZ6-bu&t=1406.  ZK can and will be universal soon, too, and then you will look back and wonder “Why did we pick RISC-V, after all?”.

Author: mrLSD
Date: 2025-04-23T18:40:27.645Z

levs57:

LLVM has a lot of compiler bugs. Solidity, in comparison, has excellent track record. This is largely thanks to much simpler pipeline.


You claim that LLVM is one big bug. You won’t believe it – the Rust compile backend is LLVM. By saying this, you’re essentially stating that all languages with an LLVM backend are full of bugs. That’s a very bold statement. Compared to LLVM, Solidity is a helpless ant facing an elephant, and on top of that, it is by design unsafe and aimed at finding the best way to shoot yourself in the head – and not miss.

Author: sorpaas
Date: 2025-04-23T19:48:06.924Z

Just as a thought experiment, I’m trying to see what it would look like if we added 64-bit mode to EVM. Here’s what I came up with: Add EIP: 64-bit mode EVM operations by sorpaas · Pull Request #9687 · ethereum/EIPs · GitHub

Author: mrLSD
Date: 2025-04-23T20:02:00.280Z

Thanks for the detailed and relevant comment.

Author: matt
Date: 2025-04-23T20:34:14.318Z

I find it very concerning that before our latest major rework of Ethereum’s VM, there are already proposals for replacing it. EOF was even touted as “better for zk proving” when pitched to ACD.



 vbuterin:

the gas schedule will reflect proving times, and so there will be economic pressure to stop using more expensive precompiles


The same will be said for EVM. We have to maintain backwards compatibility in this way, because we have a made a strong guarantee that contracts today will continue working. However, if proving is 100x more expensive and EVM is charged proportionally, it is a de facto deprecation.
Not that this is bad, and not that I don’t think we shouldn’t move to RISC-V – I simply want us to have more confidence in the technical projects we embark on. The userspace is more delicate than system-facing protocol features. There is substantial downstream tooling that is being disregarded.
What we do today should align with our long term goals. We all agree real time ZKPs of mainnet blocks is where we want to go. If we think there is a better path to that than EOF, we should immediately pull EOF from Osaka. There is still a lot work to get EOF ready from clients, compilers, dapps, devs, FV tooling, etc. Going forward with it, knowing we need some different for real time ZKP is a major strategic misstep.

Author: ericsson49
Date: 2025-04-23T21:50:51.240Z

matt:

What we do today should align with our long term goals. We all agree real time ZKPs of mainnet blocks is where we want to go.


I believe there is a confusion about the actual goal behind the proposal: e.g. whether it’s prover efficiency or faster direct execution of smart-contracts.

Author: peersky
Date: 2025-04-23T23:04:32.064Z

edubart:

One of the biggest advantages I see in adopting RISC-V is the immediate access to mature tooling and ecosystems.


+9000%



 vbuterin:

contracts written in Rust are actually quite ugly, and Solidity and Vyper are much more readable


In shiny theory - yes. In practice support and tooling matters more.
E.g: How do I catch abi.decode errors? This feature request is open for over 4(!) years: `try`/`catch` for `abi.decode()` or `abi.tryDecode` · Issue #10381 · ethereum/solidity · GitHub
Similar problems are facing not just Ethereum owned tooling, e.g. Hardhat fails to implement vscode pnpm import resolver for 1.5 years (!) by now: imports autocomplete does not work with pnpm · Issue #522 · NomicFoundation/hardhat-vscode · GitHub
I could go on and on. If you give me ugly syntax but with improvements on that side, I would prefer it.

Author: u59149403
Date: 2025-04-24T02:08:47.539Z

levs57:

Interestingly enough, under all these conditions it might turn out that the actual ISA that is optimal for this task is not RISC-V, but, rather, something similar to EOF-EVM.
…
Similarly, to minimize branching overhead, in our recent paper Morgana (eprint/2025/065) we show how to prove the code with static jumps (similar to EOF) with precompile-level performance.


Totally agree with these parts!

Author: u59149403
Date: 2025-04-24T02:22:07.578Z

vbuterin:

ZK-EVMs today are written as ZK RISC-V plus an EVM implementation in RISC-V. … So exposing RISC-V to the user directly cuts out the middleman.


As well as I understand existing implementations do this, because it allows to implement all needed checks and gas computations. “EVM implementation in RISC-V” checks that you don’t increase your balance (creating new ETH out of nothing), that gas is properly calculated, that you don’t overflow stack, etc. If we allow users to submit arbitrary RISC-V code directly, the users will simply increase their own balance.
So, as well as I understand, we cannot simply throw away middleman. It is there for a reason.
(Note: I know nothing about zk. Everything I wrote above is simply my amateur understanding.)

Author: MASDXI
Date: 2025-04-24T02:35:35.353Z

I think this post should be here
Glue and coprocessor architectures some RISC-V, FPGA for intensive task

Author: JJang
Date: 2025-04-24T05:53:40.679Z

Please don’t say that " ZK-EVMs today are written as ZK RISC-V". The RISC-V-based zk-VM approach is not the standard of zk-EVM. It is just one of many approaches that have been proposed to address the shortcomings of the traditional zk-EVM circuit.
The RISC-V-based zk-VMs indeed have mitigated some of the shortcomings of the traditional zk-EVMs, but they also introduce new shortcomings: excessive compiler dependency (interpreting EVM as RISC-V). The mathematics in ZKP is not very effective against compiler intervention. In other words, the more we rely on the compiler, the smaller the area of security that ZKP covers. And the integrity of the compiler’s work is completely based on trust.

Author: ericsson49
Date: 2025-04-24T06:12:12.064Z

JJang:

Please don’t say that " ZK-EVMs today are written as ZK RISC-V". The RISC-V-based zk-VM approach is not the standard of zk-EVM. It is just one of many approaches that have been proposed to address the shortcomings of the traditional zk-EVM circuit.


100% agree here. It looks like there is a (not so) implicit assumption that by going the RISC-V way, we are gaining both prover efficiency and faster smart-contract execution. If it were so then replacing the EVM with RISC-V would be the way to go.
However, it caters only the direct smart-contract execution needs (which is IMHO a very reasonable option here).
For the ZKP side, it at least raises multiple questions. Though I personally believe it’s a sub-optimal choice, especially wrt the 100x prover efficiency objective.

Author: ericsson49
Date: 2025-04-24T06:25:08.481Z

clarus:

Hi, can Yul be a good choice for a zk-friendly ISA?


Doesn’t look like really different compared to EVM+EOF. In practice, the Yul’s EVM flavor defines single u256 type and it assumes variables are stack allocated (e.g. Variable Declarations, Function Declarations).
Due to the EVM stack size limit, it might be difficult to overcome, since one wants a predictable behavior here. Though, an imaginary Yul’s CPU flavor might be more flexible.

Author: koute
Date: 2025-04-24T07:56:51.096Z

xxuejie:

Some have misbeliefs that cycle(think of it just like gas but in the CPU world everyone talks about cycles) calculations will be impossible for RISC-V. This is also false. We have implemented proper cycle calculations ( /github.com/nervosnetwork/rfcs/blob/master/rfcs/0014-vm-cycle-limits/0014-vm-cycle-limits.md) across the whole umbrella of Nervos CKB-VM implementations, including interpeter based VMs and AOT based VMs. It has never been a problem for us to keep cycle consumptions at every step, and error out when a particular smart contracts run out of cycles. In fact, even for a hardware based RISC-V core, we don’t believe cycle consumptions will be a problem. Performance counters( /www.intel.com/content/www/us/en/developer/articles/tool/performance-counter-monitor.html) have long existed in modern CPUs, even the cycles calculated for a particular blockchain are quite different from the internal cycles of a particular RISC-V CPU die, one can definitely implement such blockchain cycles as a CPU performance counter, and have a real CPU die emit those cycles matching blockchain consensus.


Unfortunately this is wildly incorrect. (: You’re right that it’s possible, but the details are wrong.

Implementing safe gas metering isn’t as simple as just assigning a best-case cycle value to each instruction and calling it a day. For example, looking at your list of costs for each instruction I can see that you’ve assigned a cost of 3 cycles to each memory load instruction. It’s possible to relatively easily write a program that will make this instruction takes orders of magnitudes more cycles by deliberately triggering cache misses (and a cache miss can be hundreds of CPU cycles, which is a little more than just 3!). Even if you severely limit the maximum amount of memory the program can access (so that its working set fits in L3 cache) its still possible to exploit various microarchitectural corner cases to make memory accesses significantly more expensive. You can use such simple gas cost model in the average case and it will work, but as soon as someone is motivated enough to take down your chain they can launch a denial of service attack exploiting this.
You cannot use hardware performance counters to do gas metering, simply because they are not portable across different hardware and they are non deterministic - even if you run exactly the same program on exactly the same hardware you will get a different cycle count!

Author: mratsim
Date: 2025-04-24T08:22:44.426Z

benaadams:

A difficulty of going as low level as a cpu architecture for the VM means it’s difficult to optimize back up
So at the moment the UInt256 operations in the Evm are usually implemented with Avx2 or Avx512 (equivalent on Arm); operating with 256bit or 512bit registers.
If that was decomposed to RISC-V 64bit or worse 32bit instructions; that then becomes a extremely hard problem to recognise the patterns and then recompose back to 256bit operations when the RISC-V code is then run on AMDx64 or ARM64 that most blockbuilders and validators will be running (as there is currently no high performance RISC-V hardware).
C/C++ compilers; which spend a long time compiling, have a hard time doing auto-vectorisation in this way; and they only auto-vectorize simple repetitive structures, they don’t recognise entire algorithms and convert them to a totally different form (which is normally the case with using specific CPU SIMD instructions effectively).
The risk here is that zk-proving may get better, but blockbuiling and execution will deteriorate significantly?


It’s true that deoptimizing and getting back the bigger picture is impossible but in the case of the 256-bit EVM arithmetic it does not matter.
They are not implemented with AVX2 or Neon, they are implemented with add-with-carry which also does not exist in RISC-V or WASM unfortunately.

Author: xxuejie
Date: 2025-04-24T08:26:02.633Z

You are definitely correct here, memory load can indeed take variable amount of time. A hit on L1 cache and a total cache miss will certainly have significant different loading time. That being said, I do believe we have to compromise somewhere, I personally doubt any gas metering design can fully capture all the memory loading characteristics of a modern CPU, and even if a gas metering design has been put together to model exactly one CPU, what will happen on a different CPU model? Eventually we will have to stick to an approximation of a CPU. The bottomline I see here is: such a model which is inspired from true CPUs ( actually the original cycle charges in CKB-VM, come exactly from a true CPU: see Section 3.3 of /sifive.cdn.prismic.io/sifive%2F449c97ba-41e6-4b70-b522-8ddde5d3a34e_sifive+u54+manual+v19.08p0p1.pdf ), is already miles better than current EVM’s gas metering. Maybe it makes more sense to build a MMU model so cycle charges are not always the best case as it is in CKB-VM now, but I would argue it might be the best thing we will have now.
I think there is some confusion, apologies for not making myself clear. But I’m not taking about existing performance counters in modern CPUs, they are indeed indeterministic in a way. I’m just picturing a future where we employ a real RISC-V chip as a blockchain VM, in this sense, we can build a deterministic performance counter following a particular blockchain consensus cycle metering model, so in real hardware we can do cycle metering for blockchains as well.

Author: mratsim
Date: 2025-04-24T08:36:16.941Z

One thing that’s missing in the discussion so far are calling conventions and register handling.
On a physical CPU, you have a limited amount of registers, hence when a function calls another functions, it needs to save registers and restore them.
The calling convention defines:

who saves what registers between the caller and the callee
what registers are used to pass parameters
what registers are used to pass results
how the stack space is used (concept of red zone)

People are very encouraged to write small functions, meaning if they are not inlined you waste a lot of proof time proving data movements.
An ISA optimized for ZK would actually optimize for reducing those data movements. They make sense in the physical world because local memory (in register) is 15x to 150x faster than remote memory (L1 cache needs 15 cycles, L2 cache needs 100 cycles, RAM needs ~1000 cycles), but it’s useless for ZK proof.
A function has usually between 4~6 inputs and output, so naively following physical CPU calling conventions requires 2x4~6 proofs of data movements per function.
See Latency Numbers Every Programmer Should Know · GitHub, Latency numbers every programmer should know · GitHub
A close but related concept is addressing mode. Some architectures only allow operations to work on registers and require LOAD/STORE before, but what if you could do replace:
LOAD RegA <-- [addr 0x0001]
LOAD RegB <-- [addr 0x0002]
ADD   RegC <-- RegA, RegB
STORE [addr 0x0003] <-- RegC

by
ADD [addr 0x0003] <-- [addr 0x0001], [addr 0x0002] 

We get 4x smaller trace and so 4x faster prover.

Author: benaadams
Date: 2025-04-24T09:00:59.404Z

mratsim:

They are not implemented with AVX2 or Neon, they are implemented with add-with-carry which also does not exist in RISC-V or WASM unfortunately.


However they can be implemented more efficiently with AVX512 or AVX512IFMA

Author: mratsim
Date: 2025-04-24T09:09:47.534Z

However they can be implemented more efficiently with AVX512 or AVX512IFMA

They can’t
If you have an implementation with AVX512  or AVX512IFMA feel free to send it over, I will benchmark it against my library, or you can run the benchmark yourself:


github.com/mratsim/constantine


README-PERFORMANCE.md

master

# Performance

High-performance is a sought out property.
Note that security and side-channel resistance takes priority over performance.

New applications of elliptic curve cryptography like zero-knowledge proofs or
proof-of-stake based blockchain protocols are bottlenecked by cryptography.

## In blockchain

Ethereum 2 clients spent or use to spend anywhere between 30% to 99% of their processing time verifying the signatures of block validators on R&D testnets
Assuming we want nodes to handle a thousand peers, if a cryptographic pairing takes 1ms, that represents 1s of cryptography per block to sign with a target
block frequency of 1 every 6 seconds.

## In zero-knowledge proofs

According to https://medium.com/loopring-protocol/zksnark-prover-optimizations-3e9a3e5578c0
a 16-core CPU can prove 20 transfers/second or 10 transactions/second.
The previous implementation was 15x slower and one of the key optimizations
was changing the elliptic curve cryptography backend.




  This file has been truncated. show original

Author: xxuejie
Date: 2025-04-24T09:12:01.414Z

And to further clarify myself(apologies for not making it clear earlier):

With RISC-V as a blockchain VM, we can only have an approximation of real memory load metrics on modern CPU. It will never be 100% accurate, but I personally would argue it is close enough, and it might be the best we can have in blockchains which require determinism. By limiting the memory of a VM(and we should do this even if not considering memory loads) and introducing a minimal but reasonable MMU model, I doubt if a denial of service attack can be performed by abusing memory loads.
My initial description, simply states the fact that implementing cycle metering has never been a problem for CKB-VM, our RISC-V VM(some have doubted this, stating for JIT/AOT VM this is not possible). I do admit that right now in CKB-VM we are slightly over optimistic by assuming memory loads would hit cache. We do keep monitor inconsistencies between true running time and charged cycles in CKB-VM smart contracts, and fix those inconsistencies periodically in hardforks when we can.
My discussion on hardware performance counters, does not refer to performance counters in modern x64 or aarch64 CPUs. I’m merely talking about taking an existing open source RISC-V CPU implementation, one can add a performance counter following CKB-VM’s(or other RISC-V blockchain VM’s) cycle metering design. The result will be a real RISC-V CPU that can also measure blockchain-style cycles independent from CPU’s own internal cycles. I’m merely stating that this is a possible thing to do.

Author: xxuejie
Date: 2025-04-24T09:21:18.240Z

For the record, while RISC-V does not have the adc instruction directly, there are ways to achieve similar effect:
Solution 1: by chaining add and sltu, one can get similar code chains to add w/ adc: /godbolt.org/z/v165TYKqb
Solution 2: in CKB-VM, we have abused the idea of macro-op fusion (please use archive to look for s://riscv.org/wp-content/uploads/2016/07/Tue1130celio-fusion-finalV2.pdf ) and introduce adc to CKB-VM: /github.com/nervosnetwork/rfcs/blob/master/rfcs/0033-ckb-vm-version-1/0033-ckb-vm-version-1.md#42-mop

Author: mratsim
Date: 2025-04-24T09:51:58.259Z

xxuejie:

Solution 1: by chaining add and sltu, one can get similar code chains to add w/ adc: /godbolt.org/z/v165TYKqb


For 256-bit, RISC-V has a 2x longer trace than ARMv7: Compiler Explorer
image2282×1265 390 KB
using Clang 13 because afterwards, Clang stopped generating code for >128-bit integer with the C ExtInt/BitInt extension.

Solution 2: in CKB-VM, we have abused the idea of macro-op fusion

This is something that can indeed be implemented in an interpreter to reduce VM traces, though the precompile approach is already ubiquitous and more performant for most bottlenecks (cryptography, u256, hashes).

Author: koute
Date: 2025-04-24T09:54:18.719Z

xxuejie:

That being said, I do believe we have to compromise somewhere […] My initial description, simply states the fact that implementing cycle metering has never been a problem for CKB-VM


Yes. But I disagree that it’s the best we can do. (: The way to do it is to assume the worst case, and then extend the model to lower those costs in cases when we know it’s safe. If you assume the best/average case then you’re just opening yourself up to denial of service attacks. The fact that you haven’t had any problems so far only means that no one bothered to attack your chain yet, not that your gas metering is safe.



 xxuejie:

I’m just picturing a future where we employ a real RISC-V chip as a blockchain VM, in this sense, we can build a deterministic performance counter following a particular blockchain consensus cycle metering model, so in real hardware we can do cycle metering for blockchains as well.


And what makes you think that on this hypothetical future RISC-V CPU the performance counters will be deterministic? (:
In fact, I can guarantee you that they will not be deterministic. The non-determinism of the performance counters is not an arbitrary decision that the hardware designers made; it’s a direct consequence of making a high performance, superscalar, pipelined, out-of-order CPU core with multi-level caches.
Yes, you can in theory add such performance counters to a CPU, but that means the CPU will have to be slow to keep the counters deterministic, so what’s the point of running on a slow CPU with deterministic hardware gas metering if we can get faster performance by doing the gas metering in software on a fast CPU?

Author: edubart
Date: 2025-04-24T12:38:08.581Z

mratsim:

For 256-bit, RISC-V has a 2x longer trace than ARMv7


This comparison is based on the rv32gc ISA. If you switch to rv64gc on the same page, the trace is actually smaller than ARMv7. I’m not certain why most RISC-V based zkVMs prefer rv32 over rv64, but larger registers naturally lead to fewer operations when handling 256-bit values. In the future, I hope to see more zkVMs based on RISC-V with 64-bit registers. RISC-V even has rv128 well defined which would lead to even fewer operations, although I’m not advocating for it given its limited support by the current compilers.

An ISA optimized for ZK would actually optimize for reducing those data movements.

I think this choice represents a fundamental trade-off between performance and tooling maturity.
Optimizing purely for speed would suggest creating a custom ISA tailored to ZK constraints, but this requires significant research, implementation, auditing and tooling development - ultimately creating higher barriers to adoption and taking more time to fully develop it.
Alternatively, using a stable, well-defined ISA like RISC-V leverages years of development and growing adoption. I believe this approach sacrifices some performance but significantly reduces implementation effort through existing tooling.
For a blockchain base layer intended to be open and widely adopted, I believe leveraging RISC-V’s openness and mature tooling ecosystem maximizes adoption. While custom ISAs may have their place in specific projects, for Ethereum specifically, I would prefer the path that offers greater developer freedom and broader adoption - which is the goal of open standard ISAs like RISC-V.

Author: zonu
Date: 2025-04-24T12:46:18.705Z

RISC-V is simple, yes — but not optimized for zero-knowledge. Custom ZK-friendly ISAs can outperform it significantly. There’s nothing inherently ZK-native about RISC-V other than being “not as bad as EVM.” Smaller opcode amount compared to WASM … but this also does not really matter as a’la’carte opcode selecting in proving schemes exist.

Author: kladkogex
Date: 2025-04-24T13:44:54.858Z

I wonder how is the problem of



 gcolvin:

Why would this have any more chance of success than switching to Wasm did?


This is exactly the point.
There are billions of dollars invested in all kinds of Solidity—from developer tools to security audits. The security of smart contracts depends on how widely the code is used.
Hundreds of thousands of people have learned Solidity.
Rust is a complex, general-purpose language, which makes security incredibly hard to achieve. There are simply too many moving parts.
Usually, once a community is formed, people stick to the language no matter what. It’s simply network effect.
The chances of success here are extremely low. People like Solidity, and there’s no reason for them to switch. Rust is not a magic bullet for anything.

Author: elistark
Date: 2025-04-24T14:01:39.608Z

Just a short message to say we - StarkWare - will provide our thoughts on this very important topic in a few weeks. We have a lot to say because the considerations regarding which VM to pick have been deeply and hotly discussed by our team internally a few years ago before embarking on the Cairo VM, which was where we landed.
FWIW, I was probably the most staunchly opposed to that approach at the start, and was in favor of providing proofs for some off-the-shelf VM, for the exact reasons you’d think: better to focus on proving something already built, than to “boil the ocean” and go with something entirely new.
By now, what was entirely new back then isn’t so anymore, and we’ve gained a lot of insights, which we’ll share. Briefly, we went for an architecture that optimizes for both safety (as a blockchain VM), STARK-proof efficiency and also STARK soundness. This has allowed us to already formally prove the soundness of the Cairo VM and expand on to a few mathematical syscalls.
What does this imply for Ethetreum? I don’t know yet, because I need to pick the brains of all the smarter folks in StarkWare that know way more than me about how to build a VM that’s safe, ergonomic, usable and efficient for blockchain and STARK-proving. But I assure you we have a lot to say. 
It would really help if @vbuterin or someone on leadership of EF specifies what exactly are the desiderata and considerations for picking a next VM for Ethereum. After all, Ethereum has the unique position to determine The Gold Standard for blockchain VMs, i.e., Ethereum can say “here’s what I want” and that may become the standard.
This is a bit similar to an earlier process we led on behalf of the EF, that of recommending STARK-friendly hash functions. Would be great to have a similar effort for STARK-friendly VM.

Author: xxuejie
Date: 2025-04-24T15:28:29.093Z

Yes. But I disagree that it’s the best we can do. (: The way to do it is to assume the worst case, and then extend the model to lower those costs in cases when we know it’s safe. If you assume the best/average case then you’re just opening yourself up to denial of service attacks. The fact that you haven’t had any problems so far only means that no one bothered to attack your chain yet, not that your gas metering is safe.

Please correct me if I’m wrong, but my general feeling is that we are approaching the same solution from 2 sides. One side could be starting from the optimistic side, and gradually incur cycles at places where metering is wrong. And yes it totally possible to start from the other side, where the worst case(assuming every memory load results in a cache miss) is used first, and only lower the cost when it is safe. I don’t think it tampers the main point: modelling VM like a real CPU, enables us to build a much more accurate cycle model.
And I totally agree that CKB might still be in a stage that no one bothers to attack it, we definitely are watching things, and be prepared to revise our cycle metering model when fit.

In fact, I can guarantee you that they will not be deterministic. The non-determinism of the performance counters is not an arbitrary decision that the hardware designers made; it’s a direct consequence of making a high performance, superscalar, pipelined, out-of-order CPU core with multi-level caches.


Yes, you can in theory add such performance counters to a CPU, but that means the CPU will have to be slow to keep the counters deterministic, so what’s the point of running on a slow CPU with deterministic hardware gas metering if we can get faster performance by doing the gas metering in software on a fast CPU?

I totally agree with you, for superscalar, pipelined out-of-order CPU core, performance counters will be indeterministic. However I think there is a middle ground between the following 2:

A slow in-order, simple RISC-V hardware core
A software VM running on a modern performant OOO CPU

It’s not one side or the other, there might well exist cases where a suitable solution can be found in between the two.
That being said, a real hardware as a blockchain VM, can be a quite niche case, I can drop this argument if you still think otherwise.

Author: xxuejie
Date: 2025-04-24T15:45:44.050Z

@edubart has helped with the first part(thank you!) so I will skip it.

This is something that can indeed be implemented in an interpreter to reduce VM traces, though the precompile approach is already ubiquitous and more performant for most bottlenecks (cryptography, u256, hashes).

If you know the exact algorithm people will use and only use, yes precompiles are the ideal solution. In fact, people in the RISC-V world do it all the time: all kinds of custom instructions are added to different RISC-V cores, just to solve a particular task.
That being said, all those macro-op fusions, as well as V & P extensions mentioned in earlier post, helps optimize program in a more general way: the optimizations are only introduced to the VM once(or much fewer times than we are adding new precompiles), and a series of cryptographic algorithms compiled down to RISC-V can all embrace those optimizations.
I do believe all the discussions on new precompiles we see here and in the EIP repo, already speak the fact that a more general approach might be yearned for than simply adding new precompiles. I still remember when /ethereum-magicians.org/t/eip-7212-precompiled-for-secp256r1-curve-support/14789 is being discussed…

Author: mratsim
Date: 2025-04-24T15:50:10.399Z

edubart:

Optimizing purely for speed would suggest creating a custom ISA tailored to ZK constraints, but this requires significant research, implementation, auditing and tooling development - ultimately creating higher barriers to adoption and taking more time to fully develop it.
Alternatively, using a stable, well-defined ISA like RISC-V leverages years of development and growing adoption. I believe this approach sacrifices some performance but significantly reduces implementation effort through existing tooling.


It does not sacrifice just “some performance” but it starts with a 4x~7x lag from the load-compute-store overhead. If (3) is the most important bottleneck to solve (from Vitalik’s original post), then
I’d argue that Risc-V is not good enough.



 vbuterin:


Stability of data availability sampling and history storage protocols
Desire to keep block production a competitive market
ZK-EVM proving capabilities



There are ISAs that have been developed for a long-time, some that are used in production like Cairo or Valida that can be targeted from C, Rust, Nim and WASM today (and can easily add Zig for example tomorrow and C++ needs some work on the stdlib). See Valida spec here (Technical Design: VM | Lita Docs, disclaimer I’m working on Valida).
On the tooling side, Valida at the very least is using LLVM toolchains, can reuse usual tooling like gdb/lldb for debugging, and even perf for optimization.



 edubart:

I’m not certain why most RISC-V based zkVMs prefer rv32 over rv64


It was simpler. 2 years ago, zkVMs were unproven, it was unsure if they were feasible vs zkEVMs with each EVM opcodes being a circuit: zkevm-circuits/zkevm-circuits/src at main · privacy-scaling-explorations/zkevm-circuits · GitHub

Author: wjmelements
Date: 2025-04-24T16:49:06.721Z

ZK-EVM provers today already work by proving over implementations of the EVM compiled down to RISC-V

Is RISC-V really the best architecture for proofs or can we make a better one? RISC-V wasn’t designed for ZK. If there is a better architecture in 2 years, how much of our RISC-V development would transfer to the next architecture?

then the gas schedule will reflect proving times

The gas itself has to be calculated during runtime to solve the halting problem. Gas accounting is a non-negligible part of both execution and proof. Many current operations have variable gas costs. It is possible that computing these variable costs will increase proof complexity, increasing gas complexity, etc. This is a chicken-and-egg problem because we have to know to charge gas in order to know how much gas to charge.
Instead, perhaps the EVM/EOF/EWASM can all be JIT’d into (RISC-V) using separate gas schedules. (RISC-V) would be the base execution layer and everything would transpile into it, injecting gas calculations at each step. Every hard fork would need their own transpilers, but these should never change.

Author: u59149403
Date: 2025-04-24T18:54:42.341Z

Please, don’t.

RISC-V is not simple! pdf spec for RISC-V (latest ratified spec, unprivileged instructions) is 670 pages long!!! ( unpriv-isa-asciidoc.pdf - Google Drive ). For comparision: current wasm spec (2.0) is 226 pages long, i. e. 3 times smaller ( https://webassembly.github.io/spec/core/_download/WebAssembly.pdf ). Also for comparision: Shanghai yellow paper is 42 pages ( https://ethereum.github.io/yellowpaper/paper.pdf ), i. e. RISC-V is a lot more complex than Shanghai EVM
RISC-V (similarly to all usual CPU ISAs) allows reading program code and even self-modifying code. Code and data live in the same address space. And code is not checked before execution. All these are exactly things we avoided in EOF. So, RISC-V is simply step back. EOF (and wasm) doesn’t allow code introspection, separates code and data and requires upfront code checking. In short, EOF and wasm are a lot better for execution layer than RISC-V. PolkaVM author wrote above ( Long-term L1 execution layer proposal: replace the EVM with RISC-V - #32 by koute ) that they didn’t take RISC-V as-is, instead they made RISC-V more EOF-like by removing introspection and other similar things
Wasm is deterministic. This is critical thing for us. Wasm 2.0 spec says: “…execution – is
deterministic. WebAssembly has only very few exceptions to this, which are noted explicitly in this specification”. As well as I understand there is no similar level of dedication to determinism in RISC-V
Wasm has very precise spec. For example, look here: Types — WebAssembly 2.0 (Draft 2025-01-28) . Moreover, it was decided that future versions of wasm will be written using spectec: SpecTec has been adopted - WebAssembly . In short, this is machine readable description of wasm, which is used to generate all other artifacts: human-readable spec, reference interpreter and definitions for Coq/Rocq! (Note: “reference interpreter” part is not finished yet.) Here is an analogy: this is as if we had single machine readable text, which is used to generate both yellow paper and python execution layer spec!!!  From that news article: “it [SpecTec] takes Wasm to a new level of rigor and assurance that is unprecedented when it comes to language standards… One feature that sets Wasm apart from other mainstream programming technologies is that it comes with a complete formalization… it enabled the soundness of the language — i.e., the fact that it has no undefined behavior and no runtime type errors can occur — to be machine-verified before the first version of the standard was published”. As well as I understand, RISC-V has nothing like this.
Wasm is more high-level. It has concept of functions, similarly to EOF. RISC-V doesn’t

Author: ericsson49
Date: 2025-04-25T10:34:32.298Z

wjmelements:

Is RISC-V really the best architecture for proofs or can we make a better one? RISC-V wasn’t designed for ZK. If there is a better architecture in 2 years, how much of our RISC-V development would transfer to the next architecture?


I believe the main problem not the ISA per se, but code generation/optimization performed using CPU cost model.
Problematic ISA aspects can be (at least, partially) alleviated via binary recompilation. But re-optimization of code with ZK cost profile will be more complicated, e.g. static analysis of code RISC-V will be more difficult (due to aliasing).
I’d say that EVM+EOF is much better in that respect, since it’s higher level, easier to analyze statically (EOF is designed to be so) and does not include low-level CPU-oriented optimizations.

Author: koute
Date: 2025-04-25T10:49:33.456Z

u59149403:

RISC-V is not simple! pdf spec for RISC-V (latest ratified spec, unprivileged instructions) is 670 pages long!!!. For comparision: current wasm spec (2.0) is 226 pages long, i. e. 3 times smaller. Also for comparision: Shanghai yellow paper is 42 pages, i. e. RISC-V is a lot more complex than Shanghai EVM


This is misleading. The RISC-V spec PDF has so many pages because it includes all of the ratified optional extensions up until this point. The baseline RISC-V instruction set is super simple. It’s so simple that I implemented a RISC-V interpreter in a single day, and a recompiler (which recompiles RISC-V into native code and runs it) in two days for my initial PolkaVM prototype. (Try doing that with WASM, especially since for WASM you also need to write a register allocator.) And the great thing about RISC-V is that you can chose which exact extensions you want to use.
WASM definitely doesn’t win against RISC-V when it comes to complexity. 172 instructions in the 1.0 WASM spec and 220 instructions in the 2.0 spec is not simple (up to total of 541 last time I counted if we include all proposed WASM extensions), especially compared to RISC-V’s 47 instructions in the base spec. And, again, with RISC-V you have the choice - you can only use the base spec! With WASM this is not supported, and compilers are already slowly sunsetting support for WASM 1.0 (e.g. the signext extension is now enabled by default; in Polkadot we have to forcibly disable it when building our WASM runtimes, but eventually that will stop being supported and we’ll be screwed). With RISC-V you can use the baseline target with only 47 instructions forever, and decide yourself when/if you want to opt into any extensions; with WASM eventually you’ll be forced to either fork all of the compilers and toolchains, or get on the complexity treadmill and implement all of the instructions that the newest WASM spec implements.



 u59149403:

RISC-V (similarly to all usual CPU ISAs) allows reading program code and even self-modifying code. Code and data live in the same address space. And code is not checked before execution.


This is an entirely orthogonal issue. There’s nothing in RISC-V that prevents you from making the program code unreadable, or making self-modifying code impossible, or splitting the address space, or being able to check the code before execution. It’s just an issue of how much effort you want to invest. It’s possible to decide what you want to use from vanilla RISC-V and what you want to change; we went all the way with PolkaVM and got rid of almost every downside of RISC-V, but you can pick and choose:

Do you use ELF as a container, or do you use a custom container? (We went with a WASM-like custom container.)
Do you use RISC-V’s instruction encoding as-is, or do you use a custom encoding? (We went with a custom encoding that’s more compact and allows full width immediates while not being slower to decode.)
Do you make a von Neuman machine (data and code live in the same address space) or do you make a Harvard machine (data and code live in separate address spaces)? (We went with a Harvard machine.)
Do you only use vanilla RISC-V instructions (regardless of how you chose to encode them), or do you add custom extensions? (We have some custom extensions - for example, we do macro op fusion offline which allows us to both get better performance and make VM implementations simpler).

So strictly speaking I agree with you, out of box WASM is better than RISC-V for the reasons you’ve mentioned, but you can fix those problems by just not naively taking RISC-V as-is as it’s used for native hardware and tweak certain aspects of it. It depends on how much of a perfectionist you are, and whether you want to maximize “keep it as close to RISC-V as possible”, or you want to maximize “be as fast as possible and as simple as possible while still being able to use vanilla RISC-V toolchains”, or something in-between.
For Polkadot we were already using WASM, so we wanted to migrate to something that’s strictly superior on all fronts, which is why we went all the way and tried to change/improve on almost every aspect of RISC-V that can be changed to make it better for our use case.



 u59149403:

Wasm is deterministic. This is critical thing for us. Wasm 2.0 spec says: “…execution – is
deterministic. WebAssembly has only very few exceptions to this, which are noted explicitly in this specification”. As well as I understand there is no similar level of dedication to determinism in RISC-V


RISC-V is also 100% deterministic, and it’s actually easier to make RISC-V deterministic than WASM. For example, with RISC-V you can just not support floating point (and get the compilers to emit softfloats instead, so programs can still use them); with WASM you don’t have that choice, and you have to deal with issues like NaN canonicalization. Or, as another example, it’s a lot easier to make RISC-V’s stack deterministic, because unlike with WASM on RISC-V the stack is not a special thing and just lives in normal address space.



 u59149403:

Wasm is more high-level. It has concept of functions, similarly to EOF. RISC-V doesn’t


Note that this is a downside if you want to write a high performance recompiler that achieves near native performance. The ideal you’d want to achieve for performance is “one bytecode instruction == one native instruction”, as this makes writing a recompiler very simple (because you don’t need any complex logic, no register allocation, no op fusion, no interprocedural analysis, etc.) and is the reason why PolkaVM can recompile programs into native code in O(n) time and do it faster than you can calculate a hash and still have the resulting code be near-native speed, while wasmtime’s recompilation is not O(n), needs a recompiler whose complexity is many orders of magnitude higher, and needs hundreds times more resources to generate similarly fast code as PolkaVM.

Author: u59149403
Date: 2025-04-25T13:12:51.198Z

koute:

out of box WASM is better than RISC-V for the reasons you’ve mentioned, but you can fix those problems by just not naively taking RISC-V as-is as it’s used for native hardware and tweak certain aspects of it. It depends on how much of a perfectionist you are


Thank you for your post! Now I see

Author: shemnon
Date: 2025-04-25T16:07:51.085Z

I don’t think there has been much consideration of how a transition to RISC-V would look.  Here’s my brief take that shows how EOF is a valuable part of that transition:



HackMD



EOF: Ethereum’s Gateway to RISC-V Execution - HackMD
# EOF: Ethereum’s Gateway to RISC-V Execution *Danno Ferrin, 25 April 2025*  Architectural transitio

Author: chfast
Date: 2025-04-26T20:11:36.297Z

vbuterin:

Some numbers (see here) suggest that in limited cases, this could give efficiency gains over 100x:


From the linked article:

The code to reproduce these experiments is available at GitHub - succinctlabs/overhead: Measuring revm and wasmi overhead for SP1 programs..

But this repo doesn’t exist or is private. So I’m guessing it’s only me trying to reproduce these numbers.
I’m assuming the “Fibonacci-100k (u128)” benchmark computes the 100k’th element of the Fibonacci sequence with 128-bit precision. By the way, this number has almost 70k bits.
So I’ve written a simple EVM implementation of fibonacci:
5f195f355f60015b90810183830192600757035f5260205ff3

and EOF variant (just replaced JUMPDEST/JUMPI with RJUMPI):
ef00010100040200010018ff000000008000065f195f355f600190810183830192e1fff6035f5260205ff3

Using evmone and “native” CPU (x86) execution takes 5.0M cycles (legacy EVM) and 3.8M cycles (EOF).
I don’t know how to execute this in SP1 yet, but to get any upper bound estimate I’ve compiled evmone to riscv32 and counted host CPU cycles of the execution in the qemu emulator: 127M cycles (legacy EVM) and 114M (EOF).
This is still one order of magnitude lower than the number in the paper (1002M cycles).

Author: u59149403
Date: 2025-04-27T08:56:14.161Z

shemnon:

Here’s my brief take


You wrote:


The current EVM bytecode is a mess: …allows dynamic code modification


What do you mean? There is no self-modifying code. It seems you mean that initcode can generate contract code on-the-fly. I. e. “generation” should be, not “modification”

Author: chfast
Date: 2025-04-27T17:09:32.607Z

The source code of the benchmark has been published.
It uses the following solidity code for the “Fibonacci-100k (u128)” benchmark:
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.2 <0.9.0;

contract MyFib {
    function fib(uint128 n) external pure returns (uint128 b) {
        if (n == 0) {
            return 0;
        }
        uint128 a = 1;
        b = 1;
        for (uint128 i = 2; i < n; i++) {
            uint128 c = (a + b) % 170141183460469231731687303715884105727;
            a = b;
            b = c;
        }
        return b;
    }
}

Using this as the evaluation of the EVM interpreter performance comparing with Rust equivalent has number of issues:

It looks the solidity program has been compiled with optimizations disabled. I’m getting the same number of bytes (671) of the runtime bytecode compiling locally as in the bytecode used in the benchmark. The optimized version is 138 bytes shorter.
Usage of uint128 instead of uint256 makes it unnecessarily slower for no reason.
The checked arithmetic is used unnecessarily. Switching to unchecked variant removes another 181 bytes from the bytecode comparing with the optimized version.
The expression like (a + b) % 170141183460469231731687303715884105727 can be implemented with a single ADDMOD instruction.

Author: prasincs
Date: 2025-04-28T01:26:41.320Z

While this is an intriguing proposal, my concerns revolve around RISC-V (also repeated by others)


It’s a general-purpose ISA with a lot of gotchas
I’ll admit that picking a general-purpose ISA comes with numerous toolchain benefits, such as being able to use LLVM with a custom backend. However, is it worth it to discard our existing toolchains? There is already work being done on compiling and transpiling the EVM to RISC-V native code, which may help us achieve the goal of faster ZK proofs. Even PolkaVM doesn’t take the ELF binary as-is. There’s the “world computer” aspect of being able to run anything Turing-complete, but the need to move funds around makes it a much tougher attack surface to audit compared to all the knowledge we’ve gained around EVM over the past ~10 years.


It is not designed for ZK proving
Folks have noted that RISC-V wasn’t designed with ZK provers in mind. It works very well compared to EVM, but it needs to be compared against approaches taken by Valida and CairoVM, which were explicitly designed for ZK, as others have noted. This means that we are likely still examining the local maxima of ZK-focused design with RISC-V.


EOF vs incremental steps
I’m not an expert on EOF but here’s my understanding. EOF already addresses many ZK proving inefficiencies by introducing static jumps, code/data separation, and function-level abstractions while maintaining ecosystem compatibility. It represents an incremental improvement already underway for the Osaka hard fork, rather than a revolutionary approach, potentially delivering significant efficiency gains with less disruption to existing toolchains and developer workflows. Are there other incremental steps also worth considering? For instance, would adding Poseidon hash function as a precompile speed up to a “good enough” point?


Time to Implement + advances in other VM technologies
Given the complexity of the project, there is a risk that, with advances in optimized ZKVMs and hardware capabilities, migrating to RISC-V could be too late, even if we start now.

Author: prasincs
Date: 2025-04-28T01:30:09.424Z

(Apparently I can edit posts now), so fixed the original post.
Here’s a corollary to the first point around RISC-V complexity
I think this has been brought up too but “which” parts of RISC-V specs to take is also worth considering. I’ve been tracking hardware for the finalized vector instruction and not everyone implements it correctly. We could run into similar situation with client code too.

Author: rodiazet
Date: 2025-04-28T09:03:53.332Z

I generally agree. I’m not sure if “it works well compared to EVM” in the context of @chfast analysis above. Regarding poseidon hash we prepared EVMMAX proposal which is still not finished and it depends on EOF. We used evmone implementation to run some benchmarks on top of EVMMAX and here are some results evmmax: Poseidon hash amd Falcon primitive `nttfw` implementation in EVMMAX [DO NOT MERGE] by rodiazet · Pull Request #1126 · ethereum/evmone · GitHub
You can use this extension to implement cryptographic primitives w/o waiting for a precompile. As we know i takes years to add them.

Author: SirSpudlington
Date: 2025-04-28T20:23:48.339Z

I think the important takeaway here is this quote:



 vbuterin:

In the long term


This would be years away at best, especially with EOF just being implemented. It could be possible that risc-v is superceded by a superior ISA with better proving capabilties, or that STARK/SNARK proving EVM code becomes more computationally viable, we cannot predict future technology especially in this field where it changes every 30 seconds.
We’d also probably migrate to ZK-friendly hashes like Poseidon for the state trie (as Vitalik first said) before we even consider the feasability of starting to migrate to risc-v.

Author: gcolvin
Date: 2025-04-29T03:47:26.238Z

ericsson49:

I’d say that EVM+EOF is much better in that respect, since it’s higher level, easier to analyze statically (EOF is designed to be so) and does not include low-level CPU-oriented optimizations.


The lack of low-level optimizations is a defect from my point of view.  These optimizations cannot be done at runtime because they don’t all run in linear time, they have to be done at init time. EIP-2315 retained a level of static analysis close to EOF while also supporting linear time code generation.

Author: SirSpudlington
Date: 2025-04-29T06:40:33.107Z

magicians:

Longterm doesn’t mean kicking the can down the road like lazy governments do


Absolutely, we want to keep going down the ZK path but the switch to risc-v (should) come later, so we can focus on statelessness, proving, etc.

Author: PKirill
Date: 2025-04-29T10:29:04.152Z

Why to take RISC-V?
Isn’t Webassembly better for this purpose?
It is designed better and more secure

Author: gcolvin
Date: 2025-05-04T22:28:45.495Z

I take it that you do not use RISC-V as you front end?  That is, you can still target other back ends if you want to?

Author: kladkogex
Date: 2025-05-05T14:27:03.869Z

chfast:

This is still one order of magnitude lower than the number in the paper (1002M cycles).



The numbers are totally off.  I have over 1000 TPS running EVM on my laptop.
Virtually any interpreter can be made fast with JIT compilation — just look at Google Chrome, Node.js, or the JVM.
The EVM itself is not the bottleneck. It is pointless to make it faster, it is already fast.  Whats the point of fast EVM if consensus is miserable and runs at 15 TPS?  Not mentioned consensus being overloaded with rollup blobs that bring zero money to the network.
The real performance limit lies in the historical state database and network bandwidth. Reads and writes to the state DB take up the most time. The consensus is archaic and not competitive with other blockchains. Thats where the efforts should go, not into breaking what works well.
I understand that the ZK community is advocating for a RISC-based architecture. But why not simply compile to RISC, as they already do? If the current compiler isn’t efficient enough, improving the compiler seems like a more focused path forward.
Interestingly, switching to RISC may not help ZK at all. If gas limits are raised by 100x as Dankrad suggested, ZK systems could struggle to keep up — potentially to the point where they become unusable. So this seems like a case where the proposed change doesn’t address user needs, could degrade overall performance, and would require significant development resources that the Ethereum Foundation likely can’t afford.

Author: gcolvin
Date: 2025-05-05T15:51:09.588Z

Faster VMs mainly matter for EVM-compatible VMs that are not running in a ZK, or a gas-constrained environment, or with a better state database, or other applicaitons.  That includes code that traverses the entire history of the chain.  And even onchain it helps contracts that are not bound by state access, but by heavy crypto computation.

Author: gcolvin
Date: 2025-05-05T16:10:47.854Z

This is (again) the original paper on zkVM versus zkEVM performance.
https://arxiv.org/pdf/2504.14809
The way it works, more or less, is that an EVM interpreter is implemented in Rust, the Rust compiled to RISC-V, and that is what is run, slowly, by the zkVM.   The comparison is to contracts written directly in Rust and compiled to RISC-V, which run much faster.
What is not tested is compiling the EVM code to RISC-V code and running that.  Even simple transpilation should run faster than an interpreter, and optimizing compilers should be able to get close enough to Rust as not to matter.
So whatever other reasons there might be for changing to a RISC-V front end, performance has not been demonstrated to be one of them.

Author: ericsson49
Date: 2025-05-06T10:09:46.103Z

gcolvin:

The lack of low-level optimizations is a defect from my point of view. These optimizations cannot be done at runtime because they don’t all run in linear time, they have to be done at init time.


True, but given 50x prover efficiency as a goal, CPU-oriented low-level optimizations will be a big obstacle. Undoing these low-level stuff and re-optimizing for ZKP will be harder due to loss of higher level information (and loss of precision of static analysis as a consequence).
I’s say that 50x prover efficiency is a tough goal, so I believe building a pipeline which caters ZKP needs is necessary, at least, in near future.

Author: gcolvin
Date: 2025-05-06T15:50:29.574Z

Then I would think the RISC-V output of a Rust compiler would be a poor candidate.
(Any links to this 50X?  And 50X what?  The big differences between the EVM and purte Rust reported here had everything to do with interpreting vs. compiling and nothing to do with the EVM.)

Author: ericsson49
Date: 2025-05-06T18:00:56.291Z

gcolvin:

Any links to this 50X? And 50X what?


Vitalik wrote in the very first post:



 vbuterin:

If we want to 100x total prover efficiency, there’s no getting around the fact that we need to at least 50x EVM prover efficiency.


I believe the 100x/50x goal is to make block proving “real-time”, e.g. seconds instead of minutes, see https://ethproofs.org/

Author: ericsson49
Date: 2025-05-06T18:59:04.499Z

gcolvin:

The big differences between the EVM and purte Rust reported here had everything to do with interpreting vs. compiling and nothing to do with the EVM.


As far as I can understand the first post, the idea is that RISC-V smart-contracts can be executed much faster than EVM smart-contracts executed by EVM interpreter, compiled to RISC-V code. Therefore, we can hope for much faster ZK proving of such smart-contracts too, when using RISC-V-based zkVM.
In practice, as argued above (e.g. the post), the actual workload involves cryptography and storage access (which is not present in the Fibonacci example). So, relying on RISC-V smart-contracts is not enough (to reach 50x faster proving time). Moreover, it can become a serious obstacle.

Author: gcolvin
Date: 2025-05-06T19:00:25.733Z

ericsson49:




 gcolvin:

Any links to this 50X? And 50X what?


Vitalik wrote in the very first post:



 vbuterin:

If we want to 100x total prover efficiency, there’s no getting around the fact that we need to at least 50x EVM prover efficiency.


I believe the 100x/50x goal is to make block proving “real-time”, e.g. seconds instead of minutes, see https://ethproofs.org/


OK.  I thought the claim was that RISC-V has already made those gains, and that was a reason to replace the EVM with it.

Author: gcolvin
Date: 2025-05-06T19:07:17.377Z

ericsson49:

As far as I can understand the first post, the idea is that RISC-V smart-contracts can be executed much faster than EVM smart-contracts executed by EVM interpreter, compiled to RISC-V code. Therefore, we can hope for much faster ZK proving of such smart-contracts too, when using RISC-V-based zkVM.


Right.  And I’m saying that of course running an interpreter is going to be slower than compiling anything to RISC-V.  So we should compile EVM code to RISC-V.  (Or whatever language is native to the proof system.)

Author: koute
Date: 2025-05-08T14:21:19.631Z

gcolvin:

I take it that you do not use RISC-V as you front end? That is, you can still target other back ends if you want to?


Not sure if I understand the question (what do you mean by “target other back ends”?), but in general our pipeline looks like this:

We use a normal, standard compiler (like rustc, clang, etc.) to build a normal, standard RISC-V ELF file. (Alternatively, we also have a Solidity compiler which uses LLVM to compile bog standard Solidity programs into a RISC-V ELF file).
We take that ELF file and relink it into our custom RISC-V-like bytecode and custom container. This happens offline (on the dev’s machine), and is the part where we apply extra optimizations to the program (like e.g. instruction fusion), simplify the semantics, and in general make it appropriate for on-chain execution.
Then the on-chain VM (which can stay simple because we do most of the work offline when we translate the raw RISC-V into our own bytecode) recompiles the bytecode into the native code and runs it.

Technically our bytecode doesn’t have to be recompiled into the native code - it could also be interpreted, or it could be even be executed to generate a ZK proof, although we haven’t implemented a ZK backend yet. We might someday, and it would be a cool project (if someone wanted to work on a ZK backend for PolkaVM I would gladly merge that PR) but we don’t really have any immediate use for it, since we can get much better and much cheaper scaling without ZK through other means. Compute-wise last time I benchmarked it I can execute the same computation from scratch something like ~20 times in the same time it’d take to verify a single ZK proof of it, nevermind needing to actually generate the proof (which is orders of magnitude more expensive), so there’s literally no point for us go the ZK route.
Technically what Ethereum could do (but won’t due to political reasons) is:

Take our PolkaVM and use it for L1 execution (it’s a general purpose VM and it’s not really specific to any particular chain). This automatically gets you wide toolchain support (you can use almost any language, not just Solidity) and blazing fast near-native execution speed for free, and we have 30+ independent implementations of the VM itself in-progress to make sure the spec is implementable independently.
Write a ZK backend for it and do whatever ZK stuff you need to do. (It should be as fast or faster than current RISC-V ZK VMs.)
Scale down on the ZK use for those parts of the system which now maybe don’t need to use ZK due to better efficiency of the base VM.

Author: gcolvin
Date: 2025-05-08T15:57:36.799Z

OK, I think I understand now, thanks.  I think there would technical issues, not just political ones here, but I won’t try to dig into those now.  The politics is so bad that after ten years we can’t even add subroutine instructions to the EVM, so I don’t expect to see the EVM change in my lifetime.

Author: ericsson49
Date: 2025-05-09T07:22:57.395Z

gcolvin:

So we should compile EVM code to RISC-V. (Or whatever language is native to the proof system.)


Compilation is clearly beneficial for direct (CPU/GPU) execution.
For ZKP, it’s more tricky. SNARKs do not prove the program execution directly, but rather prove knowledge of the program execution trace (on some input).
Let’s assume f(x) is our program, x is some input to the program, w is the program execution trace (in some form). There is also some circuit C(x, w, y) to check the trace validity, i.e. C(x, w, f(x)) should output true for valid traces.
A SNARK prover typically proves satisfiability of such circuit (and that it knows the w witness), which is existentially quantified (due to the additional parameter w) and (in case of proving program execution) uniform (inputs/traces of different lengths are served by the same circuit).
So, it’s drastically different from the direct execution. The difference is critical for performance, as you can transform evaluation (sub)problems to circuit satisfiability (sub)problems, which might be much cheaper to prove (e.g. for proving 1 / a operation one has to provide some b and check that a * b == 1, while calculating the inverse directly will require proving much more intermediate steps).
Moreover, since the execution trace is available to prover it can select a cheaper implementation option, depending on the concrete trace content. E.g. a value can be u256 in general, but a particular occurrence can fit byte, so its properties/operations can be proved using less steps than the full u256 value.
So, the ability to inspect the trace can largely compensate absence of compilation. Static analyses/optimizations can still benefit ZKP (a call site can be recognized statically as monomorphic, so one can skip proving branch decisions). However, such optimizations are not that trivial to implement in practice:

one need to withstand “JIT bombs” attacks
one should prove somehow that such optimizations preserve semantics

With that said, I generally agree that compilation is the right direction. However, in the case of ZK proving of EVM code execution it’s not really clear whether compilation worth implementing given the associated costs. The EVM+EOF would definitely help here (e.g. static analysis, separate validation).

Author: gcolvin
Date: 2025-05-09T15:22:39.171Z

Compilation is of course useful in it’s own right.  What I’m trying do here though is avoid the apparently high overheads of proving a program on an EVM interpreter written in RISC-V rather than proving a program written in RISV-V.  Or even better, directly prove EVM programs.

Author: ericsson49
Date: 2025-05-10T10:35:42.250Z

gcolvin:

Or even better, directly prove EVM programs.


This is the best option IMO.
It’s strange that Vitalik didn’t even consider it.