Formal Land's Avatar

Formal Land

@formalland.bsky.social

Formal verification for everyday-life applications We use math to ensure your code has no vulnerabilities For Rust, Solidity, zk circuits. We use Rocq. https://formal.land/

41 Followers  |  31 Following  |  105 Posts  |  Joined: 21.11.2024  |  2.0023

Latest posts by formalland.bsky.social on Bluesky

Preview
๐Ÿฅท Pretty-printing of Rust ZK constraints | Formal Land Many zkVMs are implemented in Rust, using the Plonky3 library to describe their circuits. While Rust is efficient and expressive for describing complex circuits, it is a complex language when it comes...

โœจ New work from our grantee @formalland.bsky.social, formally verifying ZK circuits for zkVMs!

Their new blog post presents how to pretty-print the constraints from a Plonky3 circuit, ensuring their modeling is correct.

formal.land/blog/2025/08...

18.09.2025 13:33 โ€” ๐Ÿ‘ 4    ๐Ÿ” 3    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

We will post more updates when the proof is complete! ๐ŸŽ„

08.08.2025 15:43 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

To that end, we state that if the circuit runs until the end on a witness, then it must be the encoding with field elements of a Keccak computation.

Frequent intermediate operations are showing that arrays hold boolean field elements, as well as manipulations of limbs of binary integers.

08.08.2025 15:41 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

We verify these logical tricks by brute-forcing all the possible values for the booleans, as there are only up to five or six such booleans for each formula.

The main property we show is that the circuit is deterministic (no under-constraints).

08.08.2025 15:37 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Post image

Then we write our proofs, trying to be careful to follow the organization of the original code, by verifying each loop independently and composing their behavior in a second step.

A few logical tricks are used in the definition of Keccak to replace some XOR operations by equivalent additions.

08.08.2025 15:34 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Post image

We might choose to refine those choices later, once we better understand the bottlenecks in the proofs.

Our base definitions are in github.com/formal-land/...

08.08.2025 15:31 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

For now, we use rather simple data structures. For example, for field elements with use explicit Z elements with a modulo "p" operation, "p" being supposed as a prime number.

For arrays, we use the total function of their indices, returning a default value when out of bounds

08.08.2025 15:29 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

It is important to keep the original structure of the code, with explicit loops, in order to keep the number of equations small.

It will be simpler to reason about loops rather than a larger number of equations. In addition, the loops are rather simple here in terms of invariants.

08.08.2025 15:27 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Post image

The Rust source code is available at github.com/Plonky3/Plon...

For now, we translate it by hand to the corresponding constraints in Rocq in the Garden project github.com/formal-land/...

We will ensure later with "coq-of-rust" that it corresponds to the original implementation.

08.08.2025 15:24 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

The Keccak hash function, one of the most frequently used hash primitives in the Ethereum protocol, is implemented here efficiently using zero-knowledge constraints.

This amounts to encoding boolean operations like XOR or shift using equations over polynomials of integers modulo a prime number.

08.08.2025 15:21 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Post image

We are currently formally verifying, in Rocq, the implementation of the Keccak hash function from Plonky3 in AIR.

Here is a code extract in Rust:

08.08.2025 15:17 โ€” ๐Ÿ‘ 1    ๐Ÿ” 1    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Preview
๐Ÿฅท Formal verification of LLZK circuits in Rocq | Formal Land In this blog post, we present a short example about how we define reasoning rules in Rocq to formally verify the safety of zero-knowledge circuits written in LLZK.

The blog post: formal.land/blog/2025/07...

Happy to discuss the proof strategy/choices of representation!

31.07.2025 13:49 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
Post image

Here is our last blog post about the formal verification of LLZK circuits in Rocq.

We present the reasoning rules, as well as how to apply them to verify that an example has no under-constraints. โœ…

The link ๐Ÿ‘‡

31.07.2025 13:49 โ€” ๐Ÿ‘ 1    ๐Ÿ” 1    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Preview
๐Ÿฅท Semantics for LLZK in Rocq | Formal Land LLZK is a language designed to implement zero-knowledge circuits. We wrote a translation tool from this language to a representation in the formal language Rocq.

The link: formal.land/blog/2025/07...

