Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alter the ChaCha20Poly1305@Bitcoin AEAD to the new specification #20962

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,8 @@ crypto_libbitcoin_crypto_base_la_LDFLAGS = $(AM_LDFLAGS) -static
crypto_libbitcoin_crypto_base_la_SOURCES = \
crypto/aes.cpp \
crypto/aes.h \
crypto/chacha_poly_aead.h \
crypto/chacha_poly_aead.cpp \
crypto/bip324_suite.h \
crypto/bip324_suite.cpp \
crypto/chacha20.h \
crypto/chacha20.cpp \
crypto/common.h \
Expand All @@ -504,6 +504,8 @@ crypto_libbitcoin_crypto_base_la_SOURCES = \
crypto/poly1305.cpp \
crypto/muhash.h \
crypto/muhash.cpp \
crypto/rfc8439.h \
crypto/rfc8439.cpp \
crypto/ripemd160.cpp \
crypto/ripemd160.h \
crypto/sha1.cpp \
Expand Down
3 changes: 2 additions & 1 deletion src/Makefile.bench.include
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ bench_bench_bitcoin_SOURCES = \
bench/bench.cpp \
bench/bench.h \
bench/bench_bitcoin.cpp \
bench/bip324_suite.cpp \
bench/block_assemble.cpp \
bench/ccoins_caching.cpp \
bench/chacha20.cpp \
bench/chacha_poly_aead.cpp \
bench/checkblock.cpp \
bench/checkqueue.cpp \
bench/crypto_hash.cpp \
Expand All @@ -41,6 +41,7 @@ bench_bench_bitcoin_SOURCES = \
bench/peer_eviction.cpp \
bench/poly1305.cpp \
bench/prevector.cpp \
bench/rfc8439.cpp \
bench/rollingbloom.cpp \
bench/rpc_blockchain.cpp \
bench/rpc_mempool.cpp \
Expand Down
4 changes: 2 additions & 2 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,12 @@ test_fuzz_fuzz_SOURCES = \
test/fuzz/crypto.cpp \
test/fuzz/crypto_aes256.cpp \
test/fuzz/crypto_aes256cbc.cpp \
test/fuzz/crypto_bip324_suite.cpp \
test/fuzz/crypto_chacha20.cpp \
test/fuzz/crypto_chacha20_poly1305_aead.cpp \
test/fuzz/crypto_common.cpp \
test/fuzz/crypto_diff_fuzz_chacha20.cpp \
test/fuzz/crypto_hkdf_hmac_sha256_l32.cpp \
test/fuzz/crypto_poly1305.cpp \
test/fuzz/crypto_rfc8439.cpp \
test/fuzz/cuckoocache.cpp \
test/fuzz/decode_tx.cpp \
test/fuzz/descriptor_parse.cpp \
Expand Down
117 changes: 117 additions & 0 deletions src/bench/bip324_suite.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright (c) 2019-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.


#include <assert.h>
#include <bench/bench.h>
#include <crypto/bip324_suite.h>
#include <crypto/rfc8439.h> // for the RFC8439_TAGLEN constant
#include <hash.h>

#include <array>
#include <cstddef>
#include <vector>

/* Number of bytes to process per iteration */
static constexpr uint64_t BUFFER_SIZE_TINY = 64;
static constexpr uint64_t BUFFER_SIZE_SMALL = 256;
static constexpr uint64_t BUFFER_SIZE_LARGE = 1024 * 1024;

static const std::vector<std::byte> zero_vec(BIP324_KEY_LEN, std::byte{0x00});

