Extract util::Xor, Add key_offset option, Add bench

pull/28060/head
MarcoFalke 1 year ago
parent 99b3af78bd
commit 9999a49b32
No known key found for this signature in database

@ -52,7 +52,8 @@ bench_bench_bitcoin_SOURCES = \
bench/streams_findbyte.cpp \ bench/streams_findbyte.cpp \
bench/strencodings.cpp \ bench/strencodings.cpp \
bench/util_time.cpp \ bench/util_time.cpp \
bench/verify_script.cpp bench/verify_script.cpp \
bench/xor.cpp
nodist_bench_bench_bitcoin_SOURCES = $(GENERATED_BENCH_FILES) nodist_bench_bench_bitcoin_SOURCES = $(GENERATED_BENCH_FILES)

@ -14,7 +14,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <bench/nanobench.h> #include <bench/nanobench.h> // IWYU pragma: export
/* /*
* Usage: * Usage:

@ -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);

@ -23,6 +23,27 @@
#include <utility> #include <utility>
#include <vector> #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> template<typename Stream>
class OverrideStream class OverrideStream
{ {
@ -316,20 +337,7 @@ public:
*/ */
void Xor(const std::vector<unsigned char>& key) void Xor(const std::vector<unsigned char>& key)
{ {
if (key.size() == 0) { util::Xor(MakeWritableByteSpan(*this), MakeByteSpan(key));
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;
}
} }
}; };
@ -469,7 +477,6 @@ public:
} }
}; };
/** Non-refcounted RAII wrapper for FILE* /** Non-refcounted RAII wrapper for FILE*
* *
* Will automatically close the file when it goes out of scope if not null. * Will automatically close the file when it goes out of scope if not null.

Loading…
Cancel
Save