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