Browse Source

Add specialization of SipHash for 256 + 32 bit data

We'll need a version of SipHash for tuples of 256 bits and 32 bits
data, when CCoinsViewCache switches from using txids to COutPoints as
keys.
0.15
Pieter Wuille 7 years ago
parent
commit
7e00322906
  1. 41
      src/hash.cpp
  2. 1
      src/hash.h
  3. 17
      src/test/hash_tests.cpp

41
src/hash.cpp

@ -208,3 +208,44 @@ uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val) @@ -208,3 +208,44 @@ uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val)
SIPROUND;
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 d = val.GetUint64(0);
uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
SIPROUND;
SIPROUND;
v0 ^= d;
d = val.GetUint64(1);
v3 ^= d;
SIPROUND;
SIPROUND;
v0 ^= d;
d = val.GetUint64(2);
v3 ^= d;
SIPROUND;
SIPROUND;
v0 ^= d;
d = val.GetUint64(3);
v3 ^= d;
SIPROUND;
SIPROUND;
v0 ^= d;
d = (((uint64_t)36) << 56) | extra;
v3 ^= d;
SIPROUND;
SIPROUND;
v0 ^= d;
v2 ^= 0xFF;
SIPROUND;
SIPROUND;
SIPROUND;
SIPROUND;
return v0 ^ v1 ^ v2 ^ v3;
}

1
src/hash.h

@ -241,5 +241,6 @@ public: @@ -241,5 +241,6 @@ 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);
#endif // BITCOIN_HASH_H

17
src/test/hash_tests.cpp

@ -128,6 +128,23 @@ BOOST_AUTO_TEST_CASE(siphash) @@ -128,6 +128,23 @@ BOOST_AUTO_TEST_CASE(siphash)
tx.nVersion = 1;
ss << tx;
BOOST_CHECK_EQUAL(SipHashUint256(1, 2, ss.GetHash()), 0x79751e980c2a0a35ULL);
// Check consistency between CSipHasher and SipHashUint256[Extra].
FastRandomContext ctx;
for (int i = 0; i < 16; ++i) {
uint64_t k1 = ctx.rand64();
uint64_t k2 = ctx.rand64();
uint256 x = GetRandHash();
uint32_t n = ctx.rand32();
uint8_t nb[4];
WriteLE32(nb, n);
CSipHasher sip256(k1, k2);
sip256.Write(x.begin(), 32);
CSipHasher sip288 = sip256;
sip288.Write(nb, 4);
BOOST_CHECK_EQUAL(SipHashUint256(k1, k2, x), sip256.Finalize());
BOOST_CHECK_EQUAL(SipHashUint256Extra(k1, k2, x, n), sip288.Finalize());
}
}
BOOST_AUTO_TEST_SUITE_END()

Loading…
Cancel
Save