Bitcoin Core 30.99.0
P2P Digital Currency
siphash.cpp
Go to the documentation of this file.
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#include <crypto/siphash.h>
6
7#include <uint256.h>
8
9#include <bit>
10#include <cassert>
11#include <span>
12
13#define SIPROUND do { \
14 v0 += v1; v1 = std::rotl(v1, 13); v1 ^= v0; \
15 v0 = std::rotl(v0, 32); \
16 v2 += v3; v3 = std::rotl(v3, 16); v3 ^= v2; \
17 v0 += v3; v3 = std::rotl(v3, 21); v3 ^= v0; \
18 v2 += v1; v1 = std::rotl(v1, 17); v1 ^= v2; \
19 v2 = std::rotl(v2, 32); \
20} while (0)
21
22CSipHasher::CSipHasher(uint64_t k0, uint64_t k1)
23{
24 v[0] = 0x736f6d6570736575ULL ^ k0;
25 v[1] = 0x646f72616e646f6dULL ^ k1;
26 v[2] = 0x6c7967656e657261ULL ^ k0;
27 v[3] = 0x7465646279746573ULL ^ k1;
28 count = 0;
29 tmp = 0;
30}
31
33{
34 uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
35
36 assert(count % 8 == 0);
37
38 v3 ^= data;
41 v0 ^= data;
42
43 v[0] = v0;
44 v[1] = v1;
45 v[2] = v2;
46 v[3] = v3;
47
48 count += 8;
49 return *this;
50}
51
52CSipHasher& CSipHasher::Write(std::span<const unsigned char> data)
53{
54 uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
55 uint64_t t = tmp;
56 uint8_t c = count;
57
58 while (data.size() > 0) {
59 t |= uint64_t{data.front()} << (8 * (c % 8));
60 c++;
61 if ((c & 7) == 0) {
62 v3 ^= t;
65 v0 ^= t;
66 t = 0;
67 }
68 data = data.subspan(1);
69 }
70
71 v[0] = v0;
72 v[1] = v1;
73 v[2] = v2;
74 v[3] = v3;
75 count = c;
76 tmp = t;
77
78 return *this;
79}
80
81uint64_t CSipHasher::Finalize() const
82{
83 uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
84
85 uint64_t t = tmp | (((uint64_t)count) << 56);
86
87 v3 ^= t;
90 v0 ^= t;
91 v2 ^= 0xFF;
96 return v0 ^ v1 ^ v2 ^ v3;
97}
98
99uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val)
100{
101 /* Specialized implementation for efficiency */
102 uint64_t d = val.GetUint64(0);
103
104 uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
105 uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
106 uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
107 uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
108
109 SIPROUND;
110 SIPROUND;
111 v0 ^= d;
112 d = val.GetUint64(1);
113 v3 ^= d;
114 SIPROUND;
115 SIPROUND;
116 v0 ^= d;
117 d = val.GetUint64(2);
118 v3 ^= d;
119 SIPROUND;
120 SIPROUND;
121 v0 ^= d;
122 d = val.GetUint64(3);
123 v3 ^= d;
124 SIPROUND;
125 SIPROUND;
126 v0 ^= d;
127 v3 ^= (uint64_t{4}) << 59;
128 SIPROUND;
129 SIPROUND;
130 v0 ^= (uint64_t{4}) << 59;
131 v2 ^= 0xFF;
132 SIPROUND;
133 SIPROUND;
134 SIPROUND;
135 SIPROUND;
136 return v0 ^ v1 ^ v2 ^ v3;
137}
138
139uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256& val, uint32_t extra)
140{
141 /* Specialized implementation for efficiency */
142 uint64_t d = val.GetUint64(0);
143
144 uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
145 uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
146 uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
147 uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
148
149 SIPROUND;
150 SIPROUND;
151 v0 ^= d;
152 d = val.GetUint64(1);
153 v3 ^= d;
154 SIPROUND;
155 SIPROUND;
156 v0 ^= d;
157 d = val.GetUint64(2);
158 v3 ^= d;
159 SIPROUND;
160 SIPROUND;
161 v0 ^= d;
162 d = val.GetUint64(3);
163 v3 ^= d;
164 SIPROUND;
165 SIPROUND;
166 v0 ^= d;
167 d = ((uint64_t{36}) << 56) | extra;
168 v3 ^= d;
169 SIPROUND;
170 SIPROUND;
171 v0 ^= d;
172 v2 ^= 0xFF;
173 SIPROUND;
174 SIPROUND;
175 SIPROUND;
176 SIPROUND;
177 return v0 ^ v1 ^ v2 ^ v3;
178}
SipHash-2-4.
Definition: siphash.h:15
uint64_t v[4]
Definition: siphash.h:17
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
Definition: siphash.cpp:81
CSipHasher(uint64_t k0, uint64_t k1)
Construct a SipHash calculator initialized with 128-bit key (k0, k1)
Definition: siphash.cpp:22
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data It is treated as if this was the little-endian interpretation of ...
Definition: siphash.cpp:32
uint64_t tmp
Definition: siphash.h:18
uint8_t count
Definition: siphash.h:19
constexpr uint64_t GetUint64(int pos) const
Definition: uint256.h:109
256-bit opaque blob.
Definition: uint256.h:196
uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256 &val, uint32_t extra)
Definition: siphash.cpp:139
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256 &val)
Optimized SipHash-2-4 implementation for uint256.
Definition: siphash.cpp:99
#define SIPROUND
Definition: siphash.cpp:13
assert(!tx.IsCoinBase())