diff --git a/src/script/intmath.h b/src/script/intmath.h new file mode 100644 --- /dev/null +++ b/src/script/intmath.h @@ -0,0 +1,46 @@ +// Copyright (c) 2021 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. +#ifndef BITCOIN_SCRIPT_INTMATH_H +#define BITCOIN_SCRIPT_INTMATH_H + +#include +#include + +/** + * Computes a + b and stores it in result. If the sum overflows or results in an + * invalid 63+sign-bit integer, return true, otherwise false. Overflow checks + * are emulated and don't rely on built-in overflow checks. + */ +static bool AddInt63OverflowEmulated(int64_t a, int64_t b, int64_t &result) { + if (a > 0 && b > std::numeric_limits::max() - a) { + // integer overflow + return true; + } + if (a < 0 && b <= std::numeric_limits::min() - a) { + // integer underflow + return true; + } + result = a + b; + return result == std::numeric_limits::min(); +} + +/** + * Computes a - b and stores it in result. If the difference overflows or + * results in an invalid 63+sign-bit integer, return true, otherwise false. + * Overflow checks are emulated and don't rely on built-in overflow checks. + */ +static bool SubInt63OverflowEmulated(int64_t a, int64_t b, int64_t &result) { + if (a < 0 && b > std::numeric_limits::max() + a) { + // integer overflow + return true; + } + if (a > 0 && b <= std::numeric_limits::min() + a) { + // integer underflow + return true; + } + result = a - b; + return result == std::numeric_limits::min(); +} + +#endif // BITCOIN_SCRIPT_INTMATH_H diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -159,6 +159,7 @@ getarg_tests.cpp hash_tests.cpp interfaces_tests.cpp + intmath_tests.cpp inv_tests.cpp key_io_tests.cpp key_tests.cpp diff --git a/src/test/intmath_tests.cpp b/src/test/intmath_tests.cpp new file mode 100644 --- /dev/null +++ b/src/test/intmath_tests.cpp @@ -0,0 +1,147 @@ +// Copyright (c) 2021 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include + +#include