mirror of
https://github.com/thunderbrewhq/squall.git
synced 2025-12-12 02:22:30 +00:00
feat(big): add SBigPowMod
This commit is contained in:
parent
c2a6459c94
commit
09d2481be9
5 changed files with 244 additions and 0 deletions
|
|
@ -58,6 +58,10 @@ void SBigMul(BigData* a, BigData* b, BigData* c) {
|
||||||
Mul(a->Primary(), b->Primary(), c->Primary(), a->Stack());
|
Mul(a->Primary(), b->Primary(), c->Primary(), a->Stack());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SBigPowMod(BigData* a, BigData* b, BigData* c, BigData* d) {
|
||||||
|
PowMod(a->Primary(), b->Primary(), c->Primary(), d->Primary(), a->Stack());
|
||||||
|
}
|
||||||
|
|
||||||
void SBigShl(BigData* a, BigData* b, uint32_t shift) {
|
void SBigShl(BigData* a, BigData* b, uint32_t shift) {
|
||||||
Shl(a->Primary(), b->Primary(), shift);
|
Shl(a->Primary(), b->Primary(), shift);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ void SBigMul(BigData* a, BigData* b, BigData* c);
|
||||||
|
|
||||||
void SBigNew(BigData** num);
|
void SBigNew(BigData** num);
|
||||||
|
|
||||||
|
void SBigPowMod(BigData* a, BigData* b, BigData* c, BigData* d);
|
||||||
|
|
||||||
void SBigShl(BigData* a, BigData* b, uint32_t shift);
|
void SBigShl(BigData* a, BigData* b, uint32_t shift);
|
||||||
|
|
||||||
void SBigShr(BigData* a, BigData* b, uint32_t shift);
|
void SBigShr(BigData* a, BigData* b, uint32_t shift);
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,63 @@ void MulMod(BigBuffer& a, const BigBuffer& b, const BigBuffer& c, const BigBuffe
|
||||||
stack.Free(allocCount);
|
stack.Free(allocCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PowMod(BigBuffer& a, const BigBuffer& b, const BigBuffer& c, const BigBuffer& d, BigStack& stack) {
|
||||||
|
c.Trim();
|
||||||
|
|
||||||
|
if (c.Count() == 0) {
|
||||||
|
SetOne(a);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t allocCount = 0;
|
||||||
|
auto& temp = stack.Alloc(&allocCount);
|
||||||
|
auto& b2 = stack.Alloc(&allocCount);
|
||||||
|
auto& b3 = stack.Alloc(&allocCount);
|
||||||
|
|
||||||
|
auto& aa = stack.MakeDistinct(a, &a == &b || &a == &c || &a == &d);
|
||||||
|
|
||||||
|
MulMod(b2, b, b, d, stack);
|
||||||
|
MulMod(b3, b2, b, d, stack);
|
||||||
|
|
||||||
|
const BigBuffer* bPower[3];
|
||||||
|
bPower[0] = &b;
|
||||||
|
bPower[1] = &b2;
|
||||||
|
bPower[2] = &b3;
|
||||||
|
|
||||||
|
SetOne(aa);
|
||||||
|
|
||||||
|
for (uint32_t i = c.Count() - 1; i + 1 > 0; i--) {
|
||||||
|
auto v12 = c[i];
|
||||||
|
uint32_t v23 = 32;
|
||||||
|
|
||||||
|
if (i == c.Count() - 1 && !(v12 & 0xC0000000)) {
|
||||||
|
do {
|
||||||
|
v12 *= 4;
|
||||||
|
v23 -= 2;
|
||||||
|
} while (!(v12 & 0xC0000000));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v23) {
|
||||||
|
for (uint32_t j = ((v23 - 1) >> 1) + 1; j > 0; j--) {
|
||||||
|
Square(aa, aa, stack);
|
||||||
|
Div(temp, aa, aa, d, stack);
|
||||||
|
Square(aa, aa, stack);
|
||||||
|
Div(temp, aa, aa, d, stack);
|
||||||
|
|
||||||
|
if (v12 >> 30) {
|
||||||
|
auto& power = *bPower[(v12 >> 30) - 1];
|
||||||
|
MulMod(aa, aa, power, d, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
v12 *= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stack.UnmakeDistinct(a, aa);
|
||||||
|
stack.Free(allocCount);
|
||||||
|
}
|
||||||
|
|
||||||
void SetOne(BigBuffer& buffer) {
|
void SetOne(BigBuffer& buffer) {
|
||||||
buffer.SetCount(1);
|
buffer.SetCount(1);
|
||||||
buffer[0] = 1;
|
buffer[0] = 1;
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ void Mul(BigBuffer& a, const BigBuffer& b, const BigBuffer& c, BigStack& stack);
|
||||||
|
|
||||||
void MulMod(BigBuffer& a, const BigBuffer& b, const BigBuffer& c, const BigBuffer& d, BigStack& stack);
|
void MulMod(BigBuffer& a, const BigBuffer& b, const BigBuffer& c, const BigBuffer& d, BigStack& stack);
|
||||||
|
|
||||||
|
void PowMod(BigBuffer& a, const BigBuffer& b, const BigBuffer& c, const BigBuffer& d, BigStack& stack);
|
||||||
|
|
||||||
void SetOne(BigBuffer& buffer);
|
void SetOne(BigBuffer& buffer);
|
||||||
|
|
||||||
void SetZero(BigBuffer& buffer);
|
void SetZero(BigBuffer& buffer);
|
||||||
|
|
|
||||||
179
test/Big.cpp
179
test/Big.cpp
|
|
@ -717,6 +717,154 @@ TEST_CASE("MakeLarge", "[big]") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("PowMod", "[big]") {
|
||||||
|
SECTION("takes 0 to the 0th power and mods the result by 1") {
|
||||||
|
BigData* a;
|
||||||
|
SBigNew(&a);
|
||||||
|
|
||||||
|
BigData* b;
|
||||||
|
SBigNew(&b);
|
||||||
|
SBigFromUnsigned(b, 0);
|
||||||
|
|
||||||
|
BigData* c;
|
||||||
|
SBigNew(&c);
|
||||||
|
SBigFromUnsigned(c, 0);
|
||||||
|
|
||||||
|
BigData* d;
|
||||||
|
SBigNew(&d);
|
||||||
|
SBigFromUnsigned(d, 1);
|
||||||
|
|
||||||
|
PowMod(a->Primary(), b->Primary(), c->Primary(), d->Primary(), a->Stack());
|
||||||
|
|
||||||
|
a->Primary().Trim();
|
||||||
|
|
||||||
|
CHECK(a->Primary().Count() == 1);
|
||||||
|
CHECK(a->Primary()[0] == 1);
|
||||||
|
|
||||||
|
SBigDel(a);
|
||||||
|
SBigDel(b);
|
||||||
|
SBigDel(c);
|
||||||
|
SBigDel(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("takes 2 to the 0th power and mods the result by 7") {
|
||||||
|
BigData* a;
|
||||||
|
SBigNew(&a);
|
||||||
|
|
||||||
|
BigData* b;
|
||||||
|
SBigNew(&b);
|
||||||
|
SBigFromUnsigned(b, 2);
|
||||||
|
|
||||||
|
BigData* c;
|
||||||
|
SBigNew(&c);
|
||||||
|
SBigFromUnsigned(c, 0);
|
||||||
|
|
||||||
|
BigData* d;
|
||||||
|
SBigNew(&d);
|
||||||
|
SBigFromUnsigned(d, 7);
|
||||||
|
|
||||||
|
PowMod(a->Primary(), b->Primary(), c->Primary(), d->Primary(), a->Stack());
|
||||||
|
|
||||||
|
a->Primary().Trim();
|
||||||
|
|
||||||
|
CHECK(a->Primary().Count() == 1);
|
||||||
|
CHECK(a->Primary()[0] == 1);
|
||||||
|
|
||||||
|
SBigDel(a);
|
||||||
|
SBigDel(b);
|
||||||
|
SBigDel(c);
|
||||||
|
SBigDel(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("takes 2 to the 4th power and mods the result by 7") {
|
||||||
|
BigData* a;
|
||||||
|
SBigNew(&a);
|
||||||
|
|
||||||
|
BigData* b;
|
||||||
|
SBigNew(&b);
|
||||||
|
SBigFromUnsigned(b, 2);
|
||||||
|
|
||||||
|
BigData* c;
|
||||||
|
SBigNew(&c);
|
||||||
|
SBigFromUnsigned(c, 4);
|
||||||
|
|
||||||
|
BigData* d;
|
||||||
|
SBigNew(&d);
|
||||||
|
SBigFromUnsigned(d, 7);
|
||||||
|
|
||||||
|
PowMod(a->Primary(), b->Primary(), c->Primary(), d->Primary(), a->Stack());
|
||||||
|
|
||||||
|
a->Primary().Trim();
|
||||||
|
|
||||||
|
CHECK(a->Primary().Count() == 1);
|
||||||
|
CHECK(a->Primary()[0] == 2);
|
||||||
|
|
||||||
|
SBigDel(a);
|
||||||
|
SBigDel(b);
|
||||||
|
SBigDel(c);
|
||||||
|
SBigDel(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("takes 256 to the 8th power and mods the result by 999") {
|
||||||
|
BigData* a;
|
||||||
|
SBigNew(&a);
|
||||||
|
|
||||||
|
BigData* b;
|
||||||
|
SBigNew(&b);
|
||||||
|
SBigFromUnsigned(b, 256);
|
||||||
|
|
||||||
|
BigData* c;
|
||||||
|
SBigNew(&c);
|
||||||
|
SBigFromUnsigned(c, 8);
|
||||||
|
|
||||||
|
BigData* d;
|
||||||
|
SBigNew(&d);
|
||||||
|
SBigFromUnsigned(d, 999);
|
||||||
|
|
||||||
|
PowMod(a->Primary(), b->Primary(), c->Primary(), d->Primary(), a->Stack());
|
||||||
|
|
||||||
|
a->Primary().Trim();
|
||||||
|
|
||||||
|
CHECK(a->Primary().Count() == 1);
|
||||||
|
CHECK(a->Primary()[0] == 160);
|
||||||
|
|
||||||
|
SBigDel(a);
|
||||||
|
SBigDel(b);
|
||||||
|
SBigDel(c);
|
||||||
|
SBigDel(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("takes 0x100000000 to the 2nd power and mods the result by 0xAAAAFFFF") {
|
||||||
|
BigData* a;
|
||||||
|
SBigNew(&a);
|
||||||
|
|
||||||
|
BigData* b;
|
||||||
|
SBigNew(&b);
|
||||||
|
uint64_t b_ = 0x100000000;
|
||||||
|
SBigFromBinary(b, reinterpret_cast<uint8_t*>(&b_), sizeof(b_));
|
||||||
|
|
||||||
|
BigData* c;
|
||||||
|
SBigNew(&c);
|
||||||
|
SBigFromUnsigned(c, 2);
|
||||||
|
|
||||||
|
BigData* d;
|
||||||
|
SBigNew(&d);
|
||||||
|
SBigFromUnsigned(d, 0xAAAAFFFF);
|
||||||
|
|
||||||
|
PowMod(a->Primary(), b->Primary(), c->Primary(), d->Primary(), a->Stack());
|
||||||
|
|
||||||
|
a->Primary().Trim();
|
||||||
|
|
||||||
|
CHECK(a->Primary().Count() == 1);
|
||||||
|
CHECK(a->Primary()[0] == 0x6AA94002);
|
||||||
|
|
||||||
|
SBigDel(a);
|
||||||
|
SBigDel(b);
|
||||||
|
SBigDel(c);
|
||||||
|
SBigDel(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("SBigAdd", "[big]") {
|
TEST_CASE("SBigAdd", "[big]") {
|
||||||
SECTION("adds 0 and 1") {
|
SECTION("adds 0 and 1") {
|
||||||
BigData* a;
|
BigData* a;
|
||||||
|
|
@ -1135,6 +1283,37 @@ TEST_CASE("SBigMul", "[big]") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("SBigPowMod", "[big]") {
|
||||||
|
SECTION("takes 256 to the 8th power and mods the result by 999") {
|
||||||
|
BigData* a;
|
||||||
|
SBigNew(&a);
|
||||||
|
|
||||||
|
BigData* b;
|
||||||
|
SBigNew(&b);
|
||||||
|
SBigFromUnsigned(b, 256);
|
||||||
|
|
||||||
|
BigData* c;
|
||||||
|
SBigNew(&c);
|
||||||
|
SBigFromUnsigned(c, 8);
|
||||||
|
|
||||||
|
BigData* d;
|
||||||
|
SBigNew(&d);
|
||||||
|
SBigFromUnsigned(d, 999);
|
||||||
|
|
||||||
|
SBigPowMod(a, b, c, d);
|
||||||
|
|
||||||
|
a->Primary().Trim();
|
||||||
|
|
||||||
|
CHECK(a->Primary().Count() == 1);
|
||||||
|
CHECK(a->Primary()[0] == 160);
|
||||||
|
|
||||||
|
SBigDel(a);
|
||||||
|
SBigDel(b);
|
||||||
|
SBigDel(c);
|
||||||
|
SBigDel(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("SBigShl", "[big]") {
|
TEST_CASE("SBigShl", "[big]") {
|
||||||
SECTION("shifts 256 left 7 bits") {
|
SECTION("shifts 256 left 7 bits") {
|
||||||
BigData* a;
|
BigData* a;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue