Add SafeCmp lib - a library to safely compare felts
🧐 Motivation
Currently using assertion functions in math.cairo and comparison functions in math_cmp.cairo for felts is confusing, and therefore insecure. Those assertion/comparison functions can be split into two groups:
- first:
assert_le,assert_lt,assert_nn,is_le,is_lt,is_nn - second:
assert_le_felt,assert_lt_felt,is_le_felt,is_lt_felt
Functions in the first group should only be used in Uint256 context - so with Uint256.low and Uint256.high, since they operate in range [0, 2**128), and Uint256 members are in the same range [0, 2**128).
However, developers tend to use functions from the first group outside the context of Uint256, this creates a lot of insecure scenarios. To provide few examples of unexpected behavior:
-
is_le(1, 2**128 + 2)returns falseFALSE -
is_nn(2**128)returnsFALSE(even though negative numbers arefeltsin range(P/2, P-1])
Functions from the second group return proper results, however they assume that arguments are unsigned felts, i.e. represent numbers in range [0, P). This creates confusion when working with signed felts, i.e. in range (-P/2, P/2). Currently there are no assertion/comparison functions that would allow safely compare two signed felts or assert that the number is non-negative.
📝 Details
SafeCmp library would contain functions for safe assertion and comparison of unsigned felts and signed felts. This would be done by:
- providing functions that would allow for safe assertions/comparisons of signed
felts - providing names of functions that would clearly indicate in what range
feltarguments are expected (signed/unsigned)
Really supportive of this initiative.
With Cairo 1.0 all of this might get more clearer as a native typing system is added into the language and we have a safe intermediate representation. However I'm pretty sure the issue you're mentioning is currently present on a few contracts out there as we have no fuzzing tools open source (do we?) to check this out.
Closing this since it will not be relevant anymore after the ongoing Cairo 1.0 migration. If you think this is a mistake, feel free to open a new issue.