Line data Source code
1 : // Copyright (c) 2012-2014 The Bitcoin Core developers
2 : // Copyright (c) 2017-2019 The PIVX Core developers
3 : // Distributed under the MIT/X11 software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #include "libzerocoin/bignum.h"
7 : #include "script/script.h"
8 : #include "test/test_pivx.h"
9 :
10 : #include <boost/test/unit_test.hpp>
11 : #include <limits.h>
12 : #include <stdint.h>
13 :
14 : BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup)
15 :
16 : /** A selection of numbers that do not trigger int64_t overflow
17 : * when added/subtracted. */
18 : static const int64_t values[] = { 0, 1, -2, 127, 128, -255, 256, (1LL << 15) - 1, -(1LL << 16), (1LL << 24) - 1, (1LL << 31), 1 - (1LL << 32), 1LL << 40 };
19 :
20 : static const int64_t offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000};
21 :
22 13545 : static bool verify(const CBigNum& bignum, const CScriptNum& scriptnum)
23 : {
24 50686 : return bignum.getvch() == scriptnum.getvch() && bignum.getint() == scriptnum.getint();
25 : }
26 :
27 351 : static void CheckCreateVch(const long& num)
28 : {
29 630 : CBigNum bignum(num);
30 351 : CScriptNum scriptnum(num);
31 702 : BOOST_CHECK(verify(bignum, scriptnum));
32 :
33 702 : CBigNum bignum2(bignum.getvch());
34 423 : CScriptNum scriptnum2(scriptnum.getvch(), false);
35 558 : BOOST_CHECK(verify(bignum2, scriptnum2));
36 :
37 630 : CBigNum bignum3(scriptnum2.getvch());
38 279 : CScriptNum scriptnum3(bignum2.getvch(), false);
39 279 : BOOST_CHECK(verify(bignum3, scriptnum3));
40 279 : }
41 :
42 351 : static void CheckCreateInt(const long& num)
43 : {
44 702 : CBigNum bignum(num);
45 351 : CScriptNum scriptnum(num);
46 702 : BOOST_CHECK(verify(bignum, scriptnum));
47 1008 : BOOST_CHECK(verify(bignum.getint(), CScriptNum(scriptnum.getint())));
48 1008 : BOOST_CHECK(verify(scriptnum.getint(), CScriptNum(bignum.getint())));
49 1008 : BOOST_CHECK(verify(CBigNum(scriptnum.getint()).getint(), CScriptNum(CScriptNum(bignum.getint()).getint())));
50 351 : }
51 :
52 :
53 1404 : static void CheckAdd(const long& num1, const long& num2)
54 : {
55 2808 : const CBigNum bignum1(num1);
56 2808 : const CBigNum bignum2(num2);
57 1404 : const CScriptNum scriptnum1(num1);
58 1404 : const CScriptNum scriptnum2(num2);
59 2808 : CBigNum bignum3(num1);
60 1404 : CBigNum bignum4(num1);
61 1404 : CScriptNum scriptnum3(num1);
62 1404 : CScriptNum scriptnum4(num1);
63 :
64 : // int64_t overflow is undefined.
65 2808 : bool invalid = (((num2 > 0) && (num1 > (std::numeric_limits<long>::max() - num2))) ||
66 594 : ((num2 < 0) && (num1 < (std::numeric_limits<long>::min() - num2))));
67 1404 : if (!invalid)
68 : {
69 2808 : BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + scriptnum2));
70 2808 : BOOST_CHECK(verify(bignum1 + bignum2, scriptnum1 + num2));
71 2808 : BOOST_CHECK(verify(bignum1 + bignum2, scriptnum2 + num1));
72 : }
73 1404 : }
74 :
75 1404 : static void CheckNegate(const long& num)
76 : {
77 2808 : const CBigNum bignum(num);
78 1404 : const CScriptNum scriptnum(num);
79 :
80 : // -INT64_MIN is undefined
81 1404 : if (num != std::numeric_limits<long>::min())
82 2808 : BOOST_CHECK(verify(-bignum, -scriptnum));
83 1404 : }
84 :
85 1404 : static void CheckSubtract(const long& num1, const long& num2)
86 : {
87 2808 : const CBigNum bignum1(num1);
88 1404 : const CBigNum bignum2(num2);
89 1404 : const CScriptNum scriptnum1(num1);
90 1404 : const CScriptNum scriptnum2(num2);
91 1404 : bool invalid = false;
92 :
93 : // int64_t overflow is undefined.
94 1404 : invalid = ((num2 > 0 && num1 < std::numeric_limits<long>::min() + num2) ||
95 594 : (num2 < 0 && num1 > std::numeric_limits<long>::max() + num2));
96 1404 : if (!invalid)
97 : {
98 2808 : BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - scriptnum2));
99 2808 : BOOST_CHECK(verify(bignum1 - bignum2, scriptnum1 - num2));
100 : }
101 :
102 2808 : invalid = ((num1 > 0 && num2 < std::numeric_limits<long>::min() + num1) ||
103 492 : (num1 < 0 && num2 > std::numeric_limits<long>::max() + num1));
104 1404 : if (!invalid)
105 : {
106 2808 : BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - scriptnum1));
107 2808 : BOOST_CHECK(verify(bignum2 - bignum1, scriptnum2 - num1));
108 : }
109 1404 : }
110 :
111 1404 : static void CheckCompare(const long& num1, const long& num2)
112 : {
113 2808 : const CBigNum bignum1(num1);
114 2808 : const CBigNum bignum2(num2);
115 1404 : const CScriptNum scriptnum1(num1);
116 1404 : const CScriptNum scriptnum2(num2);
117 :
118 2808 : BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == scriptnum1));
119 2808 : BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != scriptnum1));
120 2808 : BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < scriptnum1));
121 2808 : BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > scriptnum1));
122 2808 : BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= scriptnum1));
123 2808 : BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= scriptnum1));
124 :
125 2808 : BOOST_CHECK((bignum1 == bignum1) == (scriptnum1 == num1));
126 2808 : BOOST_CHECK((bignum1 != bignum1) == (scriptnum1 != num1));
127 2808 : BOOST_CHECK((bignum1 < bignum1) == (scriptnum1 < num1));
128 2808 : BOOST_CHECK((bignum1 > bignum1) == (scriptnum1 > num1));
129 2808 : BOOST_CHECK((bignum1 >= bignum1) == (scriptnum1 >= num1));
130 2808 : BOOST_CHECK((bignum1 <= bignum1) == (scriptnum1 <= num1));
131 :
132 2808 : BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == scriptnum2));
133 2808 : BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != scriptnum2));
134 2808 : BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < scriptnum2));
135 2808 : BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > scriptnum2));
136 2808 : BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= scriptnum2));
137 2808 : BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= scriptnum2));
138 :
139 2808 : BOOST_CHECK((bignum1 == bignum2) == (scriptnum1 == num2));
140 2808 : BOOST_CHECK((bignum1 != bignum2) == (scriptnum1 != num2));
141 2808 : BOOST_CHECK((bignum1 < bignum2) == (scriptnum1 < num2));
142 2808 : BOOST_CHECK((bignum1 > bignum2) == (scriptnum1 > num2));
143 2808 : BOOST_CHECK((bignum1 >= bignum2) == (scriptnum1 >= num2));
144 2808 : BOOST_CHECK((bignum1 <= bignum2) == (scriptnum1 <= num2));
145 1404 : }
146 :
147 351 : static void RunCreate(const long& num)
148 : {
149 351 : CheckCreateInt(num);
150 351 : CScriptNum scriptnum(num);
151 688 : if (scriptnum.getvch().size() <= CScriptNum::nDefaultMaxNumSize)
152 279 : CheckCreateVch(num);
153 : else
154 : {
155 144 : BOOST_CHECK_THROW (CheckCreateVch(num), scriptnum_error);
156 : }
157 351 : }
158 :
159 1404 : static void RunOperators(const long& num1, const int64_t& num2)
160 : {
161 1404 : CheckAdd(num1, num2);
162 1404 : CheckSubtract(num1, num2);
163 1404 : CheckNegate(num1);
164 1404 : CheckCompare(num1, num2);
165 1404 : }
166 :
167 2 : BOOST_AUTO_TEST_CASE(creation)
168 : {
169 14 : for(size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i)
170 : {
171 130 : for(size_t j = 0; j < sizeof(offsets) / sizeof(offsets[0]); ++j)
172 : {
173 117 : RunCreate(values[i]);
174 117 : RunCreate(values[i] + offsets[j]);
175 117 : RunCreate(values[i] - offsets[j]);
176 : }
177 : }
178 1 : }
179 :
180 2 : BOOST_AUTO_TEST_CASE(operators)
181 : {
182 14 : for(size_t i = 0; i < sizeof(values) / sizeof(values[0]); ++i)
183 : {
184 130 : for(size_t j = 0; j < sizeof(offsets) / sizeof(offsets[0]); ++j)
185 : {
186 117 : RunOperators(values[i], values[i]);
187 117 : RunOperators(values[i], -values[i]);
188 117 : RunOperators(values[i], values[j]);
189 117 : RunOperators(values[i], -values[j]);
190 117 : RunOperators(values[i] + values[j], values[j]);
191 117 : RunOperators(values[i] + values[j], -values[j]);
192 117 : RunOperators(values[i] - values[j], values[j]);
193 117 : RunOperators(values[i] - values[j], -values[j]);
194 117 : RunOperators(values[i] + values[j], values[i] + values[j]);
195 117 : RunOperators(values[i] + values[j], values[i] - values[j]);
196 117 : RunOperators(values[i] - values[j], values[i] + values[j]);
197 117 : RunOperators(values[i] - values[j], values[i] - values[j]);
198 : }
199 : }
200 1 : }
201 :
202 : BOOST_AUTO_TEST_SUITE_END()
|