diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2019-07-11 21:36:46 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2019-07-11 22:00:16 +0200 |
commit | 28d1353f48370402956e5f07a4cc519e5e09dcce (patch) | |
tree | e32e30c5d059c36f2703a6462c10bf3817d02b92 /src/bench | |
parent | 4fcccdac785e09ad5627b3bf4811dfba353693e8 (diff) | |
parent | bb326add9f38f2a8e5ce5ee29d98ce08038200d8 (diff) |
Merge #15649: Add ChaCha20Poly1305@Bitcoin AEAD
bb326add9f38f2a8e5ce5ee29d98ce08038200d8 Add ChaCha20Poly1305@Bitcoin AEAD benchmark (Jonas Schnelli)
99aea045d688059caf89c0e485fa427bd28eddd8 Add ChaCha20Poly1305@Bitcoin tests (Jonas Schnelli)
af5d1b5f4a7b56628a76af21284c258d845894f0 Add ChaCha20Poly1305@Bitcoin AEAD implementation (Jonas Schnelli)
Pull request description:
This adds a new AEAD (authenticated encryption with additional data) construct optimised for small messages (like used in Bitcoins p2p network).
Includes: #15519, #15512 (please review those first).
The construct is specified here.
https://gist.github.com/jonasschnelli/c530ea8421b8d0e80c51486325587c52#ChaCha20Poly1305Bitcoin_Cipher_Suite
This aims for being used in v2 peer-to-peer messages.
ACKs for top commit:
laanwj:
code review ACK bb326add9f38f2a8e5ce5ee29d98ce08038200d8
Tree-SHA512: 15bcb86c510fce7abb7a73536ff2ae89893b24646bf108c6cf18f064d672dbbbea8b1dd0868849fdac0c6854e498f1345d01dab56d1c92031afd728302234686
Diffstat (limited to 'src/bench')
-rw-r--r-- | src/bench/chacha_poly_aead.cpp | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/src/bench/chacha_poly_aead.cpp b/src/bench/chacha_poly_aead.cpp new file mode 100644 index 0000000000..f5f7297490 --- /dev/null +++ b/src/bench/chacha_poly_aead.cpp @@ -0,0 +1,123 @@ +// Copyright (c) 2019 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 <iostream> + +#include <bench/bench.h> +#include <crypto/chacha_poly_aead.h> +#include <crypto/poly1305.h> // for the POLY1305_TAGLEN constant +#include <hash.h> + +#include <limits> +#include <assert.h> + +/* 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 unsigned char k1[32] = {0}; +static const unsigned char k2[32] = {0}; + +static ChaCha20Poly1305AEAD aead(k1, 32, k2, 32); + +static void CHACHA20_POLY1305_AEAD(benchmark::State& state, size_t buffersize, bool include_decryption) +{ + std::vector<unsigned char> in(buffersize + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0); + std::vector<unsigned char> out(buffersize + CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN, 0); + uint64_t seqnr_payload = 0; + uint64_t seqnr_aad = 0; + int aad_pos = 0; + uint32_t len = 0; + while (state.KeepRunning()) { + // encrypt or decrypt the buffer with a static key + assert(aead.Crypt(seqnr_payload, seqnr_aad, aad_pos, out.data(), out.size(), in.data(), buffersize, true)); + + if (include_decryption) { + // if we decrypt, include the GetLength + assert(aead.GetLength(&len, seqnr_aad, aad_pos, in.data())); + assert(aead.Crypt(seqnr_payload, seqnr_aad, aad_pos, out.data(), out.size(), in.data(), buffersize, true)); + } + + // increase main sequence number + seqnr_payload++; + // increase aad position (position in AAD keystream) + aad_pos += CHACHA20_POLY1305_AEAD_AAD_LEN; + if (aad_pos + CHACHA20_POLY1305_AEAD_AAD_LEN > CHACHA20_ROUND_OUTPUT) { + aad_pos = 0; + seqnr_aad++; + } + if (seqnr_payload + 1 == std::numeric_limits<uint64_t>::max()) { + // reuse of nonce+key is okay while benchmarking. + seqnr_payload = 0; + seqnr_aad = 0; + aad_pos = 0; + } + } +} + +static void CHACHA20_POLY1305_AEAD_64BYTES_ONLY_ENCRYPT(benchmark::State& state) +{ + CHACHA20_POLY1305_AEAD(state, BUFFER_SIZE_TINY, false); +} + +static void CHACHA20_POLY1305_AEAD_256BYTES_ONLY_ENCRYPT(benchmark::State& state) +{ + CHACHA20_POLY1305_AEAD(state, BUFFER_SIZE_SMALL, false); +} + +static void CHACHA20_POLY1305_AEAD_1MB_ONLY_ENCRYPT(benchmark::State& state) +{ + CHACHA20_POLY1305_AEAD(state, BUFFER_SIZE_LARGE, false); +} + +static void CHACHA20_POLY1305_AEAD_64BYTES_ENCRYPT_DECRYPT(benchmark::State& state) +{ + CHACHA20_POLY1305_AEAD(state, BUFFER_SIZE_TINY, true); +} + +static void CHACHA20_POLY1305_AEAD_256BYTES_ENCRYPT_DECRYPT(benchmark::State& state) +{ + CHACHA20_POLY1305_AEAD(state, BUFFER_SIZE_SMALL, true); +} + +static void CHACHA20_POLY1305_AEAD_1MB_ENCRYPT_DECRYPT(benchmark::State& state) +{ + CHACHA20_POLY1305_AEAD(state, BUFFER_SIZE_LARGE, true); +} + +// Add Hash() (dbl-sha256) bench for comparison + +static void HASH(benchmark::State& state, size_t buffersize) +{ + uint8_t hash[CHash256::OUTPUT_SIZE]; + std::vector<uint8_t> in(buffersize,0); + while (state.KeepRunning()) + CHash256().Write(in.data(), in.size()).Finalize(hash); +} + +static void HASH_64BYTES(benchmark::State& state) +{ + HASH(state, BUFFER_SIZE_TINY); +} + +static void HASH_256BYTES(benchmark::State& state) +{ + HASH(state, BUFFER_SIZE_SMALL); +} + +static void HASH_1MB(benchmark::State& state) +{ + HASH(state, BUFFER_SIZE_LARGE); +} + +BENCHMARK(CHACHA20_POLY1305_AEAD_64BYTES_ONLY_ENCRYPT, 500000); +BENCHMARK(CHACHA20_POLY1305_AEAD_256BYTES_ONLY_ENCRYPT, 250000); +BENCHMARK(CHACHA20_POLY1305_AEAD_1MB_ONLY_ENCRYPT, 340); +BENCHMARK(CHACHA20_POLY1305_AEAD_64BYTES_ENCRYPT_DECRYPT, 500000); +BENCHMARK(CHACHA20_POLY1305_AEAD_256BYTES_ENCRYPT_DECRYPT, 250000); +BENCHMARK(CHACHA20_POLY1305_AEAD_1MB_ENCRYPT_DECRYPT, 340); +BENCHMARK(HASH_64BYTES, 500000); +BENCHMARK(HASH_256BYTES, 250000); +BENCHMARK(HASH_1MB, 340); |