Security fixes on Int64 which are enabled when switching to "v2" versions of some methods.
The problem that this attempts to solve:
Int64s represent signed integers as a sign: Sign and magnitude: UInt64. This allows for many efficient implementations. However, it also means that 0 has two representations: +0 and -0.
This leads to ambiguity in the isPositive() function, which ignores the magnitude.
[...]
A malicious prover may choose to use either positive or negative zero.
[...]
For example, Int64.mod() uses the expression Provable.if(this.isPositive(), rest, y.value.sub(rest)) to select between rest and y - rest when computing the remainder modulo y. By choosing this to -0, an attacker may output y instead of 0.
isPositive() is deprecated, because it is both misleadingly named and incorrect
returns true for +0 and false for -0
depending on whether you interpret it as "> 0" or ">= 0", that result is wrong for either +0 or for -0.
the new isPositiveV2() avoids the ambiguity by checking "> 0", returns false for all versions of 0
mod() is deprecated, because it is wrong on -0 inputs
modV2() is correct
There's also a new "v2" version of check(), which fixes the root of the problem: That 0 can be represented in two different ways. It can only be enabled when upgrading to v2, because it breaks many circuits
Security fixes on Int64 which are enabled when switching to "v2" versions of some methods.
The problem that this attempts to solve:
isPositive()
is deprecated, because it is both misleadingly named and incorrecttrue
for+0
andfalse
for-0
+0
or for-0
.isPositiveV2()
avoids the ambiguity by checking "> 0", returns false for all versions of 0mod()
is deprecated, because it is wrong on-0
inputsmodV2()
is correctcheck()
, which fixes the root of the problem: That 0 can be represented in two different ways. It can only be enabled when upgrading to v2, because it breaks many circuits