Repository: bitcoin/bitcoin
File: src/crypto/chacha20.cpp (C++)

Code before:
#include <support/cleanse.h>
#include <span.h>

#include <algorithm>
#include <bit>
#include <string.h>

#define QUARTERROUND(a,b,c,d) \
  a += b; d = std::rotl(d ^ a, 16); \
  c += d; b = std::rotl(b ^ c, 12); \
  a += b; d = std::rotl(d ^ a, 8); \
  c += d; b = std::rotl(b ^ c, 7);

#define REPEAT10(a) do { {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; } while(0)

void ChaCha20Aligned::SetKey(Span<const std::byte> key) noexcept
{
    assert(key.size() == KEYLEN);
    input[0] = ReadLE32(UCharCast(key.data() + 0));
    input[1] = ReadLE32(UCharCast(key.data() + 4));
    input[2] = ReadLE32(UCharCast(key.data() + 8));
    input[3] = ReadLE32(UCharCast(key.data() + 12));
    input[4] = ReadLE32(UCharCast(key.data() + 16));
    input[5] = ReadLE32(UCharCast(key.data() + 20));
    input[6] = ReadLE32(UCharCast(key.data() + 24));
    input[7] = ReadLE32(UCharCast(key.data() + 28));
    input[8] = 0;
    input[9] = 0;
    input[10] = 0;
    input[11] = 0;
}

ChaCha20Aligned::~ChaCha20Aligned()
{
    memory_cleanse(input, sizeof(input));
}

ChaCha20Aligned::ChaCha20Aligned(Span<const std::byte> key) noexcept
{
    SetKey(key);
}

void ChaCha20Aligned::Seek(Nonce96 nonce, uint32_t block_counter) noexcept
{
    input[8] = block_counter;
    input[9] = nonce.first;
    input[10] = nonce.second;
    input[11] = nonce.second >> 32;
}

inline void ChaCha20Aligned::Keystream(Span<std::byte> output) noexcept

Review comment (suggestion):
maybe we can roll back the loop now to something like:
```C++
void ChaCha20Aligned::SetKey(Span<const std::byte> key) noexcept
{
    assert(key.size() == KEYLEN);
    constexpr int words{KEYLEN / sizeof(uint32_t)};
    for (int i{0}; i < words; ++i) input[i] = ReadLE32(key.data() + i * sizeof(uint32_t));
    std::memset(&input[words], 0, (std::size(input) - words) * sizeof(uint32_t));
}
```

Code after:
#include <support/cleanse.h>
#include <span.h>

#include <algorithm>
#include <bit>
#include <string.h>

#define QUARTERROUND(a,b,c,d) \
  a += b; d = std::rotl(d ^ a, 16); \
  c += d; b = std::rotl(b ^ c, 12); \
  a += b; d = std::rotl(d ^ a, 8); \
  c += d; b = std::rotl(b ^ c, 7);

#define REPEAT10(a) do { {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; {a}; } while(0)

void ChaCha20Aligned::SetKey(Span<const std::byte> key) noexcept
{
    assert(key.size() == KEYLEN);
    input[0] = ReadLE32(key.data() + 0);
    input[1] = ReadLE32(key.data() + 4);
    input[2] = ReadLE32(key.data() + 8);
    input[3] = ReadLE32(key.data() + 12);
    input[4] = ReadLE32(key.data() + 16);
    input[5] = ReadLE32(key.data() + 20);
    input[6] = ReadLE32(key.data() + 24);
    input[7] = ReadLE32(key.data() + 28);
    input[8] = 0;
    input[9] = 0;
    input[10] = 0;
    input[11] = 0;
}

ChaCha20Aligned::~ChaCha20Aligned()
{
    memory_cleanse(input, sizeof(input));
}

ChaCha20Aligned::ChaCha20Aligned(Span<const std::byte> key) noexcept
{
    SetKey(key);
}

void ChaCha20Aligned::Seek(Nonce96 nonce, uint32_t block_counter) noexcept
{
    input[8] = block_counter;
    input[9] = nonce.first;
    input[10] = nonce.second;
    input[11] = nonce.second >> 32;
}

inline void ChaCha20Aligned::Keystream(Span<std::byte> output) noexcept