aboutsummaryrefslogtreecommitdiff
path: root/src/crypto/chacha20.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/chacha20.h')
-rw-r--r--src/crypto/chacha20.h49
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