Bitcoin ABC 0.30.7
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
55CSipHasher &CSipHasher::Write(const uint8_t *data, size_t size) {
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 (size--) {
61 t |= uint64_t(*(data++)) << (8 * (c % 8));
62 c++;
63 if ((c & 7) == 0) {
64 v3 ^= t;
67 v0 ^= t;
68 t = 0;
69 }
70 }
71
72 v[0] = v0;
73 v[1] = v1;
74 v[2] = v2;
75 v[3] = v3;
76 count = c;
77 tmp = t;
78
79 return *this;
80}
81
82uint64_t CSipHasher::Finalize() const {
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 /* Specialized implementation for efficiency */
101 uint64_t d = val.GetUint64(0);
102
103 uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
104 uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
105 uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
106 uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
107
108 SIPROUND;
109 SIPROUND;
110 v0 ^= d;
111 d = val.GetUint64(1);
112 v3 ^= d;
113 SIPROUND;
114 SIPROUND;
115 v0 ^= d;
116 d = val.GetUint64(2);
117 v3 ^= d;
118 SIPROUND;
119 SIPROUND;
120 v0 ^= d;
121 d = val.GetUint64(3);
122 v3 ^= d;
123 SIPROUND;
124 SIPROUND;
125 v0 ^= d;
126 v3 ^= uint64_t(4) << 59;
127 SIPROUND;
128 SIPROUND;
129 v0 ^= uint64_t(4) << 59;
130 v2 ^= 0xFF;
131 SIPROUND;
132 SIPROUND;
133 SIPROUND;
134 SIPROUND;
135 return v0 ^ v1 ^ v2 ^ v3;
136}
137
138uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256 &val,
139 uint32_t extra) {
140 /* Specialized implementation for efficiency */
141 uint64_t d = val.GetUint64(0);
142
143 uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
144 uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
145 uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
146 uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
147
148 SIPROUND;
149 SIPROUND;
150 v0 ^= d;
151 d = val.GetUint64(1);
152 v3 ^= d;
153 SIPROUND;
154 SIPROUND;
155 v0 ^= d;
156 d = val.GetUint64(2);
157 v3 ^= d;
158 SIPROUND;
159 SIPROUND;
160 v0 ^= d;
161 d = val.GetUint64(3);
162 v3 ^= d;
163 SIPROUND;
164 SIPROUND;
165 v0 ^= d;
166 d = (uint64_t(36) << 56) | extra;
167 v3 ^= d;
168 SIPROUND;
169 SIPROUND;
170 v0 ^= d;
171 v2 ^= 0xFF;
172 SIPROUND;
173 SIPROUND;
174 SIPROUND;
175 SIPROUND;
176 return v0 ^ v1 ^ v2 ^ v3;
177}
static const uint8_t k1[32]
SipHash-2-4.
Definition: siphash.h:13
uint64_t v[4]
Definition: siphash.h:15
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
Definition: siphash.cpp:82
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:16
uint8_t count
Definition: siphash.h:18
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:138
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:9
assert(!tx.IsCoinBase())