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