Skip to content

Commit 4fb789e

Browse files
committed
Extract CSipHasher to it's own file in crypto/ directory.
This is a move-only commit with the exception of changes to includes.
1 parent 6b8d0a2 commit 4fb789e

15 files changed

+234
-206
lines changed

src/Makefile.am

+3-1
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,9 @@ crypto_libbitcoin_crypto_base_a_SOURCES = \
321321
crypto/sha256.cpp \
322322
crypto/sha256.h \
323323
crypto/sha512.cpp \
324-
crypto/sha512.h
324+
crypto/sha512.h \
325+
crypto/siphash.cpp \
326+
crypto/siphash.h
325327

326328
if USE_ASM
327329
crypto_libbitcoin_crypto_base_a_SOURCES += crypto/sha256_sse4.cpp

src/bench/block_assemble.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <coins.h>
88
#include <consensus/merkle.h>
99
#include <consensus/validation.h>
10+
#include <crypto/sha256.h>
1011
#include <miner.h>
1112
#include <policy/policy.h>
1213
#include <pow.h>

src/bench/crypto_hash.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <crypto/sha1.h>
1515
#include <crypto/sha256.h>
1616
#include <crypto/sha512.h>
17+
#include <crypto/siphash.h>
1718

1819
/* Number of bytes to hash per iteration */
1920
static const uint64_t BUFFER_SIZE = 1000*1000;

src/blockencodings.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
#include <consensus/consensus.h>
77
#include <consensus/validation.h>
88
#include <chainparams.h>
9-
#include <hash.h>
9+
#include <crypto/sha256.h>
10+
#include <crypto/siphash.h>
1011
#include <random.h>
1112
#include <streams.h>
1213
#include <txmempool.h>

src/blockfilter.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <blockfilter.h>
6+
#include <crypto/siphash.h>
67
#include <hash.h>
78
#include <primitives/transaction.h>
89
#include <script/script.h>

src/coins.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <consensus/consensus.h>
88
#include <random.h>
9+
#include <version.h>
910

1011
bool CCoinsView::GetCoin(const COutPoint &outpoint, Coin &coin) const { return false; }
1112
uint256 CCoinsView::GetBestBlock() const { return uint256(); }

src/coins.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <primitives/transaction.h>
1010
#include <compressor.h>
1111
#include <core_memusage.h>
12-
#include <hash.h>
12+
#include <crypto/siphash.h>
1313
#include <memusage.h>
1414
#include <serialize.h>
1515
#include <uint256.h>

src/crypto/siphash.cpp

