<p>Bitcoin Core has its own <code>arith_uint256</code> class for calculations on 256-bit unsigned integers.  Its code to convert "bits" (so-called compact format) to <code>arith_uint256</code> can be found in <code>arith_uint256::SetCompact</code> in the file <a href="https://github.com/bitcoin/bitcoin/blob/master/src/arith_uint256.cpp" rel="nofollow noreferrer"><code>arith_uint256.cpp</code></a>.  </p>

<p>So you could always just use its code directly.  This might be a good idea because if your version differs in any way from their behavior (e.g. rounding errors), you could disagree with Bitcoin Core on the validity of a block.  If your version is in a widely-used client, this would fork the block chain.</p>

CC BY-SA 3.0
2017-09-30T14:45:23.767Z
2017-09-30T14:45:23.767Z
Nate Eldredge
<p>I have come up with following version that seems to be working correctly for few test cases I have defined.</p>
<p>First we need a helper function that prints hex value given binary data:</p>

<pre class="lang-cpp prettyprint-override"><code>void hexdump(unsigned char *data, int len)
{
    int c = 0;
    while (c &lt; len)
    {
        cout &lt;&lt; hex &lt;&lt; std::setw(2) &lt;&lt; std::setfill('0') &lt;&lt; static_cast&lt;int&gt;(data[c++]);
    }
    printf(&quot;\n&quot;);
}
</code></pre>
<p>Now lets define the actual function that takes block.bits and converts it to 256 bit value in memory:</p>
<pre class="lang-cpp prettyprint-override"><code>bool convert_bits(uint32_t bits, uint64_t* value, int val_len = 4)
{
    assert(val_len == 4);
    assert(value != NULL);

    if (val_len != 4 || value == NULL)
    {
        return false;
    }

    // if bits =  0x1b0404cb, hex target = 0x0404cb * 2**(8*(0x1b - 3)) 
    uint32_t x = 8 * ((bits &gt;&gt; 24) - 3); // number of zero bits on right
    uint64_t val = bits &amp; 0x00FFFFFF;

    // Number of maximum bits required for val is 24.
    assert(x &lt;= (256 - 24));
    if (x &gt; (256 - 24))
    {
        return false;
    }   

    int startq = (3 - int(x / 64));
    int endq = (3 - int((x + 24) / 64));

    int shift = ((3 + endq) * 64 - x);
    if (startq != endq)
    {
        shift = 64 - shift;
    }

    value[startq] = htobe64(val &lt;&lt; shift);
    value[endq] = htobe64(val &gt;&gt; shift);

    return true;
}
</code></pre>
<p>Now lets test the above function:</p>
<pre class="lang-cpp prettyprint-override"><code>int main()
{
    uint64_t num[4] = { 0, 0, 0, 0 };
    if(convert_bits(0x1b0404cb, num))
    {
        hexdump((unsigned char *)num, sizeof(uint64_t) * 4);
    }
    return 0;
}
</code></pre>
<p>This prints: 00000000000404cb000000000000000000000000000000000000000000000000</p>

CC BY-SA 4.0
2023-04-28T16:31:20.840Z
`htobe64` is particularly slow (about 50 executions in a single thread with my i5-1240P).
Benjamin Loison
CC BY-SA 4.0
2023-04-28T17:16:12.003Z
I ended up using https://gist.github.com/Ending2015a/70373b2f6f665a765b4d0b0c427f052b
Benjamin Loison
CC BY-SA 4.0
2023-08-16T07:25:58.477Z
Bytes shift don't need us to pay attention to the endianness. Endianness must be taken in account iff the code is copying integers with memcpy.
Loopite
CC BY-SA 4.0
2017-08-22T14:47:07.520Z
2023-08-15T19:49:39.550Z
2023-08-15T19:49:39.550Z
Maruf Maniruzzaman
<p>I have two values </p>

<pre><code>1. h = hash of the block (32 bytes long in memory representation - not hex)
2. bits (uint32_t)
</code></pre>

