diff options
Diffstat (limited to 'src/crypto/chacha20.h')
-rw-r--r-- | src/crypto/chacha20.h | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/crypto/chacha20.h b/src/crypto/chacha20.h index f2ec21d82e..d1b2094e7e 100644 --- a/src/crypto/chacha20.h +++ b/src/crypto/chacha20.h @@ -5,6 +5,10 @@ #ifndef BITCOIN_CRYPTO_CHACHA20_H #define BITCOIN_CRYPTO_CHACHA20_H +#include <span.h> + +#include <array> +#include <cstddef> #include <cstdlib> #include <stdint.h> #include <utility> @@ -29,6 +33,9 @@ public: /** Initialize a cipher with specified 32-byte key. */ ChaCha20Aligned(const unsigned char* key32); + /** Destructor to clean up private memory. */ + ~ChaCha20Aligned(); + /** set 32-byte key. */ void SetKey32(const unsigned char* key32); @@ -72,6 +79,9 @@ public: /** Initialize a cipher with specified 32-byte key. */ ChaCha20(const unsigned char* key32) : m_aligned(key32) {} + /** Destructor to clean up private memory. */ + ~ChaCha20(); + /** set 32-byte key. */ void SetKey32(const unsigned char* key32) { @@ -98,4 +108,43 @@ public: void Crypt(const unsigned char* input, unsigned char* output, size_t bytes); }; +/** Forward-secure ChaCha20 + * + * This implements a stream cipher that automatically transitions to a new stream with a new key + * and new nonce after a predefined number of encryptions or decryptions. + * + * See BIP324 for details. + */ +class FSChaCha20 +{ +private: + /** Internal stream cipher. */ + ChaCha20 m_chacha20; + + /** The number of encryptions/decryptions before a rekey happens. */ + const uint32_t m_rekey_interval; + + /** The number of encryptions/decryptions since the last rekey. */ + uint32_t m_chunk_counter{0}; + + /** The number of rekey operations that have happened. */ + uint64_t m_rekey_counter{0}; + +public: + /** Length of keys expected by the constructor. */ + static constexpr unsigned KEYLEN = 32; + + // No copy or move to protect the secret. + FSChaCha20(const FSChaCha20&) = delete; + FSChaCha20(FSChaCha20&&) = delete; + FSChaCha20& operator=(const FSChaCha20&) = delete; + FSChaCha20& operator=(FSChaCha20&&) = delete; + + /** Construct an FSChaCha20 cipher that rekeys every rekey_interval Crypt() calls. */ + FSChaCha20(Span<const std::byte> key, uint32_t rekey_interval) noexcept; + + /** Encrypt or decrypt a chunk. */ + void Crypt(Span<const std::byte> input, Span<std::byte> output) noexcept; +}; + #endif // BITCOIN_CRYPTO_CHACHA20_H |