diff --git a/storm/Big.cpp b/storm/Big.cpp index 3b6731c..790e99e 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 SBigShr(BigData* a, BigData* b, uint32_t shift) { + Shr(a->Primary(), b->Primary(), shift); +} + void SBigSquare(BigData* a, BigData* b) { Square(a->Primary(), b->Primary(), a->Stack()); } diff --git a/storm/Big.hpp b/storm/Big.hpp index c12c1a6..1608e50 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 SBigShr(BigData* a, BigData* b, uint32_t shift); + void SBigSquare(BigData* a, BigData* b); void SBigSub(BigData* a, BigData* b, BigData* c); diff --git a/storm/big/Ops.cpp b/storm/big/Ops.cpp index 725a7e3..38b8e95 100644 --- a/storm/big/Ops.cpp +++ b/storm/big/Ops.cpp @@ -170,6 +170,24 @@ void SetZero(BigBuffer& buffer) { buffer.Clear(); } +void Shr(BigBuffer& a, const BigBuffer& b, uint32_t shift) { + auto v4 = shift >> 5; + auto v9 = shift & 0x1F; + + uint32_t i = 0; + for (i = 0; b.IsUsed(i + v4); i++) { + auto v6 = b[i + v4] >> v9; + + if (v9) { + v6 += b[i + v4 + 1] << (32 - v9); + } + + a[i] = v6; + } + + a.SetCount(i); +} + void Square(BigBuffer& a, const BigBuffer& b, BigStack& stack) { auto& aa = stack.MakeDistinct(a, &a == &b); aa.Clear(); diff --git a/storm/big/Ops.hpp b/storm/big/Ops.hpp index 7d46b91..95ad529 100644 --- a/storm/big/Ops.hpp +++ b/storm/big/Ops.hpp @@ -37,6 +37,8 @@ void SetOne(BigBuffer& buffer); void SetZero(BigBuffer& buffer); +void Shr(BigBuffer& a, const BigBuffer& b, uint32_t shift); + void Square(BigBuffer& a, const BigBuffer& b, BigStack& stack); void Sub(BigBuffer& a, const BigBuffer& b, const BigBuffer& c); diff --git a/test/Big.cpp b/test/Big.cpp index 2e66e86..73ab044 100644 --- a/test/Big.cpp +++ b/test/Big.cpp @@ -855,6 +855,27 @@ TEST_CASE("SBigMul", "[big]") { } } +TEST_CASE("SBigShr", "[big]") { + SECTION("shifts 256 right 7 bits") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 256); + + SBigShr(a, b, 7); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 2); + + SBigDel(a); + SBigDel(b); + } +} + TEST_CASE("SBigSquare", "[square]") { SECTION("squares 0xFFFFFFFF") { BigData* a; @@ -983,6 +1004,161 @@ TEST_CASE("SetZero", "[big]") { } } +TEST_CASE("Shr", "[big]") { + SECTION("shifts 0 right 1 bit") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 0); + + Shr(a->Primary(), b->Primary(), 1); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 0); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 1 right 0 bits") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 1); + + Shr(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 right 1 bit") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 1); + + Shr(a->Primary(), b->Primary(), 1); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 0); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 2 right 1 bit") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 2); + + Shr(a->Primary(), b->Primary(), 1); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 1); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 2 right 1 bit") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 2); + + Shr(a->Primary(), b->Primary(), 1); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 1); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 256 right 7 bits") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + SBigFromUnsigned(b, 256); + + Shr(a->Primary(), b->Primary(), 7); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 2); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 0x1000000000000000 right 2 bits") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + uint64_t b_ = 0x1000000000000000; + SBigFromBinary(b, reinterpret_cast(&b_), sizeof(b_)); + + Shr(a->Primary(), b->Primary(), 2); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 2); + CHECK(a->Primary()[0] == 0); + CHECK(a->Primary()[1] == 0x4000000); + + SBigDel(a); + SBigDel(b); + } + + SECTION("shifts 0x1000000000000000 right 32 bits") { + BigData* a; + SBigNew(&a); + + BigData* b; + SBigNew(&b); + uint64_t b_ = 0x1000000000000000; + SBigFromBinary(b, reinterpret_cast(&b_), sizeof(b_)); + + Shr(a->Primary(), b->Primary(), 32); + + a->Primary().Trim(); + + CHECK(a->Primary().Count() == 1); + CHECK(a->Primary()[0] == 0x10000000); + + SBigDel(a); + SBigDel(b); + } +} + TEST_CASE("Square", "[big]") { SECTION("squares 0") { BigData* a;