diff --git a/src/crypto/siphash.cpp b/src/crypto/siphash.cpp index d604969d3ec..c8ea824979e 100644 --- a/src/crypto/siphash.cpp +++ b/src/crypto/siphash.cpp @@ -132,17 +132,12 @@ uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val) return v0 ^ v1 ^ v2 ^ v3; } -uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256& val, uint32_t extra) +/* Specialized implementation for efficiency */ +uint64_t Uint256ExtraSipHasher::operator()(const uint256& val, uint32_t extra) const noexcept { - /* Specialized implementation for efficiency */ + uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3]; uint64_t d = val.GetUint64(0); - - // TODO moved in next commit - uint64_t v0 = CSipHasher::C0 ^ k0; - uint64_t v1 = CSipHasher::C1 ^ k1; - uint64_t v2 = CSipHasher::C2 ^ k0; - uint64_t v3 = CSipHasher::C3 ^ k1 ^ d; - + v3 ^= d; SIPROUND; SIPROUND; v0 ^= d; diff --git a/src/crypto/siphash.h b/src/crypto/siphash.h index c3da7247554..c0d048c6733 100644 --- a/src/crypto/siphash.h +++ b/src/crypto/siphash.h @@ -48,6 +48,19 @@ public: * .Finalize() */ uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val); -uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256& val, uint32_t extra); + +class Uint256ExtraSipHasher { + uint64_t v[4]; + +public: + Uint256ExtraSipHasher(const uint64_t k0, const uint64_t k1) noexcept { + v[0] = CSipHasher::C0 ^ k0; + v[1] = CSipHasher::C1 ^ k1; + v[2] = CSipHasher::C2 ^ k0; + v[3] = CSipHasher::C3 ^ k1; + } + + uint64_t operator()(const uint256& val, uint32_t extra) const noexcept; +}; #endif // BITCOIN_CRYPTO_SIPHASH_H diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp index 2e51eac3078..3c27d340377 100644 --- a/src/test/fuzz/integer.cpp +++ b/src/test/fuzz/integer.cpp @@ -119,7 +119,7 @@ FUZZ_TARGET(integer, .init = initialize_integer) (void)MillisToTimeval(i64); (void)SighashToStr(uch); (void)SipHashUint256(u64, u64, u256); - (void)SipHashUint256Extra(u64, u64, u256, u32); + (void)Uint256ExtraSipHasher(u64, u64)(u256, u32); (void)ToLower(ch); (void)ToUpper(ch); { diff --git a/src/test/hash_tests.cpp b/src/test/hash_tests.cpp index f6e15db1f1e..56e448f8920 100644 --- a/src/test/hash_tests.cpp +++ b/src/test/hash_tests.cpp @@ -130,7 +130,7 @@ BOOST_AUTO_TEST_CASE(siphash) ss << TX_WITH_WITNESS(tx); BOOST_CHECK_EQUAL(SipHashUint256(1, 2, ss.GetHash()), 0x79751e980c2a0a35ULL); - // Check consistency between CSipHasher and SipHashUint256[Extra]. + // Check consistency between CSipHasher and SipHashUint256 and Uint256ExtraSipHasher. FastRandomContext ctx; for (int i = 0; i < 16; ++i) { uint64_t k0 = ctx.rand64(); @@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE(siphash) CSipHasher sip288 = sip256; sip288.Write(nb); BOOST_CHECK_EQUAL(SipHashUint256(k0, k1, x), sip256.Finalize()); - BOOST_CHECK_EQUAL(SipHashUint256Extra(k0, k1, x, n), sip288.Finalize()); // TODO modified in follow-up commit + BOOST_CHECK_EQUAL(Uint256ExtraSipHasher(k0, k1)(x, n), sip288.Finalize()); } } diff --git a/src/util/hasher.cpp b/src/util/hasher.cpp index 3109ba02a8d..3e918aaf33c 100644 --- a/src/util/hasher.cpp +++ b/src/util/hasher.cpp @@ -11,9 +11,9 @@ SaltedTxidHasher::SaltedTxidHasher() : k0{FastRandomContext().rand64()}, k1{FastRandomContext().rand64()} {} -SaltedOutpointHasher::SaltedOutpointHasher(bool deterministic) : - k0{deterministic ? 0x8e819f2607a18de6 : FastRandomContext().rand64()}, - k1{deterministic ? 0xf4020d2e3983b0eb : FastRandomContext().rand64()} +SaltedOutpointHasher::SaltedOutpointHasher(bool deterministic) : hasher{ + deterministic ? 0x8e819f2607a18de6 : FastRandomContext().rand64(), + deterministic ? 0xf4020d2e3983b0eb : FastRandomContext().rand64()} {} SaltedSipHasher::SaltedSipHasher() : diff --git a/src/util/hasher.h b/src/util/hasher.h index e4594c7ddaf..5f7940a8789 100644 --- a/src/util/hasher.h +++ b/src/util/hasher.h @@ -30,12 +30,10 @@ public: class SaltedOutpointHasher { -private: - /** Salt */ - const uint64_t k0, k1; + const Uint256ExtraSipHasher hasher; public: - SaltedOutpointHasher(bool deterministic = false); + explicit SaltedOutpointHasher(bool deterministic = false); /** * Having the hash noexcept allows libstdc++'s unordered_map to recalculate @@ -47,7 +45,7 @@ public: * @see https://gcc.gnu.org/onlinedocs/gcc-13.2.0/libstdc++/manual/manual/unordered_associative.html */ size_t operator()(const COutPoint& id) const noexcept { - return SipHashUint256Extra(k0, k1, id.hash, id.n); + return hasher(id.hash, id.n); } };