Mismatch between Uint521
type and its documentation
Description
The sdk provides the type Uint521
, implemented in sdk/api_uint521.go, which the documentation describes as supporting arithmetic up to 521 bits. However, this type is given by emulated field elements of the field with 2^521 - 1
elements. In particular, arithmetic operations are modulo 2^521 - 1
, and there is one 521-bit value (2^521 - 1
itself) that cannot be represented as a Uint521
.
For the various arithmetic operations, it is documented that an overflow can happen if the result is bigger than . However, an overflow happens already whenever the result is equal to .
Overflow behavior also differs from other UintN
types, such as Uint248
. These other types are stored in a single circuit variable, so as elements of a field with order r
, with r
being 254 bits wide. Operations are carried out in that field and so are reduced modulo r
. In particular, it can happen that, for example, the sum of two Uint248
is stored as a value that is wider than 248 bits, so outside of the range the type is intended to represent. In contrast, for Uint521
, arithmetic is wrapping modulo 2^521 - 1
.
Impact
The Uint521
cannot represent the full range implied by its name and documentation. This, as well as other discrepancies between the behavior of this type and its documentation and the behavior of similar types offered by the sdk, can result in incorrect usage.
Recommendations
We recommend to clearly document the range of Uint521
and its behavior regarding overflows.
Remediation
This issue has been acknowledged by Brevis, and a fix was implemented in commit ffea9394↗.