diff --git a/storm/Big.cpp b/storm/Big.cpp index 97a36e8..298a924 100644 --- a/storm/Big.cpp +++ b/storm/Big.cpp @@ -142,3 +142,7 @@ void SBigToBinaryBuffer(BigData* num, uint8_t* data, uint32_t maxBytes, uint32_t *bytes = n; } } + +void SBigXor(BigData* a, BigData* b, BigData* c) { + Xor(a->Primary(), b->Primary(), c->Primary()); +} diff --git a/storm/Big.hpp b/storm/Big.hpp index 4daeea3..f39a90e 100644 --- a/storm/Big.hpp +++ b/storm/Big.hpp @@ -58,4 +58,6 @@ void SBigSub(BigData* a, BigData* b, BigData* c); void SBigToBinaryBuffer(BigData* num, uint8_t* data, uint32_t maxBytes, uint32_t* bytes); +void SBigXor(BigData* a, BigData* b, BigData* c); + #endif diff --git a/storm/big/Ops.cpp b/storm/big/Ops.cpp index fe636b5..b40623f 100644 --- a/storm/big/Ops.cpp +++ b/storm/big/Ops.cpp @@ -482,3 +482,12 @@ void ToStream(TSGrowableArray& output, const BigBuffer& buffer) { EncodeDataBytes(output, output.Count()); ToBinaryAppend(output, buffer); } + +void Xor(BigBuffer& a, const BigBuffer& b, const BigBuffer& c) { + uint32_t i = 0; + for (; b.IsUsed(i) || c.IsUsed(i); i++) { + a[i] = c[i] ^ b[i]; + } + + a.SetCount(i); +} diff --git a/storm/big/Ops.hpp b/storm/big/Ops.hpp index 3743078..3f38596 100644 --- a/storm/big/Ops.hpp +++ b/storm/big/Ops.hpp @@ -75,4 +75,6 @@ void ToBinary(TSGrowableArray& output, const BigBuffer& buffer); void ToStream(TSGrowableArray& output, const BigBuffer& buffer); +void Xor(BigBuffer& a, const BigBuffer& b, const BigBuffer& c); + #endif diff --git a/test/Big.cpp b/test/Big.cpp index e5665ec..cd924e4 100644 --- a/test/Big.cpp +++ b/test/Big.cpp @@ -745,3 +745,49 @@ TEST_CASE("SBigToBinaryBuffer", "[big]") { CHECK(*reinterpret_cast(buffer) == 0x123456789ABCDEF0); } } + +TEST_CASE("SBigXor", "[big]") { + BigDataTest a, b, c; + + SECTION("performs bitwise xor on small numbers") { + auto v = GENERATE( + std::make_pair(0UL, 0UL), + std::make_pair(0UL, 123UL), + std::make_pair(41689UL, 786740UL) + ); + + SBigFromUnsigned(b, v.first); + SBigFromUnsigned(c, v.second); + SBigXor(a, b, c); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == (v.first ^ v.second)); + } + + SECTION("performs bitwise xor on large number") { + SBigFromStr(b, std::to_string(0xFF00FF00FF00FF00ULL).c_str()); + SBigFromStr(c, std::to_string(0xFF00FF00FF00FULL).c_str()); + SBigXor(a, b, c); + + CHECK(a->Primary().Count() == 2); + CHECK(a->Primary()[0] == 0xF0F0F0F); + CHECK(a->Primary()[1] == 0xFF0F0F0F); + } + + SECTION("performs bitwise xor on huge value") { + uint32_t data[] = { 0xF00DFEEDUL, 0xBA1DUL, 0xBEEBBEEBUL, 0x12345678UL, 0x9ABCDEFUL, 0xDEADCADUL, 0xD011AUL }; + + SBigFromBinary(b, data, sizeof(data)); + SBigFromUnsigned(c, 0x1111111FUL); + SBigXor(a, b, c); + + CHECK(a->Primary().Count() == 7); + CHECK(a->Primary()[0] == 0xE11CEFF2); + CHECK(a->Primary()[1] == data[1]); + CHECK(a->Primary()[2] == data[2]); + CHECK(a->Primary()[3] == data[3]); + CHECK(a->Primary()[4] == data[4]); + CHECK(a->Primary()[5] == data[5]); + CHECK(a->Primary()[6] == data[6]); + } +}