15#ifndef CIPHERS_UINT256_T_HPP_
16#define CIPHERS_UINT256_T_HPP_
36 if (str.size() > 1 && str[1] ==
'x') {
37 for (
auto i = 2; i < str.size(); ++i) {
39 if (str[i] >=
'0' && str[i] <=
'9') {
40 *
this += (str[i] -
'0');
41 }
else if (str[i] >=
'A' && str[i] <=
'F') {
42 *
this += (str[i] -
'A' + 10);
43 }
else if (str[i] >=
'a' && str[i] <=
'f') {
44 *
this += (str[i] -
'a' + 10);
64 template <
typename T,
typename =
typename std::enable_if<
65 std::is_integral<T>::value, T>::type>
87 : f(std::move(num.f)), s(std::move(num.s)) {}
95 : f(std::move(high)), s(std::move(low)) {}
102 uint256_t(
const uint64_t high,
const uint64_t low) : f(high), s(low) {}
118 return 128 + s._lez();
130 return 128 + f._trz();
137 inline explicit operator bool()
const {
return f || s; }
144 template <
typename T,
typename =
typename std::enable_if<
145 std::is_integral<T>::value, T>::type>
146 inline explicit operator T()
const {
147 return static_cast<T
>(s);
154 inline explicit operator uint128_t()
const {
return s; }
173 inline uint256_t &
operator=(
const uint256_t &p) =
default;
181 template <
typename T,
typename =
typename std::enable_if<
182 std::is_integral<T>::value, T>::type>
209 template <
typename T,
typename =
typename std::enable_if<
210 std::is_integral<T>::value, T>::type>
212 bool app = s + p < s;
213 return uint256_t(f + app, s + p);
222 bool app = (s + p.s < s);
223 return {f + app + p.f, s + p.s};
232 template <
typename T,
typename =
typename std::enable_if<
233 std::is_integral<T>::value, T>::type>
235 bool app = (p + s < s);
247 bool app = (s + p.s < s);
277 template <
typename T,
typename =
typename std::enable_if<
278 std::is_integral<T>::value, T>::type>
281 return uint256_t(f - app, s - p);
291 return {f - p.f - app, s - p.s};
298 inline uint256_t
operator-() {
return ~*
this + uint256_t(1); }
324 template <
typename T,
typename =
typename std::enable_if<
325 std::is_integral<T>::value, T>::type>
351 template <
typename T,
typename =
typename std::enable_if<
352 std::is_integral<T>::value, T>::type>
354 return *
this * uint256_t(p);
363 uint128_t f_first(s.upper()), f_second(s.lower()), s_first(p.s.
upper()),
364 s_second(p.s.
lower());
365 uint128_t fi = f_first * s_first, se = f_first * s_second,
366 th = s_first * f_second, fo = s_second * f_second;
367 uint128_t tmp = se << 64, tmp2 = th << 64;
368 int cc = (tmp + tmp2 < tmp);
370 cc += (tmp + fo < tmp);
371 return {f * p.s + s * p.f + fi + se.
upper() + th.upper() + cc,
381 template <
typename T,
typename =
typename std::enable_if<
382 std::is_integral<T>::value, T>::type>
384 return (*
this *= uint256_t(p));
393 uint128_t f_first(s.upper()), f_second(s.lower()), s_first(p.s.
upper()),
394 s_second(p.s.
lower());
395 uint128_t fi = f_first * s_first, se = f_first * s_second,
396 th = s_first * f_second, fo = s_second * f_second;
397 uint128_t tmp = se << 64, tmp2 = th << 64;
398 int cc = (tmp + tmp2 < tmp);
400 cc += (tmp + fo < tmp);
401 f = f * p.s + s * p.f + fi + se.
upper() + th.upper() + cc;
412 std::pair<uint256_t, uint256_t>
divide(
const uint256_t &p) {
414 return {uint256_t(0), *
this};
415 }
else if (*
this == p) {
416 return {uint256_t(1), uint256_t(0)};
418 uint256_t tmp = p, tmp2 = *
this;
419 uint16_t left = tmp.
_lez() -
_lez();
421 uint256_t quotient(0);
424 uint16_t shf = tmp2._lez() - tmp.
_lez();
438 return {quotient << left, tmp2};
447 template <
typename T,
typename =
typename std::enable_if<
448 std::is_integral<T>::value, T>::type>
450 uint256_t tmp = *
this;
478 template <
typename T,
typename =
typename std::enable_if<
479 std::is_integral<T>::value, T>::type>
481 *
this /= uint256_t(p);
498 template <
typename T,
typename =
typename std::enable_if<
499 std::is_integral<T>::value, T>::type>
501 uint256_t tmp = *
this;
522 template <
typename T,
typename =
typename std::enable_if<
523 std::is_integral<T>::value, T>::type>
525 *
this %= uint256_t(p);
535 return f < other.f || (f == other.f && s < other.s);
544 return f < other.f || (f == other.f && s <= other.s);
553 return f > other.f || (f == other.f && s > other.s);
562 return (f > other.f) || (f == other.f && s >= other.s);
571 return f == other.f && s == other.s;
580 return !((*this) == other);
595 return (s || f) && (b.s || b.f);
604 return (s || f) || (b.s || b.f);
619 template <
typename T,
typename =
typename std::enable_if<
620 std::is_integral<T>::value, T>::type>
622 return *
this < uint256_t(other);
631 template <
typename T,
typename =
typename std::enable_if<
632 std::is_integral<T>::value, T>::type>
634 return *
this <= uint256_t(other);
643 template <
typename T,
typename =
typename std::enable_if<
644 std::is_integral<T>::value, T>::type>
646 return *
this > uint256_t(other);
655 template <
typename T,
typename =
typename std::enable_if<
656 std::is_integral<T>::value, T>::type>
658 return *
this >= uint256_t(other);
667 template <
typename T,
typename =
typename std::enable_if<
668 std::is_integral<T>::value, T>::type>
670 return *
this == uint256_t(other);
679 template <
typename T,
typename =
typename std::enable_if<
680 std::is_integral<T>::value, T>::type>
682 return *
this != uint256_t(other);
691 template <
typename T,
typename =
typename std::enable_if<
692 std::is_integral<T>::value, T>::type>
694 return (s || f) && (b);
704 template <
typename T,
typename =
typename std::enable_if<
705 std::is_integral<T>::value, T>::type>
707 return (s || f) || (b);
722 template <
typename T,
typename =
typename std::enable_if<
723 std::is_integral<T>::value, T>::type>
726 return {this->f, this->s};
727 }
else if (p >= 128) {
728 return uint256_t((this->s << (p - 128)),
uint128_t(0));
730 return uint256_t((this->f << p) + (this->s >> (128 - p)),
740 template <
typename T,
typename =
typename std::enable_if<
741 std::is_integral<T>::value, T>::type>
745 this->f = (this->s << (p - 128));
748 f = ((this->s >> (128 - p)) + (this->f << p));
761 template <
typename T,
typename =
typename std::enable_if<
762 std::is_integral<T>::value, T>::type>
765 return {this->f, this->s};
766 }
else if (p >= 128) {
767 return uint256_t(
uint128_t(0), (this->f >> (p - 128)));
769 return uint256_t((this->f >> p),
770 (this->s >> p) + (this->f << (128 - p)));
779 template <
typename T,
typename =
typename std::enable_if<
780 std::is_integral<T>::value, T>::type>
785 s = (this->f >> (p - 128));
787 s = (this->s >> p) + (this->f << (128 - p));
800 template <
typename T,
typename =
typename std::enable_if<
801 std::is_integral<T>::value, T>::type>
803 return *
this & uint256_t(p);
812 return {f & p.f, s & p.s};
832 template <
typename T,
typename =
typename std::enable_if<
833 std::is_integral<T>::value, T>::type>
845 template <
typename T,
typename =
typename std::enable_if<
846 std::is_integral<T>::value, T>::type>
848 return *
this | uint256_t(p);
857 return {this->f | p.f, this->s | p.s};
866 template <
typename T,
typename =
typename std::enable_if<
867 std::is_integral<T>::value, T>::type>
890 template <
typename T,
typename =
typename std::enable_if<
891 std::is_integral<T>::value, T>::type>
893 return uint256_t(f, s ^ p);
902 return {this->f ^ p.f, this->s ^ p.s};
922 template <
typename T,
typename =
typename std::enable_if<
923 std::is_integral<T>::value, T>::type>
938 friend std::ostream &
operator<<(std::ostream &op, uint256_t p) {
942 std::string out =
"0", p_2 =
"1";
944 for (uint64_t i = 0; i < 128; ++i) {
952 for (
int i = 0; i < 128; ++i) {
966template <
typename T,
typename =
typename std::enable_if<
967 std::is_integral<T>::value, T>::type>
972template <
typename T,
typename =
typename std::enable_if<
973 std::is_integral<T>::value, T>::type>
978template <
typename T,
typename =
typename std::enable_if<
979 std::is_integral<T>::value, T>::type>
984template <
typename T,
typename =
typename std::enable_if<
985 std::is_integral<T>::value, T>::type>
990template <
typename T,
typename =
typename std::enable_if<
991 std::is_integral<T>::value, T>::type>
997template <
typename T,
typename =
typename std::enable_if<
998 std::is_integral<T>::value, T>::type>
1003template <
typename T,
typename =
typename std::enable_if<
1004 std::is_integral<T>::value, T>::type>
1009template <
typename T,
typename =
typename std::enable_if<
1010 std::is_integral<T>::value, T>::type>
1016template <
typename T,
typename =
typename std::enable_if<
1017 std::is_integral<T>::value, T>::type>
1018inline bool operator&&(
const T p,
const uint256_t &q) {
1022template <
typename T,
typename =
typename std::enable_if<
1023 std::is_integral<T>::value, T>::type>
1024inline bool operator||(
const T p,
const uint256_t &q) {
1029template <
typename T,
typename =
typename std::enable_if<
1030 std::is_integral<T>::value, T>::type>
1031inline bool operator==(
const T p,
const uint256_t &q) {
1035template <
typename T,
typename =
typename std::enable_if<
1036 std::is_integral<T>::value, T>::type>
1037inline bool operator!=(
const T p,
const uint256_t &q) {
1041template <
typename T,
typename =
typename std::enable_if<
1042 std::is_integral<T>::value, T>::type>
1043inline bool operator<(
const T p,
const uint256_t &q) {
1047template <
typename T,
typename =
typename std::enable_if<
1048 std::is_integral<T>::value, T>::type>
1049inline bool operator<=(
const T p,
const uint256_t &q) {
1053template <
typename T,
typename =
typename std::enable_if<
1054 std::is_integral<T>::value, T>::type>
1055inline bool operator>(
const T p,
const uint256_t &q) {
1059template <
typename T,
typename =
typename std::enable_if<
1060 std::is_integral<T>::value, T>::type>
1061inline bool operator>=(
const T p,
const uint256_t &q) {
class for 128-bit unsigned integer
uint64_t upper() const
returns upper 64-bit integer part
uint64_t lower() const
returns lower 64-bit integer part
class for 256-bit unsigned integer
uint256_t(uint128_t high, uint128_t low)
Parameterized constructor.
bool operator!()
operator ! for uint256_t
uint32_t _lez()
Leading zeroes in binary.
uint256_t(uint256_t &&num) noexcept
Move constructor.
uint256_t & operator<<=(const T &p)
operator <<= for uint256_t
bool operator<=(const uint256_t &other)
operator <= for uint256_t
uint256_t(const std::string &str)
Parameterized constructor.
bool operator<=(const T &other)
operator <= for other types
uint256_t operator+(const T &p)
operator + for uint256_t and other integer types.
uint256_t(const uint64_t high, const uint64_t low)
Parameterized constructor.
uint256_t & operator%=(const uint256_t &p)
operator %= for uint256_t
uint256_t operator|(const uint256_t &p)
operator | for uint256_t (bitwise operator)
bool operator&&(const T &b)
operator && for other types
uint256_t & operator&=(const uint256_t &p)
operator &= for uint256_t (bitwise operator)
uint256_t & operator^=(const T &p)
operator ^= for other types (bitwise operator)
~uint256_t()=default
Destructor for uint256_t.
uint256_t operator-()
operator - using twos complement
bool operator||(const uint256_t &b)
operator || for uint256_t
uint256_t(const uint256_t &num)=default
Copy constructor.
uint256_t & operator*=(const uint256_t &p)
operator *= for uint256_t and other integer types.
uint256_t operator>>(const T &p)
operator >> for uint256_t
uint256_t operator<<(const T &p)
operator << for uint256_t
bool operator||(const T &b)
operator || for other types
uint256_t & operator=(const uint256_t &p)=default
operator = for uint256_t
uint256_t operator/(const uint256_t &p)
operator / for uint256_t and other integer types.
uint256_t & operator+=(const T &p)
operator += for uint256_t and other integer types.
uint256_t & operator-=(const uint256_t &p)
operator -= for uint256_t
uint256_t operator--(int)
operator – (post-decrement)
uint256_t & operator=(uint256_t &&p)=default
Move assignment operator.
uint256_t operator&(const T &p)
operator & for other types (bitwise operator)
uint256_t operator~()
operator ~ for uint256_t
uint256_t operator^(const uint256_t &p)
operator ^ for uint256_t (bitwise operator)
uint256_t & operator%=(const T &p)
operator %= for uint256_t
bool operator()()
operator () for uint256_t
uint256_t operator++(int)
post-increment operator
uint256_t operator%(const T &p)
operator % for uint256_t and other integer types.
std::pair< uint256_t, uint256_t > divide(const uint256_t &p)
divide function for uint256_t and other integer types.
uint256_t & operator=(const std::string &p)
operator = for type string
uint256_t operator-(const T &p)
operator - for uint256_t and other integer types.
bool operator!=(const T &other)
operator != for other types
bool operator==(const uint256_t &other)
operator == for uint256_t
friend std::ostream & operator<<(std::ostream &op, uint256_t p)
operator << for printing uint256_t integer
bool operator==(const T &other)
operator == for other types
uint256_t operator&(const uint256_t &p)
operator & for uint256_t (bitwise operator)
uint32_t _trz()
Trailing zeroes in binary.
uint256_t & operator--()
operator – (pre-decrement)
bool operator&&(const uint256_t &b)
operator && for uint256_t
uint256_t & operator|=(const uint256_t &p)
operator |= for uint256_t (bitwise operator)
uint128_t lower() const
returns lower 128-bit integer part
uint256_t operator*(const uint256_t &p)
operator * for uint256_t and other integer types.
uint256_t operator*(const T &p)
operator * for uint256_t and other integer types.
bool operator!=(const uint256_t &other)
operator != for uint256_t
uint256_t operator-(const uint256_t &p)
operator - for uint256_t
uint256_t & operator/=(const T &p)
operator /= for uint256_t and other integer types.
uint256_t & operator/=(const uint256_t &p)
operator /= for uint256_t
bool operator<(const T &other)
operator < for other types
uint256_t & operator+=(const uint256_t &p)
operator += for uint256_t
uint256_t & operator^=(const uint256_t &p)
operator ^= for uint256_t (bitwise operator)
uint256_t operator/(const T &p)
operator / for uint256_t and other integer types.
bool operator>(const uint256_t &other)
operator > for uint256_t
uint256_t operator^(const T &p)
operator ^ for other types (bitwise operator)
uint256_t operator-=(const T p)
operator -= for uint256_t and other integer types.
uint256_t operator|(const T &p)
operator | for other types (bitwise operator)
uint256_t operator%(const uint256_t &p)
operator % for uint256_t
bool operator>(const T &other)
operator > for other types
uint256_t & operator>>=(const T &p)
operator >>= for uint256_t
uint256_t & operator=(const T &p)
operator = for other types
bool operator>=(const uint256_t &other)
operator >= for uint256_t
uint128_t upper() const
returns upper 128-bit integer part
uint256_t(T low)
Parameterized constructor.
uint256_t & operator|=(const T &p)
operator |= for other types (bitwise operator)
uint256_t & operator++()
pre-increment operator
uint256_t operator+(const uint256_t &p)
operator + for uint256_t and other integer types.
uint256_t & operator*=(const T &p)
operator *= for uint256_t and other integer types.
uint256_t & operator&=(const T p)
operator &= for other types (bitwise operator)
bool operator<(const uint256_t &other)
operator < for uint256_t
void __get_integer_from_string(const std::string &str)
First and second half of 256 bit number.
bool operator>=(const T &other)
operator >= for other types
std::string add(const std::string &first, const std::string &second)
Adding two string.