/root/bitcoin/src/crypto/siphash.h
Line | Count | Source |
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 | 0 | 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 | 0 | 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 |