Coverage Report

Created: 2025-06-10 13:21

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