arith_uint256.cpp raw

   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);
 237