port code from +17 branch, fix operator *=
[novacoin.git] / src / uint256.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin 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
7 #include "uint256.h"
8
9 #include <openssl/rand.h>
10
11 #include <cassert>
12 #include <cstdio>
13 #include <cstring>
14 #include <stdexcept>
15
16
17 //////////////////////////////////////////////////////////////////////////////
18 //
19 // uint160
20 //
21
22 uint160::uint160()
23 {
24     for (int i = 0; i < WIDTH; i++)
25         pn[i] = 0;
26 }
27
28 uint160::uint160(const basetype& b)
29 {
30     for (int i = 0; i < WIDTH; i++)
31         pn[i] = b.pn[i];
32 }
33
34 uint160& uint160::operator=(const basetype& b)
35 {
36     for (int i = 0; i < WIDTH; i++)
37         pn[i] = b.pn[i];
38     return *this;
39 }
40
41 uint160::uint160(uint64_t b)
42 {
43     pn[0] = (uint32_t)b;
44     pn[1] = (uint32_t)(b >> 32);
45     for (int i = 2; i < WIDTH; i++)
46         pn[i] = 0;
47 }
48
49 uint160& uint160::operator=(uint64_t b)
50 {
51     pn[0] = (uint32_t)b;
52     pn[1] = (uint32_t)(b >> 32);
53     for (int i = 2; i < WIDTH; i++)
54         pn[i] = 0;
55     return *this;
56 }
57
58 uint160::uint160(const std::string& str)
59 {
60     SetHex(str);
61 }
62
63 uint160::uint160(const std::vector<unsigned char>& vch)
64 {
65     if (vch.size() == sizeof(pn))
66         memcpy(pn, &vch[0], sizeof(pn));
67     else
68         *this = 0;
69 }
70
71 //////////////////////////////////////////////////////////////////////////////
72 //
73 // uint256
74 //
75
76 uint256::uint256()
77 {
78     for (int i = 0; i < WIDTH; i++)
79         pn[i] = 0;
80 }
81
82 uint256::uint256(const basetype& b)
83 {
84     for (int i = 0; i < WIDTH; i++)
85         pn[i] = b.pn[i];
86 }
87
88 uint256& uint256::operator=(const basetype& b)
89 {
90     for (int i = 0; i < WIDTH; i++)
91         pn[i] = b.pn[i];
92     return *this;
93 }
94
95 uint256::uint256(uint64_t b)
96 {
97     pn[0] = (uint32_t)b;
98     pn[1] = (uint32_t)(b >> 32);
99     for (int i = 2; i < WIDTH; i++)
100         pn[i] = 0;
101 }
102
103 uint256& uint256::operator=(uint64_t b)
104 {
105     pn[0] = (uint32_t)b;
106     pn[1] = (uint32_t)(b >> 32);
107     for (int i = 2; i < WIDTH; i++)
108         pn[i] = 0;
109     return *this;
110 }
111
112 uint256& uint256::SetCompact(uint32_t nCompact, bool *pfNegative, bool *pfOverflow)
113 {
114     int nSize = nCompact >> 24;
115     uint32_t nWord = nCompact & 0x007fffff;
116     if (nSize <= 3) {
117         nWord >>= 8*(3-nSize);
118         *this = nWord;
119     } else {
120         *this = nWord;
121         *this <<= 8*(nSize-3);
122     }
123     if (pfNegative)
124         *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
125     if (pfOverflow)
126         *pfOverflow = nWord != 0 && ((nSize > 34) ||
127                                  (nWord > 0xff && nSize > 33) ||
128                                  (nWord > 0xffff && nSize > 32));
129     return *this;
130 }
131
132 uint32_t uint256::GetCompact(bool fNegative) const
133 {
134     int nSize = (bits() + 7) / 8;
135     uint32_t nCompact = 0;
136     if (nSize <= 3) {
137         nCompact = Get64(0) << 8*(3-nSize);
138     } else {
139         uint256 n = *this;
140         uint256 bn = n >> 8*(nSize-3);
141         nCompact = bn.Get64(0);
142     }
143     // The 0x00800000 bit denotes the sign.
144     // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
145     if (nCompact & 0x00800000) {
146         nCompact >>= 8;
147         nSize++;
148     }
149     assert((nCompact & ~0x007fffff) == 0);
150     assert(nSize < 256);
151     nCompact |= nSize << 24;
152     nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
153     return nCompact;
154 }
155
156 uint256& uint256::operator*=(uint32_t b32)
157 {
158     uint64_t carry = 0;
159     for (int i = 0; i < WIDTH; i++) {
160         uint64_t n = carry + (uint64_t)b32 * pn[i];
161         pn[i] = n & 0xffffffff;
162         carry = n >> 32;
163     }
164     return *this;
165 }
166
167 uint256& uint256::operator*=(const uint256& b)
168 {
169     uint256 a;
170     for (int j = 0; j < WIDTH; j++) {
171         uint64_t carry = 0;
172         for (int i = 0; i + j < WIDTH; i++) {
173             uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
174             pn[i + j] = n & 0xffffffff;
175             carry = n >> 32;
176         }
177     }
178     *this = a;
179     return *this;
180 }
181
182 uint256& uint256::operator/=(const uint256& b)
183 {
184     uint256 div = b;     // make a copy, so we can shift.
185     uint256 num = *this; // make a copy, so we can subtract.
186     *this = 0;                   // the quotient.
187     int num_bits = num.bits();
188     int div_bits = div.bits();
189     if (div_bits == 0)
190         throw uint256_error("Division by zero");
191     if (div_bits > num_bits) // the result is certainly 0.
192         return *this;
193     int shift = num_bits - div_bits;
194     div <<= shift; // shift so that div and num align.
195     while (shift >= 0) {
196         if (num >= div) {
197             num -= div;
198             pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.
199         }
200         div >>= 1; // shift back.
201         shift--;
202     }
203     // num now contains the remainder of the division.
204     return *this;
205 }
206
207 uint256::uint256(const std::string& str)
208 {
209     SetHex(str);
210 }
211
212 uint256::uint256(const std::vector<unsigned char>& vch)
213 {
214     if (vch.size() == sizeof(pn))
215         memcpy(pn, &vch[0], sizeof(pn));
216     else
217         *this = 0;
218 }
219
220 uint256 GetRandHash()
221 {
222     uint256 hash;
223     RAND_bytes(hash.begin(), hash.size());
224     return hash;
225 }