arith_uint256.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto 2 // Copyright (c) 2009-present The Bitcoin Core developers 3 // Distributed under the MIT software license, see the accompanying 4 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 6 #include <arith_uint256.h> 7 8 #include <crypto/common.h> 9 #include <uint256.h> 10 #include <util/overflow.h> 11 12 #include <cassert> 13 14 template <unsigned int BITS> 15 base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift) 16 { 17 base_uint<BITS> a(*this); 18 for (int i = 0; i < WIDTH; i++) 19 pn[i] = 0; 20 int k = shift / 32; 21 shift = shift % 32; 22 for (int i = 0; i < WIDTH; i++) { 23 if (i + k + 1 < WIDTH && shift != 0) 24 pn[i + k + 1] |= (a.pn[i] >> (32 - shift)); 25 if (i + k < WIDTH) 26 pn[i + k] |= (a.pn[i] << shift); 27 } 28 return *this; 29 } 30 31 template <unsigned int BITS> 32 base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift) 33 { 34 base_uint<BITS> a(*this); 35 for (int i = 0; i < WIDTH; i++) 36 pn[i] = 0; 37 int k = shift / 32; 38 shift = shift % 32; 39 for (int i = 0; i < WIDTH; i++) { 40 if (i - k - 1 >= 0 && shift != 0) 41 pn[i - k - 1] |= (a.pn[i] << (32 - shift)); 42 if (i - k >= 0) 43 pn[i - k] |= (a.pn[i] >> shift); 44 } 45 return *this; 46 } 47 48 template <unsigned int BITS> 49 base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32) 50 { 51 uint64_t carry = 0; 52 for (int i = 0; i < WIDTH; i++) { 53 uint64_t n = carry + (uint64_t)b32 * pn[i]; 54 pn[i] = n & 0xffffffff; 55 carry = n >> 32; 56 } 57 return *this; 58 } 59 60 template <unsigned int BITS> 61 base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b) 62 { 63 base_uint<BITS> a; 64 for (int j = 0; j < WIDTH; j++) { 65 uint64_t carry = 0; 66 for (int i = 0; i + j < WIDTH; i++) { 67 uint64_t n = carry + a.pn[i + j] + (uint64_t)pn[j] * b.pn[i]; 68 a.pn[i + j] = n & 0xffffffff; 69 carry = n >> 32; 70 } 71 } 72 *this = a; 73 return *this; 74 } 75 76 template <unsigned int BITS> 77 base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b) 78 { 79 base_uint<BITS> div = b; // make a copy, so we can shift. 80 base_uint<BITS> num = *this; // make a copy, so we can subtract. 81 *this = 0; // the quotient. 82 int num_bits = num.bits(); 83 int div_bits = div.bits(); 84 if (div_bits == 0) 85 throw uint_error("Division by zero"); 86 if (div_bits > num_bits) // the result is certainly 0. 87 return *this; 88 int shift = num_bits - div_bits; 89 div <<= shift; // shift so that div and num align. 90 while (shift >= 0) { 91 if (num >= div) { 92 num -= div; 93 pn[shift / 32] |= (1U << (shift & 31)); // set a bit of the result. 94 } 95 div >>= 1; // shift back. 96 shift--; 97 } 98 // num now contains the remainder of the division. 99 return *this; 100 } 101 102 template <unsigned int BITS> 103 int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const 104 { 105 for (int i = WIDTH - 1; i >= 0; i--) { 106 if (pn[i] < b.pn[i]) 107 return -1; 108 if (pn[i] > b.pn[i]) 109 return 1; 110 } 111 return 0; 112 } 113 114 template <unsigned int BITS> 115 bool base_uint<BITS>::EqualTo(uint64_t b) const 116 { 117 for (int i = WIDTH - 1; i >= 2; i--) { 118 if (pn[i]) 119 return false; 120 } 121 if (pn[1] != (b >> 32)) 122 return false; 123 if (pn[0] != (b & 0xfffffffful)) 124 return false; 125 return true; 126 } 127 128 template <unsigned int BITS> 129 double base_uint<BITS>::getdouble() const 130 { 131 double ret = 0.0; 132 double fact = 1.0; 133 for (int i = 0; i < WIDTH; i++) { 134 ret += fact * pn[i]; 135 fact *= 4294967296.0; 136 } 137 return ret; 138 } 139 140 template <unsigned int BITS> 141 std::string base_uint<BITS>::GetHex() const 142 { 143 base_blob<BITS> b; 144 for (int x = 0; x < this->WIDTH; ++x) { 145 WriteLE32(b.begin() + x*4, this->pn[x]); 146 } 147 return b.GetHex(); 148 } 149 150 template <unsigned int BITS> 151 std::string base_uint<BITS>::ToString() const 152 { 153 return GetHex(); 154 } 155 156 template <unsigned int BITS> 157 unsigned int base_uint<BITS>::bits() const 158 { 159 for (int pos = WIDTH - 1; pos >= 0; pos--) { 160 if (pn[pos]) { 161 for (int nbits = 31; nbits > 0; nbits--) { 162 if (pn[pos] & 1U << nbits) 163 return 32 * pos + nbits + 1; 164 } 165 return 32 * pos + 1; 166 } 167 } 168 return 0; 169 } 170 171 // Explicit instantiations for base_uint<256> 172 template class base_uint<256>; 173 174 // This implementation directly uses shifts instead of going 175 // through an intermediate MPI representation. 176 arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow) 177 { 178 int nSize = nCompact >> 24; 179 uint32_t nWord = nCompact & 0x007fffff; 180 if (nSize <= 3) { 181 nWord >>= 8 * (3 - nSize); 182 *this = nWord; 183 } else { 184 *this = nWord; 185 *this <<= 8 * (nSize - 3); 186 } 187 if (pfNegative) 188 *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0; 189 if (pfOverflow) 190 *pfOverflow = nWord != 0 && ((nSize > 34) || 191 (nWord > 0xff && nSize > 33) || 192 (nWord > 0xffff && nSize > 32)); 193 return *this; 194 } 195 196 uint32_t arith_uint256::GetCompact(bool fNegative) const 197 { 198 int nSize = CeilDiv(bits(), 8u); 199 uint32_t nCompact = 0; 200 if (nSize <= 3) { 201 nCompact = GetLow64() << 8 * (3 - nSize); 202 } else { 203 arith_uint256 bn = *this >> 8 * (nSize - 3); 204 nCompact = bn.GetLow64(); 205 } 206 // The 0x00800000 bit denotes the sign. 207 // Thus, if it is already set, divide the mantissa by 256 and increase the exponent. 208 if (nCompact & 0x00800000) { 209 nCompact >>= 8; 210 nSize++; 211 } 212 assert((nCompact & ~0x007fffffU) == 0); 213 assert(nSize < 256); 214 nCompact |= nSize << 24; 215 nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0); 216 return nCompact; 217 } 218 219 uint256 ArithToUint256(const arith_uint256 &a) 220 { 221 uint256 b; 222 for(int x=0; x<a.WIDTH; ++x) 223 WriteLE32(b.begin() + x*4, a.pn[x]); 224 return b; 225 } 226 arith_uint256 UintToArith256(const uint256 &a) 227 { 228 arith_uint256 b; 229 for(int x=0; x<b.WIDTH; ++x) 230 b.pn[x] = ReadLE32(a.begin() + x*4); 231 return b; 232 } 233 234 // Explicit instantiations for base_uint<6144> (used in test/fuzz/muhash.cpp). 235 template base_uint<6144>& base_uint<6144>::operator*=(const base_uint<6144>& b); 236 template base_uint<6144>& base_uint<6144>::operator/=(const base_uint<6144>& b);