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

#25361 bip324-cipher-suite #12

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
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 @@ -524,8 +524,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 @@ -539,6 +539,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 @@ -43,6 +43,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
3 changes: 2 additions & 1 deletion src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,13 @@ 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
116 changes: 116 additions & 0 deletions src/bench/bip324_suite.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// 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>
#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 contents_len, bool include_decryption)
{
BIP324Key zero_arr;
std::memcpy(zero_arr.data(), zero_vec.data(), BIP324_KEY_LEN);
BIP324CipherSuite enc{zero_arr, zero_arr};
BIP324CipherSuite dec{zero_arr, zero_arr};

auto packet_len = BIP324_LENGTH_FIELD_LEN + BIP324_HEADER_LEN + contents_len + RFC8439_EXPANSION;

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

BIP324HeaderFlags flags{BIP324_NONE};

bench.batch(contents_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> encrypted_pkt_len;
std::memcpy(encrypted_pkt_len.data(), out.data(), BIP324_LENGTH_FIELD_LEN);
(void)dec.DecryptLength(encrypted_pkt_len);
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::PriorityLevel::HIGH);
BENCHMARK(BIP324_CIPHER_SUITE_256BYTES_ONLY_ENCRYPT, benchmark::PriorityLevel::HIGH);
BENCHMARK(BIP324_CIPHER_SUITE_1MB_ONLY_ENCRYPT, benchmark::PriorityLevel::HIGH);
BENCHMARK(BIP324_CIPHER_SUITE_64BYTES_ENCRYPT_DECRYPT, benchmark::PriorityLevel::HIGH);
BENCHMARK(BIP324_CIPHER_SUITE_256BYTES_ENCRYPT_DECRYPT, benchmark::PriorityLevel::HIGH);
BENCHMARK(BIP324_CIPHER_SUITE_1MB_ENCRYPT_DECRYPT, benchmark::PriorityLevel::HIGH);
BENCHMARK(HASH_64BYTES, benchmark::PriorityLevel::HIGH);
BENCHMARK(HASH_256BYTES, benchmark::PriorityLevel::HIGH);
BENCHMARK(HASH_1MB, benchmark::PriorityLevel::HIGH);
126 changes: 0 additions & 126 deletions src/bench/chacha_poly_aead.cpp

This file was deleted.

78 changes: 78 additions & 0 deletions src/bench/rfc8439.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// 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 <bench/bench.h>
#include <crypto/rfc8439.h>

#include <array>
#include <cassert>
#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 const std::vector<std::byte> AAD(AAD_SIZE, std::byte{0x00});
static const 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)
{
RFC8439Key zero_key;
std::memset(zero_key.data(), 0, zero_key.size());
std::vector<std::byte> plaintext_in(plaintext_size, std::byte{0x00});
std::vector<std::byte> output(plaintext_size + POLY1305_TAGLEN, std::byte{0x00});

bench.batch(plaintext_size).unit("byte").run([&] {
RFC8439Encrypt(AAD, zero_key, NONCE, plaintext_in, output);

if (include_decryption) {
std::vector<std::byte> decrypted_plaintext(plaintext_size);
auto authenticated = RFC8439Decrypt(AAD, zero_key, NONCE, output, decrypted_plaintext);
assert(authenticated);
assert(std::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::PriorityLevel::HIGH);
BENCHMARK(RFC8439_AEAD_256BYTES_ONLY_ENCRYPT, benchmark::PriorityLevel::HIGH);
BENCHMARK(RFC8439_AEAD_1MB_ONLY_ENCRYPT, benchmark::PriorityLevel::HIGH);
BENCHMARK(RFC8439_AEAD_64BYTES_ENCRYPT_DECRYPT, benchmark::PriorityLevel::HIGH);
BENCHMARK(RFC8439_AEAD_256BYTES_ENCRYPT_DECRYPT, benchmark::PriorityLevel::HIGH);
BENCHMARK(RFC8439_AEAD_1MB_ENCRYPT_DECRYPT, benchmark::PriorityLevel::HIGH);
Loading