GHSA-j622-qffp-rc27
verify_math returns VERIFIED for incorrect results on large numbers due to 15-digit evaluation precision
Summary
VerificationEngine.verify_math() (src/qwed_new/core/verifier.py ~L128) evaluates the expression with expr.evalf(), whose default precision is 15 significant digits, then quantizes to 6 decimals and compares with the claimed value. For values with more than 15 significant digits, the computed value is rounded before comparison, so:
| Expression | Claimed | Result | Correct |
|---|---|---|---|
10000000000000001 |
10000000000000000 |
VERIFIED | CORRECTION_NEEDED |
10000000000000001 |
10000000000000001 |
CORRECTION_NEEDED | VERIFIED |
2**64 |
18446744073709551616 |
CORRECTION_NEEDED | VERIFIED |
Impact
/verify/math, ControlPlane.process_natural_language and consensus math accept off-by-small-amount claims on large values and reject correct ones. Financial integrations that use minor units (paise/cents/wei) commonly exceed 15 digits. An attacker or a faulty LLM can get an incorrect total attested as VERIFIED.
Patches
- If
expris an exactInteger/Rational, compare exactly withDecimal(str(claimed))/Rational, with noevalf. - Otherwise evaluate with
evalf(n=max(30, digits(claimed) + 10))and fail closed (BLOCKED) when the precision needed cannot be established. - Regression tests: the table above plus negative/rational variants.
Workarounds
Keep values below 15 significant digits (e.g. compare in major units) or re-verify large values with exact integer arithmetic.