In this blog post, we show how we state the functional correctness of the implementation of the STATIC_CALL instruction in Revm, an implementation of the Ethereum's virtual machine EVM in Rust. This involves running rocq-of-rust to translate the Rust code to the theorem prover Rocq, and then making a proof by refinements until obtaining a specification of the code written in purely functional style, optimized for formal verification. This also proves the code cannot panic, as our specifications are free of panics.
25 posts tagged with "Rust"
View All Tags🦀 Functional specification of the ADD instruction of the EVM
In this blog post, we present how we specify and verify the implementation of the ADD instruction of the EVM virtual machine in Rust.
We give a functional specification, meaning that we show the implementation to be equivalent to an idealized version written in the Rocq language. As the Rust code for this instruction involves rather advanced features of Rust, the same techniques could apply to verify a large set of Rust programs.
🦀 Beginning of translation of OpenVM to Rocq
Here, we present our beginning work of translating part of the OpenVM code to the proof assistant Rocq. The aim is to experiment around the formal verification of the zero-knowledge circuits of this zkVM based on the Plonky3 library. One of the aims of the zkVMs is to increase the scalability of the blockchains by packing many transactions in a single zk proof.
🦀 Typing and naming of Rust code in Rocq (2/3)
In this blog post we present how represent a proof of execution for translated 🦀 Rust programs in Rocq/Coq, to show that it is possible to type the values and resolve the names. Resolving the names amounts to finding the trait instances and an ordering for the function definitions.
We call these proofs of execution "links". They do not contain memory allocation strategies, which can be defined later in a second step called "simulation". From these links we have all the information to extract a typed execution that is equivalent to the translated code from coq-of-rust. The core of the work presented in this article is in the file CoqOfRust/links/M.v on GitHub.
🦀 Typing and naming of Rust code in Rocq (1/3)
In this article we show how we re-build the type and naming information of 🦀 Rust code in Rocq/Coq, the formal verification system we use. A challenge is to be able to represent arbitrary Rust programs, including the standard library of Rust and the whole of Revm, a virtual machine to run EVM programs.
🦀 Verification of one instruction of the Move's type-checker
This is the last article of a series of blog post presenting our formal verification effort in Rocq/Coq to ensure the correctness of the type-checker of the Move language for Sui.
Here we show how the formal proof works to check that the type-checker is correct on a particular instruction, for any possible initial states. The general idea is to symbolically execute the code step by step on the type-checker side, accumulating properties about the stack assuming the type-checker succeeds, and then to show that the interpreter will produce a stack of the expected type as a result.
🦀 Example of verification for the Move's checker of Sui
We are continuing our formal verification work for the implementation of the type-checker of the Move language in the 💧 Sui blockchain. We verify a manual translation in the proof system 🐓 Coq of the 🦀 Rust code of the Move checker as available on GitHub.
In this blog post, we present in detail the verification of a particular function AbstractStack::pop_eq_n that manipulates 📚 stacks of types to show that it is equivalent to its naive implementation.
All the code presented here is on our GitHub at github.com/formal-land/coq-of-rust 🧑🏫.
🦀 Formal verification of the type checker of Sui – part 3
In the previous blog post, we have seen how we represent side-effects from the Rust code of the Sui's Move type-checker of bytecode in Coq. This translation represents about 3,200 lines of Coq code excluding comments. We need to trust that this translation is faithful to the original Rust code, as we generate it by hand or with GitHub Copilot.
In this blog post, we present how we test this translation to ensure it is correct by running the type-checker on each opcode of the Move bytecode and comparing the results with the Rust code, testing the success and error cases.
🦀 Formal verification of the type checker of Sui – part 2
We are working on formally verifying the 🦀 Rust implementation of the Move type-checker for bytecode in the proof system 🐓 Coq. You can find the code of this type-checker in the crate move-bytecode-verifier.
This requires translating all the Rust code in idiomatic Coq on which we will write our specifications and proofs. We write this translation by hand relying as much as possible on generative AI tools such as GitHub Copilot, as there are many particular cases. We plan, eventually, to prove it equivalent to the translation automatically generated by coq-of-rust.
In this blog post we present how we organize our 🔮 monad to represent the side-effects used in this Rust code. We believe this organization should work for other Rust projects as well.
🌲 What we do at Formal Land
In this blog post, we present what we do at Formal Land 🌲, what tools and services we are developing to provide more security for our customers 🦸. We believe that for critical applications such as blockchains (L1, L2, dApps) you should always use the most advanced technologies to find bugs, otherwise bad actors will do and overtake you in the never-ending race for security 🏎️.
Formal verification is one of the best techniques to ensure that your code is correct, as it checks every possible input ✨ of your program. For a long, formal verification was reserved for specific fields, such as the space industry 🧑🚀. We are making this technology accessible for the blockchain industry and general programming thanks to tools and services we develop, like coq-of-solidity and coq-of-rust.
