very warped boob do NOT look

This commit is contained in:
malloc 2018-03-23 16:31:13 -05:00
parent e0f604bb04
commit 82182d3c48
3 changed files with 138 additions and 93 deletions

View file

@ -1,5 +1,6 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <ctime>
#include "sock/tcpsock.hpp" #include "sock/tcpsock.hpp"
#include "utils/string.hpp" #include "utils/string.hpp"
#include "utils/net.hpp" #include "utils/net.hpp"
@ -50,7 +51,10 @@ int main(int argc, char **argv) {
sosc::BigUInt a, b; sosc::BigUInt a, b;
/*
a.Parse("368BEADA711E83274DAF974D1A1A10EB915023D016CFC8BFAB58E5D848CF8D45"); a.Parse("368BEADA711E83274DAF974D1A1A10EB915023D016CFC8BFAB58E5D848CF8D45");
b.Parse("abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcd");
*/
//assert(a - b == sosc::BigUInt("feff01")); //assert(a - b == sosc::BigUInt("feff01"));
@ -64,8 +68,15 @@ int main(int argc, char **argv) {
//std::cout << sosc::BigUInt::GenerateRandomPrime(64).ToString(); //std::cout << sosc::BigUInt::GenerateRandomPrime(64).ToString();
//std::cout << a.IsProbablePrime(); //std::cout << a.IsProbablePrime();
for(int i = 0; i < 250; ++i) //for(int i = 0; i < 250; ++i)
a*a;
/*time_t start = time(NULL);
sosc::BigUInt::ModPow(a, a, b);
std::cout << (time(NULL) - start) << std::endl;*/
a.Parse("ff0000ff00000000");
a = a >> 8;
std::cout << a.ToString();
//std::cout << a.ToString(); //std::cout << a.ToString();

View file

@ -6,66 +6,103 @@ static bool is_hex_char(char c) {
|| ((c >= '0') && (c <= '9')); || ((c >= '0') && (c <= '9'));
} }
static const uint32_t left_shift_masks[32] = {
0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 0x0000001f,
0x0000003f, 0x0000007f, 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 0x0001ffff,
0x0003ffff, 0x0007ffff, 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 0x1fffffff,
0x3fffffff, 0x7fffffff
};
static const uint32_t right_shift_masks[32] = {
0x00000000, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000,
0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000,
0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000,
0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00,
0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8,
0xfffffffc, 0xfffffffe
};
sosc::BigUInt::BigUInt() { sosc::BigUInt::BigUInt() {
this->value = { 0 }; this->value = { 0 };
} }
sosc::BigUInt::BigUInt(std::string hex_str, int byte_count) { sosc::BigUInt::BigUInt(std::string hex_str, uint64_t byte_count) {
this->Parse(hex_str, byte_count); this->Parse(hex_str, byte_count);
} }
bool sosc::BigUInt::Parse(std::string hex_str, int byte_count) { bool sosc::BigUInt::Parse(std::string hex_str, uint64_t byte_count) {
if(hex_str.length() == 0) if(hex_str.length() == 0)
hex_str = "00"; hex_str = "00000000";
if(hex_str.length() % 2 != 0) if(hex_str.length() % 8 != 0)
hex_str.insert(hex_str.begin(), '0'); for(int i = hex_str.length() % 8; i < 8; ++i)
hex_str.insert(hex_str.begin(), '0');
int str_byte_count = hex_str.length() / 2; uint64_t word_count = WORD_CNT(byte_count);
uint64_t str_word_count = hex_str.length() / 8;
this->value = this->value =
std::vector<uint8_t>(std::max(byte_count, str_byte_count), 0); std::vector<uint32_t>(std::max(word_count, str_word_count), 0);
for(int i = 0; i < hex_str.length(); i += 2) { for(int i = 0; i < hex_str.length(); i += 8) {
if(!is_hex_char(hex_str[i]) || !is_hex_char(hex_str[i + 1])) for(int j = 0; j < 8; ++j)
return false; if(!is_hex_char(hex_str[i * 8 + j]))
return false;
this->value[str_byte_count - (i / 2) - 1] this->value[str_word_count - (i / 8) - 1]
= std::stoi(hex_str.substr(i, 2), 0, 16); = std::stoul(hex_str.substr(i, 8), 0, 16);
} }
if(byte_count != -1) if(byte_count != 0)
this->value.resize(byte_count, 0); this->value.resize(word_count, 0);
return true; return true;
} }
void sosc::BigUInt::Random(int byte_count) { void sosc::BigUInt::Random(uint64_t byte_count) {
this->value = std::vector<uint8_t>(byte_count, 0); this->value = std::vector<uint32_t>(WORD_CNT(byte_count), 0);
std::string random_str = csprng::next_bytes(byte_count); std::string random_str = csprng::next_bytes(byte_count);
for(int i = 0; i < byte_count; ++i) for(int i = 0; i < this->value.size(); i++)
this->value[i] = random_str[i]; for(int j = 0; j < 4; ++j)
this->value[i] |=
(i * 4 + j < byte_count)
? random_str[i * 4 + j] << (8 * j)
: 0;
} }
sosc::BigUInt sosc::BigUInt::GenerateRandom(int byte_count) { sosc::BigUInt sosc::BigUInt::GenerateRandom(uint64_t byte_count) {
BigUInt num; BigUInt num;
num.Random(byte_count); num.Random(byte_count);
return num; return num;
} }
void sosc::BigUInt::RandomPrime(int byte_count) { 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[byte_count - 1] |= 0x80; this->value[this->value.size()]
|= (0x80 << (8 * BYTE_OFF(byte_count)));
} while(!this->IsProbablePrime()); } while(!this->IsProbablePrime());
} }
sosc::BigUInt sosc::BigUInt::GenerateRandomPrime(int byte_count) { sosc::BigUInt sosc::BigUInt::GenerateRandomPrime(uint64_t byte_count) {
BigUInt num; BigUInt num;
num.RandomPrime(byte_count); num.RandomPrime(byte_count);
return num; return num;
} }
size_t sosc::BigUInt::UsedByteCount() const { size_t sosc::BigUInt::UsedByteCount() const {
size_t ptr = this->ByteCount() - 1; uint64_t msw_off = this->UsedWordCount() - 1;
uint32_t msw = this->value[msw_off];
int count = 0;
for(; (msw & 0xFF000000) != 0; msw <<= 8);
return msw_off * 8 + (4 - count);
}
size_t sosc::BigUInt::UsedWordCount() const {
size_t ptr = this->WordCount() - 1;
for(;; --ptr) { for(;; --ptr) {
if(this->value[ptr] != 0) if(this->value[ptr] != 0)
break; break;
@ -79,7 +116,7 @@ size_t sosc::BigUInt::UsedByteCount() const {
bool sosc::BigUInt::IsZero() const { bool sosc::BigUInt::IsZero() const {
return return
std::all_of(this->value.begin(), this->value.end(), std::all_of(this->value.begin(), this->value.end(),
[](uint8_t x) { return x == 0; }); [](uint32_t x) { return x == 0; });
} }
bool sosc::BigUInt::IsOne() const { bool sosc::BigUInt::IsOne() const {
@ -89,7 +126,7 @@ bool sosc::BigUInt::IsOne() const {
return this->value.size() == 1 return this->value.size() == 1
? true ? true
: std::all_of(this->value.begin() + 1, this->value.end(), : std::all_of(this->value.begin() + 1, this->value.end(),
[](uint8_t x) { return x == 0; }); [](uint32_t x) { return x == 0; });
} }
bool sosc::BigUInt::IsEven() const { bool sosc::BigUInt::IsEven() const {
@ -118,7 +155,7 @@ bool sosc::BigUInt::IsProbablePrime(uint16_t rounds) const {
return true; return true;
for(uint16_t i = 0; i < rounds; ++i) { for(uint16_t i = 0; i < rounds; ++i) {
BigUInt rnd = BigUInt::GenerateRandom(this->ByteCount()); BigUInt rnd = BigUInt::GenerateRandom(this->WordCount());
rnd = (rnd < BigUInt(2u)) rnd = (rnd < BigUInt(2u))
? BigUInt(2u) ? BigUInt(2u)
: (rnd > *this - BigUInt(2u)) : (rnd > *this - BigUInt(2u))
@ -156,7 +193,7 @@ sosc::division_t sosc::BigUInt::DivideWithRemainder
return division_t(BigUInt(), num); return division_t(BigUInt(), num);
BigUInt quotient, remainder; BigUInt quotient, remainder;
for(size_t i = num.ByteCount() * 8 - 1;; --i) { for(size_t i = num.UsedByteCount() * 8 - 1;; --i) {
remainder = remainder << 1; remainder = remainder << 1;
remainder.SetBit(0, num.GetBit(i)); remainder.SetBit(0, num.GetBit(i));
@ -179,42 +216,38 @@ sosc::BigUInt sosc::BigUInt::ModPow
BigUInt x = exp; BigUInt x = exp;
BigUInt bpow = base; BigUInt bpow = base;
uint64_t iterations = 0; for(uint64_t i = 0; i < exp.UsedByteCount() * 4; ++i) {
while(!x.IsZero()) {
++iterations;
if(!x.IsEven()) if(!x.IsEven())
accum = (accum * bpow) % mod; accum = (accum * bpow) % mod;
x = x >> 1; x = x >> 1;
bpow = (bpow * bpow) % mod; bpow = (bpow * bpow) % mod;
} }
std::cout << std::endl << iterations << std::endl;
return accum; return accum;
} }
void sosc::BigUInt::SetBit(uint64_t bit, bool value) { void sosc::BigUInt::SetBit(uint64_t bit, bool value) {
size_t byte = bit / 8; size_t word = bit / 32;
if(byte >= this->ByteCount()) if(word >= this->WordCount())
this->value.resize(byte + 1); this->value.resize(word + 1);
if(value) if(value)
this->value[byte] |= (1 << (bit % 8)); this->value[word] |= (1 << (bit % 32));
else else
this->value[byte] &= ~(1 << (bit % 8)); this->value[word] &= ~(1 << (bit % 32));
} }
bool sosc::BigUInt::GetBit(uint64_t bit) const { bool sosc::BigUInt::GetBit(uint64_t bit) const {
size_t byte = bit / 8; size_t word = bit / 32;
if(byte >= this->ByteCount()) if(word >= this->WordCount())
return false; return false;
return (this->value[byte] & (1 << (bit % 8))) != 0; return (this->value[word] & (1 << (bit % 32))) != 0;
} }
sosc::BigUInt sosc::BigUInt::operator + (const BigUInt& rhs) const { sosc::BigUInt sosc::BigUInt::operator + (const BigUInt& rhs) const {
size_t sum_range = std::max(this->ByteCount(), rhs.ByteCount()); size_t sum_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;
@ -224,10 +257,10 @@ sosc::BigUInt sosc::BigUInt::operator + (const BigUInt& rhs) const {
BigUInt sum; BigUInt sum;
sum.value.clear(); sum.value.clear();
uint8_t carry = 0; uint32_t carry = 0;
for(size_t i = 0; i < sum_range; ++i) { for(size_t i = 0; i < sum_range; ++i) {
uint16_t result = this_v[i] + rhs_v[i] + carry; uint64_t result = this_v[i] + rhs_v[i] + carry;
carry = result >> 8; carry = result >> 32;
sum.value.push_back(result); sum.value.push_back(result);
} }
@ -247,7 +280,7 @@ sosc::BigUInt sosc::BigUInt::operator - (const BigUInt& rhs) const {
if(*this < rhs) if(*this < rhs)
return BigUInt(); return BigUInt();
size_t sub_range = std::max(this->ByteCount(), rhs.ByteCount()); size_t sub_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;
@ -257,9 +290,9 @@ sosc::BigUInt sosc::BigUInt::operator - (const BigUInt& rhs) const {
BigUInt sub; BigUInt sub;
sub.value.clear(); sub.value.clear();
uint8_t carry = 0; uint64_t carry = 0;
for(size_t i = 0; i < sub_range; ++i) { for(size_t i = 0; i < sub_range; ++i) {
uint8_t result = this_v[i] - rhs_v[i] - carry; uint32_t result = this_v[i] - rhs_v[i] - carry;
carry = (rhs_v[i] + carry > this_v[i]) ? 1 : 0; carry = (rhs_v[i] + carry > this_v[i]) ? 1 : 0;
sub.value.push_back(result); sub.value.push_back(result);
@ -281,7 +314,7 @@ sosc::BigUInt sosc::BigUInt::operator * (const BigUInt& rhs) const {
if(rhs.IsOne()) if(rhs.IsOne())
return *this; return *this;
size_t prod_range = std::max(this->ByteCount(), rhs.ByteCount()); 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;
@ -297,8 +330,8 @@ sosc::BigUInt sosc::BigUInt::operator * (const BigUInt& rhs) const {
if(this_v[j] == 0) if(this_v[j] == 0)
continue; continue;
BigUInt result((uint16_t)((uint16_t)this_v[j] * rhs_v[i])); BigUInt result((uint64_t)((uint64_t)this_v[j] * rhs_v[i]));
product += (result << (8 * (i + j))); product += (result << (32 * (i + j)));
} }
} }
@ -324,10 +357,10 @@ sosc::BigUInt sosc::BigUInt::operator % (const BigUInt& rhs) const {
} }
bool sosc::BigUInt::operator == (const BigUInt& rhs) const { bool sosc::BigUInt::operator == (const BigUInt& rhs) const {
if(this->UsedByteCount() != rhs.UsedByteCount()) if(this->UsedWordCount() != rhs.UsedWordCount())
return false; return false;
for(size_t i = 0; i < this->UsedByteCount(); ++i) for(size_t i = 0; i < this->UsedWordCount(); ++i)
if(this->value[i] != rhs.value[i]) if(this->value[i] != rhs.value[i])
return false; return false;
@ -339,12 +372,12 @@ bool sosc::BigUInt::operator != (const BigUInt& rhs) const {
} }
bool sosc::BigUInt::operator > (const BigUInt& rhs) const { bool sosc::BigUInt::operator > (const BigUInt& rhs) const {
if(this->UsedByteCount() < rhs.UsedByteCount()) if(this->UsedWordCount() < rhs.UsedWordCount())
return false; return false;
if(this->UsedByteCount() > rhs.UsedByteCount()) if(this->UsedWordCount() > rhs.UsedWordCount())
return true; return true;
size_t msb = this->UsedByteCount() - 1; size_t msb = this->UsedWordCount() - 1;
for(size_t i = msb;; --i) { for(size_t i = msb;; --i) {
if(this->value[i] != rhs.value[i]) if(this->value[i] != rhs.value[i])
return this->value[i] > rhs.value[i]; return this->value[i] > rhs.value[i];
@ -367,23 +400,21 @@ bool sosc::BigUInt::operator <= (const BigUInt& rhs) const {
} }
sosc::BigUInt sosc::BigUInt::operator >> (const uint64_t& rhs) const { sosc::BigUInt sosc::BigUInt::operator >> (const uint64_t& rhs) const {
size_t bytes = rhs / 8; size_t words = rhs / 32;
uint8_t bits = rhs % 8; uint32_t bits = rhs % 32;
if(bytes >= this->ByteCount()) if(words >= this->WordCount())
return BigUInt(); return BigUInt();
std::vector<uint8_t> this_v std::vector<uint32_t> this_v
(this->value.begin() + bytes, this->value.end()); (this->value.begin() + words, this->value.end());
std::vector<uint8_t> buffer(this_v.size(), 0); std::vector<uint32_t> buffer(this_v.size(), 0);
if(bits != 0) { if(bits != 0) {
uint8_t carry = 0, mask = 0; uint8_t carry = 0, mask = left_shift_masks[bits];
for(uint8_t i = 0; i < bits; ++i)
mask |= (1 << i);
for(size_t i = this_v.size() - 1;; --i) { for(size_t i = this_v.size() - 1;; --i) {
buffer[i] = carry | (this_v[i] >> bits); buffer[i] = carry | (this_v[i] >> bits);
carry = (buffer[i] & mask) << (8 - bits); carry = (buffer[i] & mask) << (32 - bits);
if(i == 0) if(i == 0)
break; break;
@ -396,22 +427,20 @@ sosc::BigUInt sosc::BigUInt::operator >> (const uint64_t& rhs) const {
} }
sosc::BigUInt sosc::BigUInt::operator << (const uint64_t& rhs) const { sosc::BigUInt sosc::BigUInt::operator << (const uint64_t& rhs) const {
size_t bytes = rhs / 8; size_t words = rhs / 32;
uint8_t bits = rhs % 8; uint32_t bits = rhs % 32;
std::vector<uint8_t> this_v = this->value; std::vector<uint32_t> this_v = this->value;
for(size_t i = 0; i < bytes; ++i) for(size_t i = 0; i < words; ++i)
this_v.insert(this_v.begin(), 0); this_v.insert(this_v.begin(), 0);
std::vector<uint8_t> buffer(this_v.size(), 0); std::vector<uint32_t> buffer(this_v.size(), 0);
if(bits != 0) { if(bits != 0) {
uint8_t carry = 0, mask = 0; uint8_t carry = 0, mask = right_shift_masks[bits];
for(uint8_t i = 0; i < bits; ++i)
mask |= (0x80 >> i);
for(size_t i = bytes; i < this_v.size(); i++) { for(size_t i = words; i < this_v.size(); i++) {
buffer[i] = carry | (this_v[i] << bits); buffer[i] = carry | (this_v[i] << bits);
carry = (this_v[i] & mask) >> (8 - bits); carry = (this_v[i] & mask) >> (32 - bits);
} }
if(carry != 0) if(carry != 0)
@ -425,11 +454,11 @@ sosc::BigUInt sosc::BigUInt::operator << (const uint64_t& rhs) const {
std::string sosc::BigUInt::ToString() const { std::string sosc::BigUInt::ToString() const {
std::stringstream stream; std::stringstream stream;
for(size_t i = this->ByteCount() - 1;; --i) { for(size_t i = this->WordCount() - 1;; --i) {
stream << std::setfill('0') stream << std::setfill('0')
<< std::setw(2) << std::setw(8)
<< std::hex << std::hex
<< (int)this->value[i]; << this->value[i];
if(i == 0) if(i == 0)
break; break;

View file

@ -13,6 +13,9 @@
#include <algorithm> #include <algorithm>
#include "csprng.hpp" #include "csprng.hpp"
#define BYTE_OFF(X) ((X - 1) % 4)
#define WORD_CNT(X) (X == 0 ? 0 : ((X - 1) / 4 + 1))
namespace sosc { namespace sosc {
struct division_t; struct division_t;
@ -25,19 +28,20 @@ public:
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); }
BigUInt(std::string hex_str, int byte_count = -1); BigUInt(std::string hex_str, uint64_t byte_count = 0);
bool Parse(std::string hex_str, int byte_count = -1); bool Parse(std::string hex_str, uint64_t byte_count = 0);
inline void Resize(uint64_t byte_count) { inline void Resize(uint64_t byte_count) {
this->value.resize(byte_count, 0); this->value.resize(WORD_CNT(byte_count), 0);
} }
void Random(int byte_count); void Random(uint64_t byte_count);
void RandomPrime(int byte_count); void RandomPrime(uint64_t byte_count);
static BigUInt GenerateRandom(int byte_count); static BigUInt GenerateRandom(uint64_t byte_count);
static BigUInt GenerateRandomPrime(int byte_count); static BigUInt GenerateRandomPrime(uint64_t byte_count);
size_t UsedByteCount() const; size_t UsedByteCount() const;
inline size_t ByteCount() const { size_t UsedWordCount() const;
inline size_t WordCount() const {
return value.size(); return value.size();
} }
@ -87,9 +91,10 @@ public:
private: private:
template<typename T> template<typename T>
void Initialize(T value) { void Initialize(T value) {
for(int i = 0; i < sizeof(T); ++i) { this->value.clear();
this->value.push_back(value & 0xFF); for(int i = 0; i < WORD_CNT(sizeof(T)); ++i) {
value >>= 8; this->value.push_back(value & 0xFFFFFFFF);
value >>= 32;
} }
} }
@ -97,7 +102,7 @@ private:
this->value = from.value; this->value = from.value;
} }
std::vector<uint8_t> value; std::vector<uint32_t> value;
}; };
struct division_t { struct division_t {