Newer
Older
Import / applications / MakePDF / Security / BigInteger / BigInteger.h
/*
  Big Integer Class
  Written by John Ryland (C) Copyright 2015
*/
#ifndef BIG_INTEGER_H
#define BIG_INTEGER_H

#include <stdint.h>
#include <vector>
#include <string>
#include <memory>

/*
  BigInteger is a class that behaves similar to a regular built in type
  however it can represent arbitarily large values, eg 1024 bit numbers
  which is commonly the case in cryptographic code or other special uses
  of maths. As its name suggests, it only holds integers, and positive
  ones at that. Treat it like you would an unsigned int that can't
  overflow, and in the case where it could go negative, it truncates to
  zero (this happens when subtracting a larger number from a smaller one).
*/
class BigInteger
{
public:
  BigInteger();                            // Default constructor (the value will be zero)
  BigInteger(const BigInteger& other);     // Copy constructor
  BigInteger(uint64_t a_number);           // Create from a number
  BigInteger(const char* str);             // Create from a string
  ~BigInteger();                           // Destructor
  void operator=(const BigInteger& other); // Assignment operator

  // Operator overloads
  bool operator!() const; // Is zero
  bool operator<(const BigInteger& other) const;
  bool operator>(const BigInteger& other) const;
  bool operator<=(const BigInteger& other) const;
  bool operator>=(const BigInteger& other) const;
  bool operator==(const BigInteger& other) const;
  bool operator!=(const BigInteger& other) const;
  bool operator&&(const BigInteger& other) const;
  bool operator||(const BigInteger& other) const;
  BigInteger operator>>(int shift) const;
  BigInteger operator<<(int shift) const;
  BigInteger operator--(int);
  BigInteger operator++(int);
  BigInteger operator-(const BigInteger& other) const;
  BigInteger operator+(const BigInteger& other) const;
  BigInteger operator*(const BigInteger& other) const;
  BigInteger operator/(const BigInteger& other) const;
  BigInteger operator%(const BigInteger& other) const;
  BigInteger operator&(const BigInteger& other) const;
  BigInteger operator|(const BigInteger& other) const;
  BigInteger operator^(const BigInteger& other) const;
  BigInteger operator~() const;
  BigInteger& operator>>=(int shift);
  BigInteger& operator<<=(int shift);
  BigInteger& operator--();
  BigInteger& operator++();
  BigInteger& operator-=(const BigInteger& other);
  BigInteger& operator+=(const BigInteger& other);
  BigInteger& operator*=(const BigInteger& other);
  BigInteger& operator/=(const BigInteger& other);
  BigInteger& operator%=(const BigInteger& other);
  BigInteger& operator&=(const BigInteger& other);
  BigInteger& operator|=(const BigInteger& other);
  BigInteger& operator^=(const BigInteger& other);

  explicit operator std::string() const;
  explicit operator uint64_t() const;
  uint8_t operator[](size_t index) const;

#define BIG_INTEGER_ALLOW_DIRECT_ACCESS
#if defined(BIG_INTEGER_ALLOW_DIRECT_ACCESS)
  uint8_t& operator[](size_t index);
#endif

  size_t Size() const;
  void Print() const;

  // Returns the quotent, and modulus in modulusResult of numerator / denominator
  static BigInteger DivMod(const BigInteger& numerator, const BigInteger& denominator, BigInteger& modulusResult);

  // Returns the result of:  base ^ exponent % modulus
  static BigInteger ExpMod(const BigInteger& base, const BigInteger& exponent, const BigInteger& modulus);

private:
  // Implementation hidden behind pimpl
  // helps with compile times
  // helps maintain binary compatibility
  // makes it possible to easily swap out implementations
  struct Pimpl;
  std::unique_ptr<Pimpl> m_pimpl;
};

#endif // BIG_INTEGER_H