Branch data Line data Source code
1 : : // Copyright (c) 2016-present The Bitcoin Core developers
2 : : // Distributed under the MIT software license, see the accompanying
3 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 : :
5 : : #ifndef BITCOIN_CRYPTO_SIPHASH_H
6 : : #define BITCOIN_CRYPTO_SIPHASH_H
7 : :
8 : : #include <array>
9 : : #include <cstdint>
10 : : #include <span>
11 : :
12 : : class uint256;
13 : :
14 : : /** Shared SipHash internal state v[0..3], initialized from (k0, k1). */
15 : : class SipHashState
16 : : {
17 : : static constexpr uint64_t C0{0x736f6d6570736575ULL}, C1{0x646f72616e646f6dULL}, C2{0x6c7967656e657261ULL}, C3{0x7465646279746573ULL};
18 : :
19 : : public:
20 : 4672015 : explicit SipHashState(uint64_t k0, uint64_t k1) noexcept : v{C0 ^ k0, C1 ^ k1, C2 ^ k0, C3 ^ k1} {}
21 : :
22 : : std::array<uint64_t, 4> v{};
23 : : };
24 : :
25 : : /** General SipHash-2-4 implementation. */
26 : : class CSipHasher
27 : : {
28 : : SipHashState m_state;
29 : : uint64_t m_tmp{0};
30 : : uint8_t m_count{0}; //!< Only the low 8 bits of the input size matter.
31 : :
32 : : public:
33 : : /** Construct a SipHash calculator initialized with 128-bit key (k0, k1). */
34 : : CSipHasher(uint64_t k0, uint64_t k1);
35 : : /** Hash a 64-bit integer worth of data.
36 : : * It is treated as if this was the little-endian interpretation of 8 bytes.
37 : : * This function can only be used when a multiple of 8 bytes have been written so far.
38 : : */
39 : : CSipHasher& Write(uint64_t data);
40 : : /** Hash arbitrary bytes. */
41 : : CSipHasher& Write(std::span<const unsigned char> data);
42 : : /** Compute the 64-bit SipHash-2-4 of the data written so far. The object remains untouched. */
43 : : uint64_t Finalize() const;
44 : : };
45 : :
46 : : /**
47 : : * Optimized SipHash-2-4 implementation for uint256.
48 : : *
49 : : * This class caches the initial SipHash v[0..3] state derived from (k0, k1)
50 : : * and implements a specialized hashing path for uint256 values, with or
51 : : * without an extra 32-bit word. The internal state is immutable, so
52 : : * PresaltedSipHasher instances can be reused for multiple hashes with the
53 : : * same key.
54 : : */
55 : : class PresaltedSipHasher
56 : : {
57 : : const SipHashState m_state;
58 : :
59 : : public:
60 [ + - ]: 229913 : explicit PresaltedSipHasher(uint64_t k0, uint64_t k1) noexcept : m_state{k0, k1} {}
61 : :
62 : : /** Equivalent to CSipHasher(k0, k1).Write(val).Finalize(). */
63 : : uint64_t operator()(const uint256& val) const noexcept;
64 : :
65 : : /**
66 : : * Equivalent to CSipHasher(k0, k1).Write(val).Write(extra).Finalize(),
67 : : * with `extra` encoded as 4 little-endian bytes.
68 : : */
69 : : uint64_t operator()(const uint256& val, uint32_t extra) const noexcept;
70 : : };
71 : :
72 : : #endif // BITCOIN_CRYPTO_SIPHASH_H
|