Algorithms_in_C++  1.0.0
Set of algorithms implemented in C++.
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 
18 class uint256_t;
19 
20 template <>
22 
23 template <>
25 
26 template <>
28 
29 /**
30  * @class uint256_t
31  * @brief class for 256-bit unsigned integer
32  */
33 class 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<
154  std::is_integral<T>::value, T>::type>
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<
191  std::is_integral<T>::value, T>::type>
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<
219  std::is_integral<T>::value, T>::type>
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<
242  std::is_integral<T>::value, T>::type>
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  */
266  inline uint256_t &operator++() {
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<
287  std::is_integral<T>::value, T>::type>
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  */
313  inline uint256_t &operator--() {
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<
334  std::is_integral<T>::value, T>::type>
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<
361  std::is_integral<T>::value, T>::type>
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<
391  std::is_integral<T>::value, T>::type>
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 (left >= 0 && 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<
457  std::is_integral<T>::value, T>::type>
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<
488  std::is_integral<T>::value, T>::type>
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<
508  std::is_integral<T>::value, T>::type>
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<
532  std::is_integral<T>::value, T>::type>
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<
629  std::is_integral<T>::value, T>::type>
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<
641  std::is_integral<T>::value, T>::type>
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<
653  std::is_integral<T>::value, T>::type>
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<
665  std::is_integral<T>::value, T>::type>
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<
677  std::is_integral<T>::value, T>::type>
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<
689  std::is_integral<T>::value, T>::type>
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<
701  std::is_integral<T>::value, T>::type>
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<
714  std::is_integral<T>::value, T>::type>
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<
732  std::is_integral<T>::value, T>::type>
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<
750  std::is_integral<T>::value, T>::type>
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<
771  std::is_integral<T>::value, T>::type>
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<
789  std::is_integral<T>::value, T>::type>
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<
810  std::is_integral<T>::value, T>::type>
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<
842  std::is_integral<T>::value, T>::type>
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<
855  std::is_integral<T>::value, T>::type>
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<
876  std::is_integral<T>::value, T>::type>
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<
900  std::is_integral<T>::value, T>::type>
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<
932  std::is_integral<T>::value, T>::type>
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
975 template <typename T, typename = typename std::enable_if<
976  std::is_integral<T>::value, T>::type>
977 inline uint256_t operator+(const T p, const uint256_t &q) {
978  return uint256_t(p) + q;
979 }
980 
981 template <typename T, typename = typename std::enable_if<
982  std::is_integral<T>::value, T>::type>
983 inline uint256_t operator-(const T p, const uint256_t &q) {
984  return (uint256_t(p) - q);
985 }
986 
987 template <typename T, typename = typename std::enable_if<
988  std::is_integral<T>::value, T>::type>
989 inline uint256_t operator*(const T p, const uint256_t &q) {
990  return uint256_t(p) * q;
991 }
992 
993 template <typename T, typename = typename std::enable_if<
994  std::is_integral<T>::value, T>::type>
995 inline uint256_t operator/(const T p, const uint256_t &q) {
996  return uint256_t(p) / q;
997 }
998 
999 template <typename T, typename = typename std::enable_if<
1000  std::is_integral<T>::value, T>::type>
1001 inline uint256_t operator%(const T p, const uint256_t &q) {
1002  return uint256_t(p) % q;
1003 }
1004 
1005 // Bitwise operators
1006 template <typename T, typename = typename std::enable_if<
1007  std::is_integral<T>::value, T>::type>
1008 inline uint256_t operator&(const T &p, const uint256_t &q) {
1009  return uint256_t(p) & q;
1010 }
1011 
1012 template <typename T, typename = typename std::enable_if<
1013  std::is_integral<T>::value, T>::type>
1014 inline uint256_t operator|(const T p, const uint256_t &q) {
1015  return uint256_t(p) | q;
1016 }
1017 
1018 template <typename T, typename = typename std::enable_if<
1019  std::is_integral<T>::value, T>::type>
1020 inline uint256_t operator^(const T p, const uint256_t &q) {
1021  return uint256_t(p) ^ q;
1022 }
1023 
1024 // Boolean operators
1025 template <typename T, typename = typename std::enable_if<
1026  std::is_integral<T>::value, T>::type>
1027 inline bool operator&&(const T p, const uint256_t &q) {
1028  return uint256_t(p) && q;
1029 }
1030 
1031 template <typename T, typename = typename std::enable_if<
1032  std::is_integral<T>::value, T>::type>
1033 inline bool operator||(const T p, const uint256_t &q) {
1034  return uint256_t(p) || q;
1035 }
1036 
1037 // Comparison operators
1038 template <typename T, typename = typename std::enable_if<
1039  std::is_integral<T>::value, T>::type>
1040 inline bool operator==(const T p, const uint256_t &q) {
1041  return uint256_t(p) == q;
1042 }
1043 
1044 template <typename T, typename = typename std::enable_if<
1045  std::is_integral<T>::value, T>::type>
1046 inline bool operator!=(const T p, const uint256_t &q) {
1047  return uint256_t(p) != q;
1048 }
1049 
1050 template <typename T, typename = typename std::enable_if<
1051  std::is_integral<T>::value, T>::type>
1052 inline bool operator<(const T p, const uint256_t &q) {
1053  return uint256_t(p) < q;
1054 }
1055 
1056 template <typename T, typename = typename std::enable_if<
1057  std::is_integral<T>::value, T>::type>
1058 inline bool operator<=(const T p, const uint256_t &q) {
1059  return uint256_t(p) <= q;
1060 }
1061 
1062 template <typename T, typename = typename std::enable_if<
1063  std::is_integral<T>::value, T>::type>
1064 inline bool operator>(const T p, const uint256_t &q) {
1065  return uint256_t(p) > q;
1066 }
1067 
1068 template <typename T, typename = typename std::enable_if<
1069  std::is_integral<T>::value, T>::type>
1070 inline 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 & operator/=(const uint256_t &p)
operator /= for uint256_t
Definition: uint256_t.hpp:476
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 & operator=(const std::string &p)
operator = for type string
Definition: uint256_t.hpp:202
uint256_t(uint256_t &&num) noexcept
Move constructor.
Definition: uint256_t.hpp:95
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>>=(const T &p)
operator >>= for uint256_t
Definition: uint256_t.hpp:790
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 (bitwise operator)
Definition: uint256_t.hpp:865
bool operator&&(const T &b)
operator && for other types
Definition: uint256_t.hpp:702
~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 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 T &p)
operator *= for uint256_t and other integer types.
Definition: uint256_t.hpp:392
uint256_t operator/(const uint256_t &p)
operator / for uint256_t and other integer types.
Definition: uint256_t.hpp:469
uint256_t & operator%=(const uint256_t &p)
operator %= for uint256_t
Definition: uint256_t.hpp:520
friend std::ostream & operator<<(std::ostream &op, uint256_t p)
operator << for printing uint256_t integer
Definition: uint256_t.hpp:947
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:887
uint256_t & operator|=(const T &p)
operator |= for other types (bitwise operator)
Definition: uint256_t.hpp:877
uint256_t operator^(const uint256_t &p)
operator ^ for uint256_t (bitwise operator)
Definition: uint256_t.hpp:910
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
uint256_t & operator^=(const T &p)
operator ^= for other types (bitwise operator)
Definition: uint256_t.hpp:933
uint256_t & operator++()
pre-increment operator
Definition: uint256_t.hpp:266
uint256_t & operator--()
operator – (pre-decrement)
Definition: uint256_t.hpp:313
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
uint256_t & operator%=(const T &p)
operator %= for uint256_t
Definition: uint256_t.hpp:533
uint256_t & operator&=(const T p)
operator &= for other types (bitwise operator)
Definition: uint256_t.hpp:843
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
uint256_t & operator/=(const T &p)
operator /= for uint256_t and other integer types.
Definition: uint256_t.hpp:489
uint32_t _trz()
Trailing zeroes in binary.
Definition: uint256_t.hpp:135
bool operator&&(const uint256_t &b)
operator && for uint256_t
Definition: uint256_t.hpp:603
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 (bitwise operator)
Definition: uint256_t.hpp:829
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 uint256_t &p)
operator *= for uint256_t and other integer types.
Definition: uint256_t.hpp:401
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 other types
Definition: uint256_t.hpp:192
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 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 uint256_t &p)
operator -= for uint256_t
Definition: uint256_t.hpp:347
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 uint256_t
Definition: uint256_t.hpp:751
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
uint256_t & operator=(const uint256_t &p)=default
operator = for uint256_t
bool operator>(const T &other)
operator > for other types
Definition: uint256_t.hpp:654
uint256_t & operator=(uint256_t &&p)=default
Move assignment operator.
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 uint256_t &p)
operator + for uint256_t and other integer types.
Definition: uint256_t.hpp:230
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 T &p)
operator += for uint256_t and other integer types.
Definition: uint256_t.hpp:243
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
bool operator==(const Complex &a, const Complex &b)
Operator overload of '==' on Complex class. Logical Equal overload for our Complex class.
Definition: complex_numbers.cpp:175
T move(T... args)
STL namespace.
T operator!=(T... args)
std::vector< float > operator/(std::vector< T > const &A, float const scalar)
Definition: ordinary_least_squares_regressor.cpp:174
std::vector< T > operator-(std::vector< T > const &A, std::vector< T > const &B)
Definition: ordinary_least_squares_regressor.cpp:183
std::vector< T > operator+(std::vector< T > const &A, std::vector< T > const &B)
Definition: ordinary_least_squares_regressor.cpp:204
T size(T... args)
std::string add(const std::string &first, const std::string &second)
Adding two string.
Definition: uint128_t.hpp:37