Skip to content

Commit 9999a49

Browse files
author
MarcoFalke
committed
Extract util::Xor, Add key_offset option, Add bench
1 parent 99b3af7 commit 9999a49

File tree

4 files changed

+49
-17
lines changed

4 files changed

+49
-17
lines changed

src/Makefile.bench.include

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ bench_bench_bitcoin_SOURCES = \
5252
bench/streams_findbyte.cpp \
5353
bench/strencodings.cpp \
5454
bench/util_time.cpp \
55-
bench/verify_script.cpp
55+
bench/verify_script.cpp \
56+
bench/xor.cpp
5657

5758
nodist_bench_bench_bitcoin_SOURCES = $(GENERATED_BENCH_FILES)
5859

src/bench/bench.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#include <string>
1515
#include <vector>
1616

17-
#include <bench/nanobench.h>
17+
#include <bench/nanobench.h> // IWYU pragma: export
1818

1919
/*
2020
* Usage:

src/bench/xor.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or https://opensource.org/license/mit/.
4+
5+
#include <bench/bench.h>
6+
7+
#include <random.h>
8+
#include <streams.h>
9+
10+
#include <cstddef>
11+
#include <vector>
12+
13+
static void Xor(benchmark::Bench& bench)
14+
{
15+
FastRandomContext frc{/*fDeterministic=*/true};
16+
auto data{frc.randbytes<std::byte>(1024)};
17+
auto key{frc.randbytes<std::byte>(31)};
18+
19+
bench.batch(data.size()).unit("byte").run([&] {
20+
util::Xor(data, key);
21+
});
22+
}
23+
24+
BENCHMARK(Xor, benchmark::PriorityLevel::HIGH);

src/streams.h

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,27 @@
2323
#include <utility>
2424
#include <vector>
2525

26+
namespace util {
27+
inline void Xor(Span<std::byte> write, Span<const std::byte> key, size_t key_offset = 0)
28+
{
29+
if (key.size() == 0) {
30+
return;
31+
}
32+
key_offset %= key.size();
33+
34+
for (size_t i = 0, j = key_offset; i != write.size(); i++) {
35+
write[i] ^= key[j++];
36+
37+
// This potentially acts on very many bytes of data, so it's
38+
// important that we calculate `j`, i.e. the `key` index in this
39+
// way instead of doing a %, which would effectively be a division
40+
// for each byte Xor'd -- much slower than need be.
41+
if (j == key.size())
42+
j = 0;
43+
}
44+
}
45+
} // namespace util
46+
2647
template<typename Stream>
2748
class OverrideStream
2849
{
@@ -316,20 +337,7 @@ class DataStream
316337
*/
317338
void Xor(const std::vector<unsigned char>& key)
318339
{
319-
if (key.size() == 0) {
320-
return;
321-
}
322-
323-
for (size_type i = 0, j = 0; i != size(); i++) {
324-
vch[i] ^= std::byte{key[j++]};
325-
326-
// This potentially acts on very many bytes of data, so it's
327-
// important that we calculate `j`, i.e. the `key` index in this
328-
// way instead of doing a %, which would effectively be a division
329-
// for each byte Xor'd -- much slower than need be.
330-
if (j == key.size())
331-
j = 0;
332-
}
340+
util::Xor(MakeWritableByteSpan(*this), MakeByteSpan(key));
333341
}
334342
};
335343

@@ -469,7 +477,6 @@ class BitStreamWriter
469477
}
470478
};
471479

472-
473480
/** Non-refcounted RAII wrapper for FILE*
474481
*
475482
* Will automatically close the file when it goes out of scope if not null.

0 commit comments

Comments
 (0)