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