You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
During the ICMP handling, the parser behaves incorrectly if one of the operands is negative (additionally, it does not constrain anything at the moment). The problem arises because the comparison simply compares the underlying field elements by "<", ">" etc. For negative values, which are greater than modulus / 2, this yields a wrong result.
For a fast fix, we check whether one of the operands (or both) is negative, then change the final result depending on that, as seen here:
template<typename map_type>
voidhandle_scalar_cmp(const llvm::ICmpInst *inst, map_type &variables) {
// omittedif (p == llvm::CmpInst::ICMP_EQ || p ==llvm::CmpInst::ICMP_NE) {
// omitted
} else {
auto P_HALF = BlueprintFieldType::modulus / 2;
bool leftNegative = var_value(assignmnt, lhs) > P_HALF;
bool rightNegative = var_value(assignmnt, rhs) > P_HALF;
bool res;
switch (p) {
case llvm::CmpInst::ICMP_SGE:
case llvm::CmpInst::ICMP_UGE:{
res = (var_value(assignmnt, lhs) >= var_value(assignmnt, rhs));
res ^= leftNegative;
res ^= rightNegative;
break;
}
// rest omitted....
Of course, more is needed to solve the soundness, and it requires better handling.
Here is a small example where you can reproduce the problem. The input should be 5. We compare if $(5 * -1) < 10000$, which should be clearly true. Compiled with clang++, the compiled binary writes 1 to the console. When running with the assigner binary and circuit output enabled, we can see that it, in fact, outputs 0.
During the ICMP handling, the parser behaves incorrectly if one of the operands is negative (additionally, it does not constrain anything at the moment). The problem arises because the comparison simply compares the underlying field elements by "<", ">" etc. For negative values, which are greater than modulus / 2, this yields a wrong result.
The code responsible can be seen here:
For a fast fix, we check whether one of the operands (or both) is negative, then change the final result depending on that, as seen here:
Of course, more is needed to solve the soundness, and it requires better handling.
Here is a small example where you can reproduce the problem. The input should be 5. We compare if$(5 * -1) < 10000$ , which should be clearly true. Compiled with clang++, the compiled binary writes 1 to the console. When running with the assigner binary and circuit output enabled, we can see that it, in fact, outputs 0.
The text was updated successfully, but these errors were encountered: