flat boob exchange soon
This commit is contained in:
parent
de68d93bcc
commit
a27bb453f9
3 changed files with 53 additions and 57 deletions
|
@ -51,11 +51,9 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
sosc::BigUInt a, b, c;
|
sosc::BigUInt a, b, c;
|
||||||
|
|
||||||
|
/*a = sosc::BigUInt::GenerateRandom(128);
|
||||||
bool z = a.Parse("ffeeddccbbaa1010");
|
b = sosc::BigUInt::GenerateRandom(128);
|
||||||
bool y = b.Parse("aabbccddeeff");
|
c = sosc::BigUInt::GenerateRandom(128);*/
|
||||||
bool x = c.Parse("b0b0");
|
|
||||||
|
|
||||||
|
|
||||||
//assert(a - b == sosc::BigUInt("feff01"));
|
//assert(a - b == sosc::BigUInt("feff01"));
|
||||||
|
|
||||||
|
@ -71,15 +69,24 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
//for(int i = 0; i < 250; ++i)
|
//for(int i = 0; i < 250; ++i)
|
||||||
|
|
||||||
//time_t start = time(NULL);
|
time_t start = time(NULL);
|
||||||
|
|
||||||
/*auto d = sosc::BigUInt::DivideWithRemainder(a, b);
|
/*auto d = sosc::BigUInt::DivideWithRemainder(a, b);
|
||||||
std::cout << d.result.ToString() << std::endl
|
std::cout << d.result.ToString() << std::endl
|
||||||
<< d.remainder.ToString() << std::endl;*/
|
<< d.remainder.ToString() << std::endl;*/
|
||||||
|
|
||||||
std::cout << sosc::BigUInt::ModPow(a, b, c).ToString();
|
std::cout //<< a.ToString() << std::endl
|
||||||
|
//<< b.ToString() << std::endl
|
||||||
|
//<< (a * b).ToString() << std::endl;
|
||||||
|
//<< c.ToString() << std::endl << std::endl
|
||||||
|
//<< sosc::BigUInt::ModPow(a, b, c).ToString() << std::endl;
|
||||||
|
|
||||||
//std::cout << (time(NULL) - start) << std::endl;
|
<< sosc::BigUInt::GenerateRandomPrime(32).ToString() << std::endl
|
||||||
|
<< sosc::BigUInt::GenerateRandomPrime(32).ToString() << std::endl
|
||||||
|
<< sosc::BigUInt::GenerateRandomPrime(32).ToString() << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
std::cout << (time(NULL) - start) << std::endl;
|
||||||
|
|
||||||
//std::cout << a.ToString();
|
//std::cout << a.ToString();
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ bool sosc::BigUInt::Parse(std::string hex_str, uint64_t byte_count) {
|
||||||
if(byte_count != 0)
|
if(byte_count != 0)
|
||||||
this->value.resize(word_count, 0);
|
this->value.resize(word_count, 0);
|
||||||
|
|
||||||
|
this->TrimLeadingZeroes();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ void sosc::BigUInt::Random(uint64_t byte_count) {
|
||||||
for(int j = 0; j < 4; ++j)
|
for(int j = 0; j < 4; ++j)
|
||||||
this->value[i] |=
|
this->value[i] |=
|
||||||
(i * 4 + j < byte_count)
|
(i * 4 + j < byte_count)
|
||||||
? random_str[i * 4 + j] << (8 * j)
|
? (uint8_t)random_str[i * 4 + j] << (8 * j)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ void sosc::BigUInt::RandomPrime(uint64_t byte_count) {
|
||||||
do {
|
do {
|
||||||
this->Random(byte_count);
|
this->Random(byte_count);
|
||||||
this->value[0] |= 0x01;
|
this->value[0] |= 0x01;
|
||||||
this->value[this->value.size()]
|
this->value[this->value.size() - 1]
|
||||||
|= (0x80 << (8 * BYTE_OFF(byte_count)));
|
|= (0x80 << (8 * BYTE_OFF(byte_count)));
|
||||||
} while(!this->IsProbablePrime());
|
} while(!this->IsProbablePrime());
|
||||||
}
|
}
|
||||||
|
@ -92,42 +93,19 @@ sosc::BigUInt sosc::BigUInt::GenerateRandomPrime(uint64_t byte_count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sosc::BigUInt::UsedByteCount() const {
|
size_t sosc::BigUInt::UsedByteCount() const {
|
||||||
uint64_t msw_off = this->UsedWordCount() - 1;
|
return this->UsedWordCount() * 4;
|
||||||
uint32_t msw = this->value[msw_off];
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
for(; (msw & 0xFF000000) == 0; ++count)
|
|
||||||
msw <<= 8;
|
|
||||||
|
|
||||||
return msw_off * 4 + (4 - count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t sosc::BigUInt::UsedWordCount() const {
|
size_t sosc::BigUInt::UsedWordCount() const {
|
||||||
size_t ptr = this->WordCount() - 1;
|
return this->WordCount();
|
||||||
for(;; --ptr) {
|
|
||||||
if(this->value[ptr] != 0)
|
|
||||||
break;
|
|
||||||
if(ptr == 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sosc::BigUInt::IsZero() const {
|
bool sosc::BigUInt::IsZero() const {
|
||||||
return
|
return this->value.size() == 1 && this->value[0] == 0;
|
||||||
std::all_of(this->value.begin(), this->value.end(),
|
|
||||||
[](uint32_t x) { return x == 0; });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sosc::BigUInt::IsOne() const {
|
bool sosc::BigUInt::IsOne() const {
|
||||||
if(this->value[0] != 1)
|
return this->value.size() == 1 && this->value[0] == 1;
|
||||||
return false;
|
|
||||||
|
|
||||||
return this->value.size() == 1
|
|
||||||
? true
|
|
||||||
: std::all_of(this->value.begin() + 1, this->value.end(),
|
|
||||||
[](uint32_t x) { return x == 0; });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sosc::BigUInt::IsEven() const {
|
bool sosc::BigUInt::IsEven() const {
|
||||||
|
@ -138,13 +116,6 @@ bool sosc::BigUInt::IsProbablePrime(uint16_t rounds) const {
|
||||||
if(this->IsOne())
|
if(this->IsOne())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (*this == BigUInt(2u)
|
|
||||||
|| *this == BigUInt(3u)
|
|
||||||
|| *this == BigUInt(5u))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->IsEven()
|
if (this->IsEven()
|
||||||
|| this->IsDivisibleBy(BigUInt(3u))
|
|| this->IsDivisibleBy(BigUInt(3u))
|
||||||
|| this->IsDivisibleBy(BigUInt(5u)))
|
|| this->IsDivisibleBy(BigUInt(5u)))
|
||||||
|
@ -152,9 +123,6 @@ bool sosc::BigUInt::IsProbablePrime(uint16_t rounds) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(*this < BigUInt(25u))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for(uint16_t i = 0; i < rounds; ++i) {
|
for(uint16_t i = 0; i < rounds; ++i) {
|
||||||
BigUInt rnd = BigUInt::GenerateRandom(this->WordCount());
|
BigUInt rnd = BigUInt::GenerateRandom(this->WordCount());
|
||||||
rnd = (rnd < BigUInt(2u))
|
rnd = (rnd < BigUInt(2u))
|
||||||
|
@ -193,8 +161,9 @@ sosc::division_t sosc::BigUInt::DivideWithRemainder
|
||||||
if(denom > num)
|
if(denom > num)
|
||||||
return division_t(BigUInt(), num);
|
return division_t(BigUInt(), num);
|
||||||
|
|
||||||
|
size_t upper_bound = num.UsedByteCount() * 8 - 1;
|
||||||
BigUInt quotient, remainder;
|
BigUInt quotient, remainder;
|
||||||
for(size_t i = num.UsedByteCount() * 8 - 1;; --i) {
|
for(size_t i = upper_bound;; --i) {
|
||||||
remainder = remainder << 1;
|
remainder = remainder << 1;
|
||||||
remainder.SetBit(0, num.GetBit(i));
|
remainder.SetBit(0, num.GetBit(i));
|
||||||
|
|
||||||
|
@ -207,6 +176,8 @@ sosc::division_t sosc::BigUInt::DivideWithRemainder
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(remainder.value[remainder.value.size() - 1] == 0)
|
||||||
|
remainder.value.erase(remainder.value.end() - 1);
|
||||||
return division_t(quotient, remainder);
|
return division_t(quotient, remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,11 +188,11 @@ sosc::BigUInt sosc::BigUInt::ModPow
|
||||||
BigUInt x = exp;
|
BigUInt x = exp;
|
||||||
BigUInt bpow = base;
|
BigUInt bpow = base;
|
||||||
|
|
||||||
for(uint64_t i = 0; i < exp.UsedByteCount() * 8; ++i) {
|
uint64_t upper_bound = exp.UsedByteCount() * 8;
|
||||||
if(!x.IsEven())
|
for(uint64_t i = 0; i < upper_bound; ++i) {
|
||||||
|
if(x.GetBit(i))
|
||||||
accum = (accum * bpow) % mod;
|
accum = (accum * bpow) % mod;
|
||||||
|
|
||||||
x = x >> 1;
|
|
||||||
bpow = (bpow * bpow) % mod;
|
bpow = (bpow * bpow) % mod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -299,6 +270,7 @@ sosc::BigUInt sosc::BigUInt::operator - (const BigUInt& rhs) const {
|
||||||
sub.value.push_back(result);
|
sub.value.push_back(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub.TrimLeadingZeroes();
|
||||||
return sub;
|
return sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,13 +289,13 @@ sosc::BigUInt sosc::BigUInt::operator * (const BigUInt& rhs) const {
|
||||||
|
|
||||||
size_t prod_range = std::max(this->WordCount(), rhs.WordCount());
|
size_t prod_range = std::max(this->WordCount(), rhs.WordCount());
|
||||||
|
|
||||||
auto rhs_v = rhs.value;
|
/*auto rhs_v = rhs.value;
|
||||||
auto this_v = this->value;
|
auto this_v = this->value;
|
||||||
rhs_v.resize(prod_range, 0);
|
rhs_v.resize(prod_range, 0);
|
||||||
this_v.resize(prod_range, 0);
|
this_v.resize(prod_range, 0);*/
|
||||||
|
|
||||||
BigUInt product;
|
BigUInt product;
|
||||||
for(size_t i = 0; i < prod_range; ++i) {
|
/*for(size_t i = 0; i < prod_range; ++i) {
|
||||||
if(rhs_v[i] == 0)
|
if(rhs_v[i] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -334,6 +306,15 @@ sosc::BigUInt sosc::BigUInt::operator * (const BigUInt& rhs) const {
|
||||||
BigUInt result((uint64_t)((uint64_t)this_v[j] * rhs_v[i]));
|
BigUInt result((uint64_t)((uint64_t)this_v[j] * rhs_v[i]));
|
||||||
product += (result << (32 * (i + j)));
|
product += (result << (32 * (i + j)));
|
||||||
}
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
BigUInt this_cpy = *this;
|
||||||
|
uint64_t upper_bound = rhs.UsedByteCount() * 8;
|
||||||
|
for(uint64_t i = 0; i < upper_bound; ++i) {
|
||||||
|
if(rhs.GetBit(i))
|
||||||
|
product += this_cpy;
|
||||||
|
|
||||||
|
this_cpy = this_cpy << 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return product;
|
return product;
|
||||||
|
@ -389,7 +370,7 @@ bool sosc::BigUInt::operator > (const BigUInt& rhs) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sosc::BigUInt::operator >= (const BigUInt& rhs) const {
|
bool sosc::BigUInt::operator >= (const BigUInt& rhs) const {
|
||||||
return (*this > rhs) || (*this == rhs);
|
return *this > rhs || *this == rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sosc::BigUInt::operator < (const BigUInt& rhs) const {
|
bool sosc::BigUInt::operator < (const BigUInt& rhs) const {
|
||||||
|
@ -420,6 +401,9 @@ sosc::BigUInt sosc::BigUInt::operator >> (const uint64_t& rhs) const {
|
||||||
if(i == 0)
|
if(i == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(buffer[buffer.size() - 1] == 0)
|
||||||
|
buffer.erase(buffer.end() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
sosc::BigUInt shifted;
|
sosc::BigUInt shifted;
|
||||||
|
|
|
@ -23,8 +23,6 @@ class BigUInt {
|
||||||
public:
|
public:
|
||||||
BigUInt();
|
BigUInt();
|
||||||
|
|
||||||
BigUInt(uint8_t value) { this->Initialize(value); }
|
|
||||||
BigUInt(uint16_t value) { this->Initialize(value); }
|
|
||||||
BigUInt(uint32_t value) { this->Initialize(value); }
|
BigUInt(uint32_t value) { this->Initialize(value); }
|
||||||
BigUInt(uint64_t value) { this->Initialize(value); }
|
BigUInt(uint64_t value) { this->Initialize(value); }
|
||||||
|
|
||||||
|
@ -102,6 +100,13 @@ private:
|
||||||
this->value = from.value;
|
this->value = from.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrimLeadingZeroes() {
|
||||||
|
while(!this->value.empty() && this->value.back() == 0)
|
||||||
|
this->value.pop_back();
|
||||||
|
if(this->value.size() == 0)
|
||||||
|
this->value.push_back(0);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<uint32_t> value;
|
std::vector<uint32_t> value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue