cryptonote_basic: copy difficulty hash words

This commit is contained in:
Samy
2026-07-11 02:17:33 +02:00
parent 641e5ca588
commit 7dd01b69d3
2 changed files with 28 additions and 10 deletions
+14 -6
View File
@@ -32,6 +32,7 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <vector>
#include "int-util.h"
@@ -102,18 +103,25 @@ namespace cryptonote {
return a + b < a || (c && a + b == (uint64_t) -1);
}
static inline uint64_t load_u64_from_hash(const crypto::hash &hash, size_t index) {
assert(index < sizeof(hash.data) / sizeof(uint64_t));
uint64_t word;
memcpy(&word, hash.data + index * sizeof(word), sizeof(word));
return SWAP64LE(word);
}
bool check_hash_64(const crypto::hash &hash, uint64_t difficulty) {
uint64_t low, high, top, cur;
// First check the highest word, this will most likely fail for a random hash.
mul(swap64le(((const uint64_t *) &hash)[3]), difficulty, top, high);
mul(load_u64_from_hash(hash, 3), difficulty, top, high);
if (high != 0) {
return false;
}
mul(swap64le(((const uint64_t *) &hash)[0]), difficulty, low, cur);
mul(swap64le(((const uint64_t *) &hash)[1]), difficulty, low, high);
mul(load_u64_from_hash(hash, 0), difficulty, low, cur);
mul(load_u64_from_hash(hash, 1), difficulty, low, high);
bool carry = cadd(cur, low);
cur = high;
mul(swap64le(((const uint64_t *) &hash)[2]), difficulty, low, high);
mul(load_u64_from_hash(hash, 2), difficulty, low, high);
carry = cadc(cur, low, carry);
carry = cadc(high, top, carry);
return !carry;
@@ -171,7 +179,7 @@ namespace cryptonote {
bool check_hash_128(const crypto::hash &hash, difficulty_type difficulty) {
#ifndef FORCE_FULL_128_BITS
// fast check
if (difficulty >= max64bit && ((const uint64_t *) &hash)[3] > 0)
if (difficulty >= max64bit && load_u64_from_hash(hash, 3) > 0)
return false;
#endif
// usual slow check
@@ -182,7 +190,7 @@ namespace cryptonote {
for(int i = 1; i < 4; i++) { // highest word is zero
#endif
hashVal <<= 64;
hashVal |= swap64le(((const uint64_t *) &hash)[3 - i]);
hashVal |= load_u64_from_hash(hash, 3 - i);
}
return hashVal * difficulty <= max256bit;
}
+14 -4
View File
@@ -26,6 +26,9 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstddef>
#include <cstring>
#include "gtest/gtest.h"
#include "int-util.h"
#include "cryptonote_basic/difficulty.h"
@@ -37,6 +40,13 @@ static cryptonote::difficulty_type MKDIFF(uint64_t high, uint64_t low)
return d;
}
static void set_hash_word(crypto::hash &hash, std::size_t index, uint64_t value)
{
ASSERT_LT(index, sizeof(hash.data) / sizeof(value));
value = SWAP64LE(value);
memcpy(hash.data + index * sizeof(value), &value, sizeof(value));
}
static crypto::hash MKHASH(uint64_t high, uint64_t low)
{
cryptonote::difficulty_type hash_target = high;
@@ -45,16 +55,16 @@ static crypto::hash MKHASH(uint64_t high, uint64_t low)
crypto::hash h;
uint64_t val;
val = (hash_value & 0xffffffffffffffff).convert_to<uint64_t>();
((uint64_t*)&h)[0] = SWAP64LE(val);
set_hash_word(h, 0, val);
hash_value >>= 64;
val = (hash_value & 0xffffffffffffffff).convert_to<uint64_t>();
((uint64_t*)&h)[1] = SWAP64LE(val);
set_hash_word(h, 1, val);
hash_value >>= 64;
val = (hash_value & 0xffffffffffffffff).convert_to<uint64_t>();
((uint64_t*)&h)[2] = SWAP64LE(val);
set_hash_word(h, 2, val);
hash_value >>= 64;
val = (hash_value & 0xffffffffffffffff).convert_to<uint64_t>();
((uint64_t*)&h)[3] = SWAP64LE(val);
set_hash_word(h, 3, val);
return h;
}