diff --git a/src/crypto/siphash.cpp b/src/crypto/siphash.cpp index 37ed918908f..a60297162a8 100644 --- a/src/crypto/siphash.cpp +++ b/src/crypto/siphash.cpp @@ -137,17 +137,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 PresaltedSipHasher::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 followup 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 4293fdf93b4..a4aeb3ae479 100644 --- a/src/crypto/siphash.h +++ b/src/crypto/siphash.h @@ -48,6 +48,20 @@ 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 PresaltedSipHasher +{ + uint64_t v[4]; + +public: + explicit PresaltedSipHasher(uint64_t k0, 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 2e13d4226e1..81516fd9f87 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)PresaltedSipHasher(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 46901893e9b..d4592df7eeb 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 PresaltedSipHasher. FastRandomContext ctx; for (int i = 0; i < 16; ++i) { uint64_t k0 = ctx.rand64(); @@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(siphash) uint8_t nb[4]; WriteLE32(nb, n); sip288.Write(nb); - BOOST_CHECK_EQUAL(SipHashUint256Extra(k0, k1, x, n), sip288.Finalize()); // TODO modified in follow-up commit + BOOST_CHECK_EQUAL(PresaltedSipHasher(k0, k1)(x, n), sip288.Finalize()); } } diff --git a/src/util/hasher.cpp b/src/util/hasher.cpp index c4051ae0013..cac602a893f 100644 --- a/src/util/hasher.cpp +++ b/src/util/hasher.cpp @@ -19,14 +19,15 @@ SaltedWtxidHasher::SaltedWtxidHasher() : k0{FastRandomContext().rand64()}, k1{FastRandomContext().rand64()} {} -SaltedOutpointHasher::SaltedOutpointHasher(bool deterministic) : - k0{deterministic ? 0x8e819f2607a18de6 : FastRandomContext().rand64()}, - k1{deterministic ? 0xf4020d2e3983b0eb : FastRandomContext().rand64()} +SaltedOutpointHasher::SaltedOutpointHasher(bool deterministic) : m_hasher{ + deterministic ? 0x8e819f2607a18de6 : FastRandomContext().rand64(), + deterministic ? 0xf4020d2e3983b0eb : FastRandomContext().rand64()} {} SaltedSipHasher::SaltedSipHasher() : m_k0{FastRandomContext().rand64()}, - m_k1{FastRandomContext().rand64()} {} + m_k1{FastRandomContext().rand64()} +{} size_t SaltedSipHasher::operator()(const std::span& script) const { diff --git a/src/util/hasher.h b/src/util/hasher.h index be5d9eb13df..e7e69530cc5 100644 --- a/src/util/hasher.h +++ b/src/util/hasher.h @@ -60,9 +60,7 @@ public: class SaltedOutpointHasher { -private: - /** Salt */ - const uint64_t k0, k1; + const PresaltedSipHasher m_hasher; public: SaltedOutpointHasher(bool deterministic = false); @@ -76,8 +74,9 @@ 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.ToUint256(), id.n); + size_t operator()(const COutPoint& id) const noexcept + { + return m_hasher(id.hash.ToUint256(), id.n); } };