static void BIP324_CIPHER_SUITE(benchmark::Bench& bench, size_t plaintext_len, bool include_decryption)
{
std::array<std::byte, BIP324_KEY_LEN> zero_arr;
memcpy(zero_arr.data(), zero_vec.data(), BIP324_KEY_LEN);
BIP324CipherSuite enc{zero_arr, zero_arr, zero_arr};
BIP324CipherSuite dec{zero_arr, zero_arr, zero_arr};

auto ciphertext_len = BIP324_LENGTH_FIELD_LEN + BIP324_HEADER_LEN + plaintext_len + RFC8439_TAGLEN;

std::vector<std::byte> in(plaintext_len, std::byte{0x00});
std::vector<std::byte> out(ciphertext_len, std::byte{0x00});

BIP324HeaderFlags flags{0};

bench.batch(plaintext_len).unit("byte").run([&] {
// encrypt or decrypt the buffer with a static key
const bool crypt_ok_1 = enc.Crypt(in, out, flags, true);
assert(crypt_ok_1);

if (include_decryption) {
// if we decrypt, we need to decrypt the length first
std::array<std::byte, BIP324_LENGTH_FIELD_LEN> len_ciphertext;
memcpy(len_ciphertext.data(), out.data(), BIP324_LENGTH_FIELD_LEN);
(void)dec.DecryptLength(len_ciphertext);
const bool crypt_ok_2 = dec.Crypt({out.data() + BIP324_LENGTH_FIELD_LEN, out.size() - BIP324_LENGTH_FIELD_LEN}, in, flags, false);
assert(crypt_ok_2);
}
});
}

static void BIP324_CIPHER_SUITE_64BYTES_ONLY_ENCRYPT(benchmark::Bench& bench)
{
BIP324_CIPHER_SUITE(bench, BUFFER_SIZE_TINY, false);
}

static void BIP324_CIPHER_SUITE_256BYTES_ONLY_ENCRYPT(benchmark::Bench& bench)
{
BIP324_CIPHER_SUITE(bench, BUFFER_SIZE_SMALL, false);
}

static void BIP324_CIPHER_SUITE_1MB_ONLY_ENCRYPT(benchmark::Bench& bench)
{
BIP324_CIPHER_SUITE(bench, BUFFER_SIZE_LARGE, false);
}

static void BIP324_CIPHER_SUITE_64BYTES_ENCRYPT_DECRYPT(benchmark::Bench& bench)
{
BIP324_CIPHER_SUITE(bench, BUFFER_SIZE_TINY, true);
}

static void BIP324_CIPHER_SUITE_256BYTES_ENCRYPT_DECRYPT(benchmark::Bench& bench)
{
BIP324_CIPHER_SUITE(bench, BUFFER_SIZE_SMALL, true);
}

static void BIP324_CIPHER_SUITE_1MB_ENCRYPT_DECRYPT(benchmark::Bench& bench)
{
BIP324_CIPHER_SUITE(bench, BUFFER_SIZE_LARGE, true);
}

// Add Hash() (dbl-sha256) bench for comparison

static void HASH(benchmark::Bench& bench, size_t buffersize)
{
uint8_t hash[CHash256::OUTPUT_SIZE];
std::vector<uint8_t> in(buffersize, 0);
bench.batch(in.size()).unit("byte").run([&] {
CHash256().Write(in).Finalize(hash);
});
}

static void HASH_64BYTES(benchmark::Bench& bench)
{
HASH(bench, BUFFER_SIZE_TINY);
}

static void HASH_256BYTES(benchmark::Bench& bench)
{
HASH(bench, BUFFER_SIZE_SMALL);
}

static void HASH_1MB(benchmark::Bench& bench)
{
HASH(bench, BUFFER_SIZE_LARGE);
}

BENCHMARK(BIP324_CIPHER_SUITE_64BYTES_ONLY_ENCRYPT);
BENCHMARK(BIP324_CIPHER_SUITE_256BYTES_ONLY_ENCRYPT);
BENCHMARK(BIP324_CIPHER_SUITE_1MB_ONLY_ENCRYPT);
BENCHMARK(BIP324_CIPHER_SUITE_64BYTES_ENCRYPT_DECRYPT);
BENCHMARK(BIP324_CIPHER_SUITE_256BYTES_ENCRYPT_DECRYPT);
BENCHMARK(BIP324_CIPHER_SUITE_1MB_ENCRYPT_DECRYPT);
BENCHMARK(HASH_64BYTES);
BENCHMARK(HASH_256BYTES);
BENCHMARK(HASH_1MB);
126 changes: 0 additions & 126 deletions src/bench/chacha_poly_aead.cpp

