fuzz coverage

Coverage Report

Created: 2025-06-01 19:34

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