💀Common Vulnerabilities in ZK Code

As we venture further into the realm of zero-knowledge proofs, it becomes evident that while the technology offers powerful advantages, it's not immune to pitfalls. Theoretical foundations, though robust, only come to life when they're applied in practice. And as with any technology in its practical application, certain vulnerabilities can emerge, becoming almost patterns that are observed recurrently in ZK contracts.

This section is dedicated to "Common Vulnerabilities" often encountered in ZK contracts. By cataloging and understanding these frequently occurring issues, we can preemptively address them in our designs and implementations. Whether it's due to oversight, lack of understanding, or inherent complexities of the system, these vulnerabilities serve as cautionary tales and invaluable lessons.

We'll dissect each vulnerability type, understanding its root cause, potential impact, and best practices to mitigate or eliminate it. As you progress through this section, you'll not only gain insights into the most common pitfalls but also arm yourself with the knowledge to identify, address, and prevent these vulnerabilities in future ZK endeavors.

Most of the finds can be found in the github reprository that is continually updated: https://github.com/0xPARC/zk-bug-tracker. Thank you 0xPARC.

Key

  1. <==: This operator is used to assign a value to a variable or signal. When you use this operator, you're saying "I want the variable on the left side to take on the value (or result of the expression) on the right side." Essentially, you're defining what a particular signal or variable should be.

    • Example: lowerBound.in[0] <== max_abs_value + in;

      This means you're defining or assigning the value of lowerBound.in[0] to be max_abs_value + in. Here, you're making a definitive statement about what lowerBound.in[0] should be in the circuit.

  2. ===: This operator is used to set up an equality constraint. It's like saying "The expressions on both sides of this operator must evaluate to the same value." This is a constraint within the circuit that must be satisfied for the proof to be valid.

    • Example: lowerBound.out === 0

      This means that, whatever other operations or constraints are in the circuit, for the proof to be valid, the signal lowerBound.out must equal 0.

In essence:

  • <== is directive, telling the circuit "This signal should have this value."

  • === is conditional, telling the circuit "These two signals or expressions should be equal."

This distinction is key in the construction of zk-SNARK circuits. Proper assignment and correct equality constraints ensure the circuit behaves as expected and produces valid proofs.

Last updated