We are interested in practical automated verification techniques for ZK circuits that are being built for production use cases in the near future (3-6mo).

Robust auditing and verification processes are especially important for ZK circuits because it can be impossible to tell whether or not a missing constraint in a circuit has been exploited in production.

In zkSNARK circuits that exist in production today, a circuit is represented as a set of “R1CS constraints”—essentially, degree 2 equations over variables that are elements in a prime field. A zkSNARK proof is a proof of knowledge of a satisfying assignment (witness) to this set of equations. We designate a subset of these variables as “input” variables, and a disjoint subset as “output” variables.

The goal of the ZK circuit developer is to construct a set of constraints such that satisfaction of constraints implies a specific relationship between the input variables and output variables—i.e., satisfying the constraints tells you that f(inputs) = outputs for a function f. For example, for the function y = f(x) = x^3 + x - 5, we might write the following set of constraints:

interm1 = x * x
interm2 = interm1 * x
interm3 = interm2 + x
y = interm3 - 5

It is easy to see in this case that satisfying these equations is “equivalent” to having executed the function f on a value x.

However, for more complex functions, the equations and the function definition might not line up as cleanly. Our ultimate goal is to prove the equivalence of constraints and a function specification. We are looking to award grants to proving engineers or anyone with expertise in verification methods who may be interested in working on the project directions below.

Of the approaches we have tried so far, the Ecne tool by Franklyn Wang (more details) is currently the most promising, and is able to verify witness uniqueness for most of circomlib as well as several of our more complex ECC circuits. We expect however that there is a lot we have not yet tried—for example, we haven’t even started to touch more generic solvers.

Problems

What properties do we want to verify?

We are interested in verifying a few different claims about the constraints set IR. It’s probably easier to verify certain IRs than it is to verify others, and it seems like we prefer to verify the low-level constraint IR rather than other representations of human-written programs; for these reasons, we are mostly looking at the R1CS intermediate representation.

In order of strength:

What objects and processes do we want to verify/audit?