LCOV - code coverage report
Current view: top level - src - uint256.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 52 56 92.9 %
Date: 2025-02-23 09:33:43 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2021 The Bitcoin developers
       3             : // Copyright (c) 2014-2015 The Dash developers
       4             : // Copyright (c) 2017-2021 The PIVX Core developers
       5             : // Distributed under the MIT software license, see the accompanying
       6             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       7             : 
       8             : #ifndef PIVX_UINT256_H
       9             : #define PIVX_UINT256_H
      10             : 
      11             : #include "crypto/common.h"
      12             : 
      13             : #include <assert.h>
      14             : #include <cstring>
      15             : #include <stdexcept>
      16             : #include <stdint.h>
      17             : #include <string>
      18             : #include <vector>
      19             : 
      20             : /** Template base class for fixed-sized opaque blobs. */
      21             : template<unsigned int BITS>
      22             : class base_blob
      23             : {
      24             : protected:
      25             :     static constexpr int WIDTH = BITS / 8;
      26             :     uint8_t m_data[WIDTH];
      27             : public:
      28             :     /* construct 0 value by default */
      29 19140737410 :     constexpr base_blob() : m_data() {}
      30             : 
      31             :     /* constructor for constants between 1 and 255 */
      32             :     constexpr explicit base_blob(uint8_t v) : m_data{v} {}
      33             : 
      34             :     explicit base_blob(const std::vector<unsigned char>& vch);
      35             : 
      36    48917575 :     bool IsNull() const
      37             :     {
      38   252733127 :         for (int i = 0; i < WIDTH; i++)
      39   247326620 :             if (m_data[i] != 0)
      40             :                 return false;
      41             :         return true;
      42             :     }
      43             : 
      44    15703543 :     void SetNull()
      45             :     {
      46    10930252 :         memset(m_data, 0, sizeof(m_data));
      47       62637 :     }
      48             : 
      49  1532821288 :     inline int Compare(const base_blob& other) const { return memcmp(m_data, other.m_data, sizeof(m_data)); }
      50             : 
      51   304751330 :     friend inline bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; }
      52     4078308 :     friend inline bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; }
      53  1205764724 :     friend inline bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; }
      54             : 
      55             :     std::string GetHex() const;
      56             :     void SetHex(const char* psz);
      57             :     void SetHex(const std::string& str);
      58             :     std::string ToString() const;
      59             : 
      60             :     const unsigned char* data() const { return m_data; }
      61           2 :     unsigned char* data() { return m_data; }
      62             : 
      63    11522179 :     unsigned char* begin()
      64             :     {
      65     5443688 :         return &m_data[0];
      66             :     }
      67             : 
      68      135700 :     unsigned char* end()
      69             :     {
      70      120282 :         return &m_data[WIDTH];
      71             :     }
      72             : 
      73    41103806 :     const unsigned char* begin() const
      74             :     {
      75    40985899 :         return &m_data[0];
      76             :     }
      77             : 
      78     2484062 :     const unsigned char* end() const
      79             :     {
      80     2484054 :         return &m_data[WIDTH];
      81             :     }
      82             : 
      83      504101 :     unsigned int size() const
      84             :     {
      85             :         return sizeof(m_data);
      86             :     }
      87             : 
      88   390878000 :     uint64_t GetUint64(int pos) const
      89             :     {
      90   390878000 :         const uint8_t* ptr = m_data + pos * 8;
      91   390878000 :         return ((uint64_t)ptr[0]) | \
      92   390878000 :                ((uint64_t)ptr[1]) << 8 | \
      93   390878000 :                ((uint64_t)ptr[2]) << 16 | \
      94   390878000 :                ((uint64_t)ptr[3]) << 24 | \
      95   390878000 :                ((uint64_t)ptr[4]) << 32 | \
      96   390878000 :                ((uint64_t)ptr[5]) << 40 | \
      97   390878000 :                ((uint64_t)ptr[6]) << 48 | \
      98   390878000 :                ((uint64_t)ptr[7]) << 56;
      99             :     }
     100             : 
     101             :     template<typename Stream>
     102    49046704 :     void Serialize(Stream& s) const
     103             :     {
     104    76335067 :         s.write((char*)m_data, sizeof(m_data));
     105             :     }
     106             : 
     107             :     template<typename Stream>
     108    10214274 :     void Unserialize(Stream& s)
     109             :     {
     110     9806764 :         s.read((char*)m_data, sizeof(m_data));
     111             :     }
     112             : };
     113             : 
     114             : /** 88-bit opaque blob.
     115             :  */
     116             : class blob88 : public base_blob<88> {
     117             : public:
     118       31254 :     blob88() {}
     119             :     explicit blob88(const base_blob<88>& b) : base_blob<88>(b) {}
     120             :     explicit blob88(const std::vector<unsigned char>& vch) : base_blob<88>(vch) {}
     121             : };
     122             : 
     123             : /** 160-bit opaque blob.
     124             :  * @note This type is called uint160 for historical reasons only. It is an opaque
     125             :  * blob of 160 bits and has no integer operations.
     126             :  */
     127             : class uint160 : public base_blob<160> {
     128             : public:
     129    32420013 :     uint160() {}
     130    12545269 :     explicit uint160(const std::vector<unsigned char>& vch) : base_blob<160>(vch) {}
     131             : };
     132             : 
     133             : /** 256-bit opaque blob.
     134             :  * @note This type is called uint256 for historical reasons only. It is an
     135             :  * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if
     136             :  * those are required.
     137             :  */
     138             : class uint256 : public base_blob<256> {
     139             : public:
     140  1110360783 :     uint256() {}
     141        7669 :     explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {}
     142             : 
     143             :     /** A cheap hash function that just returns 64 bits from the result, it can be
     144             :      * used when the contents are considered uniformly random. It is not appropriate
     145             :      * when the value can easily be influenced from outside as e.g. a network adversary could
     146             :      * provide values to trigger worst-case behavior.
     147             :      * @note The result of this function is not stable between little and big endian.
     148             :      */
     149    13343183 :     uint64_t GetCheapHash() const { return ReadLE64(begin()); }
     150             : 
     151             : };
     152             : 
     153             : /* uint256 from const char *.
     154             :  * This is a separate function because the constructor uint256(const char*) can result
     155             :  * in dangerously catching UINT256_ZERO.
     156             :  */
     157        8360 : inline uint256 uint256S(const char* str)
     158             : {
     159        8360 :     uint256 rv;
     160        8360 :     rv.SetHex(str);
     161        8356 :     return rv;
     162             : }
     163             : /* uint256 from std::string.
     164             :  * This is a separate function because the constructor uint256(const std::string &str) can result
     165             :  * in dangerously catching UINT256_ZERO via std::string(const char*).
     166             :  */
     167        7371 : inline uint256 uint256S(const std::string& str)
     168             : {
     169        7371 :     uint256 rv;
     170        7371 :     rv.SetHex(str);
     171        7378 :     return rv;
     172             : }
     173             : 
     174             : /** constant uint256 instances */
     175             : const uint256 UINT256_ZERO = uint256();
     176             : const uint256 UINT256_ONE = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
     177             : const uint256 UINT256_MAX = uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
     178             : 
     179             : /** 512-bit opaque blob.
     180             :  * @note This type is called uint256 for historical reasons only. It is an
     181             :  * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if
     182             :  * those are required.
     183             :  */
     184             : class uint512 : public base_blob<512> {
     185             : public:
     186           4 :     uint512() {}
     187             :     explicit uint512(const base_blob<512>& b) : base_blob<512>(b) {}
     188             :     explicit uint512(const std::vector<unsigned char>& vch) : base_blob<512>(vch) {}
     189             : };
     190             : 
     191             : /* uint512 from const char *.
     192             :  * This is a separate function because the constructor uint512(const char*) can result
     193             :  * in dangerously catching uint512(0).
     194             :  */
     195             : inline uint512 uint512S(const char* str)
     196             : {
     197             :     uint512 rv;
     198             :     rv.SetHex(str);
     199             :     return rv;
     200             : }
     201             : /* uint512 from std::string.
     202             :  * This is a separate function because the constructor uint512(const std::string &str) can result
     203             :  * in dangerously catching uint512(0) via std::string(const char*).
     204             :  */
     205           0 : inline uint512 uint512S(const std::string& str)
     206             : {
     207           0 :     uint512 rv;
     208           0 :     rv.SetHex(str);
     209           0 :     return rv;
     210             : }
     211             : 
     212             : namespace std {
     213             :     template <>
     214             :     struct hash<uint256>
     215             :     {
     216      826402 :         std::size_t operator()(const uint256& k) const
     217             :         {
     218      826402 :             return (std::size_t)k.GetCheapHash();
     219             :         }
     220             :     };
     221             : }
     222             : 
     223             : #endif // PIVX_UINT256_H

Generated by: LCOV version 1.14