Bitcoin Core  31.0.0
P2P Digital Currency
chacha20.h
Go to the documentation of this file.
1 // Copyright (c) 2017-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 #ifndef BITCOIN_CRYPTO_CHACHA20_H
6 #define BITCOIN_CRYPTO_CHACHA20_H
7 
8 #include <array>
9 #include <cstddef>
10 #include <cstdint>
11 #include <span>
12 #include <utility>
13 
14 // classes for ChaCha20 256-bit stream cipher developed by Daniel J. Bernstein
15 // https://cr.yp.to/chacha/chacha-20080128.pdf.
16 //
17 // The 128-bit input is here implemented as a 96-bit nonce and a 32-bit block
18 // counter, as in RFC8439 Section 2.3. When the 32-bit block counter overflows
19 // the first 32-bit part of the nonce is automatically incremented, making it
20 // conceptually compatible with variants that use a 64/64 split instead.
21 
24 {
25 private:
26  uint32_t input[12];
27 
28 public:
30  static constexpr unsigned KEYLEN{32};
31 
33  static constexpr unsigned BLOCKLEN{64};
34 
36  ChaCha20Aligned() noexcept = delete;
37 
39  ChaCha20Aligned(std::span<const std::byte> key) noexcept;
40 
42  ~ChaCha20Aligned();
43 
45  void SetKey(std::span<const std::byte> key) noexcept;
46 
55  using Nonce96 = std::pair<uint32_t, uint64_t>;
56 
62  void Seek(Nonce96 nonce, uint32_t block_counter) noexcept;
63 
65  void Keystream(std::span<std::byte> out) noexcept;
66 
71  void Crypt(std::span<const std::byte> input, std::span<std::byte> output) noexcept;
72 };
73 
75 class ChaCha20
76 {
77 private:
79  std::array<std::byte, ChaCha20Aligned::BLOCKLEN> m_buffer;
80  unsigned m_bufleft{0};
81 
82 public:
84  static constexpr unsigned KEYLEN = ChaCha20Aligned::KEYLEN;
85 
87  ChaCha20() noexcept = delete;
88 
90  ChaCha20(std::span<const std::byte> key) noexcept : m_aligned(key) {}
91 
93  ~ChaCha20();
94 
96  void SetKey(std::span<const std::byte> key) noexcept;
97 
100 
102  void Seek(Nonce96 nonce, uint32_t block_counter) noexcept
103  {
104  m_aligned.Seek(nonce, block_counter);
105  m_bufleft = 0;
106  }
107 
112  void Crypt(std::span<const std::byte> in_bytes, std::span<std::byte> out_bytes) noexcept;
113 
115  void Keystream(std::span<std::byte> out) noexcept;
116 };
117 
126 {
127 private:
130 
132  const uint32_t m_rekey_interval;
133 
135  uint32_t m_chunk_counter{0};
136 
138  uint64_t m_rekey_counter{0};
139 
140 public:
142  static constexpr unsigned KEYLEN = 32;
143 
144  // No copy or move to protect the secret.
145  FSChaCha20(const FSChaCha20&) = delete;
146  FSChaCha20(FSChaCha20&&) = delete;
147  FSChaCha20& operator=(const FSChaCha20&) = delete;
148  FSChaCha20& operator=(FSChaCha20&&) = delete;
149 
151  FSChaCha20(std::span<const std::byte> key, uint32_t rekey_interval) noexcept;
152 
154  void Crypt(std::span<const std::byte> input, std::span<std::byte> output) noexcept;
155 };
156 
157 #endif // BITCOIN_CRYPTO_CHACHA20_H
unsigned int nonce
Definition: miner_tests.cpp:82
void Seek(Nonce96 nonce, uint32_t block_counter) noexcept
Set the 96-bit nonce and 32-bit block counter.
Definition: chacha20.h:102
Definition: common.h:29
static constexpr unsigned BLOCKLEN
Block size (inputs/outputs to Keystream / Crypt should be multiples of this).
Definition: chacha20.h:33
ChaCha20Aligned::Nonce96 Nonce96
96-bit nonce type.
Definition: chacha20.h:99
void SetKey(std::span< const std::byte > key) noexcept
Set 32-byte key, and seek to nonce 0 and block position 0.
Definition: chacha20.cpp:24
ChaCha20Aligned m_aligned
Definition: chacha20.h:78
const uint32_t m_rekey_interval
The number of encryptions/decryptions before a rekey happens.
Definition: chacha20.h:132
static constexpr unsigned KEYLEN
Expected key length in constructor and SetKey.
Definition: chacha20.h:30
Unrestricted ChaCha20 cipher.
Definition: chacha20.h:75
uint32_t input[12]
Definition: chacha20.h:26
void Seek(Nonce96 nonce, uint32_t block_counter) noexcept
Set the 96-bit nonce and 32-bit block counter.
Definition: chacha20.cpp:51
Forward-secure ChaCha20.
Definition: chacha20.h:125
void Crypt(std::span< const std::byte > input, std::span< std::byte > output) noexcept
en/deciphers the message <input> and write the result into <output>
Definition: chacha20.cpp:160
ChaCha20Aligned() noexcept=delete
For safety, disallow initialization without key.
std::array< std::byte, ChaCha20Aligned::BLOCKLEN > m_buffer
Definition: chacha20.h:79
std::pair< uint32_t, uint64_t > Nonce96
Type for 96-bit nonces used by the Set function below.
Definition: chacha20.h:55
ChaCha20 m_chacha20
Internal stream cipher.
Definition: chacha20.h:129
void Keystream(std::span< std::byte > out) noexcept
outputs the keystream into out, whose length must be a multiple of BLOCKLEN.
Definition: chacha20.cpp:59
ChaCha20 cipher that only operates on multiples of 64 bytes.
Definition: chacha20.h:23