cryptoscape
This commit is contained in:
parent
82f0987d11
commit
bebd2def31
3 changed files with 354 additions and 21 deletions
|
@ -48,8 +48,16 @@ int main(int argc, char **argv) {
|
||||||
std::cout << hash << std::endl;
|
std::cout << hash << std::endl;
|
||||||
std::cout << sosc::cgc::bcrypt_check("test pwd", hash);*/
|
std::cout << sosc::cgc::bcrypt_check("test pwd", hash);*/
|
||||||
|
|
||||||
sosc::BigUInt bi;
|
sosc::BigUInt a, b;
|
||||||
bi.Parse("abcdef0", 10);
|
|
||||||
|
a.Parse("ff0000");
|
||||||
|
b.Parse("fff");
|
||||||
|
//assert(a - b == sosc::BigUInt("feff01"));
|
||||||
|
|
||||||
|
//a += b;
|
||||||
|
a *= b;
|
||||||
|
|
||||||
|
std::cout << a.ToString() << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,9 +21,9 @@ bool sosc::BigUInt::Parse(std::string hex_str, int byte_count) {
|
||||||
hex_str.insert(hex_str.begin(), '0');
|
hex_str.insert(hex_str.begin(), '0');
|
||||||
|
|
||||||
int str_byte_count = hex_str.length() / 2;
|
int str_byte_count = hex_str.length() / 2;
|
||||||
byte_count = std::max(byte_count, str_byte_count);
|
this->value =
|
||||||
|
std::vector<uint8_t>(std::max(byte_count, str_byte_count), 0);
|
||||||
|
|
||||||
this->value = std::vector<uint8_t>(byte_count, 0);
|
|
||||||
for(int i = 0; i < hex_str.length(); i += 2) {
|
for(int i = 0; i < hex_str.length(); i += 2) {
|
||||||
if(!is_hex_char(hex_str[i]) || !is_hex_char(hex_str[i + 1]))
|
if(!is_hex_char(hex_str[i]) || !is_hex_char(hex_str[i + 1]))
|
||||||
return false;
|
return false;
|
||||||
|
@ -32,6 +32,8 @@ bool sosc::BigUInt::Parse(std::string hex_str, int byte_count) {
|
||||||
= std::stoi(hex_str.substr(i, 2), 0, 16);
|
= std::stoi(hex_str.substr(i, 2), 0, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(byte_count != -1)
|
||||||
|
this->value.resize(byte_count, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +44,12 @@ void sosc::BigUInt::Random(int byte_count) {
|
||||||
this->value[i] = random_str[i];
|
this->value[i] = random_str[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt sosc::BigUInt::GenerateRandom(int byte_count) {
|
||||||
|
BigUInt num;
|
||||||
|
num.Random(byte_count);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
void sosc::BigUInt::RandomPrime(int byte_count) {
|
void sosc::BigUInt::RandomPrime(int byte_count) {
|
||||||
do {
|
do {
|
||||||
this->Random(byte_count);
|
this->Random(byte_count);
|
||||||
|
@ -50,6 +58,24 @@ void sosc::BigUInt::RandomPrime(int byte_count) {
|
||||||
} while(!this->IsProbablePrime());
|
} while(!this->IsProbablePrime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt sosc::BigUInt::GenerateRandomPrime(int byte_count) {
|
||||||
|
BigUInt num;
|
||||||
|
num.RandomPrime(byte_count);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t sosc::BigUInt::UsedByteCount() const {
|
||||||
|
size_t ptr = this->ByteCount() - 1;
|
||||||
|
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
|
||||||
std::all_of(this->value.begin(), this->value.end(),
|
std::all_of(this->value.begin(), this->value.end(),
|
||||||
|
@ -70,25 +96,67 @@ bool sosc::BigUInt::IsEven() const {
|
||||||
return !this->GetBit(0);
|
return !this->GetBit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sosc::BigUInt::IsProbablePrime() const {
|
bool sosc::BigUInt::IsProbablePrime(uint16_t rounds) const {
|
||||||
// TODO rabin-miller
|
if(this->IsOne())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (*this == BigUInt(2u)
|
||||||
|
|| *this == BigUInt(3u)
|
||||||
|
|| *this == BigUInt(5u))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->IsEven()
|
||||||
|
|| this->IsDivisibleBy(BigUInt(3u))
|
||||||
|
|| this->IsDivisibleBy(BigUInt(5u)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*this < BigUInt(25u))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for(uint16_t i = 0; i < rounds; ++i) {
|
||||||
|
BigUInt rnd = BigUInt::GenerateRandom(this->ByteCount());
|
||||||
|
rnd = (rnd < BigUInt(2u))
|
||||||
|
? BigUInt(2u)
|
||||||
|
: (rnd > *this - BigUInt(2u))
|
||||||
|
? *this - BigUInt(2u)
|
||||||
|
: rnd;
|
||||||
|
|
||||||
|
if(BigUInt::ModPow(rnd, *this - BigUInt(1u), *this).IsOne())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<sosc::BigUInt, sosc::BigUInt> sosc::BigUInt::DivideWithRemainder
|
bool sosc::BigUInt::IsDivisibleBy(const BigUInt& value) const {
|
||||||
|
if(value.IsZero())
|
||||||
|
return false;
|
||||||
|
if(value.IsOne())
|
||||||
|
return true;
|
||||||
|
if(value == BigUInt(2u))
|
||||||
|
return value.IsEven();
|
||||||
|
|
||||||
|
return (*this % value).IsZero();
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::division_t sosc::BigUInt::DivideWithRemainder
|
||||||
(const BigUInt& num, const BigUInt& denom)
|
(const BigUInt& num, const BigUInt& denom)
|
||||||
{
|
{
|
||||||
if(num.IsZero())
|
if(num.IsZero())
|
||||||
return std::make_tuple(BigUInt(), BigUInt());
|
return division_t(BigUInt(), BigUInt());
|
||||||
if(denom.IsZero())
|
if(denom.IsZero())
|
||||||
throw "BigUInt division by zero";
|
throw "BigUInt division by zero";
|
||||||
if(denom.IsOne())
|
if(denom.IsOne())
|
||||||
return std::make_tuple(num, BigUInt());
|
return division_t(num, BigUInt());
|
||||||
if(denom > num)
|
if(denom > num)
|
||||||
return std::make_tuple(BigUInt(), num);
|
return division_t(BigUInt(), num);
|
||||||
|
|
||||||
BigUInt quotient, remainder;
|
BigUInt quotient, remainder;
|
||||||
for(uint64_t i = num.ByteCount() * 8 - 1;; --i) {
|
for(size_t i = num.ByteCount() * 8 - 1;; --i) {
|
||||||
remainder = remainder << 1;
|
remainder = remainder << 1;
|
||||||
remainder.SetBit(0, num.GetBit(i));
|
remainder.SetBit(0, num.GetBit(i));
|
||||||
|
|
||||||
|
@ -101,7 +169,7 @@ std::tuple<sosc::BigUInt, sosc::BigUInt> sosc::BigUInt::DivideWithRemainder
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::make_tuple(quotient, remainder);
|
return division_t(quotient, remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
sosc::BigUInt sosc::BigUInt::ModPow
|
sosc::BigUInt sosc::BigUInt::ModPow
|
||||||
|
@ -123,7 +191,7 @@ sosc::BigUInt sosc::BigUInt::ModPow
|
||||||
}
|
}
|
||||||
|
|
||||||
void sosc::BigUInt::SetBit(uint64_t bit, bool value) {
|
void sosc::BigUInt::SetBit(uint64_t bit, bool value) {
|
||||||
uint64_t byte = bit / 8;
|
size_t byte = bit / 8;
|
||||||
if(byte >= this->ByteCount())
|
if(byte >= this->ByteCount())
|
||||||
this->value.resize(byte + 1);
|
this->value.resize(byte + 1);
|
||||||
|
|
||||||
|
@ -134,7 +202,7 @@ void sosc::BigUInt::SetBit(uint64_t bit, bool value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sosc::BigUInt::GetBit(uint64_t bit) const {
|
bool sosc::BigUInt::GetBit(uint64_t bit) const {
|
||||||
uint64_t byte = bit / 8;
|
size_t byte = bit / 8;
|
||||||
if(byte >= this->ByteCount())
|
if(byte >= this->ByteCount())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -142,14 +210,27 @@ bool sosc::BigUInt::GetBit(uint64_t bit) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
sosc::BigUInt sosc::BigUInt::operator + (const BigUInt& rhs) const {
|
sosc::BigUInt sosc::BigUInt::operator + (const BigUInt& rhs) const {
|
||||||
uint64_t sum_range = std::min(this->ByteCount(), rhs.ByteCount());
|
size_t sum_range = std::max(this->ByteCount(), rhs.ByteCount());
|
||||||
|
|
||||||
|
auto rhs_v = rhs.value;
|
||||||
|
auto this_v = this->value;
|
||||||
|
rhs_v.resize(sum_range, 0);
|
||||||
|
this_v.resize(sum_range, 0);
|
||||||
|
|
||||||
BigUInt sum;
|
BigUInt sum;
|
||||||
uint8_t carry = 0;
|
sum.value.clear();
|
||||||
for(uint64_t i = 0; i < sum_range; ++i) {
|
|
||||||
|
|
||||||
|
uint8_t carry = 0;
|
||||||
|
for(size_t i = 0; i < sum_range; ++i) {
|
||||||
|
uint16_t result = this_v[i] + rhs_v[i] + carry;
|
||||||
|
carry = result >> 8;
|
||||||
|
|
||||||
|
sum.value.push_back(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(carry != 0)
|
||||||
|
sum.value.push_back(carry);
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,3 +238,206 @@ sosc::BigUInt& sosc::BigUInt::operator += (const BigUInt& rhs) {
|
||||||
this->Copy(*this + rhs);
|
this->Copy(*this + rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt sosc::BigUInt::operator - (const BigUInt& rhs) const {
|
||||||
|
if(*this < rhs)
|
||||||
|
return BigUInt();
|
||||||
|
|
||||||
|
size_t sub_range = std::max(this->ByteCount(), rhs.ByteCount());
|
||||||
|
|
||||||
|
auto rhs_v = rhs.value;
|
||||||
|
auto this_v = this->value;
|
||||||
|
rhs_v.resize(sub_range, 0);
|
||||||
|
this_v.resize(sub_range, 0);
|
||||||
|
|
||||||
|
BigUInt sub;
|
||||||
|
sub.value.clear();
|
||||||
|
|
||||||
|
uint8_t carry = 0;
|
||||||
|
for(size_t i = 0; i < sub_range; ++i) {
|
||||||
|
uint8_t result = this_v[i] - rhs_v[i] - carry;
|
||||||
|
carry = (rhs_v[i] + carry > this_v[i]) ? 1 : 0;
|
||||||
|
|
||||||
|
sub.value.push_back(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt& sosc::BigUInt::operator -= (const BigUInt& rhs) {
|
||||||
|
this->Copy(*this - rhs);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt sosc::BigUInt::operator * (const BigUInt& rhs) const {
|
||||||
|
if(this->IsZero() || rhs.IsZero())
|
||||||
|
return BigUInt();
|
||||||
|
if(this->IsOne())
|
||||||
|
return rhs;
|
||||||
|
if(rhs.IsOne())
|
||||||
|
return *this;
|
||||||
|
|
||||||
|
size_t prod_range = std::max(this->ByteCount(), rhs.ByteCount());
|
||||||
|
|
||||||
|
auto rhs_v = rhs.value;
|
||||||
|
auto this_v = this->value;
|
||||||
|
rhs_v.resize(prod_range, 0);
|
||||||
|
this_v.resize(prod_range, 0);
|
||||||
|
|
||||||
|
BigUInt product;
|
||||||
|
for(size_t i = 0; i < prod_range; ++i) {
|
||||||
|
if(rhs_v[i] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for(size_t j = 0; j < prod_range; ++j) {
|
||||||
|
if(this_v[j] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BigUInt result((uint16_t)((uint16_t)this_v[j] * rhs_v[i]));
|
||||||
|
product += (result << (8 * (i + j)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return product;
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt& sosc::BigUInt::operator *= (const BigUInt& rhs) {
|
||||||
|
this->Copy(*this * rhs);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt sosc::BigUInt::operator / (const BigUInt& rhs) const {
|
||||||
|
return BigUInt::DivideWithRemainder(*this, rhs).result;
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt& sosc::BigUInt::operator /= (const BigUInt& rhs) {
|
||||||
|
this->Copy(*this / rhs);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt sosc::BigUInt::operator % (const BigUInt& rhs) const {
|
||||||
|
return BigUInt::DivideWithRemainder(*this, rhs).remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::BigUInt::operator == (const BigUInt& rhs) const {
|
||||||
|
if(this->UsedByteCount() != rhs.UsedByteCount())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
size_t cmp_range = std::max(this->ByteCount(), rhs.ByteCount());
|
||||||
|
for(size_t i = 0; i < cmp_range; ++i) {
|
||||||
|
uint8_t a = i < this->ByteCount() ? this->value[i] : 0;
|
||||||
|
uint8_t b = i < rhs.ByteCount() ? rhs.value[i] : 0;
|
||||||
|
|
||||||
|
if(a != b)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::BigUInt::operator != (const BigUInt& rhs) const {
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::BigUInt::operator > (const BigUInt& rhs) const {
|
||||||
|
if(this->UsedByteCount() < rhs.UsedByteCount())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
size_t cmp_range = std::max(this->ByteCount(), rhs.ByteCount());
|
||||||
|
|
||||||
|
for(size_t i = cmp_range - 1;; --i) {
|
||||||
|
uint8_t a = i < this->ByteCount() ? this->value[i] : 0;
|
||||||
|
uint8_t b = i < rhs.ByteCount() ? rhs.value[i] : 0;
|
||||||
|
|
||||||
|
if(a > b)
|
||||||
|
return true;
|
||||||
|
if(i == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::BigUInt::operator >= (const BigUInt& rhs) const {
|
||||||
|
return (*this > rhs) || (*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::BigUInt::operator < (const BigUInt& rhs) const {
|
||||||
|
return !(*this > rhs) && *this != rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sosc::BigUInt::operator <= (const BigUInt& rhs) const {
|
||||||
|
return !(*this > rhs) || *this == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt sosc::BigUInt::operator >> (const uint64_t& rhs) const {
|
||||||
|
size_t bytes = rhs / 8;
|
||||||
|
uint8_t bits = rhs % 8;
|
||||||
|
if(bytes >= this->ByteCount())
|
||||||
|
return BigUInt();
|
||||||
|
|
||||||
|
std::vector<uint8_t> this_v
|
||||||
|
(this->value.begin() + bytes, this->value.end());
|
||||||
|
std::vector<uint8_t> buffer(this_v.size(), 0);
|
||||||
|
|
||||||
|
if(bits != 0) {
|
||||||
|
uint8_t carry = 0, mask = 0;
|
||||||
|
for(uint8_t i = 0; i < bits; ++i)
|
||||||
|
mask |= (1 << i);
|
||||||
|
|
||||||
|
for(size_t i = this_v.size() - 1;; --i) {
|
||||||
|
buffer[i] = carry | (this_v[i] >> bits);
|
||||||
|
carry = (buffer[i] & mask) << (8 - bits);
|
||||||
|
|
||||||
|
if(i == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt shifted;
|
||||||
|
shifted.value = bits == 0 ? this_v : buffer;
|
||||||
|
return shifted;
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt sosc::BigUInt::operator << (const uint64_t& rhs) const {
|
||||||
|
size_t bytes = rhs / 8;
|
||||||
|
uint8_t bits = rhs % 8;
|
||||||
|
|
||||||
|
std::vector<uint8_t> this_v = this->value;
|
||||||
|
for(size_t i = 0; i < bytes; ++i)
|
||||||
|
this_v.insert(this_v.begin(), 0);
|
||||||
|
std::vector<uint8_t> buffer(this_v.size(), 0);
|
||||||
|
|
||||||
|
if(bits != 0) {
|
||||||
|
uint8_t carry = 0, mask = 0;
|
||||||
|
for(uint8_t i = 0; i < bits; ++i)
|
||||||
|
mask |= (0x80 >> i);
|
||||||
|
|
||||||
|
for(size_t i = bytes; i < this_v.size(); i++) {
|
||||||
|
buffer[i] = carry | (this_v[i] << bits);
|
||||||
|
carry = (this_v[i] & mask) >> (8 - bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(carry != 0)
|
||||||
|
this_v.push_back(carry);
|
||||||
|
}
|
||||||
|
|
||||||
|
sosc::BigUInt shifted;
|
||||||
|
shifted.value = bits == 0 ? this_v : buffer;
|
||||||
|
return shifted;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sosc::BigUInt::ToString() const {
|
||||||
|
std::stringstream stream;
|
||||||
|
for(size_t i = this->ByteCount() - 1;; --i) {
|
||||||
|
stream << std::setfill('0')
|
||||||
|
<< std::setw(2)
|
||||||
|
<< std::hex
|
||||||
|
<< (int)this->value[i];
|
||||||
|
|
||||||
|
if(i == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream.str();
|
||||||
|
}
|
||||||
|
|
|
@ -1,22 +1,40 @@
|
||||||
#ifndef SOSC_UTIL_BIGINT_H
|
#ifndef SOSC_UTIL_BIGINT_H
|
||||||
#define SOSC_UTIL_BIGINT_H
|
#define SOSC_UTIL_BIGINT_H
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "csprng.hpp"
|
#include "csprng.hpp"
|
||||||
|
|
||||||
namespace sosc {
|
namespace sosc {
|
||||||
|
struct division_t;
|
||||||
|
|
||||||
class BigUInt {
|
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(uint64_t value) { this->Initialize(value); }
|
||||||
|
|
||||||
BigUInt(std::string hex_str, int byte_count = -1);
|
BigUInt(std::string hex_str, int byte_count = -1);
|
||||||
bool Parse(std::string hex_str, int byte_count = -1);
|
bool Parse(std::string hex_str, int byte_count = -1);
|
||||||
|
inline void Resize(uint64_t byte_count) {
|
||||||
|
this->value.resize(byte_count, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void Random(int byte_count);
|
void Random(int byte_count);
|
||||||
void RandomPrime(int byte_count);
|
void RandomPrime(int byte_count);
|
||||||
|
static BigUInt GenerateRandom(int byte_count);
|
||||||
|
static BigUInt GenerateRandomPrime(int byte_count);
|
||||||
|
|
||||||
|
size_t UsedByteCount() const;
|
||||||
inline size_t ByteCount() const {
|
inline size_t ByteCount() const {
|
||||||
return value.size();
|
return value.size();
|
||||||
}
|
}
|
||||||
|
@ -24,9 +42,10 @@ public:
|
||||||
bool IsZero() const;
|
bool IsZero() const;
|
||||||
bool IsOne() const;
|
bool IsOne() const;
|
||||||
bool IsEven() const;
|
bool IsEven() const;
|
||||||
bool IsProbablePrime() const;
|
bool IsProbablePrime(uint16_t rounds = 5) const;
|
||||||
|
bool IsDivisibleBy(const BigUInt& value) const;
|
||||||
|
|
||||||
static std::tuple<BigUInt, BigUInt> DivideWithRemainder
|
static division_t DivideWithRemainder
|
||||||
(const BigUInt& num, const BigUInt& denom);
|
(const BigUInt& num, const BigUInt& denom);
|
||||||
|
|
||||||
static BigUInt ModPow
|
static BigUInt ModPow
|
||||||
|
@ -50,6 +69,7 @@ public:
|
||||||
BigUInt operator % (const BigUInt& rhs) const;
|
BigUInt operator % (const BigUInt& rhs) const;
|
||||||
|
|
||||||
bool operator == (const BigUInt& rhs) const;
|
bool operator == (const BigUInt& rhs) const;
|
||||||
|
bool operator != (const BigUInt& rhs) const;
|
||||||
bool operator > (const BigUInt& rhs) const;
|
bool operator > (const BigUInt& rhs) const;
|
||||||
bool operator >= (const BigUInt& rhs) const;
|
bool operator >= (const BigUInt& rhs) const;
|
||||||
bool operator < (const BigUInt& rhs) const;
|
bool operator < (const BigUInt& rhs) const;
|
||||||
|
@ -63,12 +83,33 @@ public:
|
||||||
return this->ToString();
|
return this->ToString();
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
inline void Copy(const BigUInt& from) {
|
template<typename T>
|
||||||
|
void Initialize(T value) {
|
||||||
|
for(int i = 0; i < sizeof(T); ++i) {
|
||||||
|
this->value.push_back(value & 0xFF);
|
||||||
|
value >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Copy(const BigUInt& from) {
|
||||||
|
this->value = from.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> value;
|
std::vector<uint8_t> value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct division_t {
|
||||||
|
public:
|
||||||
|
BigUInt result;
|
||||||
|
BigUInt remainder;
|
||||||
|
private:
|
||||||
|
division_t(const BigUInt& result, const BigUInt& remainder) {
|
||||||
|
this->result = result;
|
||||||
|
this->remainder = remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class BigUInt;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue