git / moonbite-core / src/arith_uint256.cpp · raw

// Copyright (c) 2009-2010 Satoshi Nakamoto// Copyright (c) 2009-2019 The Bitcoin Core developers// Distributed under the MIT software license, see the accompanying// file COPYING or http://www.opensource.org/licenses/mit-license.php.#include <arith_uint256.h>#include <uint256.h>#include <crypto/common.h>template <unsigned int BITS>base_uint<BITS>::base_uint(const std::string& str){    static_assert(BITS/32 > 0 && BITS%32 == 0, "Template parameter BITS must be a positive multiple of 32.");    SetHex(str);}template <unsigned int BITS>base_uint<BITS>& base_uint<BITS>::operator<<=(unsigned int shift){    base_uint<BITS> a(*this);    for (int i = 0; i < WIDTH; i++)        pn[i] = 0;    int k = shift / 32;    shift = shift % 32;    for (int i = 0; i < WIDTH; i++) {        if (i + k + 1 < WIDTH && shift != 0)            pn[i + k + 1] |= (a.pn[i] >> (32 - shift));        if (i + k < WIDTH)            pn[i + k] |= (a.pn[i] << shift);    }    return *this;}template <unsigned int BITS>base_uint<BITS>& base_uint<BITS>::operator>>=(unsigned int shift){    base_uint<BITS> a(*this);    for (int i = 0; i < WIDTH; i++)        pn[i] = 0;    int k = shift / 32;    shift = shift % 32;    for (int i = 0; i < WIDTH; i++) {        if (i - k - 1 >= 0 && shift != 0)            pn[i - k - 1] |= (a.pn[i] << (32 - shift));        if (i - k >= 0)            pn[i - k] |= (a.pn[i] >> shift);    }    return *this;}template <unsigned int BITS>base_uint<BITS>& base_uint<BITS>::operator*=(uint32_t b32){    uint64_t carry = 0;    for (int i = 0; i < WIDTH; i++) {        uint64_t n = carry + (uint64_t)b32 * pn[i];        pn[i] = n & 0xffffffff;        carry = n >> 32;    }    return *this;}template <unsigned int BITS>base_uint<BITS>& base_uint<BITS>::operator*=(const base_uint& b){    base_uint<BITS> a;    for (int j = 0; j < WIDTH; j++) {        uint64_t carry = 0;        for (int i = 0; i + j < WIDTH; i++) {            uint64_t n = carry + a.pn[i + j] + (uint64_t)pn[j] * b.pn[i];            a.pn[i + j] = n & 0xffffffff;            carry = n >> 32;        }    }    *this = a;    return *this;}template <unsigned int BITS>base_uint<BITS>& base_uint<BITS>::operator/=(const base_uint& b){    base_uint<BITS> div = b;     // make a copy, so we can shift.    base_uint<BITS> num = *this; // make a copy, so we can subtract.    *this = 0;                   // the quotient.    int num_bits = num.bits();    int div_bits = div.bits();    if (div_bits == 0)        throw uint_error("Division by zero");    if (div_bits > num_bits) // the result is certainly 0.        return *this;    int shift = num_bits - div_bits;    div <<= shift; // shift so that div and num align.    while (shift >= 0) {        if (num >= div) {            num -= div;            pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.        }        div >>= 1; // shift back.        shift--;    }    // num now contains the remainder of the division.    return *this;}template <unsigned int BITS>int base_uint<BITS>::CompareTo(const base_uint<BITS>& b) const{    for (int i = WIDTH - 1; i >= 0; i--) {        if (pn[i] < b.pn[i])            return -1;        if (pn[i] > b.pn[i])            return 1;    }    return 0;}template <unsigned int BITS>bool base_uint<BITS>::EqualTo(uint64_t b) const{    for (int i = WIDTH - 1; i >= 2; i--) {        if (pn[i])            return false;    }    if (pn[1] != (b >> 32))        return false;    if (pn[0] != (b & 0xfffffffful))        return false;    return true;}template <unsigned int BITS>double base_uint<BITS>::getdouble() const{    double ret = 0.0;    double fact = 1.0;    for (int i = 0; i < WIDTH; i++) {        ret += fact * pn[i];        fact *= 4294967296.0;    }    return ret;}template <unsigned int BITS>std::string base_uint<BITS>::GetHex() const{    return ArithToUint256(*this).GetHex();}template <unsigned int BITS>void base_uint<BITS>::SetHex(const char* psz){    *this = UintToArith256(uint256S(psz));}template <unsigned int BITS>void base_uint<BITS>::SetHex(const std::string& str){    SetHex(str.c_str());}template <unsigned int BITS>std::string base_uint<BITS>::ToString() const{    return (GetHex());}template <unsigned int BITS>unsigned int base_uint<BITS>::bits() const{    for (int pos = WIDTH - 1; pos >= 0; pos--) {        if (pn[pos]) {            for (int nbits = 31; nbits > 0; nbits--) {                if (pn[pos] & 1U << nbits)                    return 32 * pos + nbits + 1;            }            return 32 * pos + 1;        }    }    return 0;}// Explicit instantiations for base_uint<256>template base_uint<256>::base_uint(const std::string&);template base_uint<256>& base_uint<256>::operator<<=(unsigned int);template base_uint<256>& base_uint<256>::operator>>=(unsigned int);template base_uint<256>& base_uint<256>::operator*=(uint32_t b32);template base_uint<256>& base_uint<256>::operator*=(const base_uint<256>& b);template base_uint<256>& base_uint<256>::operator/=(const base_uint<256>& b);template int base_uint<256>::CompareTo(const base_uint<256>&) const;template bool base_uint<256>::EqualTo(uint64_t) const;template double base_uint<256>::getdouble() const;template std::string base_uint<256>::GetHex() const;template std::string base_uint<256>::ToString() const;template void base_uint<256>::SetHex(const char*);template void base_uint<256>::SetHex(const std::string&);template unsigned int base_uint<256>::bits() const;// This implementation directly uses shifts instead of going// through an intermediate MPI representation.arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow){    int nSize = nCompact >> 24;    uint32_t nWord = nCompact & 0x007fffff;    if (nSize <= 3) {        nWord >>= 8 * (3 - nSize);        *this = nWord;    } else {        *this = nWord;        *this <<= 8 * (nSize - 3);    }    if (pfNegative)        *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;    if (pfOverflow)        *pfOverflow = nWord != 0 && ((nSize > 34) ||                                     (nWord > 0xff && nSize > 33) ||                                     (nWord > 0xffff && nSize > 32));    return *this;}uint32_t arith_uint256::GetCompact(bool fNegative) const{    int nSize = (bits() + 7) / 8;    uint32_t nCompact = 0;    if (nSize <= 3) {        nCompact = GetLow64() << 8 * (3 - nSize);    } else {        arith_uint256 bn = *this >> 8 * (nSize - 3);        nCompact = bn.GetLow64();    }    // The 0x00800000 bit denotes the sign.    // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.    if (nCompact & 0x00800000) {        nCompact >>= 8;        nSize++;    }    assert((nCompact & ~0x007fffff) == 0);    assert(nSize < 256);    nCompact |= nSize << 24;    nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);    return nCompact;}uint256 ArithToUint256(const arith_uint256 &a){    uint256 b;    for(int x=0; x<a.WIDTH; ++x)        WriteLE32(b.begin() + x*4, a.pn[x]);    return b;}arith_uint256 UintToArith256(const uint256 &a){    arith_uint256 b;    for(int x=0; x<b.WIDTH; ++x)        b.pn[x] = ReadLE32(a.begin() + x*4);    return b;}