aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>2023-06-12 11:28:59 +0200
committerMarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz>2023-07-12 09:59:55 +0200
commit9999a49b3299bd25dde4805f5c68adef3876057f (patch)
treeb7f0e705f75df0f054944d0371999a3f90c5927b
parent99b3af78bd5209b3ed0b192d0b18ee2c49079d1d (diff)
downloadbitcoin-9999a49b3299bd25dde4805f5c68adef3876057f.tar.xz
Extract util::Xor, Add key_offset option, Add bench
-rw-r--r--src/Makefile.bench.include3
-rw-r--r--src/bench/bench.h2
-rw-r--r--src/bench/xor.cpp24
-rw-r--r--src/streams.h37
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.