fuzz coverage

Coverage Report

Created: 2026-04-24 13:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/crypto/sha3.cpp
Line
Count
Source
1
// Copyright (c) 2020-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
// Based on https://github.com/mjosaarinen/tiny_sha3/blob/master/sha3.c
6
// by Markku-Juhani O. Saarinen <mjos@iki.fi>
7
8
#include <crypto/sha3.h>
9
#include <crypto/common.h>
10
11
#include <algorithm>
12
#include <bit>
13
#include <cassert>
14
#include <iterator>
15
#include <span>
16
17
void KeccakF(uint64_t (&st)[25])
18
912
{
19
912
    static constexpr uint64_t RNDC[24] = {
20
912
        0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
21
912
        0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
22
912
        0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
23
912
        0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
24
912
        0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
25
912
        0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
26
912
    };
27
912
    static constexpr int ROUNDS = 24;
28
29
22.8k
    for (int round = 0; round < ROUNDS; 
++round21.8k
) {
30
21.8k
        uint64_t bc0, bc1, bc2, bc3, bc4, t;
31
32
        // Theta
33
21.8k
        bc0 = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
34
21.8k
        bc1 = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
35
21.8k
        bc2 = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
36
21.8k
        bc3 = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
37
21.8k
        bc4 = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
38
21.8k
        t = bc4 ^ std::rotl(bc1, 1); st[0] ^= t; st[5] ^= t; st[10] ^= t; st[15] ^= t; st[20] ^= t;
39
21.8k
        t = bc0 ^ std::rotl(bc2, 1); st[1] ^= t; st[6] ^= t; st[11] ^= t; st[16] ^= t; st[21] ^= t;
40
21.8k
        t = bc1 ^ std::rotl(bc3, 1); st[2] ^= t; st[7] ^= t; st[12] ^= t; st[17] ^= t; st[22] ^= t;
41
21.8k
        t = bc2 ^ std::rotl(bc4, 1); st[3] ^= t; st[8] ^= t; st[13] ^= t; st[18] ^= t; st[23] ^= t;
42
21.8k
        t = bc3 ^ std::rotl(bc0, 1); st[4] ^= t; st[9] ^= t; st[14] ^= t; st[19] ^= t; st[24] ^= t;
43
44
        // Rho Pi
45
21.8k
        t = st[1];
46
21.8k
        bc0 = st[10]; st[10] = std::rotl(t, 1); t = bc0;
47
21.8k
        bc0 = st[7]; st[7] = std::rotl(t, 3); t = bc0;
48
21.8k
        bc0 = st[11]; st[11] = std::rotl(t, 6); t = bc0;
49
21.8k
        bc0 = st[17]; st[17] = std::rotl(t, 10); t = bc0;
50
21.8k
        bc0 = st[18]; st[18] = std::rotl(t, 15); t = bc0;
51
21.8k
        bc0 = st[3]; st[3] = std::rotl(t, 21); t = bc0;
52
21.8k
        bc0 = st[5]; st[5] = std::rotl(t, 28); t = bc0;
53
21.8k
        bc0 = st[16]; st[16] = std::rotl(t, 36); t = bc0;
54
21.8k
        bc0 = st[8]; st[8] = std::rotl(t, 45); t = bc0;
55
21.8k
        bc0 = st[21]; st[21] = std::rotl(t, 55); t = bc0;
56
21.8k
        bc0 = st[24]; st[24] = std::rotl(t, 2); t = bc0;
57
21.8k
        bc0 = st[4]; st[4] = std::rotl(t, 14); t = bc0;
58
21.8k
        bc0 = st[15]; st[15] = std::rotl(t, 27); t = bc0;
59
21.8k
        bc0 = st[23]; st[23] = std::rotl(t, 41); t = bc0;
60
21.8k
        bc0 = st[19]; st[19] = std::rotl(t, 56); t = bc0;
61
21.8k
        bc0 = st[13]; st[13] = std::rotl(t, 8); t = bc0;
62
21.8k
        bc0 = st[12]; st[12] = std::rotl(t, 25); t = bc0;
63
21.8k
        bc0 = st[2]; st[2] = std::rotl(t, 43); t = bc0;
64
21.8k
        bc0 = st[20]; st[20] = std::rotl(t, 62); t = bc0;
65
21.8k
        bc0 = st[14]; st[14] = std::rotl(t, 18); t = bc0;
66
21.8k
        bc0 = st[22]; st[22] = std::rotl(t, 39); t = bc0;
67
21.8k
        bc0 = st[9]; st[9] = std::rotl(t, 61); t = bc0;
68
21.8k
        bc0 = st[6]; st[6] = std::rotl(t, 20); t = bc0;
69
21.8k
        st[1] = std::rotl(t, 44);
70
71
        // Chi Iota
72
21.8k
        bc0 = st[0]; bc1 = st[1]; bc2 = st[2]; bc3 = st[3]; bc4 = st[4];
73
21.8k
        st[0] = bc0 ^ (~bc1 & bc2) ^ RNDC[round];
74
21.8k
        st[1] = bc1 ^ (~bc2 & bc3);
75
21.8k
        st[2] = bc2 ^ (~bc3 & bc4);
76
21.8k
        st[3] = bc3 ^ (~bc4 & bc0);
77
21.8k
        st[4] = bc4 ^ (~bc0 & bc1);
78
21.8k
        bc0 = st[5]; bc1 = st[6]; bc2 = st[7]; bc3 = st[8]; bc4 = st[9];
79
21.8k
        st[5] = bc0 ^ (~bc1 & bc2);
80
21.8k
        st[6] = bc1 ^ (~bc2 & bc3);
81
21.8k
        st[7] = bc2 ^ (~bc3 & bc4);
82
21.8k
        st[8] = bc3 ^ (~bc4 & bc0);
83
21.8k
        st[9] = bc4 ^ (~bc0 & bc1);
84
21.8k
        bc0 = st[10]; bc1 = st[11]; bc2 = st[12]; bc3 = st[13]; bc4 = st[14];
85
21.8k
        st[10] = bc0 ^ (~bc1 & bc2);
86
21.8k
        st[11] = bc1 ^ (~bc2 & bc3);
87
21.8k
        st[12] = bc2 ^ (~bc3 & bc4);
88
21.8k
        st[13] = bc3 ^ (~bc4 & bc0);
89
21.8k
        st[14] = bc4 ^ (~bc0 & bc1);
90
21.8k
        bc0 = st[15]; bc1 = st[16]; bc2 = st[17]; bc3 = st[18]; bc4 = st[19];
91
21.8k
        st[15] = bc0 ^ (~bc1 & bc2);
92
21.8k
        st[16] = bc1 ^ (~bc2 & bc3);
93
21.8k
        st[17] = bc2 ^ (~bc3 & bc4);
94
21.8k
        st[18] = bc3 ^ (~bc4 & bc0);
95
21.8k
        st[19] = bc4 ^ (~bc0 & bc1);
96
21.8k
        bc0 = st[20]; bc1 = st[21]; bc2 = st[22]; bc3 = st[23]; bc4 = st[24];
97
21.8k
        st[20] = bc0 ^ (~bc1 & bc2);
98
21.8k
        st[21] = bc1 ^ (~bc2 & bc3);
99
21.8k
        st[22] = bc2 ^ (~bc3 & bc4);
100
21.8k
        st[23] = bc3 ^ (~bc4 & bc0);
101
21.8k
        st[24] = bc4 ^ (~bc0 & bc1);
102
21.8k
    }
103
912
}
104
105
SHA3_256& SHA3_256::Write(std::span<const unsigned char> data)
106
2.73k
{
107
2.73k
    if (m_bufsize && 
data.size() >= sizeof(m_buffer) - m_bufsize1.82k
) {
108
        // Fill the buffer and process it.
109
1.82k
        std::copy(data.begin(), data.begin() + (sizeof(m_buffer) - m_bufsize), m_buffer + m_bufsize);
110
1.82k
        data = data.subspan(sizeof(m_buffer) - m_bufsize);
111
1.82k
        m_state[m_pos++] ^= ReadLE64(m_buffer);
112
1.82k
        m_bufsize = 0;
113
1.82k
        if (m_pos == RATE_BUFFERS) {
114
0
            KeccakF(m_state);
115
0
            m_pos = 0;
116
0
        }
117
1.82k
    }
118
6.38k
    while (data.size() >= sizeof(m_buffer)) {
119
        // Process chunks directly from the buffer.
120
3.64k
        m_state[m_pos++] ^= ReadLE64(data.data());
121
3.64k
        data = data.subspan(8);
122
3.64k
        if (m_pos == RATE_BUFFERS) {
123
0
            KeccakF(m_state);
124
0
            m_pos = 0;
125
0
        }
126
3.64k
    }
127
2.73k
    if (data.size()) {
128
        // Keep the remainder in the buffer.
129
1.82k
        std::copy(data.begin(), data.end(), m_buffer + m_bufsize);
130
1.82k
        m_bufsize += data.size();
131
1.82k
    }
132
2.73k
    return *this;
133
2.73k
}
134
135
SHA3_256& SHA3_256::Finalize(std::span<unsigned char> output)
136
912
{
137
912
    assert(output.size() == OUTPUT_SIZE);
138
912
    std::fill(m_buffer + m_bufsize, m_buffer + sizeof(m_buffer), 0);
139
912
    m_buffer[m_bufsize] ^= 0x06;
140
912
    m_state[m_pos] ^= ReadLE64(m_buffer);
141
912
    m_state[RATE_BUFFERS - 1] ^= 0x8000000000000000;
142
912
    KeccakF(m_state);
143
4.56k
    for (unsigned i = 0; i < 4; 
++i3.64k
) {
144
3.64k
        WriteLE64(output.data() + 8 * i, m_state[i]);
145
3.64k
    }
146
912
    return *this;
147
912
}
148
149
SHA3_256& SHA3_256::Reset()
150
0
{
151
0
    m_bufsize = 0;
152
0
    m_pos = 0;
153
0
    std::fill(std::begin(m_state), std::end(m_state), 0);
154
0
    return *this;
155
0
}