Coverage Report

Created: 2026-08-05 14:35

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