diff --git a/src/util/obfuscation.h b/src/util/obfuscation.h index b1170fa3363..db7527064b4 100644 --- a/src/util/obfuscation.h +++ b/src/util/obfuscation.h @@ -14,6 +14,7 @@ #include #include #include +#include class Obfuscation { @@ -33,9 +34,26 @@ public: { if (!*this) return; - const KeyType rot_key{m_rotations[key_offset % KEY_SIZE]}; // Continue obfuscation from where we left off - for (; target.size() >= KEY_SIZE; target = target.subspan(KEY_SIZE)) { - XorWord(target.first(), rot_key); + KeyType rot_key{m_rotations[key_offset % KEY_SIZE]}; // Continue obfuscation from where we left off + if (target.size() > KEY_SIZE) { + // Obfuscate until 64-bit alignment boundary + if (const auto misalign{std::bit_cast(target.data()) % KEY_SIZE}) { + const size_t alignment{std::min(KEY_SIZE - misalign, target.size())}; + XorWord(target.first(alignment), rot_key); + + target = {std::assume_aligned(target.data() + alignment), target.size() - alignment}; + rot_key = m_rotations[(key_offset + alignment) % KEY_SIZE]; + } + // Aligned obfuscation in 64-byte chunks + for (constexpr auto unroll{8}; target.size() >= KEY_SIZE * unroll; target = target.subspan(KEY_SIZE * unroll)) { + for (size_t i{0}; i < unroll; ++i) { + XorWord(target.subspan(i * KEY_SIZE, KEY_SIZE), rot_key); + } + } + // Aligned obfuscation in 64-bit chunks + for (; target.size() >= KEY_SIZE; target = target.subspan(KEY_SIZE)) { + XorWord(target.first(), rot_key); + } } XorWord(target, rot_key); }