🌳Dark Forest v0.3: Missing Bit Length Check
Summary
Related Vulnerabilities: 1. Under-constrained Circuits, 2. Nondeterministic Circuits, 3. Arithmetic Over/Under Flows, 4. Mismatching Bit Lengths
Identified By: Daira Hopwood
A RangeProof circuit was used to prevent overflows. However, it used the CircomLib LessThan circuit to ensure this, which expects a maximum number of bits for each input. The inputs did not have any constraints on the number of bits, so an attacker could use large numbers to achieve a successful RangeProof even though the number was out of range.
Background
Dark Forest,, had a missing bit length check from its early circuits. In order to prevent underflows their circuit included a RangeProof template to ensure that an input is within bounds to prevent an overflow.
The LessThan template compares two inputs, and outputs 1 if the first input is less than the second input. In the RangeProof circuit, the LessThan circuit is essentially used as a GreaterEqThan, requiring that the output is 0. The LessThan template takes in the max number of bits for both inputs as a parameter, but does not actually check this constraint.
The Vulnerability
Therefore, in the RangeProof example the LessThan circuit is used with an expected maximum number of bits, but the inputs max_abs_value and in are never constrained to that number. An attacker could input max_abs_value and in values that contain more bits than the expected max. Since LessThan is expecting the two inputs to have a maximum number of bits, it may output an incorrect result. An attacker would be able to satisfy the RangeProof even though the input is out of range.
The Fix
In order to prevent this attack, a check was needed on the number of bits of max_abs_value and in. They must be constrained to *bits *****(the template input parameter) number of bits. The following is the implemented fix in production:
Conclusion
The Problem with RangeProof:
The RangeProof circuit's goal is to ensure that a given input number (let's call it
in
) doesn't exceed a certain maximum absolute value (max_abs_value
).To achieve this, the RangeProof circuit utilized a module named
LessThan
from the CircomLib library.The problem arose because
LessThan
was designed to work with numbers of a certain bit length, but the RangeProof didn't ensure that the numbers it received respected that bit length. This means that, with clever input, a malicious actor could make theLessThan
function return an incorrect result, which would then allow an out-of-range number to be mistakenly approved by the RangeProof.
The Specifics of
LessThan
:The
LessThan
module is pretty straightforward. It compares two numbers and outputs 1 if the first number is smaller than the second.Here’s the trick:
LessThan
is designed to work with numbers of a certain maximum bit length (specified asn
). If the numbers have more bits than that, the function will not behave correctly.
How This Can Be Exploited:
Without constraints on the inputs' bit lengths, an attacker can input numbers for
max_abs_value
andin
that have more bits than the LessThan function expects.This can cause the LessThan function to return an incorrect result, allowing the attacker to satisfy the RangeProof even if the number is actually out of range.
The Fix:
To address this vulnerability, the developers added constraints on the bit lengths of the inputs (
max_abs_value
andin
). They ensured that these inputs have a bit length that aligns with what theLessThan
function expects.
The described vulnerability has to do with a weakness in the constraint system of a zero-knowledge proof, specifically related to the RangeProof
that ensures an input number is within a certain range. Let's unpack the implications and potential attacks:
The Purpose of RangeProof: The primary purpose of a
RangeProof
is to prove that a particular number lies within a certain range without revealing the exact number. In this context, it's crucial to ensure that the proof is bulletproof, because if an attacker can convince a verifier that a number lies within a range when it actually doesn't, it can break the integrity of the whole system.Potential Attack: If an attacker can feed the
LessThan
function with numbers that have more bits than expected, they might get the function to output an incorrect result. This could potentially allow an attacker to submit an out-of-range number while still producing a validRangeProof
—effectively lying about the number being within the range.Implications: Let's use an analogy. Imagine a secured gate that only allows cars of a certain size to pass through. If someone found a way to trick the gate's sensor into allowing larger vehicles, they could potentially smuggle unauthorized or dangerous items. Similarly, if the
RangeProof
is not robust, it could lead to unauthorized or malicious transactions, a breach of privacy, or other unwanted outcomes, depending on the application.Why It's a Big Issue:
Trust: In cryptographic systems, especially ones like zero-knowledge proofs, trust is paramount. If there's a vulnerability that allows someone to produce a misleading proof, it undermines the whole system.
Financial Implications: Many zero-knowledge systems, including zk-SNARKs, are used in financial systems like certain blockchain implementations. If an attacker can misrepresent a transaction, they might be able to steal or double-spend funds.
Privacy Breach: ZK systems often handle sensitive data. A vulnerability could lead to a breach of privacy or unauthorized data access.
Integrity of Computation: In some systems, ensuring a value is within a certain range might be critical for other computations. If an out-of-bounds value is introduced, it could lead to unexpected behaviors or errors elsewhere in the system.
References:
ZKPs for Engineers: A look at the Dark Forest ZKPs (See the “Bonus 1: Range Proofs” section)
Last updated