30.07.2025 15:24 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Here is a new blog post on how we define the LLZK operator in the formal verification language Rocq, to assert that there are no under-constraints.

LLZK is a zero-knowledge circuit language based on MLIR by Veridise. This work is funded by the Ethereum Foundation.

Link: ๐Ÿ‘‡

30.07.2025 15:23 โ€” ๐Ÿ‘ 1    ๐Ÿ” 1    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Preview
๐Ÿฅท Beginning of a formal verification tool for LLZK | Formal Land Here we present the beginning of our work to develop a formal verification tool for LLZK from Veridise, a new language designed to implement zero-knowledge circuits. The zero-knowledge technology is h...

formal.land/blog/2025/07...

30.07.2025 09:15 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Here is a blog post where we explain how we translate the LLZK zero-knowledge circuit language to the proof system Rocq, in order to formally verify such circuits.

The main security property we are looking for is the absence of underconstraints. The link: ๐Ÿ‘‡

30.07.2025 09:15 โ€” ๐Ÿ‘ 1    ๐Ÿ” 1    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

It differs from what we were doing before, which was generating a typed and executable Rocq version, but without making explicit the non-aliasing and with a quite verbose version, making it difficult to use for the proofs.

13.07.2025 20:24 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
Post image

We are currently writing a whole EVM specification in the Rocq language that we prove equivalent to the original implementation in Revm.

This specification is in idiomatic Rocq but follows the structure of the Rust code. It includes the gas and versioning! ๐Ÿ‘‡

13.07.2025 20:23 โ€” ๐Ÿ‘ 1    ๐Ÿ” 1    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

1. Continue to verify a functional definition for the rest if the EVM instructions.

2. Show that this functional definition is equivalent to a semantics for the EVM in Rocq. There is at least one such project that we could show as equivalent to a reference implementation.

03.07.2025 14:50 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

For the rest of the instructions, we have a typed representation in Rocq generated with the help of "coq-of-rust". However, we do not have a clear idiomatic and functional definition like for the instruction ADD.

From there, we can go in two directions:

03.07.2025 14:48 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Finally, we update the top of the stack with the result of "Impl_Uint.wrapping_add" applied to the two top elements!

03.07.2025 14:44 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

We first try to consume a "VERYLOW" amount of gas. If it fails, we return the "OutOfGas" error message.

Otherwise, we pop one element from the stack and ask for a reference to the next one. If there are not enough elements, we return "StackUnderflow".

03.07.2025 14:43 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

In our functional specification, the first line:

Output.Success tt

says that there can be no runtime failures (no panics!), assuming none of the provided methods panic. This is an important safety property.

The rest describes how the ADD instruction behaves.

03.07.2025 14:41 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

One of the difficulties here is that the code is very abstract. The types of the stack or gas field are not defined, nor are the functions to manipulate them. Instead, they are provided as trait implementations.

We need to specify them somehow to say they admit a functional specification.

03.07.2025 14:39 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Post image

The functional specification (more verbose, partly because we unroll the macros):

03.07.2025 14:34 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

The ADD instruction as implemented in Rust:

pub fn add<WIRE: InterpreterTypes, H: Host + ?Sized>(
interpreter: &mut Interpreter<WIRE>,
_host: &mut H,
) {
gas!(interpreter, gas::VERYLOW);
popn_top!([op1], op2, interpreter);
*op2 = op1.wrapping_add(*op2);
}

03.07.2025 14:33 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

One of our primary targets these days (months) is to make a functional specification for the Rust implementation of the EVM (Ethereum Virtual Machine) named Revm.

We finally achieved that for the ADD instruction! Here is what it looks like: ๐Ÿ‘‡

03.07.2025 14:28 โ€” ๐Ÿ‘ 2    ๐Ÿ” 1    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Preview
Draft: add simulation for the ADD instruction by clarus ยท Pull Request #757 ยท formal-land/coq-of-rust Fix #753

The link to the pull request: github.com/formal-land/...

18.06.2025 15:36 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

It is a bit unusual when writing functional code, as it optionally returns a reference to be used later to mutate some state (the top element of the stack).

We obtained a proof-of-concept specification for this kind of code and are iterating on it to handle the ADD example cleanly.

18.06.2025 15:35 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

@formalland is following 20 prominent accounts