Sign bit computed but not enabled in Select
for Int248
Description
The Int248
type that is part of the sdk caches the sign for efficiency reasons; see the more detailed discussion in Finding ref↗. In the Select
function in sdk/api_int248.go, the sign bit of the result is computed based on the cached sign bits of the inputs, if they are available:
func (api *Int248API) Select(s Uint248, a, b Int248) Int248 {
v := Int248{}
v.Val = api.g.Select(s.Val, a.Val, b.Val)
if a.signBitSet && b.signBitSet {
v.SignBit = api.g.Select(s.Val, a.SignBit, b.SignBit)
}
return v
}
However, the cached sign bit v.SignBit
of the result will never be used, because v.signBitSet
will still be false
.
Impact
When the two input values have a valid cached sign bit, constraints will be used to compute the sign bit of the result, yet in a later call to ensureSignBit
, this cached sign bit will not be used and instead be recomputed from scratch using an expensive binary decomposition.
Recommendations
We recommend to set v.signBitSet
to true
in the if
body:
if a.signBitSet && b.signBitSet {
v.SignBit = api.g.Select(s.Val, a.SignBit, b.SignBit)
+ v.signBitSet = true
}
Remediation
This issue has been acknowledged by Brevis, and a fix was implemented in commit 3191f301↗.