scclib
Stable Cloud Computing C++ Library
bignum.h
Go to the documentation of this file.
1 /*
2 BSD 3-Clause License
3 
4 Copyright (c) 2022, Stable Cloud Computing, Inc.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9 1. Redistributions of source code must retain the above copyright notice, this
10  list of conditions and the following disclaimer.
11 
12 2. Redistributions in binary form must reproduce the above copyright notice,
13  this list of conditions and the following disclaimer in the documentation
14  and/or other materials provided with the distribution.
15 
16 3. Neither the name of the copyright holder nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #ifndef _SCC_CRYPTO_BIGNUM_H
32 #define _SCC_CRYPTO_BIGNUM_H
33 
34 #include <string>
35 #include <ostream>
36 #include <memory>
37 
38 class BignumCtx; // forward declaration
39 
40 namespace scc::crypto {
41 
58 class Bignum
59 {
60  std::unique_ptr<BignumCtx> m_bnctx;
61 
62 public:
64  Bignum();
65 
67  Bignum(Bignum&& other) : Bignum()
68  {
69  move(other);
70  }
73  {
74  move(other);
75  return *this;
76  }
77 
79  Bignum(const Bignum& other) : Bignum()
80  {
81  copy(other);
82  }
84  Bignum& operator =(const Bignum& other)
85  {
86  copy(other);
87  return *this;
88  }
89 
91  Bignum(uint32_t w) : Bignum()
92  {
93  set(w);
94  }
96  Bignum& operator =(uint32_t w)
97  {
98  set(w);
99  return *this;
100  }
101 
103  Bignum(const void * loc, int len) : Bignum()
104  {
105  set(loc, len);
106  }
107 
108  virtual ~Bignum();
109 
111  void* bn();
113  const void* const_bn() const;
114 
117  void set_width(int);
118 
123  void set(uint32_t);
124 
127  void set(const void *, int);
128 
131  void set_2sc(const void *, int);
132 
137  int len() const;
138 
146  void get(void *, int) const;
147 
150  int len_2sc() const;
151 
168  void get_2sc(void *, int) const;
169 
172  void copy(const Bignum&);
173 
177  void move(Bignum&);
178 
181  void clear();
182 
185  int width() const;
186 
189  void exp(const Bignum&);
191  void exp(uint32_t b)
192  {
193  Bignum bn(b);
194  exp(bn);
195  }
196 
199  void gcd(const Bignum&);
200 
210  void gen_rand(int, bool = false, bool = false);
211 
218  bool is_prime(int = -1);
219 
224  void gen_prime(int);
225 
227  void lshift(int);
229  void rshift(int);
231  void add(const Bignum&);
233  void add(uint32_t b)
234  {
235  Bignum bn(b);
236  add(bn);
237  }
239  void sub(const Bignum&);
241  void sub(uint32_t b)
242  {
243  Bignum bn(b);
244  sub(bn);
245  }
247  void mul(const Bignum&);
249  void mul(uint32_t b)
250  {
251  Bignum bn(b);
252  mul(bn);
253  }
255  void div(const Bignum&, Bignum*);
257  void div(uint32_t b, Bignum* rem)
258  {
259  Bignum bn(b);
260  div(bn, rem);
261  }
263  void mod(const Bignum&);
265  void mod(uint32_t b)
266  {
267  Bignum bn(b);
268  mod(bn);
269  }
271  void negate();
272 
274  void bit_not()
275  {
276  for (int i = 0; i < width(); i++)
277  {
278  if (is_bit_set(i))
279  {
280  clear_bit(i);
281  }
282  else
283  {
284  set_bit(i);
285  }
286  }
287  }
289  void bit_and(const Bignum& b)
290  {
291  for (int i = 0; i < std::max(width(), b.width()); i++)
292  {
293  if (is_bit_set(i) && b.is_bit_set(i))
294  {
295  set_bit(i);
296  }
297  else
298  {
299  clear_bit(i);
300  }
301  }
302  }
304  void bit_or(const Bignum& b)
305  {
306  for (int i = 0; i < std::max(width(), b.width()); i++)
307  {
308  if (is_bit_set(i) || b.is_bit_set(i))
309  {
310  set_bit(i);
311  }
312  else
313  {
314  clear_bit(i);
315  }
316  }
317  }
319  void bit_xor(const Bignum& b)
320  {
321  for (int i = 0; i < std::max(width(), b.width()); i++)
322  {
323  if ((is_bit_set(i) && !b.is_bit_set(i)) || (!is_bit_set(i) && b.is_bit_set(i)))
324  {
325  set_bit(i);
326  }
327  else
328  {
329  clear_bit(i);
330  }
331  }
332  }
333 
340  bool is_bit_set(int) const;
341 
348  void set_bit(int);
349 
356  void clear_bit(int);
357 
359  void gcd(uint32_t b)
360  {
361  Bignum bn(b);
362  gcd(bn);
363  }
364 
366  static bool is_prime(uint32_t w)
367  {
368  Bignum bn(w);
369  return bn.is_prime();
370  }
371 
373  bool is_negative() const;
374 
376  int cmp(uint32_t w) const;
377 
379  int cmp(const Bignum&) const;
380 
382  bool operator ==(const Bignum& o) const { return cmp(o) == 0; }
384  bool operator !=(const Bignum& o) const { return cmp(o) != 0; }
386  bool operator <(const Bignum& o) const { return cmp(o) < 0; }
388  bool operator >(const Bignum& o) const { return cmp(o) > 0; }
390  bool operator <=(const Bignum& o) const { return cmp(o) <= 0; }
392  bool operator >=(const Bignum& o) const { return cmp(o) >= 0; }
394  bool operator ==(uint32_t o) const { return cmp(o) == 0; }
396  bool operator !=(uint32_t o) const { return cmp(o) != 0; }
398  bool operator <(uint32_t o) const { return cmp(o) < 0; }
400  bool operator >(uint32_t o) const { return cmp(o) > 0; }
402  bool operator <=(uint32_t o) const { return cmp(o) <= 0; }
404  bool operator >=(uint32_t o) const { return cmp(o) >= 0; }
405 
407  Bignum operator <<(int shift) const
408  {
409  Bignum b(*this);
410  b.lshift(shift);
411  return b;
412  }
414  Bignum& operator <<=(int shift)
415  {
416  lshift(shift);
417  return *this;
418  }
420  Bignum operator >>(int shift) const
421  {
422  Bignum b(*this);
423  b.rshift(shift);
424  return b;
425  }
427  Bignum& operator >>=(int shift)
428  {
429  rshift(shift);
430  return *this;
431  }
433  Bignum operator +(const Bignum& a) const
434  {
435  Bignum r(*this);
436  r.add(a);
437  return r;
438  }
441  {
442  add(a);
443  return *this;
444  }
446  Bignum operator +(uint32_t a) const
447  {
448  Bignum r(*this);
449  r.add(a);
450  return r;
451  }
453  Bignum operator +=(uint32_t a)
454  {
455  add(a);
456  return *this;
457  }
460  {
461  add(1); // prefix
462  return *this;
463  }
466  {
467  Bignum r(*this);
468  add(1); // postfix
469  return r;
470  }
473  {
474  negate();
475  return *this;
476  }
478  Bignum operator -(const Bignum& a) const
479  {
480  Bignum r(*this);
481  r.sub(a);
482  return r;
483  }
486  {
487  sub(a);
488  return *this;
489  }
491  Bignum operator -(uint32_t a) const
492  {
493  Bignum r(*this);
494  r.sub(a);
495  return r;
496  }
498  Bignum operator -=(uint32_t a)
499  {
500  sub(a);
501  return *this;
502  }
505  {
506  sub(1); // prefix
507  return *this;
508  }
511  {
512  Bignum r(*this);
513  sub(1); // postfix
514  return r;
515  }
517  Bignum operator *(const Bignum& a) const
518  {
519  Bignum r(*this);
520  r.mul(a);
521  return r;
522  }
525  {
526  mul(a);
527  return *this;
528  }
530  Bignum operator *(uint32_t a) const
531  {
532  Bignum r(*this);
533  r.mul(a);
534  return r;
535  }
537  Bignum operator *=(uint32_t a)
538  {
539  mul(a);
540  return *this;
541  }
543  Bignum operator /(const Bignum& a) const
544  {
545  Bignum r(*this);
546  r.div(a, nullptr);
547  return r;
548  }
551  {
552  div(a, nullptr);
553  return *this;
554  }
556  Bignum operator /(uint32_t a) const
557  {
558  Bignum r(*this);
559  r.div(a, nullptr);
560  return r;
561  }
563  Bignum operator /=(uint32_t a)
564  {
565  div(a, nullptr);
566  return *this;
567  }
569  Bignum operator %(const Bignum& a) const
570  {
571  Bignum r(*this);
572  r.mod(a);
573  return r;
574  }
577  {
578  mod(a);
579  return *this;
580  }
582  Bignum operator %(uint32_t a) const
583  {
584  Bignum r(*this);
585  r.mod(a);
586  return r;
587  }
589  Bignum operator %=(uint32_t a)
590  {
591  mod(a);
592  return *this;
593  }
595  Bignum operator &(const Bignum& a) const
596  {
597  Bignum r(*this);
598  r.bit_and(a);
599  return r;
600  }
603  {
604  bit_and(a);
605  return *this;
606  }
608  Bignum operator &(uint32_t a) const
609  {
610  Bignum r(*this);
611  Bignum b(a);
612  r.bit_and(b);
613  return r;
614  }
616  Bignum operator &=(uint32_t a)
617  {
618  Bignum b(a);
619  bit_and(b);
620  return *this;
621  }
623  Bignum operator |(const Bignum& a) const
624  {
625  Bignum r(*this);
626  r.bit_or(a);
627  return r;
628  }
631  {
632  bit_or(a);
633  return *this;
634  }
636  Bignum operator |(uint32_t a) const
637  {
638  Bignum r(*this);
639  Bignum b(a);
640  r.bit_or(b);
641  return r;
642  }
644  Bignum operator |=(uint32_t a)
645  {
646  Bignum b(a);
647  bit_or(b);
648  return *this;
649  }
651  Bignum operator ^(const Bignum& a) const
652  {
653  Bignum r(*this);
654  r.bit_xor(a);
655  return r;
656  }
659  {
660  bit_xor(a);
661  return *this;
662  }
664  Bignum operator ^(uint32_t a) const
665  {
666  Bignum r(*this);
667  Bignum b(a);
668  r.bit_xor(b);
669  return r;
670  }
672  Bignum operator ^=(uint32_t a)
673  {
674  Bignum b(a);
675  bit_xor(b);
676  return *this;
677  }
680  {
681  Bignum r(*this);
682  r.bit_not();
683  return r;
684  }
685 
690  std::string str(bool=false) const;
691 };
692 
697 void PrintTo(const Bignum&, std::ostream*);
698 
699 }
700 
702 std::ostream& operator <<(std::ostream&, const scc::crypto::Bignum&);
711 
712 #endif
scc::crypto::Bignum exp(const scc::crypto::Bignum &, const scc::crypto::Bignum &)
Exponent helper.
scc::crypto::Bignum gcd(const scc::crypto::Bignum &, const scc::crypto::Bignum &)
Greatest common divisor helper.
std::ostream & operator<<(std::ostream &, const scc::crypto::Bignum &)
Print the bignum to a stream.
Big number.
Definition: bignum.h:59
Bignum operator^(const Bignum &a) const
Xor operator.
Definition: bignum.h:651
bool is_bit_set(int) const
Is the bit set?
void sub(const Bignum &)
Subtract a-b.
void exp(uint32_t b)
Exponent a^b.
Definition: bignum.h:191
void get(void *, int) const
Octal (byte) output of a positive number.
void div(uint32_t b, Bignum *rem)
Divide a/b.
Definition: bignum.h:257
Bignum operator^=(const Bignum &a)
Xor assign operator.
Definition: bignum.h:658
Bignum operator-=(const Bignum &a)
Subtract assign operator.
Definition: bignum.h:485
const void * const_bn() const
Bignum context for use by external services.
void mul(uint32_t b)
Word multiply.
Definition: bignum.h:249
void set_2sc(const void *, int)
Set integer from twos complement input stream.
void mod(const Bignum &)
Modulus ab.
std::string str(bool=false) const
Return a string representation in decimal or hex.
void lshift(int)
Left bit shift.
Bignum & operator<<=(int shift)
Right shift assign operator.
Definition: bignum.h:414
void set_width(int)
Set the number to a specified bit width.
bool operator>=(const Bignum &o) const
Greater than equal operator.
Definition: bignum.h:392
int cmp(uint32_t w) const
Arithmetic compare for an integer.
void move(Bignum &)
Move into this bignum.
void exp(const Bignum &)
Exponent a^b.
Bignum operator%(const Bignum &a) const
Modulus operator.
Definition: bignum.h:569
void bit_xor(const Bignum &b)
Bitwise xor a^b.
Definition: bignum.h:319
void * bn()
Bignum context for use by external services.
Bignum operator*(const Bignum &a) const
Multiply operator.
Definition: bignum.h:517
void clear_bit(int)
Clear a bit.
Bignum & operator++()
Prefix addition operator.
Definition: bignum.h:459
void set(uint32_t)
Set to a word.
void gcd(const Bignum &)
Greatest common divisor for a and b.
void negate()
Negate (change sign).
Bignum(uint32_t w)
Word constructor.
Definition: bignum.h:91
Bignum & operator=(Bignum &&other)
Move assignment.
Definition: bignum.h:72
int len() const
Required length of get() output in bytes.
void set_bit(int)
Set a bit.
void copy(const Bignum &)
Copy into this bignum.
Bignum operator<<(int shift) const
Right shift operator.
Definition: bignum.h:407
Bignum()
Construct and set to 0.
void get_2sc(void *, int) const
Octal (byte) output, in two's complement form.
void mul(const Bignum &)
Mulitply a*b.
Bignum & operator--()
Prefix decrement.
Definition: bignum.h:504
static bool is_prime(uint32_t w)
Is prime for an integer.
Definition: bignum.h:366
int width() const
Number of significant bits.
void mod(uint32_t b)
Word modulus.
Definition: bignum.h:265
int len_2sc() const
Get the length of octal output in twos complement form.
void clear()
Clear and set to 0.
Bignum & operator>>=(int shift)
Right shift assign operator.
Definition: bignum.h:427
void add(const Bignum &)
Add a+b.
Bignum operator*=(const Bignum &a)
Multiply assign operator.
Definition: bignum.h:524
Bignum operator/(const Bignum &a) const
Divide operator.
Definition: bignum.h:543
Bignum operator&=(const Bignum &a)
And assign operator.
Definition: bignum.h:602
void gcd(uint32_t b)
Greatest common divisor of a and b.
Definition: bignum.h:359
Bignum operator/=(const Bignum &a)
Divide assign operator.
Definition: bignum.h:550
void div(const Bignum &, Bignum *)
Divide a/b.
bool operator<=(const Bignum &o) const
Less than equal operator.
Definition: bignum.h:390
Bignum operator|=(const Bignum &a)
Or assign operator.
Definition: bignum.h:630
Bignum operator>>(int shift) const
Right shift operator.
Definition: bignum.h:420
Bignum operator~() const
Not operator.
Definition: bignum.h:679
void gen_prime(int)
Generate a random pseudo-prime number of the specified bit width.
Bignum operator|(const Bignum &a) const
Or operator.
Definition: bignum.h:623
bool is_prime(int=-1)
Perform a Miller-Rabin prime test to test primality.
bool operator==(const Bignum &o) const
Equal operator.
Definition: bignum.h:382
void gen_rand(int, bool=false, bool=false)
Generate a random number of the specified bit width.
void bit_and(const Bignum &b)
Bitwise not a&b.
Definition: bignum.h:289
Bignum(const Bignum &other)
Copy constructor.
Definition: bignum.h:79
Bignum operator+(const Bignum &a) const
Add operator.
Definition: bignum.h:433
bool operator!=(const Bignum &o) const
Not equal operator.
Definition: bignum.h:384
void sub(uint32_t b)
Subtract an integer.
Definition: bignum.h:241
void set(const void *, int)
Set a positive integer from input bytes.
Bignum(Bignum &&other)
Move constructor.
Definition: bignum.h:67
Bignum operator&(const Bignum &a) const
And operator.
Definition: bignum.h:595
void add(uint32_t b)
Word add a+b.
Definition: bignum.h:233
void bit_or(const Bignum &b)
Bitwise or a|b.
Definition: bignum.h:304
int cmp(const Bignum &) const
Arithmetic compare.
bool operator>(const Bignum &o) const
Greater than operator.
Definition: bignum.h:388
bool is_negative() const
Is negative?
Bignum(const void *loc, int len)
Set to data.
Definition: bignum.h:103
bool operator<(const Bignum &o) const
Less than operator.
Definition: bignum.h:386
Bignum operator%=(const Bignum &a)
Modulus assign operator.
Definition: bignum.h:576
void rshift(int)
Right bit shift.
void bit_not()
Bitwise not ~a.
Definition: bignum.h:274
Bignum operator-()
Negation operator -a.
Definition: bignum.h:472
Bignum operator+=(const Bignum &a)
Add assign operator.
Definition: bignum.h:440