This file was deleted.

75 changes: 75 additions & 0 deletions src/bench/rfc8439.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright (c) 2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <assert.h>
#include <bench/bench.h>
#include <crypto/rfc8439.h>

#include <array>
#include <cstddef>
#include <vector>

static constexpr uint64_t AAD_SIZE = 32;
static constexpr uint64_t PLAINTEXT_SIZE_TINY = 64;
static constexpr uint64_t PLAINTEXT_SIZE_SMALL = 256;
static constexpr uint64_t PLAINTEXT_SIZE_LARGE = 1024 * 1024;

static std::vector<std::byte> zero_key(32, std::byte{0x00});
static std::vector<std::byte> aad(AAD_SIZE, std::byte{0x00});
std::array<std::byte, 12> nonce = {std::byte{0x00}, std::byte{0x01}, std::byte{0x02}, std::byte{0x03},
std::byte{0x04}, std::byte{0x05}, std::byte{0x06}, std::byte{0x07},
std::byte{0x08}, std::byte{0x09}, std::byte{0x0a}, std::byte{0x0b}};

static void RFC8439_AEAD(benchmark::Bench& bench, size_t plaintext_size, bool include_decryption)
{
const std::vector<std::byte> plaintext_in(plaintext_size, std::byte{0x00});
std::vector<Span<const std::byte>> ins{plaintext_in};

bench.batch(plaintext_size).unit("byte").run([&] {
auto encrypted = RFC8439Encrypt(aad, zero_key, nonce, ins);

if (include_decryption) {
auto decrypted = RFC8439Decrypt(aad, zero_key, nonce, encrypted);
assert(decrypted.success);
assert(memcmp(decrypted.plaintext.data(), plaintext_in.data(), plaintext_in.size()) == 0);
}
});
}

static void RFC8439_AEAD_64BYTES_ONLY_ENCRYPT(benchmark::Bench& bench)
{
RFC8439_AEAD(bench, PLAINTEXT_SIZE_TINY, false);
}

static void RFC8439_AEAD_256BYTES_ONLY_ENCRYPT(benchmark::Bench& bench)
{
RFC8439_AEAD(bench, PLAINTEXT_SIZE_SMALL, false);
}

static void RFC8439_AEAD_1MB_ONLY_ENCRYPT(benchmark::Bench& bench)
{
RFC8439_AEAD(bench, PLAINTEXT_SIZE_LARGE, false);
}

static void RFC8439_AEAD_64BYTES_ENCRYPT_DECRYPT(benchmark::Bench& bench)
{
RFC8439_AEAD(bench, PLAINTEXT_SIZE_TINY, true);
}

static void RFC8439_AEAD_256BYTES_ENCRYPT_DECRYPT(benchmark::Bench& bench)
{
RFC8439_AEAD(bench, PLAINTEXT_SIZE_SMALL, true);
}

static void RFC8439_AEAD_1MB_ENCRYPT_DECRYPT(benchmark::Bench& bench)
{
RFC8439_AEAD(bench, PLAINTEXT_SIZE_LARGE, true);
}

BENCHMARK(RFC8439_AEAD_64BYTES_ONLY_ENCRYPT);
BENCHMARK(RFC8439_AEAD_256BYTES_ONLY_ENCRYPT);
BENCHMARK(RFC8439_AEAD_1MB_ONLY_ENCRYPT);
BENCHMARK(RFC8439_AEAD_64BYTES_ENCRYPT_DECRYPT);
BENCHMARK(RFC8439_AEAD_256BYTES_ENCRYPT_DECRYPT);
BENCHMARK(RFC8439_AEAD_1MB_ENCRYPT_DECRYPT);