Bitcoin ABC 0.32.4
P2P Digital Currency
siphash.cpp
Go to the documentation of this file.
1// Copyright (c) 2016-2018 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#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
8
9#define SIPROUND \
10 do { \
11 v0 += v1; \
12 v1 = ROTL(v1, 13); \
13 v1 ^= v0; \
14 v0 = ROTL(v0, 32); \
15 v2 += v3; \
16 v3 = ROTL(v3, 16); \
17 v3 ^= v2; \
18 v0 += v3; \
19 v3 = ROTL(v3, 21); \
20 v3 ^= v0; \
21 v2 += v1; \
22 v1 = ROTL(v1, 17); \
23 v1 ^= v2; \
24 v2 = ROTL(v2, 32); \
25 } while (0)
26
27CSipHasher::CSipHasher(uint64_t k0, uint64_t k1) {
28 v[0] = 0x736f6d6570736575ULL ^ k0;
29 v[1] = 0x646f72616e646f6dULL ^ k1;
30 v[2] = 0x6c7967656e657261ULL ^ k0;
31 v[3] = 0x7465646279746573ULL ^ k1;
32 count = 0;
33 tmp = 0;
34}
35
37 uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
38
39 assert(count % 8 == 0);
40
41 v3 ^= data;
44 v0 ^= data;
45
46 v[0] = v0;
47 v[1] = v1;
48 v[2] = v2;
49 v[3] = v3;
50
51 count += 8;
52 return *this;
53}
54
56 uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
57 uint64_t t = tmp;
58 uint8_t c = count;
59
60 while (data.size() > 0) {
61 t |= uint64_t{data.front()} << (8 * (c % 8));
62 c++;
63 if ((c & 7) == 0) {
64 v3 ^= t;
67 v0 ^= t;
68 t = 0;
69 }
70 data = data.subspan(1);
71 }
72
73 v[0] = v0;
74 v[1] = v1;
75 v[2] = v2;
76 v[3] = v3;
77 count = c;
78 tmp = t;
79
80 return *this;
81}
82
83uint64_t CSipHasher::Finalize() const {
84 uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
85
86 uint64_t t = tmp | (uint64_t(count) << 56);
87
88 v3 ^= t;
91 v0 ^= t;
92 v2 ^= 0xFF;
97 return v0 ^ v1 ^ v2 ^ v3;
98}
99
100uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256 &val) {
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,
140 uint32_t extra) {
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:14
uint64_t v[4]
Definition: siphash.h:16
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
Definition: siphash.cpp:83
CSipHasher(uint64_t k0, uint64_t k1)
Construct a SipHash calculator initialized with 128-bit key (k0, k1)
Definition: siphash.cpp:27
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data.
Definition: siphash.cpp:36
uint64_t tmp
Definition: siphash.h:17
uint8_t count
Definition: siphash.h:19
constexpr std::size_t size() const noexcept
Definition: span.h:210
CONSTEXPR_IF_NOT_DEBUG Span< C > subspan(std::size_t offset) const noexcept
Definition: span.h:219
CONSTEXPR_IF_NOT_DEBUG C & front() const noexcept
Definition: span.h:202
uint64_t GetUint64(int pos) const
Definition: uint256.h:95
256-bit opaque blob.
Definition: uint256.h:129
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:100
#define SIPROUND
Definition: siphash.cpp:9
assert(!tx.IsCoinBase())