/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 | } |