Bitcoin ABC  0.22.12
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 
27 CSipHasher::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 
36 CSipHasher &CSipHasher::Write(uint64_t data) {
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;
42  SIPROUND;
43  SIPROUND;
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 
55 CSipHasher &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  int c = count;
59 
60  while (size--) {
61  t |= uint64_t(*(data++)) << (8 * (c % 8));
62  c++;
63  if ((c & 7) == 0) {
64  v3 ^= t;
65  SIPROUND;
66  SIPROUND;
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 
82 uint64_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;
88  SIPROUND;
89  SIPROUND;
90  v0 ^= t;
91  v2 ^= 0xFF;
92  SIPROUND;
93  SIPROUND;
94  SIPROUND;
95  SIPROUND;
96  return v0 ^ v1 ^ v2 ^ v3;
97 }
98 
99 uint64_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 
138 uint64_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 }
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256 &val)
Optimized SipHash-2-4 implementation for uint256.
Definition: siphash.cpp:99
uint64_t v[4]
Definition: siphash.h:15
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data.
Definition: siphash.cpp:36
CSipHasher(uint64_t k0, uint64_t k1)
Construct a SipHash calculator initialized with 128-bit key (k0, k1)
Definition: siphash.cpp:27
#define SIPROUND
Definition: siphash.cpp:9
int count
Definition: siphash.h:17
uint64_t Finalize() const
Compute the 64-bit SipHash-2-4 of the data written so far.
Definition: siphash.cpp:82
uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256 &val, uint32_t extra)
Definition: siphash.cpp:138
static const uint8_t k1[32]
uint64_t tmp
Definition: siphash.h:16
256-bit opaque blob.
Definition: uint256.h:120
SipHash-2-4.
Definition: siphash.h:13
uint64_t GetUint64(int pos) const
Definition: uint256.h:86