Transaction

69535fb1e17ea0e14805a3a37ee05e4f78bd81aa11074330e3a25a80f5e6d11f
2024-03-25 18:17:54
0.00000025 BSV
(
0.01126304 BSV
-
0.01126279 BSV
)
10.04 sat/KB
1
73,837
2,489 B

2 Outputs

Total Output:
0.01126279 BSV
  • j"1LAnZuoQdcKCkpDBKQMCgziGMoPC4VQUckM½<div class="post">Hi,<br/><br/>The Hash() function in util.h forms the backbone of most of bitcoin's crypto:<br/><br/><div class="codeheader">Code:</div><div class="code">template&lt;typename T1&gt;<br/>inline uint256 Hash(const T1 pbegin, const T1 pend)<br/>{<br/>&nbsp; &nbsp; uint256 hash1;<br/>&nbsp; &nbsp; SHA256((unsigned char*)&amp;pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&amp;hash1);<br/>&nbsp; &nbsp; uint256 hash2;<br/>&nbsp; &nbsp; SHA256((unsigned char*)&amp;hash1, sizeof(hash1), (unsigned char*)&amp;hash2);<br/>&nbsp; &nbsp; return hash2;<br/>}<br/></div><br/>As you can see, this tries to be more secure by hashing twice. However, this actually reduces security. To break pure SHA256, an attacker needs to find a d' such that SHA256(d') == SHA256(d), for a known d. This is also sufficient to break Hash(). However the attacker can also attack the outer layer of the hash, finding a d' such that SHA256(SHA256(d')) == SHA256(SHA256(d)), even though SHA256(d') != SHA256(d). As you can see, the double hashing here makes it _easier_ to break the hash!<br/><br/>A better solution would be something like:<br/><br/><div class="codeheader">Code:</div><div class="code">template&lt;typename T1&gt;<br/>inline vector&lt;unsigned char&gt; HashV(const T1 pbegin, const T1 pend)<br/>{<br/>&nbsp; &nbsp; uint256 sharesult;<br/>&nbsp; &nbsp; uint160 riperesult;<br/>&nbsp; &nbsp; SHA256((unsigned char*)&amp;pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char *)&amp;sharesult);<br/>&nbsp; &nbsp; RIPEMD160((unsigned char*)&amp;pbegin[0], (pend - pbegin) * sizeof(pbegin[0]), (unsigned char *)&amp;riperesult);<br/><br/>&nbsp; &nbsp; vector&lt;unsigned char&gt; ret;<br/>&nbsp; &nbsp; ret.insert(ret.end(), (unsigned char *)(&amp;sharesult), (unsigned char *)(&amp;sharesult + 1));<br/>&nbsp; &nbsp; ret.insert(ret.end(), (unsigned char *)(&amp;riperesult), (unsigned char *)(&amp;riperesult + 1));<br/>&nbsp; &nbsp; return ret;<br/>}<br/></div><br/>The key is to concatenate the hashes, not merge them. This means the attacker has to break both hashes - even in the worst case, this cannot be less secure than a single hash.<br/><br/>Unfortunately, changing hashes would break the chain...</div> text/html
    https://whatsonchain.com/tx/69535fb1e17ea0e14805a3a37ee05e4f78bd81aa11074330e3a25a80f5e6d11f