Bitcoin ABC 0.32.4
P2P Digital Currency
chacha20.h
Go to the documentation of this file.
1// Copyright (c) 2017 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 <span.h>
9
10#include <array>
11#include <cstddef>
12#include <cstdint>
13#include <cstdlib>
14#include <utility>
15
16// classes for ChaCha20 256-bit stream cipher developed by Daniel J. Bernstein
17// https://cr.yp.to/chacha/chacha-20080128.pdf.
18//
19// The 128-bit input is here implemented as a 96-bit nonce and a 32-bit block
20// counter, as in RFC8439 Section 2.3. When the 32-bit block counter overflows
21// the first 32-bit part of the nonce is automatically incremented, making it
22// conceptually compatible with variants that use a 64/64 split instead.
23
26private:
27 uint32_t input[12];
28
29public:
31 static constexpr unsigned KEYLEN{32};
32
37 static constexpr unsigned BLOCKLEN{64};
38
40 ChaCha20Aligned() noexcept = delete;
41
43 ChaCha20Aligned(Span<const std::byte> key) noexcept;
44
47
49 void SetKey(Span<const std::byte> key) noexcept;
50
62 using Nonce96 = std::pair<uint32_t, uint64_t>;
63
71 void Seek(Nonce96 nonce, uint32_t block_counter) noexcept;
72
77 void Keystream(Span<std::byte> out) noexcept;
78
85 void Crypt(Span<const std::byte> input, Span<std::byte> output) noexcept;
86};
87
89class ChaCha20 {
90private:
92 std::array<std::byte, ChaCha20Aligned::BLOCKLEN> m_buffer;
93 unsigned m_bufleft{0};
94
95public:
97 static constexpr unsigned KEYLEN = ChaCha20Aligned::KEYLEN;
98
100 ChaCha20() noexcept = delete;
101
103 ChaCha20(Span<const std::byte> key) noexcept : m_aligned(key) {}
104
106 ~ChaCha20();
107
109 void SetKey(Span<const std::byte> key) noexcept;
110
113
118 void Seek(Nonce96 nonce, uint32_t block_counter) noexcept {
119 m_aligned.Seek(nonce, block_counter);
120 m_bufleft = 0;
121 }
122
129 void Crypt(Span<const std::byte> in_bytes,
130 Span<std::byte> out_bytes) noexcept;
131
133 void Keystream(Span<std::byte> out) noexcept;
134};
135
146private:
149
151 const uint32_t m_rekey_interval;
152
154 uint32_t m_chunk_counter{0};
155
157 uint64_t m_rekey_counter{0};
158
159public:
161 static constexpr unsigned KEYLEN = 32;
162
163 // No copy or move to protect the secret.
164 FSChaCha20(const FSChaCha20 &) = delete;
165 FSChaCha20(FSChaCha20 &&) = delete;
166 FSChaCha20 &operator=(const FSChaCha20 &) = delete;
168
173 FSChaCha20(Span<const std::byte> key, uint32_t rekey_interval) noexcept;
174
176 void Crypt(Span<const std::byte> input, Span<std::byte> output) noexcept;
177};
178
179#endif // BITCOIN_CRYPTO_CHACHA20_H
ChaCha20 cipher that only operates on multiples of 64 bytes.
Definition: chacha20.h:25
void Keystream(Span< std::byte > out) noexcept
outputs the keystream into out, whose length must be a multiple of BLOCKLEN.
Definition: chacha20.cpp:79
void Crypt(Span< const std::byte > input, Span< std::byte > output) noexcept
en/deciphers the message <input> and write the result into <output>
Definition: chacha20.cpp:178
ChaCha20Aligned() noexcept=delete
For safety, disallow initialization without key.
std::pair< uint32_t, uint64_t > Nonce96
Type for 96-bit nonces used by the Set function below.
Definition: chacha20.h:62
void SetKey(Span< const std::byte > key) noexcept
Set 32-byte key, and seek to nonce 0 and block position 0.
Definition: chacha20.cpp:46
uint32_t input[12]
Definition: chacha20.h:27
void Seek(Nonce96 nonce, uint32_t block_counter) noexcept
Set the 96-bit nonce and 32-bit block counter.
Definition: chacha20.cpp:72
static constexpr unsigned BLOCKLEN
Block size (inputs/outputs to Keystream / Crypt should be multiples of this).
Definition: chacha20.h:37
static constexpr unsigned KEYLEN
Expected key length in constructor and SetKey.
Definition: chacha20.h:31
Unrestricted ChaCha20 cipher.
Definition: chacha20.h:89
ChaCha20() noexcept=delete
For safety, disallow initialization without key.
std::array< std::byte, ChaCha20Aligned::BLOCKLEN > m_buffer
Definition: chacha20.h:92
void Seek(Nonce96 nonce, uint32_t block_counter) noexcept
Set the 96-bit nonce and 32-bit block counter.
Definition: chacha20.h:118
ChaCha20Aligned m_aligned
Definition: chacha20.h:91
ChaCha20Aligned::Nonce96 Nonce96
96-bit nonce type.
Definition: chacha20.h:112
Forward-secure ChaCha20.
Definition: chacha20.h:145
ChaCha20 m_chacha20
Internal stream cipher.
Definition: chacha20.h:148
FSChaCha20 & operator=(const FSChaCha20 &)=delete
FSChaCha20(FSChaCha20 &&)=delete
const uint32_t m_rekey_interval
The number of encryptions/decryptions before a rekey happens.
Definition: chacha20.h:151
FSChaCha20 & operator=(FSChaCha20 &&)=delete
FSChaCha20(const FSChaCha20 &)=delete
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:94
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259