<p>To make the calculation easier we create a function difficulty such that:</p>

<pre><code>auto d = difficulty(bits)
</code></pre>

<p>Now what is the best way to create such a difficulty function that, I believe should, return a 256 bit value?</p>

<p>Then I am thinking casting both h and d values into an array of type uint64_t and compare all 4 elements from msb (bit 255) to make sure the condition holds.</p>

<p>Is there a better way for comparing as well?</p>

<difficulty><c++>
What is most efficient way to validate bitcoin target (difficulty) value in C++
Maruf Maniruzzaman
# What is most efficient way to validate bitcoin target (difficulty) value in C++

(Asked by: username_0 on 2017-08-20)

I have two values 
1. h = hash of the block (32 bytes long in memory representation - not hex)
2. bits (uint32_t)

To make the calculation easier we create a function difficulty such that:
auto d = difficulty(bits)

Now what is the best way to create such a difficulty function that, I believe should, return a 256 bit value?
Then I am thinking casting both h and d values into an array of type uint64_t and compare all 4 elements from msb (bit 255) to make sure the condition holds.
Is there a better way for comparing as well?

**Tags:** difficulty, c++


---

## 2 answers

### Answer by username_1 on 2017-09-30. Score: 2

Bitcoin Core has its own `arith_uint256` class for calculations on 256-bit unsigned integers. Its code to convert "bits" (so-called compact format) to `arith_uint256` can be found in `arith_uint256::SetCompact` in the file [`arith_uint256.cpp`](https://github.com/bitcoin/bitcoin/blob/master/src/arith_uint256.cpp).

So you could always just use its code directly. This might be a good idea because if your version differs in any way from their behavior (e.g. rounding errors), you could disagree with Bitcoin Core on the validity of a block. If your version is in a widely-used client, this would fork the block chain.


---

### Answer by username_0 on 2017-08-22. Score: 0

I have come up with following version that seems to be working correctly for few test cases I have defined.
First we need a helper function that prints hex value given binary data:
void hexdump(unsigned char *data, int len)
{
    int c = 0;
    while (c < len)
    {
        cout << hex << std::setw(2) << std::setfill('0') << static_cast(data[c++]);
    }
    printf("\n");
}

Now lets define the actual function that takes block.bits and converts it to 256 bit value in memory:
bool convert_bits(uint32_t bits, uint64_t* value, int val_len = 4)
{
    assert(val_len == 4);
    assert(value != NULL);

    if (val_len != 4 || value == NULL)
    {
        return false;
    }

    // if bits =  0x1b0404cb, hex target = 0x0404cb * 2**(8*(0x1b - 3)) 
    uint32_t x = 8 * ((bits >> 24) - 3); // number of zero bits on right
    uint64_t val = bits & 0x00FFFFFF;

    // Number of maximum bits required for val is 24.
    assert(x <= (256 - 24));
    if (x > (256 - 24))
    {
        return false;
    }   

    int startq = (3 - int(x / 64));
    int endq = (3 - int((x + 24) / 64));

    int shift = ((3 + endq) * 64 - x);
    if (startq != endq)
    {
        shift = 64 - shift;
    }

    value[startq] = htobe64(val << shift);
    value[endq] = htobe64(val >> shift);

    return true;
}

Now lets test the above function:
int main()
{
    uint64_t num[4] = { 0, 0, 0, 0 };
    if(convert_bits(0x1b0404cb, num))
    {
        hexdump((unsigned char *)num, sizeof(uint64_t) * 4);
    }
    return 0;
}

This prints: 00000000000404cb000000000000000000000000000000000000000000000000

> **Comments:**
> **username_2**: `htobe64` is particularly slow (about 50 executions in a single thread with my i5-1240P).  
> **username_2**: I ended up using https://gist.github.com/Ending2015a/70373b2f6f665a765b4d0b0c427f052b  
> **username_3**: Bytes shift don't need us to pay attention to the endianness. Endianness must be taken in account iff the code is copying integers with memcpy.  

---

