Sorted everything into namespaces

Added headers for some common mathematical fields
  - Started adding class structures
  - Added declarations for useful functions
Added operator-assignment operator overloads to BigInteger
This commit is contained in:
Gabriel Tofvesson 2018-02-26 02:28:58 +01:00
parent 1448af586d
commit 179cbc234b
9 changed files with 719 additions and 573 deletions

View File

@ -1,5 +1,17 @@
#pragma once #pragma once
struct PublicKey { namespace CryptoCPP {
namespace RSA {
struct PublicKey
{
// Big integer modulus
// Big integer exponent
};
}; class RSA
{
public:
//RSA(PublicKey* key, Math::BigInteger* privateKey);
};
}
}

View File

@ -69,7 +69,7 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>

View File

@ -2,8 +2,10 @@
#include "BigInteger.h" #include "BigInteger.h"
BIGINT_API BigInteger::BigInteger(int64_t initialValue) namespace CryptoCPP {
{ namespace Math {
BIGINT_API BigInteger::BigInteger(int64_t initialValue)
{
data = new std::vector<BYTE>(); data = new std::vector<BYTE>();
// We know how big this should be and we know the size won't change // We know how big this should be and we know the size won't change
@ -18,169 +20,193 @@ BIGINT_API BigInteger::BigInteger(int64_t initialValue)
} }
clip_zeroes(); clip_zeroes();
} }
BIGINT_API BigInteger::BigInteger(const BigInteger & initialvalue) BIGINT_API BigInteger::BigInteger(const BigInteger & initialvalue)
{ {
size_t size = initialvalue.data->size(); size_t size = initialvalue.data->size();
data = new std::vector<BYTE>(size); data = new std::vector<BYTE>(size);
for (size_t t = 0; t < size; ++t) (*data)[t] = (*initialvalue.data)[t]; for (size_t t = 0; t < size; ++t) (*data)[t] = (*initialvalue.data)[t];
sign = initialvalue.sign; sign = initialvalue.sign;
} }
BIGINT_API BigInteger * BigInteger::operator+(const BigInteger & val) const BIGINT_API BigInteger * BigInteger::operator+(const BigInteger & val) const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->iadd(val, false); create->iadd(val, false);
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator-(const BigInteger & val) const BIGINT_API BigInteger * BigInteger::operator-(const BigInteger & val) const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->isub(val, false); create->isub(val, false);
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator*(const BigInteger & val) const BIGINT_API BigInteger * BigInteger::operator*(const BigInteger & val) const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->imul(val, false); create->imul(val, false);
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator/(const BigInteger & val) const BIGINT_API BigInteger * BigInteger::operator/(const BigInteger & val) const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->idiv(val, false); create->idiv(val, false);
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator%(const BigInteger & val) const BIGINT_API BigInteger * BigInteger::operator%(const BigInteger & val) const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->imod(val, false); create->imod(val, false);
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator^(const BigInteger & val) const BIGINT_API BigInteger * BigInteger::operator^(const BigInteger & val) const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->ixor(val, false); create->ixor(val, false);
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator&(const BigInteger & val) const BIGINT_API BigInteger * BigInteger::operator&(const BigInteger & val) const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->iand(val, false); create->iand(val, false);
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator|(const BigInteger & val) const BIGINT_API BigInteger * BigInteger::operator|(const BigInteger & val) const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->ior(val, false); create->ior(val, false);
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator~() const BIGINT_API BigInteger * BigInteger::operator~() const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->inot(); create->inot();
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator<<(uint64_t shiftcount) const BIGINT_API BigInteger * BigInteger::operator<<(uint64_t shiftcount) const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->ishl(shiftcount); create->ishl(shiftcount);
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator>>(uint64_t shiftcount) const BIGINT_API BigInteger * BigInteger::operator>>(uint64_t shiftcount) const
{ {
BigInteger* create = new BigInteger(*this); BigInteger* create = new BigInteger(*this);
create->ishr(shiftcount); create->ishr(shiftcount);
return create; return create;
} }
BIGINT_API BigInteger * BigInteger::operator+(const BigInteger * val) const
{
return operator+(*val);
}
BIGINT_API BigInteger * BigInteger::operator-(const BigInteger * val) const
{
return operator-(*val);
}
BIGINT_API BigInteger * BigInteger::operator*(const BigInteger * val) const BIGINT_API BigInteger* BigInteger::operator+=(const BigInteger& val)
{ {
return operator*(*val); iadd(val, false);
} return this;
}
BIGINT_API BigInteger * BigInteger::operator/(const BigInteger * val) const BIGINT_API BigInteger* BigInteger::operator-=(const BigInteger& val)
{ {
return operator/(*val); isub(val, false);
} return this;
}
BIGINT_API BigInteger * BigInteger::operator%(const BigInteger * val) const BIGINT_API BigInteger* BigInteger::operator*=(const BigInteger& val)
{ {
return operator%(*val); imul(val, false);
} return this;
}
BIGINT_API BigInteger * BigInteger::operator^(const BigInteger * val) const BIGINT_API BigInteger* BigInteger::operator/=(const BigInteger& val)
{ {
return operator^(*val); idiv(val, false);
} return this;
}
BIGINT_API BigInteger * BigInteger::operator&(const BigInteger * val) const BIGINT_API BigInteger* BigInteger::operator%=(const BigInteger& val)
{ {
return operator&(*val); imod(val, false);
} return this;
}
BIGINT_API BigInteger * BigInteger::operator|(const BigInteger * val) const BIGINT_API BigInteger* BigInteger::operator^=(const BigInteger& val)
{ {
return operator|(*val); ixor(val, false);
} return this;
}
BIGINT_API bool BigInteger::operator<(const BigInteger& val) const BIGINT_API BigInteger* BigInteger::operator&=(const BigInteger& val)
{ {
iand(val, false);
return this;
}
BIGINT_API BigInteger* BigInteger::operator|=(const BigInteger& val)
{
ior(val, false);
return this;
}
BIGINT_API BigInteger* BigInteger::operator<<=(uint64_t shiftcount)
{
ishl(shiftcount);
return this;
}
BIGINT_API BigInteger* BigInteger::operator>>=(uint64_t shiftcount)
{
ishr(shiftcount);
return this;
}
BIGINT_API bool BigInteger::operator<(const BigInteger& val) const
{
return cmp(val, false) == 1; return cmp(val, false) == 1;
} }
BIGINT_API bool BigInteger::operator>(const BigInteger& val) const BIGINT_API bool BigInteger::operator>(const BigInteger& val) const
{ {
return cmp(val, true) == 1; return cmp(val, true) == 1;
} }
BIGINT_API bool BigInteger::operator<=(const BigInteger& val) const BIGINT_API bool BigInteger::operator<=(const BigInteger& val) const
{ {
return cmp(val, false) != 0; return cmp(val, false) != 0;
} }
BIGINT_API bool BigInteger::operator>=(const BigInteger& val) const BIGINT_API bool BigInteger::operator>=(const BigInteger& val) const
{ {
return cmp(val, true) != 0; return cmp(val, true) != 0;
} }
BIGINT_API bool BigInteger::operator==(const BigInteger& val) const BIGINT_API bool BigInteger::operator==(const BigInteger& val) const
{ {
if (sign != val.sign || data->size() != val.data->size()) return false; if (sign != val.sign || data->size() != val.data->size()) return false;
for (size_t i = 0; i < data->size(); ++i) if ((*data)[i] != (*val.data)[i]) return false; for (size_t i = 0; i < data->size(); ++i) if ((*data)[i] != (*val.data)[i]) return false;
return true; return true;
} }
BIGINT_API bool BigInteger::operator!=(const BigInteger& val) const BIGINT_API bool BigInteger::operator!=(const BigInteger& val) const
{ {
return !(*this == val); return !(*this == val);
} }
BIGINT_API char* BigInteger::toString() BIGINT_API char* BigInteger::toString()
{ {
char* string = new char[data->size()*2 + 3]; char* string = new char[data->size() * 2 + 3];
string[0] = '0'; string[0] = '0';
string[1] = 'x'; string[1] = 'x';
string[data->size() * 2 + 2] = 0; string[data->size() * 2 + 2] = 0;
@ -189,11 +215,11 @@ BIGINT_API char* BigInteger::toString()
string[(data->size() - 1 - t) * 2 + 2] = (data->at(t) >> 4) + ((data->at(t) >> 4) > 9 ? 87 : 48); string[(data->size() - 1 - t) * 2 + 2] = (data->at(t) >> 4) + ((data->at(t) >> 4) > 9 ? 87 : 48);
} }
return string; return string;
} }
void BigInteger::iadd(const BigInteger & other, bool swaptarget) BIGINT_API void BigInteger::iadd(const BigInteger & other, bool swaptarget)
{ {
if ((other.sign != sign) ^ swaptarget) if ((other.sign != sign) ^ swaptarget)
{ {
if (other.sign ^ swaptarget) if (other.sign ^ swaptarget)
@ -213,7 +239,7 @@ void BigInteger::iadd(const BigInteger & other, bool swaptarget)
size_t min = greater ? data->size() : other.data->size(); size_t min = greater ? data->size() : other.data->size();
const BigInteger* larger = greater ? &other : other.data->size() < data->size() ? this : nullptr; const BigInteger* larger = greater ? &other : other.data->size() < data->size() ? this : nullptr;
for (size_t i = 0; i<min; ++i) for (size_t i = 0; i < min; ++i)
{ {
int res = (*data)[i] + (*other.data)[i] + (carry ? 1 : 0); int res = (*data)[i] + (*other.data)[i] + (carry ? 1 : 0);
carry = res > 255; carry = res > 255;
@ -221,7 +247,7 @@ void BigInteger::iadd(const BigInteger & other, bool swaptarget)
} }
if (larger == &other) if (larger == &other)
{ {
for (size_t i = min; i<larger->data->size(); ++i) for (size_t i = min; i < larger->data->size(); ++i)
{ {
int res = larger->data->at(i) + (carry ? 1 : 0); int res = larger->data->at(i) + (carry ? 1 : 0);
carry = res < larger->data->at(i); carry = res < larger->data->at(i);
@ -246,10 +272,10 @@ void BigInteger::iadd(const BigInteger & other, bool swaptarget)
} }
clip_zeroes(); clip_zeroes();
if (!data->size()) data->push_back(0); if (!data->size()) data->push_back(0);
} }
void BigInteger::isub(const BigInteger & other, bool swaptarget) BIGINT_API void BigInteger::isub(const BigInteger & other, bool swaptarget)
{ {
if (other.sign ^ sign ^ swaptarget) // this - (-other) = this + other if (other.sign ^ sign ^ swaptarget) // this - (-other) = this + other
{ {
bool swap = !sign; bool swap = !sign;
@ -286,10 +312,10 @@ void BigInteger::isub(const BigInteger & other, bool swaptarget)
cpy(tc, false); cpy(tc, false);
} }
if (!data->size()) data->push_back(0); if (!data->size()) data->push_back(0);
} }
void BigInteger::imul(const BigInteger & val, bool swaptarget) BIGINT_API void BigInteger::imul(const BigInteger & val, bool swaptarget)
{ {
bool hb, passed = false; bool hb, passed = false;
size_t track = -1; size_t track = -1;
size_t bit, prev = 0; size_t bit, prev = 0;
@ -298,7 +324,7 @@ void BigInteger::imul(const BigInteger & val, bool swaptarget)
data->clear(); data->clear();
Loop: Loop:
bit = val.nth_set_bit(++track, true, &hb); bit = val.nth_set_bit(++track, true, &hb);
if (!hb || (passed && track == 0)) return; if (!hb || (passed && track == 0)) return;
passed = true; passed = true;
@ -308,10 +334,10 @@ Loop:
prev = bit; prev = bit;
goto Loop; goto Loop;
} }
BigInteger* BigInteger::idiv(const BigInteger & val, bool swaptarget) BIGINT_API BigInteger* BigInteger::idiv(const BigInteger & val, bool swaptarget)
{ {
if (val.is_zero()) throw new std::exception("Divide by zero!"); if (val.is_zero()) throw new std::exception("Divide by zero!");
BigInteger* rem = new BigInteger(0); BigInteger* rem = new BigInteger(0);
BigInteger quot = BigInteger(0); BigInteger quot = BigInteger(0);
@ -321,7 +347,7 @@ BigInteger* BigInteger::idiv(const BigInteger & val, bool swaptarget)
for (size_t t = highest_set_bit(&hb) + 1; hb && t > 0; --t) for (size_t t = highest_set_bit(&hb) + 1; hb && t > 0; --t)
{ {
rem->ishl(1); rem->ishl(1);
(*rem->data)[0] |= ((*data)[(t - 1) /8] >> ((t - 1) % 8)) & 1; (*rem->data)[0] |= ((*data)[(t - 1) / 8] >> ((t - 1) % 8)) & 1;
if (*rem >= val) if (*rem >= val)
{ {
@ -333,52 +359,52 @@ BigInteger* BigInteger::idiv(const BigInteger & val, bool swaptarget)
sign = val.sign ^ sign ^ swaptarget; sign = val.sign ^ sign ^ swaptarget;
if (!data->size()) data->push_back(0); if (!data->size()) data->push_back(0);
return rem; return rem;
} }
void BigInteger::imod(const BigInteger & val, bool swaptarget) BIGINT_API void BigInteger::imod(const BigInteger & val, bool swaptarget)
{ {
BigInteger* modres = idiv(val, swaptarget); BigInteger* modres = idiv(val, swaptarget);
cpy(*modres, true); cpy(*modres, true);
delete modres; delete modres;
} }
void BigInteger::ixor(const BigInteger & val, bool swaptarget) BIGINT_API void BigInteger::ixor(const BigInteger & val, bool swaptarget)
{ {
size_t s1 = val.data->size(), s2 = data->size(); size_t s1 = val.data->size(), s2 = data->size();
for (size_t t = 0; t < s1; ++t) for (size_t t = 0; t < s1; ++t)
if (t < s2) if (t < s2)
(*data)[t] ^= val.data->at(t); (*data)[t] ^= val.data->at(t);
else else
data->push_back(val.data->at(t)); data->push_back(val.data->at(t));
} }
void BigInteger::iand(const BigInteger & val, bool swaptarget) BIGINT_API void BigInteger::iand(const BigInteger & val, bool swaptarget)
{ {
size_t s1 = data->size(), s2 = val.data->size(); size_t s1 = data->size(), s2 = val.data->size();
for (size_t t = 0; t < s1; ++t) for (size_t t = 0; t < s1; ++t)
if (t < s2) if (t < s2)
(*data)[t] &= val.data->at(t); (*data)[t] &= val.data->at(t);
else else
break; break;
} }
void BigInteger::ior(const BigInteger & val, bool swaptarget) BIGINT_API void BigInteger::ior(const BigInteger & val, bool swaptarget)
{ {
size_t s1 = val.data->size(), s2 = data->size(); size_t s1 = val.data->size(), s2 = data->size();
for (size_t t = 0; t < s1; ++t) for (size_t t = 0; t < s1; ++t)
if (t < s2) if (t < s2)
(*data)[t] |= val.data->at(t); (*data)[t] |= val.data->at(t);
else else
data->push_back(val.data->at(t)); data->push_back(val.data->at(t));
} }
void BigInteger::inot() BIGINT_API void BigInteger::inot()
{ {
for (size_t t = 0; t < data->size(); ++t) (*data)[t] = ~(*data)[t]; for (size_t t = 0; t < data->size(); ++t) (*data)[t] = ~(*data)[t];
} }
void BigInteger::ishl(uint64_t shift) BIGINT_API void BigInteger::ishl(uint64_t shift)
{ {
size_t set = shift / 8; size_t set = shift / 8;
char sub = shift % 8; char sub = shift % 8;
BYTE bm = shift_mask(sub, true); BYTE bm = shift_mask(sub, true);
@ -402,10 +428,10 @@ void BigInteger::ishl(uint64_t shift)
for (size_t t = 0; t < cl; ++t) data->push_back(create[t]); for (size_t t = 0; t < cl; ++t) data->push_back(create[t]);
delete[] create; delete[] create;
clip_zeroes(); clip_zeroes();
} }
void BigInteger::ishr(uint64_t shift) BIGINT_API void BigInteger::ishr(uint64_t shift)
{ {
size_t offset = shift / 8; size_t offset = shift / 8;
char sub = shift % 8; char sub = shift % 8;
BYTE bm = shift_mask(sub, false); BYTE bm = shift_mask(sub, false);
@ -424,33 +450,33 @@ void BigInteger::ishr(uint64_t shift)
for (size_t t = 0; t < collect.size(); ++t) for (size_t t = 0; t < collect.size(); ++t)
{ {
(*data)[t] = (collect[t] >> sub); (*data)[t] = (collect[t] >> sub);
if (t+1 < collect.size()) (*data)[t] |= (collect[t + 1] & bm) << (8 - sub); if (t + 1 < collect.size()) (*data)[t] |= (collect[t + 1] & bm) << (8 - sub);
} }
if (!data->size()) data->push_back(0); if (!data->size()) data->push_back(0);
} }
void BigInteger::twos_complement() BIGINT_API void BigInteger::twos_complement()
{ {
for (size_t i = 0; i < data->size(); ++i) (*data)[i] = ~(*data)[i]; for (size_t i = 0; i < data->size(); ++i) (*data)[i] = ~(*data)[i];
iadd(BigInteger(1), false); iadd(BigInteger(1), false);
} }
void BigInteger::set_bit(size_t index, bool value) BIGINT_API void BigInteger::set_bit(size_t index, bool value)
{ {
BYTE fill = sign ? 0xFF : 0x00; BYTE fill = sign ? 0xFF : 0x00;
while (index >= data->size() * 8) data->push_back(fill); while (index >= data->size() * 8) data->push_back(fill);
(*data)[index / 8] = ((*data)[index / 8] & ~(1 << (index % 8))) | ((value ? 1 : 0) << (index % 8)); (*data)[index / 8] = ((*data)[index / 8] & ~(1 << (index % 8))) | ((value ? 1 : 0) << (index % 8));
} }
void BigInteger::cpy(const BigInteger& val, bool withsign) BIGINT_API void BigInteger::cpy(const BigInteger& val, bool withsign)
{ {
if(withsign) sign = val.sign; if (withsign) sign = val.sign;
data->clear(); data->clear();
for (BYTE b : *val.data) data->push_back(b); for (BYTE b : *val.data) data->push_back(b);
} }
char BigInteger::cmp(const BigInteger & other, bool grt) const BIGINT_API char BigInteger::cmp(const BigInteger & other, bool grt) const
{ {
// If the other number is less than zero and this is a positive number, this number is larger and vice versa // If the other number is less than zero and this is a positive number, this number is larger and vice versa
if (other.sign && !sign && other.data->size() != 0) return grt ? 1 : 0; if (other.sign && !sign && other.data->size() != 0) return grt ? 1 : 0;
if (sign && !other.sign && data->size() != 0) return grt ? 0 : 1; if (sign && !other.sign && data->size() != 0) return grt ? 0 : 1;
@ -463,34 +489,34 @@ char BigInteger::cmp(const BigInteger & other, bool grt) const
if (!hb1) return 2; if (!hb1) return 2;
} }
return ((l1 > l2 && (!sign == grt)) || ((sign == grt) && l1 < l2)) ? 1 : 0; return ((l1 > l2 && (!sign == grt)) || ((sign == grt) && l1 < l2)) ? 1 : 0;
} }
char BigInteger::shift_mask(int64_t shift, bool left) BIGINT_API char BigInteger::shift_mask(int64_t shift, bool left)
{ {
BYTE res = 0; BYTE res = 0;
for (uint64_t i = shift; i > 0; --i) res = left ? (res >> 1) | 128 : (res << 1) | 1; for (uint64_t i = shift; i > 0; --i) res = left ? (res >> 1) | 128 : (res << 1) | 1;
return res; return res;
} }
void BigInteger::clip_zeroes() BIGINT_API void BigInteger::clip_zeroes()
{ {
while (data->size()>1 && !data->at(data->size()-1)) data->pop_back(); while (data->size() > 1 && !data->at(data->size() - 1)) data->pop_back();
} }
size_t BigInteger::highest_set_bit(bool * hasbits) const BIGINT_API size_t BigInteger::highest_set_bit(bool * hasbits) const
{ {
*hasbits = true; *hasbits = true;
for (size_t t = data->size(); t > 0; --t) for (size_t t = data->size(); t > 0; --t)
if (data->at(t-1)) if (data->at(t - 1))
for (size_t t1 = 8; t1 > 0; --t1) for (size_t t1 = 8; t1 > 0; --t1)
if (data->at(t-1) & (1 << (t1 - 1))) if (data->at(t - 1) & (1 << (t1 - 1)))
return (t1 - 1) + ((t - 1) * 8); return (t1 - 1) + ((t - 1) * 8);
*hasbits = false; *hasbits = false;
return 0; return 0;
} }
size_t BigInteger::lowest_set_bit(bool * hasbits) const BIGINT_API size_t BigInteger::lowest_set_bit(bool * hasbits) const
{ {
*hasbits = true; *hasbits = true;
for (size_t t = 0; t < data->size(); ++t) for (size_t t = 0; t < data->size(); ++t)
if (data->at(t)) if (data->at(t))
@ -499,23 +525,26 @@ size_t BigInteger::lowest_set_bit(bool * hasbits) const
return t1 + (t * 8); return t1 + (t * 8);
*hasbits = false; *hasbits = false;
return 0; return 0;
} }
size_t BigInteger::nth_set_bit(size_t index, bool minfirst, bool * hasbits) const BIGINT_API size_t BigInteger::nth_set_bit(size_t index, bool minfirst, bool * hasbits) const
{ {
*hasbits = true; *hasbits = true;
size_t target = index + 1; size_t target = index + 1;
for (size_t l = minfirst ? 1 : (data->size() * 8); (minfirst && l<=data->size() * 8) || (!minfirst && l > 0); l += minfirst ? 1 : -1) for (size_t l = minfirst ? 1 : (data->size() * 8); (minfirst && l <= data->size() * 8) || (!minfirst && l > 0); l += minfirst ? 1 : -1)
if (((*data)[(int)((l-1) / 8)] & (1 << (int)((l-1) % 8))) && --target == 0) if (((*data)[(int)((l - 1) / 8)] & (1 << (int)((l - 1) % 8))) && --target == 0)
return l - 1; return l - 1;
*hasbits = false; *hasbits = false;
return 0; return 0;
} }
bool BigInteger::is_zero() const BIGINT_API bool BigInteger::is_zero() const
{ {
for (size_t t = 0; t < data->size(); ++t) for (size_t t = 0; t < data->size(); ++t)
if (data->at(t)) if (data->at(t))
return false; return false;
return true; return true;
}
}
} }

View File

@ -1,7 +1,6 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include <queue>
#ifdef BIGINT_API #ifdef BIGINT_API
#define BIGINT_API __declspec(dllexport) #define BIGINT_API __declspec(dllexport)
@ -12,8 +11,11 @@
#define BYTE unsigned char #define BYTE unsigned char
class BigInteger { namespace CryptoCPP {
public: namespace Math {
class BigInteger
{
public:
BIGINT_API BigInteger(int64_t initialValue); BIGINT_API BigInteger(int64_t initialValue);
BIGINT_API BigInteger(const BigInteger& initialvalue); BIGINT_API BigInteger(const BigInteger& initialvalue);
@ -30,16 +32,16 @@ public:
BIGINT_API BigInteger* operator<<(uint64_t shiftcount) const; BIGINT_API BigInteger* operator<<(uint64_t shiftcount) const;
BIGINT_API BigInteger* operator>>(uint64_t shiftcount) const; BIGINT_API BigInteger* operator>>(uint64_t shiftcount) const;
BIGINT_API BigInteger* operator+=(const BigInteger& val);
BIGINT_API BigInteger* operator+(const BigInteger* val) const; BIGINT_API BigInteger* operator-=(const BigInteger& val);
BIGINT_API BigInteger* operator-(const BigInteger* val) const; BIGINT_API BigInteger* operator*=(const BigInteger& val);
BIGINT_API BigInteger* operator*(const BigInteger* val) const; BIGINT_API BigInteger* operator/=(const BigInteger& val);
BIGINT_API BigInteger* operator/(const BigInteger* val) const; BIGINT_API BigInteger* operator%=(const BigInteger& val);
BIGINT_API BigInteger* operator%(const BigInteger* val) const; BIGINT_API BigInteger* operator^=(const BigInteger& val);
BIGINT_API BigInteger* operator^(const BigInteger* val) const; BIGINT_API BigInteger* operator&=(const BigInteger& val);
BIGINT_API BigInteger* operator&(const BigInteger* val) const; BIGINT_API BigInteger* operator|=(const BigInteger& val);
BIGINT_API BigInteger* operator|(const BigInteger* val) const; BIGINT_API BigInteger* operator<<=(uint64_t shiftcount);
BIGINT_API BigInteger* operator>>=(uint64_t shiftcount);
BIGINT_API bool operator<(const BigInteger& val) const; BIGINT_API bool operator<(const BigInteger& val) const;
BIGINT_API bool operator>(const BigInteger& val) const; BIGINT_API bool operator>(const BigInteger& val) const;
@ -50,35 +52,37 @@ public:
BIGINT_API char* toString(); BIGINT_API char* toString();
protected: protected:
std::vector<BYTE>* data; std::vector<BYTE>* data;
bool sign; bool sign;
// Internal functions: manipulate the object they are called on // Internal functions: manipulate the object they are called on
void iadd(const BigInteger& val, bool swaptarget); BIGINT_API void iadd(const BigInteger& val, bool swaptarget);
void isub(const BigInteger& val, bool swaptarget); BIGINT_API void isub(const BigInteger& val, bool swaptarget);
void imul(const BigInteger& val, bool swaptarget); BIGINT_API void imul(const BigInteger& val, bool swaptarget);
BigInteger* idiv(const BigInteger& val, bool swaptarget); BIGINT_API BigInteger* idiv(const BigInteger& val, bool swaptarget);
void imod(const BigInteger& val, bool swaptarget); BIGINT_API void imod(const BigInteger& val, bool swaptarget);
void ixor(const BigInteger& val, bool swaptarget); BIGINT_API void ixor(const BigInteger& val, bool swaptarget);
void iand(const BigInteger& val, bool swaptarget); BIGINT_API void iand(const BigInteger& val, bool swaptarget);
void ior(const BigInteger& val, bool swaptarget); BIGINT_API void ior(const BigInteger& val, bool swaptarget);
void inot(); BIGINT_API void inot();
void ishl(uint64_t shift); BIGINT_API void ishl(uint64_t shift);
void ishr(uint64_t shift); BIGINT_API void ishr(uint64_t shift);
void twos_complement(); BIGINT_API void twos_complement();
void set_bit(size_t index, bool value); BIGINT_API void set_bit(size_t index, bool value);
void cpy(const BigInteger& val, bool withsign); BIGINT_API void cpy(const BigInteger& val, bool withsign);
char cmp(const BigInteger& other, bool grt) const; BIGINT_API char cmp(const BigInteger& other, bool grt) const;
// Math helper functions // Math helper functions
char shift_mask(int64_t shift, bool left); BIGINT_API char shift_mask(int64_t shift, bool left);
// For sorting and whatnot // For sorting and whatnot
void clip_zeroes(); BIGINT_API void clip_zeroes();
size_t highest_set_bit(bool* hasbits) const; BIGINT_API size_t highest_set_bit(bool* hasbits) const;
size_t lowest_set_bit(bool* hasbits) const; BIGINT_API size_t lowest_set_bit(bool* hasbits) const;
size_t nth_set_bit(size_t index, bool minfirst, bool* hasbits) const; BIGINT_API size_t nth_set_bit(size_t index, bool minfirst, bool* hasbits) const;
bool is_zero() const; BIGINT_API bool is_zero() const;
}; };
}
}

21
XMath/Galois.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
namespace CryptoCPP {
namespace Math {
class Galois
{
public:
Galois(size_t characteristic, size_t exponent, size_t irreducible);
Galois * add(const Galois * value) const; // Add
Galois * sub(const Galois * value) const; // Subtract
Galois * mul(const Galois * value) const; // Multiply
Galois * inv(const Galois * value) const; // Inverse multiply
protected:
size_t characteristic, exponent, irreducible;
// Reduce the value of this galois to one that fits the field parameters
void reduce();
};
}
}

56
XMath/Matrix.h Normal file
View File

@ -0,0 +1,56 @@
#pragma once
#include <vector>
#ifdef MATRIX_API
#define MATRIX_API __declspec(dllexport)
#else
#define MATRIX_API __declspec(dllimport)
#endif
namespace CryptoCPP {
namespace Math {
class Matrix
{
public:
MATRIX_API typedef void(*ChainFunction) (Vector & valueSet);
MATRIX_API Matrix(size_t height, size_t width);
MATRIX_API Matrix(Matrix & copy);
MATRIX_API ChainFunction set_row(const Vector & row);
MATRIX_API ChainFunction set_col(const Vector & col);
MATRIX_API Vector* at_row(size_t index) const;
MATRIX_API Vector* at_col(size_t index) const;
MATRIX_API long long at(size_t row, size_t col) const;
MATRIX_API Matrix* mul(const Matrix & factor) const;
MATRIX_API Matrix* mul(long long scalar) const;
MATRIX_API Matrix* minor(size_t row, size_t col) const;
MATRIX_API long long det() const;
protected:
Vector * columns;
size_t height;
size_t width;
};
class Vector
{
public:
MATRIX_API Vector(size_t count);
MATRIX_API Vector(size_t count, long long * values);
MATRIX_API long long at(size_t index) const;
MATRIX_API long long at(size_t index, long long newval);
protected:
long double * valueSet;
size_t count;
};
}
}

12
XMath/Primes.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include "BigInteger.h"
namespace CryptoCPP {
namespace Primes {
bool fermat_prime_test(const BigInteger & value, size_t certainty);
bool miller_rabin_prime_test(const BigInteger & value, size_t certainty);
BigInteger * generate_prime(size_t byteCount, size_t certainty);
}
}

View File

@ -116,6 +116,9 @@
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="BigInteger.h" /> <ClInclude Include="BigInteger.h" />
<ClInclude Include="Galois.h" />
<ClInclude Include="Matrix.h" />
<ClInclude Include="Primes.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="BigInteger.cpp" /> <ClCompile Include="BigInteger.cpp" />

View File

@ -23,5 +23,14 @@
<ClInclude Include="BigInteger.h"> <ClInclude Include="BigInteger.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Matrix.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Galois.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Primes.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>