1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
|
/* ****************************************************************************
*
* Copyright 2013 Nedim Srndic
*
* This file is part of rsa - the RSA implementation in C++.
*
* rsa is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* rsa is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rsa. If not, see <http://www.gnu.org/licenses/>.
*
* BigInt.h
*
* Author: Nedim Srndic
* Release date: 14th of March 2008
*
* A class representing a positive or negative integer that may
* be too large to fit in any of the standard C++ integer types
* (i. e. 2^128 is "just" 39 digits long).
* The digits are stored in a dinamic array of tipe unsigned char*,
* with values from 0 to 9 (not '0' to '9'), so that the CPU can
* add/subtract individual digits.
*
* The array has "length" memory locations, one byte each (the size of
* unsigned char is probably one byte). There are "digitCount" digits actually
* in use, the rest is spare space.
* The number of digits is constrained by available memory and the limit of the
* unsigned long int type used for indexing (the "length" property).
* The individual digits are stored right-to-left, to speed up computing and
* allow for faster growth of numbers (no need to reallocate memory when
* the digitCount grows).
*
* The class handles its own memory management. There are no memory leaks
* reported until this date.
* When creating a BigInt from const char* or unsigned long int,
* copying from an other BigInt with (digitCount + 2 <= length)
* (soon to be full), new memory is allocated and
* length is adjusted to (length * FACTOR + 1). This is done to expand the
* capacity of the digits array to accomodate potential new digits.
* When assigning a BigInt "bInt" that is twice as small or bigger than *this,
* the length is set to (bInt.length + 2).
*
* BigInt supports:
*
* - addition (unary +, binary +, +=, prefix ++, postfix ++)
*
* - subtraction (unary -, binary -, -=, prefix --, postfix --)
*
* - multiplication (*, *=)
* For multiplication, one can choose between the Square and multiply
* or Karatsuba algorithm, or long multiplication at compile time
* (this can be done by defining or undefining the macro "KARATSUBA"
* in BigInt.cpp).
* The Karatsuba algorithm multiplies integers in O(n^log2(3))
* complexity. log2(3) is approximately 1.585, so this should be
* significantly faster than long multiplication, if the numbers are
* big enough. Currently, the long multiplication is better implemented,
* and runs faster than the Karatsuba multiplication for numbers shorter
* than about 100 digits.
*
* - C-style integer division (/, /=)
*
* - C-style integer division remainder (%, %=)
* When calculating the remainder, the number is first divided.
*
* - comparison (==, !=, <, <=, >, >=)
* All of the <, <=, >, >= operators are equally fast.
*
* - exponentiation (GetPower(), SetPower(), GetPowerMod(), SetPowerMod())
* For exponentiation, the Exponantiation by squaring
* (or Square and multiply or Binary exponentiation) algorithm is used.
* It uses O(log(n)) multiplications and therefore is significantly faster
* than multiplying x with itself n-1 times.
*
* In addition to mathematical operations, BigInt supports:
*
* - automatic conversion from const char *, std::string and unsigned long int
* - safe construction, copying, assignment and destruction
* - automatic conversion to std::string
* - writing to the standard output (operator <<(std::ostream, BigInt))
* - reading from the standard input (operator >>(std::istream, BigInt))
* - getting and setting individual digits (GetDigit(), SetDigit())
* - returning the number of digits (Length())
* - returning a string of digits (ToString())
* This can be useful for human-readable output.
* - returning a value indicating wether the number is odd (IsOdd())
* - returning a value indicating wether the number is positive (IsPositive())
* - returning a value indicating wether the BigInt equals zero (EqualsZero())
* The fastest way to determine this.
* - returning absolute value (Abs())
*
* There are a few static constants defined in this file:
*
* - BigIntZero : a zero of type BigInt
* If you need a zero fast, use this.
* - BigIntOne : a one of type BigInt
* If you need a one fast, use this.
*
* ****************************************************************************
*/
#ifndef BIGINT_H_
#define BIGINT_H_
#include "coreSQLiteStudio_global.h"
#include <iostream> //ostream, istream
#include <cmath> //sqrt()
#include <string> //ToString(), BigInt(std::string)
class API_EXPORT BigInt
{
private:
/* An array of digits stored right to left,
* i.e. int 345 = unsigned char {[5], [4], [3]} */
unsigned char *digits;
// The total length of the allocated memory
unsigned long int length;
// Number of digits
unsigned long int digitCount;
// Sign
bool positive;
/* Multiplication factor for the length property
* when creating or copying objects. */
static const double FACTOR;
/* Transforms the number from unsigned long int to unsigned char[]
* and pads the result with zeroes. Returns the number of digits. */
static unsigned long int int2uchar( unsigned long int number,
unsigned char *digits,
unsigned long int padding);
/* Converts ASCII digits to equivalent unsigned char numeric values. */
static void char2uchar( unsigned char *array,
unsigned long int length);
/* Check if all ASCII values are digits '0' to '9'. */
static bool allCharsAreDigits( const char *array,
unsigned long int length);
/* Compares two BigInt. If the last two arguments are
* omitted, the comparison is sign-insensitive (comparison by
* absolute value). Returns 0 if a == b, 1 if a > b, 2 if a < b. */
static int compareNumbers( unsigned char *a, unsigned long int na,
unsigned char *b, unsigned long int nb,
bool aPositive = true,
bool bPositive = true);
/* Multiplies two unsigned char[] using the Divide and Conquer
* a.k.a. Karatsuba algorithm .*/
static void karatsubaMultiply( unsigned char *a, unsigned char *b,
unsigned long int n,
unsigned char *buffer);
/* Multiplies two unsigned char[] the long way. */
static void longMultiply( unsigned char *a, unsigned long int na,
unsigned char *b, unsigned long int nb,
unsigned char *result);
/* Simple addition, used by the multiply function.
* Returns the remaining carry. */
static unsigned char quickAdd( unsigned char *a, unsigned char *b,
unsigned long int n);
/* Simple subtraction, used by the multiply function. */
static void quickSub( unsigned char *a, unsigned char *b,
unsigned char *end, unsigned long int n);
/* Divides two BigInt numbers. */
static void divide( const BigInt ÷nd, const BigInt &divisor,
BigInt "ient, BigInt &remainder);
/* Returns the value of the specified unsigned char[] as long int. */
static unsigned long int toInt(unsigned char *digits, int n);
/* Saves the sum of two unsigned char* shorter and longer into result.
* It must be nShorter <= nLonger. If doFill == true, it fills the
* remaining free places with zeroes (used in KaratsubaMultiply()).
* Returns true if there was an overflow at the end (meaning that
* the result.digitCount was longer.digitCount + 1. */
static bool add(unsigned char *shorter, unsigned long int nShorter,
unsigned char *longer, unsigned long int nLonger,
unsigned char *result, int nResult,
bool doFill = true);
/* Shifts the digits n places left. */
BigInt &shiftLeft(unsigned long int n);
/* Shifts the digits n places right. */
BigInt &shiftRight(unsigned long int n);
/* Expands the digits* to n. */
void expandTo(unsigned long int n);
public:
BigInt();
BigInt(const char *charNum);
BigInt(unsigned long int intNum);
BigInt(const std::string &str);
BigInt(const BigInt &number);
BigInt &operator =(const BigInt &rightNumber);
~BigInt();
operator std::string() const;
friend std::ostream &operator <<( std::ostream &cout,
const BigInt &number);
friend std::istream &operator >>( std::istream &cin,
BigInt &number);
friend bool operator <(const BigInt &a, const BigInt &b);
friend bool operator <=(const BigInt &a, const BigInt &b);
friend bool operator >(const BigInt &a, const BigInt &b);
friend bool operator >=(const BigInt &a, const BigInt &b);
friend bool operator ==(const BigInt &a, const BigInt &b);
friend bool operator !=(const BigInt &a, const BigInt &b);
friend BigInt operator + (const BigInt &a, const BigInt &b);
BigInt &operator+();
BigInt &operator++();
BigInt operator++(int);
BigInt &operator+=(const BigInt &number);
BigInt operator-() const;
friend BigInt operator-(const BigInt &a, const BigInt &b);
BigInt &operator--();
BigInt operator--(int);
BigInt &operator-=(const BigInt &number);
friend BigInt operator*(const BigInt &a, const BigInt &b);
BigInt &operator*=(const BigInt &number);
friend BigInt operator/(const BigInt &a, const BigInt &b);
BigInt &operator/=(const BigInt &number);
friend BigInt operator%(const BigInt &a, const BigInt &b);
BigInt &operator%=(const BigInt &number);
/* Returns *this to the power of n
* using the fast Square and Multiply algorithm. */
BigInt GetPower(unsigned long int n) const;
/* *this = *this to the power of n. */
void SetPower(unsigned long int n);
/* Returns *this to the power of n
* using the fast Square and Multiply algorithm. */
BigInt GetPower(BigInt n) const;
/* *this = *this to the power of n. */
void SetPower(BigInt n);
/* Returns (*this to the power of b) mod n. */
BigInt GetPowerMod(const BigInt &b, const BigInt &n) const;
/* *this = (*this to the power of b) mod n. */
void SetPowerMod(const BigInt &b, const BigInt &n);
/* Returns the 'index'th digit (zero-based, right-to-left). */
unsigned char GetDigit(unsigned long int index) const;
/* Sets the value of 'index'th digit
* (zero-based, right-to-left) to 'value'. */
void SetDigit(unsigned long int index, unsigned char value);
/* Returns the number of digits. */
unsigned long int Length() const;
/* Returns true if *this is positive, otherwise false. */
bool IsPositive() const;
/* Returns true if *this is odd, otherwise false. */
bool IsOdd() const;
/* Returns the value of BigInt as std::string. */
std::string ToString(bool forceSign = false) const;
/* Returns a value indicating whether *this equals 0. */
bool EqualsZero() const;
/* Returns the absolute value. */
BigInt Abs() const;
};
inline BigInt::~BigInt()
{
delete[] digits;
}
inline BigInt &BigInt::operator+()
{
return *this;
}
/* Returns the number of digits. */
inline unsigned long int BigInt::Length() const
{
return digitCount;
}
/* Returns true if *this is positive, otherwise false. */
inline bool BigInt::IsPositive() const
{
return positive;
}
/* Returns true if *this is odd, otherwise false. */
inline bool BigInt::IsOdd() const
{
return digits[0] & 1;
}
/* Returns a value indicating whether *this equals 0. */
inline bool BigInt::EqualsZero() const
{
return digitCount == 1 && digits[0] == 0;
}
// A BigInt number with the value of 0.
static const BigInt BigIntZero;
// A BigInt number with the value of 1.
static const BigInt BigIntOne(1L);
#endif /*BIGINT_H_*/
|