+173
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
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 do { \
10+
v0 += v1; v1 = ROTL(v1, 13); v1 ^= v0; \
11+
v0 = ROTL(v0, 32); \
12+
v2 += v3; v3 = ROTL(v3, 16); v3 ^= v2; \
13+
v0 += v3; v3 = ROTL(v3, 21); v3 ^= v0; \
14+
v2 += v1; v1 = ROTL(v1, 17); v1 ^= v2; \
15+
v2 = ROTL(v2, 32); \
16+
} while (0)
17+
18+
CSipHasher::CSipHasher(uint64_t k0, uint64_t k1)
19+
{
20+
v[0] = 0x736f6d6570736575ULL ^ k0;
21+
v[1] = 0x646f72616e646f6dULL ^ k1;
22+
v[2] = 0x6c7967656e657261ULL ^ k0;
23+
v[3] = 0x7465646279746573ULL ^ k1;
24+
count = 0;
25+
tmp = 0;
26+
}
27+
28+
CSipHasher& CSipHasher::Write(uint64_t data)
29+
{
30+
uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
31+
32+
assert(count % 8 == 0);
33+
34+
v3 ^= data;
35+
SIPROUND;
36+
SIPROUND;
37+
v0 ^= data;
38+
39+
v[0] = v0;
40+
v[1] = v1;
41+
v[2] = v2;
42+
v[3] = v3;
43+
44+
count += 8;
45+
return *this;
46+
}
47+
48+
CSipHasher& CSipHasher::Write(const unsigned char* data, size_t size)
49+
{
50+
uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
51+
uint64_t t = tmp;
52+
int c = count;
53+
54+
while (size--) {
55+
t |= ((uint64_t)(*(data++))) << (8 * (c % 8));
56+
c++;
57+
if ((c & 7) == 0) {
58+
v3 ^= t;
59+
SIPROUND;
60+
SIPROUND;
61+
v0 ^= t;
62+
t = 0;
63+
}
64+
}
65+
66+
v[0] = v0;
67+
v[1] = v1;
68+
v[2] = v2;
69+
v[3] = v3;
70+
count = c;
71+
tmp = t;
72+
73+
return *this;
74+
}
75+
76+
uint64_t CSipHasher::Finalize() const
77+
{
78+
uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
79+
80+
uint64_t t = tmp | (((uint64_t)count) << 56);
81+
82+
v3 ^= t;
83+
SIPROUND;
84+
SIPROUND;
85+
v0 ^= t;
86+
v2 ^= 0xFF;
87+
SIPROUND;
88+
SIPROUND;
89+
SIPROUND;
90+
SIPROUND;
91+
return v0 ^ v1 ^ v2 ^ v3;
92+
}
93+
94+
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val)
95+
{
96+
/* Specialized implementation for efficiency */
97+
uint64_t d = val.GetUint64(0);
98+
99+
uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
100+
uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
101+
uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
102+
uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
103+
104+
SIPROUND;
105+
SIPROUND;
106+
v0 ^= d;
107+
d = val.GetUint64(1);
108+
v3 ^= d;
109+
SIPROUND;
110+
SIPROUND;
111+
v0 ^= d;
112+
d = val.GetUint64(2);
113+
v3 ^= d;
114+
SIPROUND;
115+
SIPROUND;
116+
v0 ^= d;
117+
d = val.GetUint64(3);
118+
v3 ^= d;
119+
SIPROUND;
120+
SIPROUND;
121+
v0 ^= d;
122+
v3 ^= ((uint64_t)4) << 59;
123+
SIPROUND;
124+
SIPROUND;
125+
v0 ^= ((uint64_t)4) << 59;
126+
v2 ^= 0xFF;
127+
SIPROUND;
128+
SIPROUND;
129+
SIPROUND;
130+
SIPROUND;
131+
return v0 ^ v1 ^ v2 ^ v3;
132+
}
133+
134+
uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256& val, uint32_t extra)
135+
{
136+
/* Specialized implementation for efficiency */
137+
uint64_t d = val.GetUint64(0);
138+
139+
uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
140+
uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
141+
uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
142+
uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
143+
144+
SIPROUND;
145+
SIPROUND;
146+
v0 ^= d;
147+
d = val.GetUint64(1);
148+
v3 ^= d;
149+
SIPROUND;
150+
SIPROUND;
151+
v0 ^= d;
152+
d = val.GetUint64(2);
153+
v3 ^= d;
154+
SIPROUND;
155+
SIPROUND;
156+
v0 ^= d;
157+
d = val.GetUint64(3);
158+
v3 ^= d;
159+
SIPROUND;
160+
SIPROUND;
161+
v0 ^= d;
162+
d = (((uint64_t)36) << 56) | extra;
163+
v3 ^= d;
164+
SIPROUND;
165+
SIPROUND;
166+
v0 ^= d;
167+
v2 ^= 0xFF;
168+
SIPROUND;
169+
SIPROUND;
170+
SIPROUND;
171+
SIPROUND;
172+
return v0 ^ v1 ^ v2 ^ v3;
173+
}

src/crypto/siphash.h

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
#ifndef BITCOIN_CRYPTO_SIPHASH_H
6+
#define BITCOIN_CRYPTO_SIPHASH_H
7+
8+
#include <stdint.h>
9+
10+
#include <uint256.h>
11+
12+
/** SipHash-2-4 */
13+
class CSipHasher
14+
{
15+
private:
16+
uint64_t v[4];
17+
uint64_t tmp;
18+
int count;
19+
20+
public:
21+
/** Construct a SipHash calculator initialized with 128-bit key (k0, k1) */
22+
CSipHasher(uint64_t k0, uint64_t k1);
23+
/** Hash a 64-bit integer worth of data
24+
* It is treated as if this was the little-endian interpretation of 8 bytes.
25+
* This function can only be used when a multiple of 8 bytes have been written so far.
26+
*/
27+
CSipHasher& Write(uint64_t data);
28+
/** Hash arbitrary bytes. */
29+
CSipHasher& Write(const unsigned char* data, size_t size);
30+
/** Compute the 64-bit SipHash-2-4 of the data written so far. The object remains untouched. */
31+
uint64_t Finalize() const;
32+
};
33+
34+
/** Optimized SipHash-2-4 implementation for uint256.
35+
*
36+
* It is identical to:
37+
* SipHasher(k0, k1)
38+
* .Write(val.GetUint64(0))
39+
* .Write(val.GetUint64(1))
40+
* .Write(val.GetUint64(2))
41+
* .Write(val.GetUint64(3))
42+
* .Finalize()
43+
*/
44+
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val);
45+
uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256& val, uint32_t extra);
46+
47+
#endif // BITCOIN_CRYPTO_SIPHASH_H

0 commit comments

Comments
 (0)