diff --git a/storm/Big.cpp b/storm/Big.cpp index 790e99e..0c31ad2 100644 --- a/storm/Big.cpp +++ b/storm/Big.cpp @@ -49,6 +49,10 @@ void SBigMul(BigData* a, BigData* b, BigData* c) { Mul(a->Primary(), b->Primary(), c->Primary(), a->Stack()); } +void SBigShl(BigData* a, BigData* b, uint32_t shift) { + Shl(a->Primary(), b->Primary(), shift); +} + void SBigShr(BigData* a, BigData* b, uint32_t shift) { Shr(a->Primary(), b->Primary(), shift); } diff --git a/storm/Big.hpp b/storm/Big.hpp index 1608e50..514ae34 100644 --- a/storm/Big.hpp +++ b/storm/Big.hpp @@ -20,6 +20,8 @@ void SBigMul(BigData* a, BigData* b, BigData* c); void SBigNew(BigData** num); +void SBigShl(BigData* a, BigData* b, uint32_t shift); + void SBigShr(BigData* a, BigData* b, uint32_t shift); void SBigSquare(BigData* a, BigData* b); diff --git a/storm/big/Ops.cpp b/storm/big/Ops.cpp index 38b8e95..75ff524 100644 --- a/storm/big/Ops.cpp +++ b/storm/big/Ops.cpp @@ -170,6 +170,29 @@ void SetZero(BigBuffer& buffer) { buffer.Clear(); } +void Shl(BigBuffer& a, const BigBuffer& b, uint32_t shift) { + auto v4 = shift >> 5; + auto v14 = shift & 0x1F; + auto v5 = b.Count() + v4 + 1; + + for (uint32_t i = v5 - 1, j = v5 - v4 - 1; i + 1 > 0; i--, j--) { + uint32_t v9 = 0; + + if (i >= v4) { + v9 = b[j] << v14; + + if (i > v4 && v14) { + v9 += b[j - 1] >> (32 - v14); + } + } + + a[i] = v9; + } + + a.SetCount(v5); + a.Trim(); +} + void Shr(BigBuffer& a, const BigBuffer& b, uint32_t shift) { auto v4 = shift >> 5; auto v9 = shift & 0x1F; diff --git a/storm/big/Ops.hpp b/storm/big/Ops.hpp index 95ad529..600f3e4 100644 --- a/storm/big/Ops.hpp +++ b/storm/big/Ops.hpp @@ -37,6 +37,8 @@ void SetOne(BigBuffer& buffer); void SetZero(BigBuffer& buffer); +void Shl(BigBuffer& a, const BigBuffer& b, uint32_t shift); + void Shr(BigBuffer& a, const BigBuffer& b, uint32_t shift); void Square(BigBuffer& a, const BigBuffer& b, BigStack& stack); diff --git a/test/Big.cpp b/test/Big.cpp index 5bc324a..24798ed 100644 --- a/test/Big.cpp +++ b/test/Big.cpp @@ -855,6 +855,27 @@ TEST_CASE("SBigMul", "[big]") { } } +TEST_CASE("SBigShl", "[big]") { + SECTION("shifts 256 left 7 bits") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 256); + + SBigShl(a, b, 7); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 32768); + + SBigDel(a); + SBigDel(b); + } +} + TEST_CASE("SBigShr", "[big]") { SECTION("shifts 256 right 7 bits") { BigData* a; @@ -1004,6 +1025,166 @@ TEST_CASE("SetZero", "[big]") { } } +TEST_CASE("Shl", "[big]") { + SECTION("shifts 0 left 1 bit") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 0); + + Shl(a->Primary(), b->Primary(), 1); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 0); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 1 left 0 bits") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 1); + + Shl(a->Primary(), b->Primary(), 0); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 1); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 1 left 1 bit") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 1); + + Shl(a->Primary(), b->Primary(), 1); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 2); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 2 left 1 bit") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 2); + + Shl(a->Primary(), b->Primary(), 1); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 4); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 256 left 7 bits") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 256); + + Shl(a->Primary(), b->Primary(), 7); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 32768); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 0xFFFFFFFF left 10 bits") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + uint64_t b_ = 0xFFFFFFFF; + SBigFromBinary(b, reinterpret_cast(&b_), sizeof(b_)); + + Shl(a->Primary(), b->Primary(), 10); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 2); + CHECK(a->Primary()[0] == 0xFFFFFC00); + CHECK(a->Primary()[1] == 0x3FF); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 0x1000000000000000 left 1 bit") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + uint64_t b_ = 0x1000000000000000; + SBigFromBinary(b, reinterpret_cast(&b_), sizeof(b_)); + + Shl(a->Primary(), b->Primary(), 1); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 2); + CHECK(a->Primary()[0] == 0); + CHECK(a->Primary()[1] == 0x20000000); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 0x1000000000000000 left 16 bits") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + uint64_t b_ = 0x1000000000000000; + SBigFromBinary(b, reinterpret_cast(&b_), sizeof(b_)); + + Shl(a->Primary(), b->Primary(), 16); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 3); + CHECK(a->Primary()[0] == 0); + CHECK(a->Primary()[1] == 0); + CHECK(a->Primary()[2] == 0x1000); + + SBigDel(a); + SBigDel(b); + } +} + TEST_CASE("Shr", "[big]") { SECTION("shifts 0 right 1 bit") { BigData* a;