Updated section related to arithmetic overflows

This commit is contained in:
Fredrik Dahlgren
2023-03-17 17:29:56 +01:00
parent 9c7de76c44
commit aad1d94c13

View File

@@ -820,31 +820,41 @@ This can cause unintended consequences if there are no checks preventing these p
**Attack Scenario**
For example, lets assume there is a circuit that outputs a users new balance as the public output:
For example, consider the following circuit that computes a users new balance:
```jsx
template getNewBalance() {
signal currBal;
signal withdrawAmt;
signal output newBal;
signal currentBalance;
signal withdrawAmount;
signal output newBalance;
newBal <== currBal - withdrawAmt;
newBalance <== currentBalance - withdrawAmount;
}
```
If a user inputs a currBal < withdrawAmt, the newBal output will underflow and will be an extremely large number close to p. This is clearly not what is intended by the circuit.
If a user inputs a `withdrawAmount` that is greater than their `currentBalance`, the `newBalance` output will underflow and will be an extremely large number close to `p`. This is clearly not what was intended by the circuit writer.
**Preventative Techniques**
**The fix**
Adding range checks via the circomlib/comparators library can ensure the numbers we are working with are not within bounds of causing over/under flows:
We can use the `LessThan` and `Num2Bits` templates defined by Circomlib to ensure the values we are working with are within the correct bounds, and will not cause overflows or underflows:
```jsx
component lt = LessThan(252);
lt.in[0] = withdrawAmt;
lt.in[1] = currBal;
# Ensure that both values are positive.
component n2b1 = Num2Bits(64);
n2b1.in <== withdrawAmount;
component n2b2 = Num2Bits(64);
n2b2.in <== currentBalance;
# Ensure that withdrawAmount <= currentBalance.
component lt = LessThan(64);
lt.in[0] = withdrawAmount;
lt.in[1] = currentBalance + 1;
lt.out === 1;
```
Here, `Num2Bits(n)` is used as a range check to ensure that the input lies in the interval `[0, 2^n)`. In particular, if `n` is small enough this ensures that the input is positive. If we forgot these range checks a malicious user could input a `withdrawAmount` equal to `p - 1`. This would satisfy the constraints defined by `LessThan` as long as the current balance is non-negative since `p - 1 = -1 < currentBalance`.
## <a name="mismatching-bit-lengths">4. Mismatching Bit Lengths</a>
Many of CircomLibs circuits take in an expected number of bits. In order for their constraints and output to be accurate, the input parameters need to be constrained to that maximum number of bits outside of the CircomLib circuit. For example, the *LessThan* circuit expects *n* number of bits.