fuzz coverage

Coverage Report

Created: 2025-10-29 15:27

/Users/eugenesiegel/btc/bitcoin/src/crypto/sha3.cpp
Line
Count
Source (jump to first uncovered line)
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 <array>
13
#include <bit>
14
#include <cstdint>
15
#include <span>
16
17
void KeccakF(uint64_t (&st)[25])
18
239
{
19
239
    static constexpr uint64_t RNDC[24] = {
20
239
        0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
21
239
        0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
22
239
        0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
23
239
        0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
24
239
        0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
25
239
        0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
26
239
    };
27
239
    static constexpr int ROUNDS = 24;
28
29
5.97k
    for (int round = 0; round < ROUNDS; 
++round5.73k
) {
30
5.73k
        uint64_t bc0, bc1, bc2, bc3, bc4, t;
31
32
        // Theta
33
5.73k
        bc0 = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
34
5.73k
        bc1 = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
35
5.73k
        bc2 = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
36
5.73k
        bc3 = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
37
5.73k
        bc4 = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
38
5.73k
        t = bc4 ^ std::rotl(bc1, 1); st[0] ^= t; st[5] ^= t; st[10] ^= t; st[15] ^= t; st[20] ^= t;
39
5.73k
        t = bc0 ^ std::rotl(bc2, 1); st[1] ^= t; st[6] ^= t; st[11] ^= t; st[16] ^= t; st[21] ^= t;
40
5.73k
        t = bc1 ^ std::rotl(bc3, 1); st[2] ^= t; st[7] ^= t; st[12] ^= t; st[17] ^= t; st[22] ^= t;
41
5.73k
        t = bc2 ^ std::rotl(bc4, 1); st[3] ^= t; st[8] ^= t; st[13] ^= t; st[18] ^= t; st[23] ^= t;
42
5.73k
        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
5.73k
        t = st[1];
46
5.73k
        bc0 = st[10]; st[10] = std::rotl(t, 1); t = bc0;
47
5.73k
        bc0 = st[7]; st[7] = std::rotl(t, 3); t = bc0;
48
5.73k
        bc0 = st[11]; st[11] = std::rotl(t, 6); t = bc0;
49
5.73k
        bc0 = st[17]; st[17] = std::rotl(t, 10); t = bc0;
50
5.73k
        bc0 = st[18]; st[18] = std::rotl(t, 15); t = bc0;
51
5.73k
        bc0 = st[3]; st[3] = std::rotl(t, 21); t = bc0;
52
5.73k
        bc0 = st[5]; st[5] = std::rotl(t, 28); t = bc0;
53
5.73k
        bc0 = st[16]; st[16] = std::rotl(t, 36); t = bc0;
54
5.73k
        bc0 = st[8]; st[8] = std::rotl(t, 45); t = bc0;
55
5.73k
        bc0 = st[21]; st[21] = std::rotl(t, 55); t = bc0;
56
5.73k
        bc0 = st[24]; st[24] = std::rotl(t, 2); t = bc0;
57
5.73k
        bc0 = st[4]; st[4] = std::rotl(t, 14); t = bc0;
58
5.73k
        bc0 = st[15]; st[15] = std::rotl(t, 27); t = bc0;
59
5.73k
        bc0 = st[23]; st[23] = std::rotl(t, 41); t = bc0;
60
5.73k
        bc0 = st[19]; st[19] = std::rotl(t, 56); t = bc0;
61
5.73k
        bc0 = st[13]; st[13] = std::rotl(t, 8); t = bc0;
62
5.73k
        bc0 = st[12]; st[12] = std::rotl(t, 25); t = bc0;
63
5.73k
        bc0 = st[2]; st[2] = std::rotl(t, 43); t = bc0;
64
5.73k
        bc0 = st[20]; st[20] = std::rotl(t, 62); t = bc0;
65
5.73k
        bc0 = st[14]; st[14] = std::rotl(t, 18); t = bc0;
66
5.73k
        bc0 = st[22]; st[22] = std::rotl(t, 39); t = bc0;
67
5.73k
        bc0 = st[9]; st[9] = std::rotl(t, 61); t = bc0;
68
5.73k
        bc0 = st[6]; st[6] = std::rotl(t, 20); t = bc0;
69
5.73k
        st[1] = std::rotl(t, 44);
70
71
        // Chi Iota
72
5.73k
        bc0 = st[0]; bc1 = st[1]; bc2 = st[2]; bc3 = st[3]; bc4 = st[4];
73
5.73k
        st[0] = bc0 ^ (~bc1 & bc2) ^ RNDC[round];
74
5.73k
        st[1] = bc1 ^ (~bc2 & bc3);
75
5.73k
        st[2] = bc2 ^ (~bc3 & bc4);
76
5.73k
        st[3] = bc3 ^ (~bc4 & bc0);
77
5.73k
        st[4] = bc4 ^ (~bc0 & bc1);
78
5.73k
        bc0 = st[5]; bc1 = st[6]; bc2 = st[7]; bc3 = st[8]; bc4 = st[9];
79
5.73k
        st[5] = bc0 ^ (~bc1 & bc2);
80
5.73k
        st[6] = bc1 ^ (~bc2 & bc3);
81
5.73k
        st[7] = bc2 ^ (~bc3 & bc4);
82
5.73k
        st[8] = bc3 ^ (~bc4 & bc0);
83
5.73k
        st[9] = bc4 ^ (~bc0 & bc1);
84
5.73k
        bc0 = st[10]; bc1 = st[11]; bc2 = st[12]; bc3 = st[13]; bc4 = st[14];
85
5.73k
        st[10] = bc0 ^ (~bc1 & bc2);
86
5.73k
        st[11] = bc1 ^ (~bc2 & bc3);
87
5.73k
        st[12] = bc2 ^ (~bc3 & bc4);
88
5.73k
        st[13] = bc3 ^ (~bc4 & bc0);
89
5.73k
        st[14] = bc4 ^ (~bc0 & bc1);
90
5.73k
        bc0 = st[15]; bc1 = st[16]; bc2 = st[17]; bc3 = st[18]; bc4 = st[19];
91
5.73k
        st[15] = bc0 ^ (~bc1 & bc2);
92
5.73k
        st[16] = bc1 ^ (~bc2 & bc3);
93
5.73k
        st[17] = bc2 ^ (~bc3 & bc4);
94
5.73k
        st[18] = bc3 ^ (~bc4 & bc0);
95
5.73k
        st[19] = bc4 ^ (~bc0 & bc1);
96
5.73k
        bc0 = st[20]; bc1 = st[21]; bc2 = st[22]; bc3 = st[23]; bc4 = st[24];
97
5.73k
        st[20] = bc0 ^ (~bc1 & bc2);
98
5.73k
        st[21] = bc1 ^ (~bc2 & bc3);
99
5.73k
        st[22] = bc2 ^ (~bc3 & bc4);
100
5.73k
        st[23] = bc3 ^ (~bc4 & bc0);
101
5.73k
        st[24] = bc4 ^ (~bc0 & bc1);
102
5.73k
    }
103
239
}
104
105
SHA3_256& SHA3_256::Write(std::span<const unsigned char> data)
106
717
{
107
717
    if (m_bufsize && 
data.size() >= sizeof(m_buffer) - m_bufsize478
) {
108
        // Fill the buffer and process it.
109
478
        std::copy(data.begin(), data.begin() + (sizeof(m_buffer) - m_bufsize), m_buffer + m_bufsize);
110
478
        data = data.subspan(sizeof(m_buffer) - m_bufsize);
111
478
        m_state[m_pos++] ^= ReadLE64(m_buffer);
112
478
        m_bufsize = 0;
113
478
        if (m_pos == RATE_BUFFERS) {
114
0
            KeccakF(m_state);
115
0
            m_pos = 0;
116
0
        }
117
478
    }
118
1.67k
    while (data.size() >= sizeof(m_buffer)) {
119
        // Process chunks directly from the buffer.
120
956
        m_state[m_pos++] ^= ReadLE64(data.data());
121
956
        data = data.subspan(8);
122
956
        if (m_pos == RATE_BUFFERS) {
123
0
            KeccakF(m_state);
124
0
            m_pos = 0;
125
0
        }
126
956
    }
127
717
    if (data.size()) {
128
        // Keep the remainder in the buffer.
129
478
        std::copy(data.begin(), data.end(), m_buffer + m_bufsize);
130
478
        m_bufsize += data.size();
131
478
    }
132
717
    return *this;
133
717
}
134
135
SHA3_256& SHA3_256::Finalize(std::span<unsigned char> output)
136
239
{
137
239
    assert(output.size() == OUTPUT_SIZE);
138
239
    std::fill(m_buffer + m_bufsize, m_buffer + sizeof(m_buffer), 0);
139
239
    m_buffer[m_bufsize] ^= 0x06;
140
239
    m_state[m_pos] ^= ReadLE64(m_buffer);
141
239
    m_state[RATE_BUFFERS - 1] ^= 0x8000000000000000;
142
239
    KeccakF(m_state);
143
1.19k
    for (unsigned i = 0; i < 4; 
++i956
) {
144
956
        WriteLE64(output.data() + 8 * i, m_state[i]);
145
956
    }
146
239
    return *this;
147
239
}
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
}