very warped boob do NOT look
This commit is contained in:
parent
e0f604bb04
commit
82182d3c48
3 changed files with 138 additions and 93 deletions
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue