flat boob exchange soon

This commit is contained in:
malloc 2018-03-26 17:17:36 -05:00
parent de68d93bcc
commit a27bb453f9
3 changed files with 53 additions and 57 deletions

View file

@ -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();

View file

@ -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;

View file

@ -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;
}; };