diff options
author | MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> | 2023-06-12 11:28:59 +0200 |
---|---|---|
committer | MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> | 2023-07-12 09:59:55 +0200 |
commit | 9999a49b3299bd25dde4805f5c68adef3876057f (patch) | |
tree | b7f0e705f75df0f054944d0371999a3f90c5927b | |
parent | 99b3af78bd5209b3ed0b192d0b18ee2c49079d1d (diff) | |
download | bitcoin-9999a49b3299bd25dde4805f5c68adef3876057f.tar.xz |
Extract util::Xor, Add key_offset option, Add bench
-rw-r--r-- | src/Makefile.bench.include | 3 | ||||
-rw-r--r-- | src/bench/bench.h | 2 | ||||
-rw-r--r-- | src/bench/xor.cpp | 24 | ||||
-rw-r--r-- | src/streams.h | 37 |
4 files changed, 49 insertions, 17 deletions
diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include index 10c8389c80..51bfb1e459 100644 --- a/src/Makefile.bench.include +++ b/src/Makefile.bench.include @@ -52,7 +52,8 @@ bench_bench_bitcoin_SOURCES = \ bench/streams_findbyte.cpp \ bench/strencodings.cpp \ bench/util_time.cpp \ - bench/verify_script.cpp + bench/verify_script.cpp \ + bench/xor.cpp nodist_bench_bench_bitcoin_SOURCES = $(GENERATED_BENCH_FILES) diff --git a/src/bench/bench.h b/src/bench/bench.h index 78196134e7..6065ddf3fc 100644 --- a/src/bench/bench.h +++ b/src/bench/bench.h @@ -14,7 +14,7 @@ #include <string> #include <vector> -#include <bench/nanobench.h> +#include <bench/nanobench.h> // IWYU pragma: export /* * Usage: diff --git a/src/bench/xor.cpp b/src/bench/xor.cpp new file mode 100644 index 0000000000..edda74214a --- /dev/null +++ b/src/bench/xor.cpp @@ -0,0 +1,24 @@ +// Copyright (c) The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or https://opensource.org/license/mit/. + +#include <bench/bench.h> + +#include <random.h> +#include <streams.h> + +#include <cstddef> +#include <vector> + +static void Xor(benchmark::Bench& bench) +{ + FastRandomContext frc{/*fDeterministic=*/true}; + auto data{frc.randbytes<std::byte>(1024)}; + auto key{frc.randbytes<std::byte>(31)}; + + bench.batch(data.size()).unit("byte").run([&] { + util::Xor(data, key); + }); +} + +BENCHMARK(Xor, benchmark::PriorityLevel::HIGH); diff --git a/src/streams.h b/src/streams.h index 03df20b5db..4fbbdc573c 100644 --- a/src/streams.h +++ b/src/streams.h @@ -23,6 +23,27 @@ #include <utility> #include <vector> +namespace util { +inline void Xor(Span<std::byte> write, Span<const std::byte> key, size_t key_offset = 0) +{ + if (key.size() == 0) { + return; + } + key_offset %= key.size(); + + for (size_t i = 0, j = key_offset; i != write.size(); i++) { + write[i] ^= key[j++]; + + // This potentially acts on very many bytes of data, so it's + // important that we calculate `j`, i.e. the `key` index in this + // way instead of doing a %, which would effectively be a division + // for each byte Xor'd -- much slower than need be. + if (j == key.size()) + j = 0; + } +} +} // namespace util + template<typename Stream> class OverrideStream { @@ -316,20 +337,7 @@ public: */ void Xor(const std::vector<unsigned char>& key) { - if (key.size() == 0) { - return; - } - - for (size_type i = 0, j = 0; i != size(); i++) { - vch[i] ^= std::byte{key[j++]}; - - // This potentially acts on very many bytes of data, so it's - // important that we calculate `j`, i.e. the `key` index in this - // way instead of doing a %, which would effectively be a division - // for each byte Xor'd -- much slower than need be. - if (j == key.size()) - j = 0; - } + util::Xor(MakeWritableByteSpan(*this), MakeByteSpan(key)); } }; @@ -469,7 +477,6 @@ public: } }; - /** Non-refcounted RAII wrapper for FILE* * * Will automatically close the file when it goes out of scope if not null. |