Coverage Report

Created: 2026-04-20 22:07

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