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↗.