Algorithms_in_C++ 1.0.0
Set of algorithms implemented in C++.
Loading...
Searching...
No Matches
uint256_t.hpp
Go to the documentation of this file.
1/**
2 * @file
3 *
4 * @details Implementation of 256-bit unsigned integers.
5 * @note The implementation can be flagged as not completed. This header is used
6 * with enough operations to demonstrate the usage of ECDH (Elliptic Curve
7 * Diffie-Hellman) Key exchange.
8 * @author [Ashish Daulatabad](https://github.com/AshishYUO)
9 */
10#include <string> /// for `std::string`
11#include <utility> /// for `std::pair` library
12
13#include "uint128_t.hpp" /// for uint128_t integer
14
15#ifndef CIPHERS_UINT256_T_HPP_
16#define CIPHERS_UINT256_T_HPP_
17
18class uint256_t;
19
20template <>
22
23template <>
25
26template <>
28
29/**
30 * @class uint256_t
31 * @brief class for 256-bit unsigned integer
32 */
33class uint256_t {
34 uint128_t f{}, s{}; /// First and second half of 256 bit number
35
36 /**
37 * @brief Get integer from given string.
38 * @details Create an integer from a given string
39 * @param str integer string, can be hexadecimal (starting on 0x... or
40 * number)
41 * @returns void
42 */
44 this->f = this->s = uint128_t(0);
45 if (str.size() > 1 && str[1] == 'x') {
46 for (auto i = 2; i < str.size(); ++i) {
47 *this *= 16LL;
48 if (str[i] >= '0' && str[i] <= '9') {
49 *this += (str[i] - '0');
50 } else if (str[i] >= 'A' && str[i] <= 'F') {
51 *this += (str[i] - 'A' + 10);
52 } else if (str[i] >= 'a' && str[i] <= 'f') {
53 *this += (str[i] - 'a' + 10);
54 }
55 }
56 } else {
57 for (auto &x : str) {
58 *this *= 10LL;
59 *this += (x - '0');
60 }
61 }
62 }
63
64 public:
65 // Constructors
66 uint256_t() = default;
67
68 /**
69 * @brief Parameterized constructor
70 * @tparam T template for integer types
71 * @param low Integer denoting lower 128-bits
72 */
73 template <typename T, typename = typename std::enable_if<
75 explicit uint256_t(T low) : s(low), f(0) {}
76
77 /**
78 * @brief Parameterized constructor
79 * @param str Integer string (hexadecimal starting with 0x.. or decimal)
80 */
81 explicit uint256_t(const std::string &str) {
83 }
84
85 /**
86 * @brief Copy constructor
87 * @param num 256-bit unsigned integer
88 */
89 uint256_t(const uint256_t &num) = default;
90
91 /**
92 * @brief Move constructor
93 * @param num 256-bit unsigned integer
94 */
95 uint256_t(uint256_t &&num) noexcept
96 : f(std::move(num.f)), s(std::move(num.s)) {}
97
98 /**
99 * @brief Parameterized constructor
100 * @param high higher part 128-bit unsigned integer
101 * @param low lower part 128-bit unsigned integer
102 */
104 : f(std::move(high)), s(std::move(low)) {}
105
106 /**
107 * @brief Parameterized constructor
108 * @param high higher part 64-bit unsigned integer
109 * @param low lower part 64-bit unsigned integer
110 */
111 uint256_t(const uint64_t high, const uint64_t low) : f(high), s(low) {}
112
113 /**
114 * @brief Destructor for uint256_t
115 */
116 ~uint256_t() = default;
117
118 /**
119 * @brief Leading zeroes in binary
120 * @details Calculates leading zeros in 256-bit integer
121 * @returns Integer denoting leading zeroes
122 */
123 inline uint32_t _lez() {
124 if (f) {
125 return f._lez();
126 }
127 return 128 + s._lez();
128 }
129
130 /**
131 * @brief Trailing zeroes in binary
132 * @details Calculates leading zeros in 256-bit integer
133 * @returns Integer denoting Trailing zeroes
134 */
135 inline uint32_t _trz() {
136 if (s) {
137 return s._trz();
138 }
139 return 128 + f._trz();
140 }
141
142 /**
143 * @brief casting operator to boolean value
144 * @returns true if value of this is non-zero, else false
145 */
146 inline explicit operator bool() const { return f || s; }
147
148 /**
149 * @brief casting operator to any integer value
150 * @tparam T any integer type
151 * @returns integer value casted to mentioned type
152 */
153 template <typename T, typename = typename std::enable_if<
155 inline explicit operator T() const {
156 return static_cast<T>(s);
157 }
158
159 /**
160 * @brief casting operator to uint128_t
161 * @returns returns lower 128-bit integer part
162 */
163 inline explicit operator uint128_t() const { return s; }
164
165 /**
166 * @brief returns lower 128-bit integer part
167 * @returns returns lower 128-bit integer part
168 */
169 inline uint128_t lower() const { return s; }
170
171 /**
172 * @brief returns upper 128-bit integer part
173 * @returns returns upper 128-bit integer part
174 */
175 inline uint128_t upper() const { return f; }
176
177 /**
178 * @brief operator = for uint256_t
179 * @param p an 256-bit integer to assign it's value
180 * @returns this pointer with it's value equal to `p`
181 */
182 inline uint256_t &operator=(const uint256_t &p) = default;
183
184 /**
185 * @brief operator = for other types
186 * @tparam T denoting any integer type
187 * @param p an integer to assign it's value
188 * @returns this pointer with it's value equal to `p`
189 */
190 template <typename T, typename = typename std::enable_if<
192 inline uint256_t &operator=(const T &p) {
193 this->s = p;
194 return *this;
195 }
196
197 /**
198 * @brief operator = for type string
199 * @param p a string to assign it's value to equivalent integer
200 * @returns this pointer with it's value equal to `p`
201 */
202 inline uint256_t &operator=(const std::string &p) {
204 return *this;
205 }
206
207 /**
208 * @brief Move assignment operator
209 */
210 inline uint256_t &operator=(uint256_t &&p) = default;
211
212 /**
213 * @brief operator + for uint256_t and other integer types.
214 * @tparam T denoting integral type
215 * @param p a type of integer variable
216 * @returns addition of this and p, returning uint256_t integer
217 */
218 template <typename T, typename = typename std::enable_if<
220 inline uint256_t operator+(const T &p) {
221 bool app = s + p < s;
222 return uint256_t(f + app, s + p);
223 }
224
225 /**
226 * @brief operator + for uint256_t and other integer types.
227 * @param p 256-bit unsigned integer
228 * @returns addition of this and p, returning uint256_t integer
229 */
230 inline uint256_t operator+(const uint256_t &p) {
231 bool app = (s + p.s < s);
232 return {f + app + p.f, s + p.s};
233 }
234
235 /**
236 * @brief operator += for uint256_t and other integer types.
237 * @tparam T denoting integral type
238 * @param p a type of integer variable
239 * @returns addition of this and p, returning this
240 */
241 template <typename T, typename = typename std::enable_if<
243 inline uint256_t &operator+=(const T &p) {
244 bool app = (p + s < s);
245 this->f += app;
246 this->s += p;
247 return *this;
248 }
249
250 /**
251 * @brief operator += for uint256_t
252 * @param p 256-bit unsigned integer
253 * @returns addition of this and p, returning this
254 */
255 inline uint256_t &operator+=(const uint256_t &p) {
256 bool app = (s + p.s < s);
257 f = f + app + p.f;
258 s = s + p.s;
259 return *this;
260 }
261
262 /**
263 * @brief pre-increment operator
264 * @returns incremented value of this.
265 */
267 *this += 1;
268 return *this;
269 }
270
271 /**
272 * @brief post-increment operator
273 * @returns incremented value of this.
274 */
275 inline uint256_t operator++(int) {
276 ++*this;
277 return *this;
278 }
279
280 /**
281 * @brief operator - for uint256_t and other integer types.
282 * @tparam T denoting integral type
283 * @param p a type of integer variable
284 * @returns subtraction of this and p, returning uint256_t integer
285 */
286 template <typename T, typename = typename std::enable_if<
288 inline uint256_t operator-(const T &p) {
289 bool app = (p > s);
290 return uint256_t(f - app, s - p);
291 }
292
293 /**
294 * @brief operator - for uint256_t
295 * @param p a type of integer variable
296 * @returns subtraction of this and p, returning uint256_t integer
297 */
298 inline uint256_t operator-(const uint256_t &p) {
299 bool app = s < p.s;
300 return {f - p.f - app, s - p.s};
301 }
302
303 /**
304 * @brief operator - using twos complement
305 * @returns 2's complement of this.
306 */
307 inline uint256_t operator-() { return ~*this + uint256_t(1); }
308
309 /**
310 * @brief operator -- (pre-decrement)
311 * @returns decremented value of this
312 */
314 *this -= 1;
315 return *this;
316 }
317
318 /**
319 * @brief operator -- (post-decrement)
320 * @returns decremented value of this
321 */
322 inline uint256_t operator--(int p) {
323 --*this;
324 return *this;
325 }
326
327 /**
328 * @brief operator -= for uint256_t and other integer types.
329 * @tparam T denoting integral type
330 * @param p a type of integer variable
331 * @returns subtraction of this and p, returning this
332 */
333 template <typename T, typename = typename std::enable_if<
335 inline uint256_t operator-=(const T p) {
336 bool app = (p > s);
337 f = f - app;
338 s = s - p;
339 return *this;
340 }
341
342 /**
343 * @brief operator -= for uint256_t
344 * @param p 256-bit unsigned integer
345 * @returns subtraction of this and p, returning this
346 */
347 inline uint256_t &operator-=(const uint256_t &p) {
348 bool app = s < p.s;
349 f = f - app - p.f;
350 s = s - p.s;
351 return *this;
352 }
353
354 /**
355 * @brief operator * for uint256_t and other integer types.
356 * @tparam T denoting integral type
357 * @param p a type of integer variable
358 * @returns multiplication of this and p, returning uint256_t integer
359 */
360 template <typename T, typename = typename std::enable_if<
362 inline uint256_t operator*(const T &p) {
363 return *this * uint256_t(p);
364 }
365
366 /**
367 * @brief operator * for uint256_t and other integer types.
368 * @param p 256-bit unsigned integer
369 * @returns multiplication of this and p, returning uint256_t integer
370 */
372 uint128_t f_first(s.upper()), f_second(s.lower()), s_first(p.s.upper()),
373 s_second(p.s.lower());
374 uint128_t fi = f_first * s_first, se = f_first * s_second,
375 th = s_first * f_second, fo = s_second * f_second;
376 uint128_t tmp = se << 64, tmp2 = th << 64;
377 int cc = (tmp + tmp2 < tmp);
378 tmp += tmp2;
379 cc += (tmp + fo < tmp);
380 return {f * p.s + s * p.f + fi + se.upper() + th.upper() + cc,
381 tmp + fo};
382 }
383
384 /**
385 * @brief operator *= for uint256_t and other integer types.
386 * @tparam T denoting integral type
387 * @param p a type of integer variable
388 * @returns multiplication of this and p, returning this
389 */
390 template <typename T, typename = typename std::enable_if<
392 inline uint256_t &operator*=(const T &p) {
393 return (*this *= uint256_t(p));
394 }
395
396 /**
397 * @brief operator *= for uint256_t and other integer types.
398 * @param p 256-bit unsigned integer
399 * @returns multiplication of this and p, returning this
400 */
402 uint128_t f_first(s.upper()), f_second(s.lower()), s_first(p.s.upper()),
403 s_second(p.s.lower());
404 uint128_t fi = f_first * s_first, se = f_first * s_second,
405 th = s_first * f_second, fo = s_second * f_second;
406 uint128_t tmp = se << 64, tmp2 = th << 64;
407 int cc = (tmp + tmp2 < tmp);
408 tmp += tmp2;
409 cc += (tmp + fo < tmp);
410 f = f * p.s + s * p.f + fi + se.upper() + th.upper() + cc;
411 s = tmp + fo;
412 return *this;
413 }
414
415 /**
416 * @brief divide function for uint256_t and other integer types.
417 * @details divide this value and
418 * @param p 256-bit unsigned integer
419 * @returns pair denoting quotient and remainder.
420 */
422 if (*this < p) { // if this is less than divisor
423 return {uint256_t(0), *this};
424 } else if (*this == p) { // if this is equal to divisor
425 return {uint256_t(1), uint256_t(0)};
426 }
427 uint256_t tmp = p, tmp2 = *this;
428 uint16_t left = tmp._lez() - _lez();
429 tmp <<= left;
430 uint256_t quotient(0);
431 uint256_t zero(0);
432 while (tmp2 >= p) {
433 uint16_t shf = tmp2._lez() - tmp._lez();
434 if (shf) {
435 tmp >>= shf;
436 quotient <<= shf;
437 left -= shf;
438 }
439 if (tmp2 < tmp) {
440 tmp >>= 1;
441 quotient <<= 1;
442 --left;
443 }
444 tmp2 -= tmp;
445 ++quotient;
446 }
447 return {quotient << left, tmp2};
448 }
449
450 /**
451 * @brief operator / for uint256_t and other integer types.
452 * @tparam T denoting integral type
453 * @param p a type of integer variable
454 * @returns unsigned 256-bit quotient.
455 */
456 template <typename T, typename = typename std::enable_if<
458 inline uint256_t operator/(const T &p) {
459 uint256_t tmp = *this;
460 tmp /= uint256_t(p);
461 return tmp;
462 }
463
464 /**
465 * @brief operator / for uint256_t and other integer types.
466 * @param p 256-bit unsigned integer
467 * @returns unsigned 256-bit quotient.
468 */
469 inline uint256_t operator/(const uint256_t &p) { return divide(p).first; }
470
471 /**
472 * @brief operator /= for uint256_t
473 * @param p 256-bit unsigned integer
474 * @returns this set as unsigned 256-bit quotient.
475 */
476 inline uint256_t &operator/=(const uint256_t &p) {
477 *this = divide(p).first;
478 return *this;
479 }
480
481 /**
482 * @brief operator /= for uint256_t and other integer types.
483 * @tparam T denoting integral type
484 * @param p a type of integer variable
485 * @returns this set as unsigned 256-bit quotient.
486 */
487 template <typename T, typename = typename std::enable_if<
489 inline uint256_t &operator/=(const T &p) {
490 *this /= uint256_t(p);
491 return *this;
492 }
493
494 /**
495 * @brief operator % for uint256_t
496 * @param p 256-bit unsigned integer
497 * @returns unsigned 256-bit remainder.
498 */
499 inline uint256_t operator%(const uint256_t &p) { return divide(p).second; }
500
501 /**
502 * @brief operator % for uint256_t and other integer types.
503 * @tparam T denoting integral type
504 * @param p a type of integer variable
505 * @returns unsigned 256-bit remainder.
506 */
507 template <typename T, typename = typename std::enable_if<
509 inline uint256_t operator%(const T &p) {
510 uint256_t tmp = *this;
511 tmp %= uint256_t(p);
512 return tmp;
513 }
514
515 /**
516 * @brief operator %= for uint256_t
517 * @param p 256-bit unsigned integer
518 * @returns this set as unsigned 256-bit remainder.
519 */
520 inline uint256_t &operator%=(const uint256_t &p) {
521 *this = divide(p).second;
522 return *this;
523 }
524
525 /**
526 * @brief operator %= for uint256_t
527 * @tparam T denoting integral type
528 * @param p a type of integer variable
529 * @returns this set as unsigned 256-bit remainder.
530 */
531 template <typename T, typename = typename std::enable_if<
533 inline uint256_t &operator%=(const T &p) {
534 *this %= uint256_t(p);
535 return *this;
536 }
537
538 /**
539 * @brief operator < for uint256_t
540 * @param other number to be compared with this
541 * @returns true if this is less than other, else false
542 */
543 inline bool operator<(const uint256_t &other) {
544 return f < other.f || (f == other.f && s < other.s);
545 }
546
547 /**
548 * @brief operator <= for uint256_t
549 * @param other number to be compared with this
550 * @returns true if this is less than or equal to other, else false
551 */
552 inline bool operator<=(const uint256_t &other) {
553 return f < other.f || (f == other.f && s <= other.s);
554 }
555
556 /**
557 * @brief operator > for uint256_t
558 * @param other number to be compared with this
559 * @returns true if this is greater than other, else false
560 */
561 inline bool operator>(const uint256_t &other) {
562 return f > other.f || (f == other.f && s > other.s);
563 }
564
565 /**
566 * @brief operator >= for uint256_t
567 * @param other number to be compared with this
568 * @returns true if this is greater than or equal than other, else false
569 */
570 inline bool operator>=(const uint256_t &other) {
571 return (f > other.f) || (f == other.f && s >= other.s);
572 }
573
574 /**
575 * @brief operator == for uint256_t
576 * @param other number to be compared with this
577 * @returns true if this is equal than other, else false
578 */
579 inline bool operator==(const uint256_t &other) {
580 return f == other.f && s == other.s;
581 }
582
583 /**
584 * @brief operator != for uint256_t
585 * @param other number to be compared with this
586 * @returns true if this is not equal than other, else false
587 */
588 inline bool operator!=(const uint256_t &other) {
589 return !((*this) == other);
590 }
591
592 /**
593 * @brief operator ! for uint256_t
594 * @returns true if this has zero value, else false
595 */
596 inline bool operator!() { return !f && !s; }
597
598 /**
599 * @brief operator && for uint256_t
600 * @param b number to be compared with this
601 * @returns true if both of the values are not zero, else false
602 */
603 inline bool operator&&(const uint256_t &b) {
604 return (s || f) && (b.s || b.f);
605 }
606
607 /**
608 * @brief operator || for uint256_t
609 * @param b number to be compared with this
610 * @returns true if one of the values are not zero, else false
611 */
612 inline bool operator||(const uint256_t &b) {
613 return (s || f) || (b.s || b.f);
614 }
615
616 /**
617 * @brief operator () for uint256_t
618 * @returns true if this value is non-zero, else false
619 */
620 inline bool operator()() { return s || f; }
621
622 /**
623 * @brief operator < for other types
624 * @tparam T integral type
625 * @param other number to be compared with this
626 * @returns true if this is less than other, else false
627 */
628 template <typename T, typename = typename std::enable_if<
630 bool operator<(const T &other) {
631 return *this < uint256_t(other);
632 }
633
634 /**
635 * @brief operator <= for other types
636 * @tparam T integral type
637 * @param other number to be compared with this
638 * @returns true if this is less than or equal to other, else false
639 */
640 template <typename T, typename = typename std::enable_if<
642 bool operator<=(const T &other) {
643 return *this <= uint256_t(other);
644 }
645
646 /**
647 * @brief operator > for other types
648 * @tparam T integral type
649 * @param other number to be compared with this
650 * @returns true if this is greater than other, else false
651 */
652 template <typename T, typename = typename std::enable_if<
654 bool operator>(const T &other) {
655 return *this > uint256_t(other);
656 }
657
658 /**
659 * @brief operator >= for other types
660 * @tparam T integral type
661 * @param other number to be compared with this
662 * @returns true if this is greater than or equal other, else false
663 */
664 template <typename T, typename = typename std::enable_if<
666 bool operator>=(const T &other) {
667 return *this >= uint256_t(other);
668 }
669
670 /**
671 * @brief operator == for other types
672 * @tparam T integral type
673 * @param other number to be compared with this
674 * @returns true if this is equal to other, else false
675 */
676 template <typename T, typename = typename std::enable_if<
678 bool operator==(const T &other) {
679 return *this == uint256_t(other);
680 }
681
682 /**
683 * @brief operator != for other types
684 * @tparam T integral type
685 * @param other number to be compared with this
686 * @returns true if this is not equal to other, else false
687 */
688 template <typename T, typename = typename std::enable_if<
690 bool operator!=(const T &other) {
691 return *this != uint256_t(other);
692 }
693
694 /**
695 * @brief operator && for other types
696 * @tparam T integral type
697 * @param other number to be compared with this
698 * @returns true if this is both values are non-zero, else false
699 */
700 template <typename T, typename = typename std::enable_if<
702 inline bool operator&&(const T &b) {
703 return (s || f) && (b);
704 }
705
706 /**
707 * @brief operator || for other types
708 * @tparam T integral type
709 * @param other number to be compared with this
710 * @returns true if this is either one of the values are non-zero, else
711 * false
712 */
713 template <typename T, typename = typename std::enable_if<
715 inline bool operator||(const T &b) {
716 return (s || f) || (b);
717 }
718
719 /**
720 * @brief operator ~ for uint256_t
721 * @returns 1's complement of this number
722 */
723 inline uint256_t operator~() { return {~f, ~s}; }
724
725 /**
726 * @brief operator << for uint256_t
727 * @tparam T integral type
728 * @param p number denoting number of shifts
729 * @returns value of this shifted by p to left
730 */
731 template <typename T, typename = typename std::enable_if<
733 uint256_t operator<<(const T &p) {
734 if (!p) {
735 return {this->f, this->s};
736 } else if (p >= 128) {
737 return uint256_t((this->s << (p - 128)), uint128_t(0));
738 }
739 return uint256_t((this->f << p) + (this->s >> (128 - p)),
740 (this->s << p));
741 }
742
743 /**
744 * @brief operator <<= for uint256_t
745 * @tparam T integral type
746 * @param p number denoting number of shifts
747 * @returns this shifted by p to left
748 */
749 template <typename T, typename = typename std::enable_if<
751 uint256_t &operator<<=(const T &p) {
752 if (p) {
753 if (p >= 128) {
754 this->f = (this->s << (p - 128));
755 this->s = uint128_t(0);
756 } else {
757 f = ((this->s >> (128 - p)) + (this->f << p));
758 s = (this->s << p);
759 }
760 }
761 return *this;
762 }
763
764 /**
765 * @brief operator >> for uint256_t
766 * @tparam T integral type
767 * @param p number denoting number of shifts
768 * @returns value of this shifted by p to right
769 */
770 template <typename T, typename = typename std::enable_if<
772 uint256_t operator>>(const T &p) {
773 if (!p) {
774 return {this->f, this->s};
775 } else if (p >= 128) {
776 return uint256_t(uint128_t(0), (this->f >> (p - 128)));
777 }
778 return uint256_t((this->f >> p),
779 (this->s >> p) + (this->f << (128 - p)));
780 }
781
782 /**
783 * @brief operator >>= for uint256_t
784 * @tparam T integral type
785 * @param p number denoting number of shifts
786 * @returns this shifted by p to right
787 */
788 template <typename T, typename = typename std::enable_if<
790 uint256_t &operator>>=(const T &p) {
791 if (p) {
792 if (p >= 128) {
793 f = uint128_t(0);
794 s = (this->f >> (p - 128));
795 } else {
796 s = (this->s >> p) + (this->f << (128 - p));
797 f = (this->f >> p);
798 }
799 }
800 return *this;
801 }
802
803 /**
804 * @brief operator & for other types (bitwise operator)
805 * @tparam T integral type
806 * @param p number to be operated
807 * @returns value of this & p (& is bit-wise operator)
808 */
809 template <typename T, typename = typename std::enable_if<
811 inline uint256_t operator&(const T &p) {
812 return *this & uint256_t(p);
813 }
814
815 /**
816 * @brief operator & for uint256_t (bitwise operator)
817 * @param p number to be operated
818 * @returns value of this & p (& is bit-wise operator)
819 */
820 inline uint256_t operator&(const uint256_t &p) {
821 return {f & p.f, s & p.s};
822 }
823
824 /**
825 * @brief operator &= for uint256_t (bitwise operator)
826 * @param p number to be operated
827 * @returns this = this & p (& is bit-wise operator)
828 */
829 inline uint256_t &operator&=(const uint256_t &p) {
830 f &= p.f;
831 s &= p.s;
832 return *this;
833 }
834
835 /**
836 * @brief operator &= for other types (bitwise operator)
837 * @tparam T integral type
838 * @param p number to be operated
839 * @returns this = this & p (& is bit-wise operator)
840 */
841 template <typename T, typename = typename std::enable_if<
843 inline uint256_t &operator&=(const T p) {
844 s &= p.s;
845 return *this;
846 }
847
848 /**
849 * @brief operator | for other types (bitwise operator)
850 * @tparam T integral type
851 * @param p number to be operated
852 * @returns value of this | p (| is bit-wise operator)
853 */
854 template <typename T, typename = typename std::enable_if<
856 inline uint256_t operator|(const T &p) {
857 return *this | uint256_t(p);
858 }
859
860 /**
861 * @brief operator | for uint256_t (bitwise operator)
862 * @param p number to be operated
863 * @returns value of this | p (| is bit-wise OR operator)
864 */
865 inline uint256_t operator|(const uint256_t &p) {
866 return {this->f | p.f, this->s | p.s};
867 }
868
869 /**
870 * @brief operator |= for other types (bitwise operator)
871 * @tparam T integral type
872 * @param p number to be operated
873 * @returns this = this | p (| is bit-wise OR operator)
874 */
875 template <typename T, typename = typename std::enable_if<
877 inline uint256_t &operator|=(const T &p) {
878 s |= p;
879 return *this;
880 }
881
882 /**
883 * @brief operator |= for uint256_t (bitwise operator)
884 * @param p number to be operated
885 * @returns this = this | p (| is bit-wise OR operator)
886 */
887 inline uint256_t &operator|=(const uint256_t &p) {
888 f |= p.f;
889 s |= p.s;
890 return *this;
891 }
892
893 /**
894 * @brief operator ^ for other types (bitwise operator)
895 * @tparam T integral type
896 * @param p number to be operated
897 * @returns value of this ^ p (^ is bit-wise XOR operator)
898 */
899 template <typename T, typename = typename std::enable_if<
901 inline uint256_t operator^(const T &p) {
902 return uint256_t(f, s ^ p);
903 }
904
905 /**
906 * @brief operator ^ for uint256_t (bitwise operator)
907 * @param p number to be operated
908 * @returns value of this ^ p (^ is bit-wise XOR operator)
909 */
910 inline uint256_t operator^(const uint256_t &p) {
911 return {this->f ^ p.f, this->s ^ p.s};
912 }
913
914 /**
915 * @brief operator ^= for uint256_t (bitwise operator)
916 * @param p number to be operated
917 * @returns this = this ^ p (^ is bit-wise XOR operator)
918 */
919 inline uint256_t &operator^=(const uint256_t &p) {
920 f ^= p.f;
921 s ^= p.s;
922 return *this;
923 }
924
925 /**
926 * @brief operator ^= for other types (bitwise operator)
927 * @tparam T integral type
928 * @param p number to be operated
929 * @returns this = this ^ p (^ is bit-wise XOR operator)
930 */
931 template <typename T, typename = typename std::enable_if<
933 inline uint256_t &operator^=(const T &p) {
934 s ^= p;
935 return *this;
936 }
937
938 /**
939 * @brief operator << for printing uint256_t integer
940 * @details Prints the uint256_t integer in decimal form
941 * @note Note that this operator is costly since it uses strings to print
942 * the value
943 * @param op ostream object
944 * @param p 256-bit integer
945 * @returns op, ostream object.
946 */
948 if (!p.f) {
949 op << p.s;
950 } else {
951 std::string out = "0", p_2 = "1";
952 uint128_t L(1);
953 for (uint64_t i = 0; i < 128; ++i) {
954 if ((p.s & L)) {
955 out = add(out, p_2);
956 }
957 p_2 = add(p_2, p_2);
958 L <<= 1;
959 }
960 L = uint128_t(1);
961 for (int i = 0; i < 128; ++i) {
962 if ((p.f & L)) {
963 out = add(out, p_2);
964 }
965 p_2 = add(p_2, p_2);
966 L <<= 1;
967 }
968 op << out;
969 }
970 return op;
971 }
972};
973
974// Artihmetic
975template <typename T, typename = typename std::enable_if<
977inline uint256_t operator+(const T p, const uint256_t &q) {
978 return uint256_t(p) + q;
979}
980
981template <typename T, typename = typename std::enable_if<
983inline uint256_t operator-(const T p, const uint256_t &q) {
984 return (uint256_t(p) - q);
985}
986
987template <typename T, typename = typename std::enable_if<
989inline uint256_t operator*(const T p, const uint256_t &q) {
990 return uint256_t(p) * q;
991}
992
993template <typename T, typename = typename std::enable_if<
995inline uint256_t operator/(const T p, const uint256_t &q) {
996 return uint256_t(p) / q;
997}
998
999template <typename T, typename = typename std::enable_if<
1001inline uint256_t operator%(const T p, const uint256_t &q) {
1002 return uint256_t(p) % q;
1003}
1004
1005// Bitwise operators
1006template <typename T, typename = typename std::enable_if<
1008inline uint256_t operator&(const T &p, const uint256_t &q) {
1009 return uint256_t(p) & q;
1010}
1011
1012template <typename T, typename = typename std::enable_if<
1014inline uint256_t operator|(const T p, const uint256_t &q) {
1015 return uint256_t(p) | q;
1016}
1017
1018template <typename T, typename = typename std::enable_if<
1020inline uint256_t operator^(const T p, const uint256_t &q) {
1021 return uint256_t(p) ^ q;
1022}
1023
1024// Boolean operators
1025template <typename T, typename = typename std::enable_if<
1027inline bool operator&&(const T p, const uint256_t &q) {
1028 return uint256_t(p) && q;
1029}
1030
1031template <typename T, typename = typename std::enable_if<
1033inline bool operator||(const T p, const uint256_t &q) {
1034 return uint256_t(p) || q;
1035}
1036
1037// Comparison operators
1038template <typename T, typename = typename std::enable_if<
1040inline bool operator==(const T p, const uint256_t &q) {
1041 return uint256_t(p) == q;
1042}
1043
1044template <typename T, typename = typename std::enable_if<
1046inline bool operator!=(const T p, const uint256_t &q) {
1047 return uint256_t(p) != q;
1048}
1049
1050template <typename T, typename = typename std::enable_if<
1052inline bool operator<(const T p, const uint256_t &q) {
1053 return uint256_t(p) < q;
1054}
1055
1056template <typename T, typename = typename std::enable_if<
1058inline bool operator<=(const T p, const uint256_t &q) {
1059 return uint256_t(p) <= q;
1060}
1061
1062template <typename T, typename = typename std::enable_if<
1064inline bool operator>(const T p, const uint256_t &q) {
1065 return uint256_t(p) > q;
1066}
1067
1068template <typename T, typename = typename std::enable_if<
1070inline bool operator>=(const T p, const uint256_t &q) {
1071 return uint256_t(p) >= q;
1072}
1073
1074#endif // CIPHERS_UINT256_T_HPP_
class for 128-bit unsigned integer
Definition uint128_t.hpp:59
uint64_t upper() const
returns upper 64-bit integer part
Definition uint128_t.hpp:207
uint32_t _trz()
Trailing zeroes in binary.
Definition uint128_t.hpp:162
uint64_t lower() const
returns lower 64-bit integer part
Definition uint128_t.hpp:201
uint32_t _lez()
Leading zeroes in binary.
Definition uint128_t.hpp:139
class for 256-bit unsigned integer
Definition uint256_t.hpp:33
uint256_t(uint128_t high, uint128_t low)
Parameterized constructor.
Definition uint256_t.hpp:103
bool operator!()
operator ! for uint256_t
Definition uint256_t.hpp:596
uint32_t _lez()
Leading zeroes in binary.
Definition uint256_t.hpp:123
uint256_t(uint256_t &&num) noexcept
Move constructor.
Definition uint256_t.hpp:95
uint256_t & operator<<=(const T &p)
operator <<= for uint256_t
Definition uint256_t.hpp:751
bool operator<=(const uint256_t &other)
operator <= for uint256_t
Definition uint256_t.hpp:552
uint256_t(const std::string &str)
Parameterized constructor.
Definition uint256_t.hpp:81
bool operator<=(const T &other)
operator <= for other types
Definition uint256_t.hpp:642
uint256_t operator+(const T &p)
operator + for uint256_t and other integer types.
Definition uint256_t.hpp:220
uint256_t operator--(int p)
operator – (post-decrement)
Definition uint256_t.hpp:322
uint256_t(const uint64_t high, const uint64_t low)
Parameterized constructor.
Definition uint256_t.hpp:111
uint256_t & operator%=(const uint256_t &p)
operator %= for uint256_t
Definition uint256_t.hpp:520
uint256_t operator|(const uint256_t &p)
operator | for uint256_t (bitwise operator)
Definition uint256_t.hpp:865
bool operator&&(const T &b)
operator && for other types
Definition uint256_t.hpp:702
uint256_t & operator&=(const uint256_t &p)
operator &= for uint256_t (bitwise operator)
Definition uint256_t.hpp:829
uint256_t & operator^=(const T &p)
operator ^= for other types (bitwise operator)
Definition uint256_t.hpp:933
~uint256_t()=default
Destructor for uint256_t.
uint256_t operator-()
operator - using twos complement
Definition uint256_t.hpp:307
bool operator||(const uint256_t &b)
operator || for uint256_t
Definition uint256_t.hpp:612
uint256_t(const uint256_t &num)=default
Copy constructor.
uint256_t & operator*=(const uint256_t &p)
operator *= for uint256_t and other integer types.
Definition uint256_t.hpp:401
uint256_t operator>>(const T &p)
operator >> for uint256_t
Definition uint256_t.hpp:772
uint256_t operator<<(const T &p)
operator << for uint256_t
Definition uint256_t.hpp:733
bool operator||(const T &b)
operator || for other types
Definition uint256_t.hpp:715
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.
Definition uint256_t.hpp:469
uint256_t & operator+=(const T &p)
operator += for uint256_t and other integer types.
Definition uint256_t.hpp:243
uint256_t & operator-=(const uint256_t &p)
operator -= for uint256_t
Definition uint256_t.hpp:347
uint256_t & operator=(uint256_t &&p)=default
Move assignment operator.
uint256_t operator&(const T &p)
operator & for other types (bitwise operator)
Definition uint256_t.hpp:811
uint256_t operator~()
operator ~ for uint256_t
Definition uint256_t.hpp:723
uint256_t operator^(const uint256_t &p)
operator ^ for uint256_t (bitwise operator)
Definition uint256_t.hpp:910
uint256_t & operator%=(const T &p)
operator %= for uint256_t
Definition uint256_t.hpp:533
bool operator()()
operator () for uint256_t
Definition uint256_t.hpp:620
uint256_t operator++(int)
post-increment operator
Definition uint256_t.hpp:275
uint256_t operator%(const T &p)
operator % for uint256_t and other integer types.
Definition uint256_t.hpp:509
std::pair< uint256_t, uint256_t > divide(const uint256_t &p)
divide function for uint256_t and other integer types.
Definition uint256_t.hpp:421
uint256_t & operator=(const std::string &p)
operator = for type string
Definition uint256_t.hpp:202
uint256_t operator-(const T &p)
operator - for uint256_t and other integer types.
Definition uint256_t.hpp:288
bool operator!=(const T &other)
operator != for other types
Definition uint256_t.hpp:690
bool operator==(const uint256_t &other)
operator == for uint256_t
Definition uint256_t.hpp:579
friend std::ostream & operator<<(std::ostream &op, uint256_t p)
operator << for printing uint256_t integer
Definition uint256_t.hpp:947
bool operator==(const T &other)
operator == for other types
Definition uint256_t.hpp:678
uint256_t operator&(const uint256_t &p)
operator & for uint256_t (bitwise operator)
Definition uint256_t.hpp:820
uint32_t _trz()
Trailing zeroes in binary.
Definition uint256_t.hpp:135
uint256_t & operator--()
operator – (pre-decrement)
Definition uint256_t.hpp:313
bool operator&&(const uint256_t &b)
operator && for uint256_t
Definition uint256_t.hpp:603
uint256_t & operator|=(const uint256_t &p)
operator |= for uint256_t (bitwise operator)
Definition uint256_t.hpp:887
uint128_t lower() const
returns lower 128-bit integer part
Definition uint256_t.hpp:169
uint256_t operator*(const uint256_t &p)
operator * for uint256_t and other integer types.
Definition uint256_t.hpp:371
uint256_t operator*(const T &p)
operator * for uint256_t and other integer types.
Definition uint256_t.hpp:362
bool operator!=(const uint256_t &other)
operator != for uint256_t
Definition uint256_t.hpp:588
uint256_t operator-(const uint256_t &p)
operator - for uint256_t
Definition uint256_t.hpp:298
uint256_t & operator/=(const T &p)
operator /= for uint256_t and other integer types.
Definition uint256_t.hpp:489
uint256_t & operator/=(const uint256_t &p)
operator /= for uint256_t
Definition uint256_t.hpp:476
bool operator<(const T &other)
operator < for other types
Definition uint256_t.hpp:630
uint256_t & operator+=(const uint256_t &p)
operator += for uint256_t
Definition uint256_t.hpp:255
uint256_t & operator^=(const uint256_t &p)
operator ^= for uint256_t (bitwise operator)
Definition uint256_t.hpp:919
uint256_t operator/(const T &p)
operator / for uint256_t and other integer types.
Definition uint256_t.hpp:458
bool operator>(const uint256_t &other)
operator > for uint256_t
Definition uint256_t.hpp:561
uint256_t operator^(const T &p)
operator ^ for other types (bitwise operator)
Definition uint256_t.hpp:901
uint256_t operator-=(const T p)
operator -= for uint256_t and other integer types.
Definition uint256_t.hpp:335
uint256_t operator|(const T &p)
operator | for other types (bitwise operator)
Definition uint256_t.hpp:856
uint256_t operator%(const uint256_t &p)
operator % for uint256_t
Definition uint256_t.hpp:499
bool operator>(const T &other)
operator > for other types
Definition uint256_t.hpp:654
uint256_t & operator>>=(const T &p)
operator >>= for uint256_t
Definition uint256_t.hpp:790
uint256_t & operator=(const T &p)
operator = for other types
Definition uint256_t.hpp:192
bool operator>=(const uint256_t &other)
operator >= for uint256_t
Definition uint256_t.hpp:570
uint128_t upper() const
returns upper 128-bit integer part
Definition uint256_t.hpp:175
uint256_t(T low)
Parameterized constructor.
Definition uint256_t.hpp:75
uint256_t & operator|=(const T &p)
operator |= for other types (bitwise operator)
Definition uint256_t.hpp:877
uint256_t & operator++()
pre-increment operator
Definition uint256_t.hpp:266
uint256_t operator+(const uint256_t &p)
operator + for uint256_t and other integer types.
Definition uint256_t.hpp:230
uint256_t & operator*=(const T &p)
operator *= for uint256_t and other integer types.
Definition uint256_t.hpp:392
uint256_t & operator&=(const T p)
operator &= for other types (bitwise operator)
Definition uint256_t.hpp:843
bool operator<(const uint256_t &other)
operator < for uint256_t
Definition uint256_t.hpp:543
void __get_integer_from_string(const std::string &str)
First and second half of 256 bit number.
Definition uint256_t.hpp:43
bool operator>=(const T &other)
operator >= for other types
Definition uint256_t.hpp:666
T move(T... args)
STL namespace.
T operator!=(T... args)
T size(T... args)
std::string add(const std::string &first, const std::string &second)
Adding two string.
Definition uint128_t.hpp:37