diff --git a/storm/Big.cpp b/storm/Big.cpp index 291f6de..8723c94 100644 --- a/storm/Big.cpp +++ b/storm/Big.cpp @@ -107,6 +107,10 @@ void SBigNot(BigData* a, BigData* b) { Not(a->Primary(), b->Primary()); } +void SBigOr(BigData* a, BigData* b, BigData* c) { + Or(a->Primary(), b->Primary(), c->Primary()); +} + void SBigPowMod(BigData* a, BigData* b, BigData* c, BigData* d) { PowMod(a->Primary(), b->Primary(), c->Primary(), d->Primary(), a->Stack()); } diff --git a/storm/Big.hpp b/storm/Big.hpp index 595b872..4daeea3 100644 --- a/storm/Big.hpp +++ b/storm/Big.hpp @@ -44,6 +44,8 @@ void SBigNew(BigData** num); void SBigNot(BigData* a, BigData* b); +void SBigOr(BigData* a, BigData* b, BigData* c); + void SBigPowMod(BigData* a, BigData* b, BigData* c, BigData* d); void SBigShl(BigData* a, BigData* b, uint32_t shift); diff --git a/storm/big/Ops.cpp b/storm/big/Ops.cpp index 3f49e12..cc51358 100644 --- a/storm/big/Ops.cpp +++ b/storm/big/Ops.cpp @@ -286,6 +286,15 @@ void Not(BigBuffer& a, const BigBuffer& b) { a.SetCount(i); } +void Or(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); +} + void PowMod(BigBuffer& a, const BigBuffer& b, const BigBuffer& c, const BigBuffer& d, BigStack& stack) { c.Trim(); diff --git a/storm/big/Ops.hpp b/storm/big/Ops.hpp index ce75b49..ef523db 100644 --- a/storm/big/Ops.hpp +++ b/storm/big/Ops.hpp @@ -51,6 +51,8 @@ void MulMod(BigBuffer& a, const BigBuffer& b, const BigBuffer& c, const BigBuffe void Not(BigBuffer& a, const BigBuffer& b); +void Or(BigBuffer& a, const BigBuffer& b, const BigBuffer& c); + void PowMod(BigBuffer& a, const BigBuffer& b, const BigBuffer& c, const BigBuffer& d, BigStack& stack); void SetOne(BigBuffer& buffer); diff --git a/test/Big.cpp b/test/Big.cpp index b7d1218..e3b95b6 100644 --- a/test/Big.cpp +++ b/test/Big.cpp @@ -769,6 +769,56 @@ TEST_CASE("SBigNot", "[big]") { } } +TEST_CASE("SBigOr", "[big]") { + BigDataTest a, b, c; + + SECTION("performs bitwise or 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); + SBigOr(a, b, c); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == (v.first | v.second)); + } + + SECTION("performs bitwise or on large numbers") { + auto v = GENERATE( + std::make_pair(0xFF00FF00FF00FF00ULL, 0xFF00FF00FF00FFULL) + ); + + SBigFromStr(b, std::to_string(v.first).c_str()); + SBigFromStr(c, std::to_string(v.second).c_str()); + SBigOr(a, b, c); + + CHECK(a->Primary().Count() == 2); + CHECK(a->Primary()[0] == uint32_t(v.first | v.second)); + CHECK(a->Primary()[1] == uint32_t((v.first | v.second) >> 32)); + } + + SECTION("performs bitwise or on huge value") { + uint32_t data[] = { 0xF00DFEEDUL, 0xBA1DUL, 0xBEEBBEEBUL, 0x12345678UL, 0x9ABCDEFUL, 0xDEADCADUL, 0xD011AUL }; + + SBigFromBinary(b, data, sizeof(data)); + SBigFromUnsigned(c, 0x11111111UL); + SBigOr(a, b, c); + + CHECK(a->Primary().Count() == 7); + CHECK(a->Primary()[0] == 0xF11DFFFD); + 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]); + } +} + TEST_CASE("SBigShl", "[big]") { SECTION("shifts 256 left 7 bits") { BigData* a;