• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/BigInteger.cpp

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #include <spl/BigInteger.h>
00018 #include <spl/Exception.h>
00019 #include <spl/Int32.h>
00020 #include <spl/Int64.h>
00021 #include <spl/math/Math.h>
00022 #include <spl/UInt32.h>
00023 
00024 Random BigInteger::m_randomSource;
00025 
00026 BigIntegerPtr BigInteger::m_zero;
00027 BigIntegerPtr BigInteger::m_one;
00028 BigIntegerPtr BigInteger::m_two;
00029 
00030 // Each list has a product < 2^31
00031 const int BigInteger::m_primeLists[BIGINTEGER_PRIMELIST_ROWS][BIGINTEGER_PRIMELIST_COLS] =
00032 {
00033         { 3, 5, 7, 11, 13, 17, 19, 23, -1 },
00034         { 29, 31, 37, 41, 43, -1 },
00035         { 47, 53, 59, 61, 67, -1 },
00036         { 71, 73, 79, 83, -1 },
00037         { 89, 97, 101, 103, -1 },
00038 
00039         { 107, 109, 113, 127, -1 },
00040         { 131, 137, 139, 149, -1 },
00041         { 151, 157, 163, 167, -1 },
00042         { 173, 179, 181, 191, -1 },
00043         { 193, 197, 199, 211, -1 },
00044 
00045         { 223, 227, 229, -1 },
00046         { 233, 239, 241, -1 },
00047         { 251, 257, 263, -1 },
00048         { 269, 271, 277, -1 },
00049         { 281, 283, 293, -1 },
00050 
00051         { 307, 311, 313, -1 },
00052         { 317, 331, 337, -1 },
00053         { 347, 349, 353, -1 },
00054         { 359, 367, 373, -1 },
00055         { 379, 383, 389, -1 },
00056 
00057         { 397, 401, 409, -1 },
00058         { 419, 421, 431, -1 },
00059         { 433, 439, 443, -1 },
00060         { 449, 457, 461, -1 },
00061         { 463, 467, 479, -1 },
00062 
00063         { 487, 491, 499, -1 },
00064         { 503, 509, 521, -1 },
00065         { 523, 541, 547, -1 },
00066         { 557, 563, 569, -1 },
00067         { 571, 577, 587, -1 },
00068 
00069         { 593, 599, 601, -1 },
00070         { 607, 613, 617, -1 },
00071         { 619, 631, 641, -1 },
00072         { 643, 647, 653, -1 },
00073         { 659, 661, 673, -1 },
00074 
00075         { 677, 683, 691, -1 },
00076         { 701, 709, 719, -1 },
00077         { 727, 733, 739, -1 },
00078         { 743, 751, 757, -1 },
00079         { 761, 769, 773, -1 },
00080 
00081         { 787, 797, 809, -1 },
00082         { 811, 821, 823, -1 },
00083         { 827, 829, 839, -1 },
00084         { 853, 857, 859, -1 },
00085         { 863, 877, 881, -1 },
00086 
00087         { 883, 887, 907, -1 },
00088         { 911, 919, 929, -1 },
00089         { 937, 941, 947, -1 },
00090         { 953, 967, 971, -1 },
00091         { 977, 983, 991, -1 },
00092 
00093         { 997, 1009, 1013, -1 },
00094         { 1019, 1021, 1031, -1 }
00095 };
00096 
00097 bool BigInteger::m_primeProductsInited = false;
00098 
00099 int BigInteger::m_primeProducts[BIGINTEGER_PRIMELIST_ROWS];
00100 
00101 const int BigInteger::m_chunk2 = 1;
00102 const int BigInteger::m_chunk10 = 19;
00103 const int BigInteger::m_chunk16 = 16;
00104 
00105 void BigInteger::Init2()
00106 {
00107         for (int i = 0; i < BIGINTEGER_PRIMELIST_ROWS; ++i)
00108         {
00109                 const int * const primeList = m_primeLists[i];
00110                 int product = 1;
00111                 for (int j = 0; j < BIGINTEGER_PRIMELIST_COLS; ++j)
00112                 {
00113                         if (-1 == primeList[j])
00114                         {
00115                                 break;
00116                         }
00117                         product *= primeList[j];
00118                 }
00119                 m_primeProducts[i] = product;
00120         }
00121 }
00122 
00123 void BigInteger::ConstructWith(int signNum, RefCountPtr<Array<int32> > mag, bool checkMag)
00124 {
00125         ConstructCommon();
00126 
00127         m_sign = mag->AreElementsEqualTo(0) ? 0 : signNum;
00128 
00129         if (checkMag)
00130         {
00131                 int i = 0;
00132                 while (i < mag->Length() && (*mag)[i] == 0)
00133                 {
00134                         ++i;
00135                 }
00136 
00137                 if (i == 0)
00138                 {
00139                         m_magnitude = mag;
00140                 }
00141                 else
00142                 {
00143                         // strip leading 0 words
00144                         m_magnitude = RefCountPtr<Array<int32> >(new Array<int32>(mag->Length() - i));
00145                         Array<int32>::Copy(*mag, i, *m_magnitude, 0, m_magnitude->Length());
00146                 }
00147         }
00148         else
00149         {
00150                 m_magnitude = mag;
00151         }
00152 
00153         m_nBitLength = m_sign == 0 ? 0 : CalcBitLength(0, *m_magnitude);
00154 }
00155 
00156 void BigInteger::ConstructWith(Array<byte>& bytes, int offset, int length)
00157 {
00158         ConstructCommon();
00159 
00160         if (length == 0)
00161         {
00162                 throw new InvalidArgumentException("Zero length BigInteger");
00163         }
00164 
00166         //if ((int8)bytes[offset] < 0)
00167         //{
00168         //      m_sign = -1;
00169 
00170         //      int end = offset + length;
00171 
00172         //      int iBval;
00173         //      // strip leading sign bytes
00174         //      for (iBval = offset; iBval < end && ((int8)bytes[iBval] == -1); iBval++)
00175         //      {
00176         //      }
00177 
00178         //      if (iBval >= end)
00179         //      {
00180         //              m_magnitude = RefCountPtr<Array<int32> >(new Array<int32>(1));
00181         //              m_magnitude->ElementAtRef(0) = 1;
00182         //      }
00183         //      else
00184         //      {
00185         //              int numBytes = end - iBval;
00186         //              Array<byte> inverse(numBytes);
00187 
00188         //              int index = 0;
00189         //              while (index < numBytes)
00190         //              {
00191         //                      inverse[index++] = (byte)~bytes[iBval++];
00192         //              }
00193 
00194         //              ASSERT(iBval == end);
00195 
00196         //              while (inverse[--index] == 255)
00197         //              {
00198         //                      inverse[index] = 0;
00199         //              }
00200 
00201         //              inverse[index]++;
00202 
00203         //              m_magnitude = MakeMagnitude(inverse, 0, inverse.Length());
00204         //      }
00205         //}
00206         //else
00207         //{
00208                 // strip leading zero bytes and return magnitude bytes
00209                 m_magnitude = MakeMagnitude(bytes, offset, length);
00210                 m_sign = m_magnitude->Length() > 0 ? 1 : 0;
00211         //}
00212 
00213         m_sign = m_magnitude->AreElementsEqualTo(0) ? 0 : m_sign;
00214 
00215         m_nBitLength = m_sign == 0 ? 0 : CalcBitLength(0, *m_magnitude);
00216 }
00217 
00218 void BigInteger::ConstructWith(int sign, Array<byte>& bytes, int offset, int length)
00219 {
00220         ConstructCommon();
00221 
00222         if (sign < -1 || sign > 1)
00223         {
00224                 throw new InvalidArgumentException("Invalid sign value");
00225         }
00226 
00227         if (sign == 0)
00228         {
00229                 m_sign = 0;
00230                 m_magnitude = RefCountPtr<Array<int32> >(new Array<int32>());
00231         }
00232         else
00233         {
00234                 // copy bytes
00235                 m_magnitude = MakeMagnitude(bytes, offset, length);
00236                 m_sign = m_magnitude->Length() == 0 ? 0 : sign;
00237         }
00238 
00239         m_nBitLength = m_sign == 0 ? 0 : CalcBitLength(0, *m_magnitude);
00240 }
00241 
00242 BigInteger::BigInteger()
00243 {
00244         // ZERO
00245         ConstructWith(0, RefCountPtr<Array<int32> >(new Array<int32>()), false);
00246 }
00247 
00248 BigInteger::BigInteger(int signNum, RefCountPtr<Array<int32> >mag, bool checkMag)
00249 {
00250         ConstructWith(signNum, mag, checkMag);
00251 }
00252 
00253 BigInteger::BigInteger(Array<byte>& bytes)
00254 {
00255         ConstructWith(bytes, 0, bytes.Length());
00256 }
00257 
00258 BigInteger::BigInteger(Array<byte>& bytes, int offset, int length)
00259 {
00260         ConstructWith(bytes, offset, length);
00261 }
00262 
00263 BigInteger::BigInteger(int sign, Array<byte>& bytes, int offset, int length)
00264 {
00265         ConstructWith(sign, bytes, offset, length);
00266 }
00267 
00268 BigInteger::BigInteger(int sign, Array<byte>& bytes)
00269 {
00270         ConstructWith(sign, bytes, 0, bytes.Length());
00271 }
00272 
00273 const byte BigInteger::m_rndMask[] = { 255, 127, 63, 31, 15, 7, 3, 1 };
00274 
00275 
00276 BigInteger::BigInteger(int sizeInBits, Random& random)
00277 {
00278         ConstructCommon();
00279 
00280         if (sizeInBits < 0)
00281         {
00282                 throw new InvalidArgumentException("sizeInBits must be non-negative");
00283         }
00284 
00285         m_nBits = -1;
00286         m_nBitLength = -1;
00287 
00288         if (sizeInBits == 0)
00289         {
00290                 m_magnitude = RefCountPtr<Array<int32> >(new Array<int32>());
00291                 return;
00292         }
00293 
00294         int nBytes = GetByteLength(sizeInBits);
00295         Array<byte> b(nBytes);
00296         random.NextBytes(b, nBytes);
00297 
00298         // strip off any excess bits in the MSB
00299         b[0] &= m_rndMask[BitsPerByte * nBytes - sizeInBits];
00300 
00301         m_magnitude = MakeMagnitude(b, 0, nBytes);
00302         m_sign = m_magnitude->Length() < 1 ? 0 : 1;     
00303 
00304         m_nBitLength = m_sign == 0 ? 0 : CalcBitLength(0, *m_magnitude);
00305 }
00306 
00307 BigInteger::BigInteger(int bitLength, int certainty, Random& random)
00308 {
00309         ConstructCommon();
00310 
00311         if (bitLength < 2)
00312         {
00313                 throw new InvalidArgumentException("bitLength < 2");
00314         }
00315 
00316         m_sign = 1;
00317         m_nBitLength = bitLength;
00318 
00319         if (bitLength == 2)
00320         {
00321                 m_magnitude = RefCountPtr<Array<int32> >(new Array<int32>(1));
00322                 m_magnitude->ElementAtRef(0) = random.Next(2) == 0
00323                         ?       2
00324                         :       3;
00325                 return;
00326         }
00327 
00328         int nBytes = GetByteLength(bitLength);
00329         Array<byte> b(nBytes);
00330 
00331         int xBits = BitsPerByte * nBytes - bitLength;
00332         byte mask = m_rndMask[xBits];
00333 
00334         for (;;)
00335         {
00336                 random.NextBytes(b, nBytes);
00337 
00338                 // strip off any excess bits in the MSB
00339                 b[0] &= mask;
00340 
00341                 // ensure the leading bit is 1 (to meet the strength requirement)
00342                 b[0] |= (byte)(1 << (7 - xBits));
00343 
00344                 // ensure the trailing bit is 1 (i.e. must be odd)
00345                 b[nBytes - 1] |= 1;
00346 
00347                 m_magnitude = MakeMagnitude(b, 0, b.Length());
00348                 m_nBits = -1;
00349                 m_mQuote = -1L;
00350 
00351                 if (certainty < 1)
00352                 {
00353                         break;
00354                 }
00355 
00356                 if (CheckProbablePrime(certainty, random))
00357                 {
00358                         break;
00359                 }
00360 
00361                 if (bitLength > 32)
00362                 {
00363                         for (int rep = 0; rep < 10000; ++rep)
00364                         {
00365                                 int n = 33 + random.Next(bitLength - 2);
00366                                 (*m_magnitude)[m_magnitude->Length() - (n >> 5)] ^= (1 << (n & 31));
00367                                 (*m_magnitude)[m_magnitude->Length() - 1] ^= ((random.Next() + 1) << 1);
00368                                 m_mQuote = -1L;
00369 
00370                                 if (CheckProbablePrime(certainty, random))
00371                                 {
00372                                         return;
00373                                 }
00374                         }
00375                 }
00376         }
00377 
00378         m_nBitLength = m_sign == 0 ? 0 : CalcBitLength(0, *m_magnitude);
00379 }
00380 
00381 RefCountPtr<BigInteger> BigInteger::CreateValueOf(int64 value)
00382 {
00383         if (value < 0)
00384         {
00385                 if (value == Int64::MinValue())
00386                 {
00387                         return CreateValueOf(~value)->Not();
00388                 }
00389 
00390                 return CreateValueOf(-value)->Negate();
00391         }
00392 
00393         return CreateUValueOf((uint64)value);
00394 }
00395 
00396 RefCountPtr<BigInteger> BigInteger::CreateUValueOf(uint64 value)
00397 {
00398         uint32 *valp = reinterpret_cast<uint32 *>(&value);
00399         int32 msw = (int32)valp[1];
00400         int32 lsw = (int32)valp[0];
00401 
00402         if (msw != 0)
00403         {
00404                 Array<int32> *ar = new Array<int32>(2);
00405                 ar->ElementAtRef(0) = msw;
00406                 ar->ElementAtRef(1) = lsw;
00407 
00408                 BigInteger *bp = new BigInteger(1, RefCountPtr<Array<int32> >(ar), false);
00409                 return RefCountPtr<BigInteger>(bp);
00410         }
00411 
00412         if (lsw != 0)
00413         {
00414                 Array<int32> *ar = new Array<int32>(1);
00415                 ar->ElementAtRef(0) = lsw;
00416 
00417                 RefCountPtr<BigInteger> n = RefCountPtr<BigInteger>(new BigInteger(1, RefCountPtr<Array<int32> >(ar), false));
00418                 
00419                 // Check for a power of two
00420                 if ((lsw & -lsw) == lsw)
00421                 {
00422                         n->m_nBits = 1;
00423                 }
00424 
00425                 return n;
00426         }
00427 
00428         // Zero
00429         return RefCountPtr<BigInteger>(new BigInteger());
00430 }
00431 
00432 RefCountPtr<Array<int32> > BigInteger::MakeMagnitude(const Array<byte>& bytes, int offset, int length)
00433 {
00434         int end = offset + length;
00435         if (end > bytes.Length())
00436         {
00437                 end = bytes.Length();
00438         }
00439 
00440         // strip leading zeros
00441         int firstSignificant;
00442         for (firstSignificant = offset; firstSignificant < end && bytes[firstSignificant] == 0; firstSignificant++)
00443         {
00444         }
00445 
00446         if (firstSignificant >= end)
00447         {
00448                 // Zero
00449                 return RefCountPtr<Array<int32> >(new Array<int32>());
00450         }
00451 
00452         int nInts = (end - firstSignificant + 3) / BytesPerInt;
00453         int bCount = (end - firstSignificant) % BytesPerInt;
00454         if (bCount == 0)
00455         {
00456                 bCount = BytesPerInt;
00457         }
00458 
00459         if (nInts < 1)
00460         {
00461                 // Zero
00462                 return RefCountPtr<Array<int32> >(new Array<int32>());
00463         }
00464 
00465         Array<int32> *mag = new Array<int32>(nInts);
00466 
00467         int v = 0;
00468         int magnitudeIndex = 0;
00469         for (int i = firstSignificant; i < end; ++i)
00470         {
00471                 v <<= 8;
00472                 v |= bytes[i] & 0xff;
00473                 bCount--;
00474                 if (bCount <= 0)
00475                 {
00476                         (*mag)[magnitudeIndex] = v;
00477                         magnitudeIndex++;
00478                         bCount = BytesPerInt;
00479                         v = 0;
00480                 }
00481         }
00482 
00483         if (magnitudeIndex < mag->Length())
00484         {
00485                 (*mag)[magnitudeIndex] = v;
00486         }
00487 
00488         return RefCountPtr<Array<int32> >(mag);
00489 }
00490 
00491 bool BigInteger::CheckProbablePrime(int certainty, Random& random) const
00492 {
00493         ASSERT(certainty > 0);
00494         ASSERT(Compare(Two()) > 0);
00495         ASSERT(TestBit(0));
00496 
00497         // Try to reduce the penalty for really small numbers
00498         int numLists = Math::Min(GetBitLength() - 1, BIGINTEGER_PRIMELIST_ROWS);
00499 
00500         for (int i = 0; i < numLists; ++i)
00501         {
00502                 int test = Remainder(m_primeProducts[i]);
00503 
00504                 const int *primeList = m_primeLists[i];
00505                 for (int j = 0; j < BIGINTEGER_PRIMELIST_COLS; ++j)
00506                 {
00507                         int prime = primeList[j];
00508                         if (-1 == prime)
00509                         {
00510                                 break;
00511                         }
00512                         int qRem = test % prime;
00513                         if (qRem == 0)
00514                         {
00515                                 // We may find small numbers in the list
00516                                 return GetBitLength() < 16 && ToInt() == prime;
00517                         }
00518                 }
00519         }
00520 
00521         return RabinMillerTest(certainty, random);
00522 }
00523 
00524 bool BigInteger::RabinMillerTest(int certainty, Random& random) const
00525 {
00526         ASSERT(certainty > 0);
00527         ASSERT(GetBitLength() > 2);
00528         ASSERT(TestBit(0));
00529 
00530         // let n = 1 + d . 2^s
00531         BigInteger n = *this;
00532         RefCountPtr<BigInteger> nMinusOne = n.Subtract(One());
00533         int s = nMinusOne->GetLowestSetBit();
00534         RefCountPtr<BigInteger> r = nMinusOne->ShiftRight(s);
00535 
00536         do
00537         {
00538                 // TODO Make a method for random BigIntegers in range 0 < x < n)
00539                 // - Method can be optimized by only replacing examined bits at each trial
00540                 BigInteger a;
00541                 do
00542                 {
00543                         a = BigInteger(n.GetBitLength(), random);
00544                 }
00545                 while (a.Compare(One()) <= 0 || a.Compare(*nMinusOne) >= 0);
00546 
00547                 RefCountPtr<BigInteger> y = a.ModPow(*r, n);
00548 
00549                 if (!y->Equals(One()))
00550                 {
00551                         int j = 0;
00552                         while (!y->Equals(*nMinusOne))
00553                         {
00554                                 if (j++ == s)
00555                                         return false;
00556 
00557                                 y = y->ModPow(Two(), n);
00558 
00559                                 if (y->Equals(One()))
00560                                         return false;
00561                         }
00562                 }
00563 
00564                 certainty -= 2; // composites pass for only 1/4 possible 'a'
00565         }
00566         while (certainty > 0);
00567 
00568         return true;
00569 }
00570 
00571 int BigInteger::CalcBitLength(int indx, const Array<int32>& mag) const
00572 {
00573         for (;;)
00574         {
00575                 if (indx >= mag.Length())
00576                         return 0;
00577 
00578                 if (mag.ElementAt(indx) != 0)
00579                         break;
00580 
00581                 ++indx;
00582         }
00583 
00584         // bit length for everything after the first int
00585         int bitLength = 32 * ((mag.Length() - indx) - 1);
00586 
00587         // and determine bitlength of first int
00588         int firstMag = mag.ElementAt(indx);
00589         bitLength += BitLen(firstMag);
00590 
00591         // Check for negative powers of two
00592         if (m_sign < 0 && ((firstMag & -firstMag) == firstMag))
00593         {
00594                 do
00595                 {
00596                         if (++indx >= mag.Length())
00597                         {
00598                                 --bitLength;
00599                                 break;
00600                         }
00601                 }
00602                 while (mag.ElementAt(indx) == 0);
00603         }
00604 
00605         return bitLength;
00606 }
00607 
00608 int BigInteger::GetLowestSetBit() const
00609 {
00610         if (m_sign == 0)
00611         {
00612                 return -1;
00613         }
00614 
00615         int w = m_magnitude->Length();
00616 
00617         while (--w > 0)
00618         {
00619                 if ((*m_magnitude)[w] != 0)
00620                 {
00621                         break;
00622                 }
00623         }
00624 
00625         int word = (int) (*m_magnitude)[w];
00626         ASSERT(word != 0);
00627 
00628         int b = (word & 0x0000FFFF) == 0
00629                 ?       (word & 0x00FF0000) == 0
00630                         ?       7
00631                         :       15
00632                 :       (word & 0x000000FF) == 0
00633                         ?       23
00634                         :       31;
00635 
00636         while (b > 0)
00637         {
00638                 //if ((word << b) == Int32::Min())
00639                 if ((word & (1 << b)) != 0)
00640                 {
00641                         break;
00642                 }
00643 
00644                 b--;
00645         }
00646 
00647         return ((m_magnitude->Length() - w) * 32 - (b + 1));
00648 }
00649 
00650 bool BigInteger::TestBit(int n) const
00651 {
00652         if (n < 0)
00653         {
00654                 throw new InvalidArgumentException("Bit position must not be negative");
00655         }
00656 
00657         if (m_sign < 0)
00658         {
00659                 return !Not()->TestBit(n);
00660         }
00661 
00662         int wordNum = n / 32;
00663         if (wordNum >= m_magnitude->Length())
00664         {
00665                 return false;
00666         }
00667 
00668         int word = (*m_magnitude)[m_magnitude->Length() - 1 - wordNum];
00669         return ((word >> (n % 32)) & 1) > 0;
00670 }
00671 
00672 RefCountPtr<Array<int32> > BigInteger::LastNBits(int n) const
00673 {
00674         if (n < 1)
00675         {
00676                 return Zero().m_magnitude->Clone();
00677         }
00678 
00679         int numWords = (n + BitsPerInt - 1) / BitsPerInt;
00680         numWords = Math::Min(numWords, m_magnitude->Length());
00681         RefCountPtr<Array<int32> > result(new Array<int32>(numWords));
00682 
00683         Array<int32>::Copy(*m_magnitude, m_magnitude->Length() - numWords, *result, 0, numWords);
00684 
00685         int hiBits = n % 32;
00686         if (hiBits != 0)
00687         {
00688                 (*result)[0] &= ~(-1 << hiBits);
00689         }
00690 
00691         return result;
00692 }
00693 
00694 RefCountPtr<Array<int32> > BigInteger::DoSubBigLil(Array<int32>& bigMag, Array<int32>& lilMag)
00695 {
00696         RefCountPtr<Array<int32> > x(bigMag.Clone());
00697         if (lilMag.Length() > x->Length())
00698         {
00699                 Subtract(0, lilMag, 0, x);
00700         }
00701         else
00702         {
00703                 Subtract(0, x, 0, lilMag);
00704         }
00705         return x;
00706 }
00707 
00708 const BigInteger& BigInteger::One()
00709 {
00710         return *OnePtr();
00711 }
00712 
00713 BigIntegerPtr BigInteger::OnePtr()
00714 {
00716         if (m_one.IsNull())
00717         {
00718                 Array<int32> *mag = new Array<int32>(1);
00719                 mag->SetElementAt(0, 1);
00720                 m_one = RefCountPtr<BigInteger>(new BigInteger(1, RefCountPtr<Array<int32> >(mag), false));
00721         }
00722         ASSERT(m_one->ToInt() == 1);
00723         return m_one;
00724 }
00725 
00726 const BigInteger& BigInteger::Two()
00727 {
00729         if (m_two.IsNull())
00730         {
00731                 Array<int32> *mag = new Array<int32>(1);
00732                 mag->SetElementAt(0, 2);
00733                 m_two = RefCountPtr<BigInteger>(new BigInteger(1, RefCountPtr<Array<int32> >(mag), false));
00734         }
00735         ASSERT(m_two->ToInt() == 2);
00736         return m_two;
00737 }
00738 
00739 const BigInteger& BigInteger::Zero()
00740 {
00741         return *ZeroPtr();
00742 }
00743 
00744 BigIntegerPtr BigInteger::ZeroPtr()
00745 {
00747         if (m_zero.IsNull())
00748         {
00749                 m_zero = RefCountPtr<BigInteger>(new BigInteger());
00750         }
00751         ASSERT(m_zero->ToInt() == 0);
00752         return m_zero;
00753 }
00754 
00755 RefCountPtr<BigInteger> BigInteger::ShiftRight(int n) const
00756 {
00757         if (n == 0)
00758         {
00759                 return RefCountPtr<BigInteger>(new BigInteger(*this));
00760         }
00761 
00762         if (n < 0)
00763         {
00764                 return ShiftLeft(-n);
00765         }
00766 
00767         if (n >= GetBitLength())
00768         {
00769                 return (m_sign < 0 ? One().Negate() : ZeroPtr());
00770         }
00771 
00772         int resultLength = (GetBitLength() - n + 31) >> 5;
00773         Array<int> *res = new Array<int>(resultLength);
00774 
00775         int numInts = n >> 5;
00776         int numBits = n & 31;
00777 
00778         if (numBits == 0)
00779         {
00780                 Array<int32>::Copy(*m_magnitude, 0, *res, 0, res->Length());
00781         }
00782         else
00783         {
00784                 int numBits2 = 32 - numBits;
00785 
00786                 int magPos = m_magnitude->Length() - 1 - numInts;
00787                 for (int i = resultLength - 1; i >= 0; --i)
00788                 {
00789                         (*res)[i] = (int)((uint32) (*m_magnitude)[magPos--] >> numBits);
00790 
00791                         if (magPos >= 0)
00792                         {
00793                                 (*res)[i] |= (*m_magnitude)[magPos] << numBits2;
00794                         }
00795                 }
00796         }
00797 
00798         ASSERT((*res)[0] != 0);
00799 
00800         return RefCountPtr<BigInteger>(new BigInteger(m_sign, RefCountPtr<Array<int32> >(res), false));
00801 }
00802 
00803 RefCountPtr<Array<int32> > BigInteger::ShiftLeft(Array<int32>& mag, int n)
00804 {
00805         int nInts = (int)((uint32)n >> 5);
00806         int nBits = n & 0x1f;
00807         int magLen = mag.Length();
00808         RefCountPtr<Array<int32> > newMag;
00809 
00810         if (nBits == 0)
00811         {
00812                 newMag = RefCountPtr<Array<int32> >(new Array<int32>(magLen + nInts));
00813                 mag.CopyTo(*newMag, 0);
00814         }
00815         else
00816         {
00817                 int i = 0;
00818                 int nBits2 = 32 - nBits;
00819                 int highBits = (int)((uint32)mag[0] >> nBits2);
00820 
00821                 if (highBits != 0)
00822                 {
00823                         newMag = RefCountPtr<Array<int32> >(new Array<int32>(magLen + nInts + 1));
00824                         (*newMag)[i++] = highBits;
00825                 }
00826                 else
00827                 {
00828                         newMag = RefCountPtr<Array<int32> >(new Array<int32>(magLen + nInts));
00829                 }
00830 
00831                 int m = mag[0];
00832                 for (int j = 0; j < magLen - 1; j++)
00833                 {
00834                         int next = mag[j + 1];
00835 
00836                         (*newMag)[i++] = (m << nBits) | (int)((uint32)next >> nBits2);
00837                         m = next;
00838                 }
00839 
00840                 (*newMag)[i] = mag[magLen - 1] << nBits;
00841         }
00842 
00843         return newMag;
00844 }
00845 
00846 RefCountPtr<BigInteger> BigInteger::ShiftLeft(int n) const
00847 {
00848         if (m_sign == 0 || m_magnitude->Length() == 0)
00849         {
00850                 return ZeroPtr();
00851         }
00852 
00853         if (n == 0)
00854         {
00855                 return RefCountPtr<BigInteger>(new BigInteger(*this));
00856         }
00857 
00858         if (n < 0)
00859         {
00860                 return ShiftRight(-n);
00861         }
00862 
00863         RefCountPtr<BigInteger> result = RefCountPtr<BigInteger>(new BigInteger(m_sign, ShiftLeft(m_magnitude, n), true));
00864 
00865         if (m_nBits != -1)
00866         {
00867                 result->m_nBits = m_sign > 0
00868                         ?       m_nBits
00869                         :       m_nBits + n;
00870         }
00871 
00872         if (m_nBitLength != -1)
00873         {
00874                 result->m_nBitLength = m_nBitLength + n;
00875         }
00876 
00877         return result;
00878 }
00879 
00880 RefCountPtr<BigInteger> BigInteger::Inc() const
00881 {
00882         if (m_sign < 0)
00883         {
00884                 return RefCountPtr<BigInteger>(new BigInteger(-1, DoSubBigLil(m_magnitude, One().m_magnitude), true));
00885         }
00886         return AddToMagnitude(One().m_magnitude);
00887 }
00888 
00889 RefCountPtr<BigInteger> BigInteger::Add(const BigInteger& value) const
00890 {
00891         if (m_sign == 0)
00892         {
00893                 return RefCountPtr<BigInteger>(new BigInteger(value));
00894         }
00895 
00896         if (m_sign != value.m_sign)
00897         {
00898                 if (value.m_sign == 0)
00899                 {
00900                         return RefCountPtr<BigInteger>(new BigInteger(*this));
00901                 }
00902 
00903                 if (value.m_sign < 0)
00904                 {
00905                         return Subtract(*value.Negate());
00906                 }
00907 
00908                 return value.Subtract(*Negate());
00909         }
00910 
00911         return AddToMagnitude(value.m_magnitude);
00912 }
00913 
00914 void BigInteger::Subtract
00915 (
00916         int xStart,
00917         Array<int32>& x,
00918         int yStart,
00919         Array<int32>& y
00920 )
00921 {
00922         ASSERT(yStart < y.Length());
00923 
00924         if (!(x.Length() - xStart >= y.Length() - yStart))
00925         {
00926                 ASSERT(x.Length() - xStart >= y.Length() - yStart);
00927         }
00928 
00929         int32 iT = x.Length();
00930         int32 iV = y.Length();
00931         int64 m;
00932         int32 borrow = 0;
00933 
00934         do
00935         {
00936                 m = ((x[--iT]) & BIGINTEGER_IMASK) - ((y[--iV]) & BIGINTEGER_IMASK) + borrow;
00937                 x[iT] = (int) m;
00938 
00939 //                              borrow = (m < 0) ? -1 : 0;
00940                 borrow = (int32)(m >> 63);
00941         }
00942         while (iV > yStart);
00943 
00944         if (borrow != 0 && iT > 0)
00945         {
00946                 while (iT > 0 && --x[--iT] == -1)
00947                 {
00948                 }
00949         }
00950 
00951         //return x;
00952 }
00953 
00954 RefCountPtr<BigInteger> BigInteger::Subtract(const BigInteger& n) const
00955 {
00956         if (n.m_sign == 0)
00957                 return RefCountPtr<BigInteger>(new BigInteger(*this));
00958 
00959         if (m_sign == 0)
00960                 return n.Negate();
00961 
00962         if (m_sign != n.m_sign)
00963         {
00964                 RefCountPtr<BigInteger> nNeg = n.Negate();
00965                 return Add(*nNeg);
00966         }
00967         
00968         int compare = CompareNoLeadingZeroes(0, m_magnitude, 0, n.m_magnitude);
00969         if (compare == 0)
00970                 return ZeroPtr();
00971 
00972         BigInteger bigun, lilun;
00973         if (compare < 0)
00974         {
00975                 ASSERT(n > *this);
00976                 bigun = n;
00977                 lilun = *this;
00978         }
00979         else
00980         {
00981                 ASSERT(n < *this);
00982                 bigun = *this;
00983                 lilun = n;
00984         }
00985 
00986         return RefCountPtr<BigInteger>(new BigInteger(m_sign * compare, DoSubBigLil(bigun.m_magnitude, lilun.m_magnitude), true));
00987 }
00988 
00989 void BigInteger::AddMagnitudes(Array<int32>& a, Array<int32>& b)
00990 {
00991         int tI = a.Length() - 1;
00992         int vI = b.Length() - 1;
00993         int64 m = 0;
00994 
00995         while (vI >= 0)
00996         {
00997                 m += ((int64)(uint32)a[tI] + (int64)(uint32)b[vI--]);
00998                 a[tI--] = (int)m;
00999                 m = (int64)((uint64)m >> 32);
01000         }
01001 
01002         if (m != 0)
01003         {
01004                 while (tI >= 0 && ++(a[tI--]) == 0)
01005                 {
01006                 }
01007         }
01008 
01009         //return a;
01010 }
01011 
01012 RefCountPtr<BigInteger> BigInteger::AddToMagnitude(RefCountPtr<Array<int32> > magToAdd) const
01013 {
01014         RefCountPtr<Array<int32> > big, small;
01015         if (m_magnitude->Length() < magToAdd->Length())
01016         {
01017                 big = magToAdd;
01018                 small = m_magnitude;
01019         }
01020         else
01021         {
01022                 big = m_magnitude;
01023                 small = magToAdd;
01024         }
01025 
01026         // Conservatively avoid over-allocation when no overflow possible
01027         uint32 limit = UInt32::MaxValue();
01028         if (big->Length() == small->Length())
01029         {
01030                 limit -= (uint32)(*small)[0];
01031         }
01032 
01033         bool possibleOverflow = (uint32)(*big)[0] >= limit;
01034 
01035         RefCountPtr<Array<int32> > bigCopy;
01036         if (possibleOverflow)
01037         {
01038                 bigCopy = RefCountPtr<Array<int32> >(new Array<int32>(big->Length() + 1));
01039                 big->CopyTo(*bigCopy, 1);
01040         }
01041         else
01042         {
01043                 bigCopy = big->Clone();
01044         }
01045 
01046         AddMagnitudes(bigCopy, small);
01047 
01048         return RefCountPtr<BigInteger>(new BigInteger(m_sign, bigCopy, possibleOverflow));
01049 }
01050 
01051 static int64 FastExtEuclid(int64 a, int64 b, int64 uOut[2])
01052 {
01053         int64 u1 = 1;
01054         int64 u3 = a;
01055         int64 v1 = 0;
01056         int64 v3 = b;
01057 
01058         while (v3 > 0)
01059         {
01060                 int64 q, tn;
01061 
01062                 q = u3 / v3;
01063 
01064                 tn = u1 - (v1 * q);
01065                 u1 = v1;
01066                 v1 = tn;
01067 
01068                 tn = u3 - (v3 * q);
01069                 u3 = v3;
01070                 v3 = tn;
01071         }
01072 
01073         uOut[0] = u1;
01074         uOut[1] = (u3 - (u1 * a)) / b;
01075 
01076         return u3;
01077 }
01078 
01079 static int64 FastModInverse(int64 v, int64 m)
01080 {
01081         if (m < 1)
01082         {
01083                 throw new InvalidArgumentException("Modulus must be positive");
01084         }
01085 
01086         int64 x[2];
01087         int64 gcd = FastExtEuclid(v, m, x);
01088 
01089         if (gcd != 1)
01090         {
01091                 throw new InvalidArgumentException("Numbers not relatively prime.");
01092         }
01093 
01094         if (x[0] < 0)
01095         {
01096                 x[0] += m;
01097         }
01098 
01099         return x[0];
01100 }
01101 
01102 int64 BigInteger::GetMQuote()
01103 {
01104         ASSERT(m_sign > 0);
01105 
01106         if (m_mQuote != -1)
01107         {
01108                 return m_mQuote; // already calculated
01109         }
01110 
01111         if (m_magnitude->Length() == 0 || ((*m_magnitude)[m_magnitude->Length() - 1] & 1) == 0)
01112         {
01113                 return -1; // not for even numbers
01114         }
01115 
01116         int64 v = (((~(*m_magnitude)[m_magnitude->Length() - 1]) | 1) & 0xffffffffL);
01117 
01118 #if defined(_MSC_VER) && _MSC_VER < 1300
01119         m_mQuote = FastModInverse(v, 0x100000000);
01120 #else
01121         m_mQuote = FastModInverse(v, 0x100000000LL);
01122 #endif
01123 
01124         return m_mQuote;
01125 }
01126 
01127 void BigInteger::ShiftRightInPlace(int start, Array<int32>& mag, int n)
01128 {
01129         int nInts = (int)((uint32)n >> 5) + start;
01130         int nBits = n & 0x1f;
01131         int magEnd = mag.Length() - 1;
01132 
01133         if (nInts != start)
01134         {
01135                 int delta = (nInts - start);
01136                 int i;
01137 
01138                 for (i = magEnd; i >= nInts; i--)
01139                 {
01140                         mag[i] = mag[i - delta];
01141                 }
01142                 for (i = nInts - 1; i >= start; i--)
01143                 {
01144                         mag[i] = 0;
01145                 }
01146         }
01147 
01148         if (nBits != 0)
01149         {
01150                 int nBits2 = 32 - nBits;
01151                 int m = mag[magEnd];
01152 
01153                 for (int i = magEnd; i > nInts; --i)
01154                 {
01155                         int next = mag[i - 1];
01156 
01157                         mag[i] = (int)((uint32)m >> nBits) | (next << nBits2);
01158                         m = next;
01159                 }
01160 
01161                 mag[nInts] = (int)((uint32)mag[nInts] >> nBits);
01162         }
01163 }
01164 
01165 void BigInteger::ShiftRightOneInPlace(int start, Array<int32>& mag)
01166 {
01167         int i = mag.Length();
01168         int m = mag[i - 1];
01169 
01170         while (--i > start)
01171         {
01172                 int next = mag[i - 1];
01173                 mag[i] = ((int)((uint32)m >> 1)) | (next << 31);
01174                 m = next;
01175         }
01176 
01177         mag[start] = (int)((uint32)mag[start] >> 1);
01178 }
01179 
01180 void BigInteger::Remainder(RefCountPtr<Array<int32> > x, RefCountPtr<Array<int32> > y) const
01181 {
01182         int xStart = 0;
01183         while (xStart < x->Length() && (*x)[xStart] == 0)
01184         {
01185                 ++xStart;
01186         }
01187 
01188         int yStart = 0;
01189         while (yStart < y->Length() && (*y)[yStart] == 0)
01190         {
01191                 ++yStart;
01192         }
01193 
01194         ASSERT(yStart < y->Length());
01195 
01196         int xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y);
01197 
01198         if (xyCmp > 0)
01199         {
01200                 int yBitLength = CalcBitLength(yStart, *y);
01201                 int xBitLength = CalcBitLength(xStart, *x);
01202                 int shift = xBitLength - yBitLength;
01203 
01204                 RefCountPtr<Array<int32> > c;
01205                 int cStart = 0;
01206                 int cBitLength = yBitLength;
01207                 if (shift > 0)
01208                 {
01209                         c = ShiftLeft(y, shift);
01210                         cBitLength += shift;
01211                         ASSERT((*c)[0] != 0);
01212                 }
01213                 else
01214                 {
01215                         int len = y->Length() - yStart;
01216                         c = RefCountPtr<Array<int32> >(new Array<int32>(len));
01217                         Array<int32>::Copy(*y, yStart, *c, 0, len);
01218                 }
01219 
01220                 for (;;)
01221                 {
01222                         if (cBitLength < xBitLength || CompareNoLeadingZeroes(xStart, x, cStart, c) >= 0)
01223                         {
01224                                 Subtract(xStart, x, cStart, c);
01225 
01226                                 while ((*x)[xStart] == 0)
01227                                 {
01228                                         if (++xStart == x->Length())
01229                                                 return /*x*/;
01230                                 }
01231 
01232                                 //xBitLength = calcBitLength(xStart, x);
01233                                 xBitLength = 32 * (x->Length() - xStart - 1) + BitLen((*x)[xStart]);
01234 
01235                                 if (xBitLength <= yBitLength)
01236                                 {
01237                                         if (xBitLength < yBitLength)
01238                                         {
01239                                                 return /*x*/;
01240                                         }
01241 
01242                                         xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y);
01243 
01244                                         if (xyCmp <= 0)
01245                                         {
01246                                                 break;
01247                                         }
01248                                 }
01249                         }
01250 
01251                         shift = cBitLength - xBitLength;
01252 
01253                         // NB: The case where c[cStart] is 1-bit is harmless
01254                         if (shift == 1)
01255                         {
01256                                 uint32 firstC = (uint32)(*c)[cStart] >> 1;
01257                                 uint32 firstX = (uint32)(*x)[xStart];
01258                                 if (firstC > firstX)
01259                                 {
01260                                         ++shift;
01261                                 }
01262                         }
01263 
01264                         if (shift < 2)
01265                         {
01266                                 ShiftRightOneInPlace(cStart, c);
01267                                 --cBitLength;
01268                         }
01269                         else
01270                         {
01271                                 ShiftRightInPlace(cStart, c, shift);
01272                                 cBitLength -= shift;
01273                         }
01274 
01275                         //cStart = c.Length - ((cBitLength + 31) / 32);
01276                         while ((*c)[cStart] == 0)
01277                         {
01278                                 ++cStart;
01279                         }
01280                 }
01281         }
01282 
01283         if (xyCmp == 0)
01284         {
01285                 x->Clear(xStart, x->Length() - xStart);
01286         }
01287 
01288         return /*x*/;
01289 }
01290 
01291 int32 BigInteger::Remainder(int m) const
01292 {
01293         ASSERT(m > 0);
01294 
01295         int64 acc = 0;
01296         for (int pos = 0; pos < m_magnitude->Length(); ++pos)
01297         {
01298                 int64 posVal = (uint32)(*m_magnitude)[pos];
01299                 acc = (acc << 32 | posVal) % m;
01300         }
01301 
01302         return (int32) acc;
01303 }
01304 
01305 RefCountPtr<BigInteger> BigInteger::Remainder(const BigInteger& n) const
01306 {
01307         if (n.m_sign == 0)
01308         {
01309                 throw new InvalidArgumentException("Division by zero error");
01310         }
01311 
01312         if (m_sign == 0)
01313         {
01314                 return ZeroPtr();
01315         }
01316 
01317         // For small values, use fast remainder method
01318         if (n.m_magnitude->Length() == 1)
01319         {
01320                 int val = (*n.m_magnitude)[0];
01321 
01322                 if (val > 0)
01323                 {
01324                         if (val == 1)
01325                         {
01326                                 return ZeroPtr();
01327                         }
01328 
01329                         // TODO Make this func work on uint, and handle val == 1?
01330                         int rem = Remainder(val);
01331                         RefCountPtr<Array<int32> > ar(new Array<int32>(1));
01332                         ar->SetElementAt(0, rem);
01333                         return rem == 0
01334                                 ?       ZeroPtr()
01335                                 :       RefCountPtr<BigInteger>(new BigInteger(m_sign, ar, false));
01336                 }
01337         }
01338 
01339         if (CompareNoLeadingZeroes(0, m_magnitude, 0, n.m_magnitude) < 0)
01340         {
01341                 return RefCountPtr<BigInteger>(new BigInteger(*this));
01342         }
01343 
01344         RefCountPtr<Array<int32> > result;
01345         if (n.QuickPow2Check())  // n is power of two
01346         {
01347                 // TODO Move before small values branch above?
01348                 result = LastNBits(n.Abs()->GetBitLength() - 1);
01349         }
01350         else
01351         {
01352                 result = m_magnitude->Clone();
01353                 Remainder(result, n.m_magnitude);
01354         }
01355 
01356         return RefCountPtr<BigInteger>(new BigInteger(m_sign, result->Clone(), true));
01357 }
01358 
01363 RefCountPtr<Array<int32> > BigInteger::Divide
01364 (
01365         RefCountPtr<Array<int32> >      x,
01366         RefCountPtr<Array<int32> >      y
01367 ) const
01368 {
01369         int xStart = 0;
01370         while (xStart < x->Length() && (*x)[xStart] == 0)
01371         {
01372                 ++xStart;
01373         }
01374 
01375         int yStart = 0;
01376         while (yStart < y->Length() && (*y)[yStart] == 0)
01377         {
01378                 ++yStart;
01379         }
01380 
01381         ASSERT(yStart < y->Length());
01382 
01383         int xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y);
01384         RefCountPtr<Array<int32> > count;
01385 
01386         if (xyCmp > 0)
01387         {
01388                 int yBitLength = CalcBitLength(yStart, *y);
01389                 int xBitLength = CalcBitLength(xStart, *x);
01390                 int shift = xBitLength - yBitLength;
01391 
01392                 RefCountPtr<Array<int32> > iCount;
01393                 int iCountStart = 0;
01394 
01395                 RefCountPtr<Array<int32> > c;
01396                 int cStart = 0;
01397                 int cBitLength = yBitLength;
01398                 if (shift > 0)
01399                 {
01400 //                                      iCount = ShiftLeft(One.magnitude, shift);
01401                         iCount = RefCountPtr<Array<int32> >(new Array<int32>((shift >> 5) + 1));
01402                         (*iCount)[0] = 1 << (shift % 32);
01403 
01404                         c = ShiftLeft(y, shift);
01405                         cBitLength += shift;
01406                 }
01407                 else
01408                 {
01409                         iCount = RefCountPtr<Array<int32> >(new Array<int32>(1));
01410                         (*iCount)[0] = 1;
01411 
01412                         int len = y->Length() - yStart;
01413                         c = RefCountPtr<Array<int32> >(new Array<int32>(len));
01414                         Array<int32>::Copy(*y, yStart, *c, 0, len);
01415                 }
01416 
01417                 count = RefCountPtr<Array<int32> >(new Array<int32>(iCount->Length()));
01418 
01419                 for (;;)
01420                 {
01421                         if (cBitLength < xBitLength || CompareNoLeadingZeroes(xStart, x, cStart, c) >= 0)
01422                         {
01423                                 Subtract(xStart, x, cStart, c);
01424                                 AddMagnitudes(count, iCount);
01425 
01426                                 while ((*x)[xStart] == 0)
01427                                 {
01428                                         if (++xStart == x->Length())
01429                                                 return count;
01430                                 }
01431 
01432                                 //xBitLength = calcBitLength(xStart, x);
01433                                 xBitLength = 32 * (x->Length() - xStart - 1) + BitLen((*x)[xStart]);
01434 
01435                                 if (xBitLength <= yBitLength)
01436                                 {
01437                                         if (xBitLength < yBitLength)
01438                                                 return count;
01439 
01440                                         xyCmp = CompareNoLeadingZeroes(xStart, x, yStart, y);
01441 
01442                                         if (xyCmp <= 0)
01443                                                 break;
01444                                 }
01445                         }
01446 
01447                         shift = cBitLength - xBitLength;
01448 
01449                         // NB: The case where c[cStart] is 1-bit is harmless
01450                         if (shift == 1)
01451                         {
01452                                 uint32 firstC = (uint32) (*c)[cStart] >> 1;
01453                                 uint32 firstX = (uint32) (*x)[xStart];
01454                                 if (firstC > firstX)
01455                                 {
01456                                         ++shift;
01457                                 }
01458                         }
01459 
01460                         if (shift < 2)
01461                         {
01462                                 ShiftRightOneInPlace(cStart, c);
01463                                 --cBitLength;
01464                                 ShiftRightOneInPlace(iCountStart, iCount);
01465                         }
01466                         else
01467                         {
01468                                 ShiftRightInPlace(cStart, c, shift);
01469                                 cBitLength -= shift;
01470                                 ASSERT(cBitLength >= 0);
01471                                 ShiftRightInPlace(iCountStart, iCount, shift);
01472                         }
01473 
01474                         //cStart = c.Length - ((cBitLength + 31) / 32);
01475                         while ((*c)[cStart] == 0)
01476                         {
01477                                 ++cStart;
01478                         }
01479 
01480                         while ((*iCount)[iCountStart] == 0)
01481                         {
01482                                 ++iCountStart;
01483                         }
01484                 }
01485         }
01486         else
01487         {
01488                 count = RefCountPtr<Array<int32> >(new Array<int32>(1));
01489                 count->SetElementAt(0, 0);
01490         }
01491 
01492         if (xyCmp == 0)
01493         {
01494                 AddMagnitudes(count, One().m_magnitude);
01495                 x->Clear(xStart, x->Length() - xStart);
01496         }
01497 
01498         return count;
01499 }
01500 
01501 RefCountPtr<BigInteger> BigInteger::Divide(const BigInteger& val) const
01502 {
01503         if (val.m_sign == 0)
01504         {
01505                 throw new InvalidArgumentException("Division by zero error");
01506         }
01507 
01508         if (m_sign == 0)
01509         {
01510                 return ZeroPtr();
01511         }
01512 
01513         if (val.QuickPow2Check()) // val is power of two
01514         {
01515                 RefCountPtr<BigInteger> result = Abs()->ShiftRight(val.Abs()->GetBitLength() - 1);
01516                 return val.m_sign == m_sign ? result : result->Negate();
01517         }
01518 
01519         return RefCountPtr<BigInteger>(new BigInteger(m_sign * val.m_sign, Divide(m_magnitude->Clone(), val.m_magnitude), true));
01520 }
01521 
01522 Array<BigIntegerPtr> BigInteger::DivideAndRemainder(const BigInteger& val) const
01523 {
01524         if (val.m_sign == 0)
01525         {
01526                 throw new InvalidArgumentException("Division by zero error");
01527         }
01528 
01529         Array<BigIntegerPtr> biggies(2);
01530 
01531         if (m_sign == 0)
01532         {
01533                 biggies[0] = biggies[1] = ZeroPtr();
01534         }
01535         else if (val.QuickPow2Check()) // val is power of two
01536         {
01537                 int e = val.Abs()->GetBitLength() - 1;
01538                 RefCountPtr<BigInteger> quotient = Abs()->ShiftRight(e);
01539                 RefCountPtr<Array<int32> > remainder = LastNBits(e);
01540 
01541                 biggies[0] = (val.m_sign == m_sign ? quotient : quotient->Negate());
01542                 biggies[1] = BigIntegerPtr(new BigInteger(m_sign, remainder, true));
01543         }
01544         else
01545         {
01546                 RefCountPtr<Array<int32> > remainder = m_magnitude->Clone();
01547                 RefCountPtr<Array<int32> > quotient = Divide(remainder, val.m_magnitude);
01548 
01549                 biggies[0] = BigIntegerPtr(new BigInteger(m_sign * val.m_sign, quotient, true));
01550                 biggies[1] = BigIntegerPtr(new BigInteger(m_sign, remainder, true));
01551         }
01552 
01553         return biggies;
01554 }
01555 
01556 RefCountPtr<BigInteger> BigInteger::Multiply(const BigInteger& val) const
01557 {
01558         if (m_sign == 0 || val.m_sign == 0)
01559                 return ZeroPtr();
01560 
01561         if (val.QuickPow2Check()) // val is power of two
01562         {
01563                 RefCountPtr<BigInteger> result = ShiftLeft(val.Abs()->GetBitLength() - 1);
01564                 return val.m_sign > 0 ? result : result->Negate();
01565         }
01566 
01567         if (QuickPow2Check()) // this is power of two
01568         {
01569                 RefCountPtr<BigInteger> result = val.ShiftLeft(Abs()->GetBitLength() - 1);
01570                 return m_sign > 0 ? result : result->Negate();
01571         }
01572 
01573         int maxBitLength = GetBitLength() + val.GetBitLength();
01574         int resLength = (maxBitLength + BitsPerInt - 1) / BitsPerInt;
01575 
01576         RefCountPtr<Array<int32> > res(new Array<int32>(resLength));
01577 
01578         if (val == *this)
01579         {
01580                 Square(res, m_magnitude);
01581         }
01582         else
01583         {
01584                 Multiply(res, m_magnitude, val.m_magnitude);
01585         }
01586 
01587         return RefCountPtr<BigInteger>(new BigInteger(m_sign * val.m_sign, res, true));
01588 }
01589 
01590 void BigInteger::Multiply
01591 (
01592         Array<int32>&   x,
01593         Array<int32>&   y,
01594         Array<int32>&   z
01595 )
01596 {
01597         int i = z.Length();
01598 
01599         if (i < 1)
01600         {
01601                 //return x;
01602                 return;
01603         }
01604 
01605         int xBase = x.Length() - y.Length();
01606 
01607         for (;;)
01608         {
01609                 int64 a = z[--i] & BIGINTEGER_IMASK;
01610                 int64 val = 0;
01611 
01612                 for (int j = y.Length() - 1; j >= 0; j--)
01613                 {
01614                         val += a * (y[j] & BIGINTEGER_IMASK) + (x[xBase + j] & BIGINTEGER_IMASK);
01615 
01616                         x[xBase + j] = (int)val;
01617 
01618                         val = (int64)((uint64)val >> 32);
01619                 }
01620 
01621                 --xBase;
01622 
01623                 if (i < 1)
01624                 {
01625                         if (xBase >= 0)
01626                         {
01627                                 x[xBase] = (int)val;
01628                         }
01629                         else
01630                         {
01631                                 ASSERT(val == 0);
01632                         }
01633                         break;
01634                 }
01635 
01636                 x[xBase] = (int)val;
01637         }
01638 
01639         //return x;
01640 }
01641 
01642 uint32 BigInteger::MultiplyMontyNIsOne
01643 (
01644         uint32  x,
01645         uint32  y,
01646         uint32  m,
01647         uint64  mQuote
01648 )
01649 {
01650         uint64 um = m;
01651         uint64 prod1 = (uint64)x * (uint64)y;
01652         uint64 u = (prod1 * mQuote) & BIGINTEGER_UIMASK;
01653         uint64 prod2 = u * um;
01654         uint64 tmp = (prod1 & BIGINTEGER_UIMASK) + (prod2 & BIGINTEGER_UIMASK);
01655         uint64 carry = (prod1 >> 32) + (prod2 >> 32) + (tmp >> 32);
01656 
01657         if (carry > um)
01658         {
01659                 carry -= um;
01660         }
01661 
01662         ASSERT(carry <= UInt32::MaxValue());
01663         return (uint32)(carry & BIGINTEGER_UIMASK);
01664 }
01665 
01679 void BigInteger::MultiplyMonty
01680 (
01681         Array<int32>&   a,
01682         Array<int32>&   x,
01683         Array<int32>&   y,
01684         Array<int32>&   m,
01685         int64                   mQuote  // mQuote = -m^(-1) mod b
01686 )
01687 {
01688         if (m.Length() == 1)
01689         {
01690                 x[0] = (int)MultiplyMontyNIsOne((uint32)x[0], (uint32)y[0], (uint32)m[0], (uint64)mQuote);
01691                 return;
01692         }
01693 
01694         int n = m.Length();
01695         int nMinus1 = n - 1;
01696         int64 y_0 = y[nMinus1] & BIGINTEGER_IMASK;
01697 
01698         // 1. a = 0 (Notation: a = (a_{n} a_{n-1} ... a_{0})_{b} )
01699         a.Clear(0, n + 1);
01700 
01701         // 2. for i from 0 to (n - 1) do the following:
01702         for (int i = n; i > 0; i--)
01703         {
01704                 int64 x_i = x[i - 1] & BIGINTEGER_IMASK;
01705 
01706                 int64 u = ((((a[n] & BIGINTEGER_IMASK) + ((x_i * y_0) & BIGINTEGER_IMASK)) & BIGINTEGER_IMASK) * mQuote) & BIGINTEGER_IMASK;
01707 
01708                 // 2.2 a = (a + x_i * y + u * m) / b
01709                 int64 prod1 = x_i * y_0;
01710                 int64 prod2 = u * (m[nMinus1] & BIGINTEGER_IMASK);
01711                 int64 tmp = (a[n] & BIGINTEGER_IMASK) + (prod1 & BIGINTEGER_IMASK) + (prod2 & BIGINTEGER_IMASK);
01712                 int64 carry = (int64)((uint64)prod1 >> 32) + (int64)((uint64)prod2 >> 32) + (int64)((uint64)tmp >> 32);
01713                 for (int j = nMinus1; j > 0; j--)
01714                 {
01715                         prod1 = x_i * (y[j - 1] & BIGINTEGER_IMASK);
01716                         prod2 = u * (m[j - 1] & BIGINTEGER_IMASK);
01717                         tmp = (a[j] & BIGINTEGER_IMASK) + (prod1 & BIGINTEGER_IMASK) + (prod2 & BIGINTEGER_IMASK) + (carry & BIGINTEGER_IMASK);
01718                         carry = (int64)((uint64)carry >> 32) + (int64)((uint64)prod1 >> 32) +
01719                                 (int64)((uint64)prod2 >> 32) + (int64)((uint64)tmp >> 32);
01720                         a[j + 1] = (int)tmp; // division by b
01721                 }
01722                 carry += (a[0] & BIGINTEGER_IMASK);
01723                 a[1] = (int)carry;
01724                 a[0] = (int)((uint64)carry >> 32); // OJO!!!!!
01725         }
01726 
01727         // 3. if x >= m the x = x - m
01728         if (CompareTo(0, a, 0, m) >= 0)
01729         {
01730                 Subtract(0, a, 0, m);
01731         }
01732 
01733         // put the result in x
01734         Array<int32>::Copy(a, 1, x, 0, n);
01735 }
01736 
01740 RefCountPtr<Array<int32> > BigInteger::Square
01741 (
01742         RefCountPtr<Array<int32> >      w,
01743         RefCountPtr<Array<int32> >      x
01744 )
01745 {
01746         // Note: this method allows w to be only (2 * x.Length - 1) words if result will fit
01747 //                      if (w.Length != 2 * x.Length)
01748 //                              throw new ArgumentException("no I don't think so...");
01749 
01750         uint64 u1, u2, c;
01751 
01752         int wBase = w->Length() - 1;
01753 
01754         for (int i = x->Length() - 1; i != 0; i--)
01755         {
01756                 uint64 v = (uint64)(uint32) (*x)[i];
01757 
01758                 u1 = v * v;
01759                 u2 = u1 >> 32;
01760                 u1 = (uint32) u1;
01761 
01762                 u1 += (uint64)(uint32) (*w)[wBase];
01763 
01764                 (*w)[wBase] = (int)(uint32) u1;
01765                 c = u2 + (u1 >> 32);
01766 
01767                 for (int j = i - 1; j >= 0; j--)
01768                 {
01769                         --wBase;
01770                         u1 = v * (uint64)(uint32) (*x)[j];
01771                         u2 = u1 >> 31; // multiply by 2!
01772                         u1 = (uint32)(u1 << 1); // multiply by 2!
01773                         u1 += c + (uint64)(uint32) (*w)[wBase];
01774 
01775                         (*w)[wBase] = (int)(uint32) u1;
01776                         c = u2 + (u1 >> 32);
01777                 }
01778 
01779                 c += (uint64)(uint32) (*w)[--wBase];
01780                 (*w)[wBase] = (int)(uint32) c;
01781 
01782                 if (--wBase >= 0)
01783                 {
01784                         (*w)[wBase] = (int)(uint32)(c >> 32);
01785                 }
01786                 else
01787                 {
01788                         ASSERT((uint32)(c >> 32) == 0);
01789                 }
01790                 wBase += i;
01791         }
01792 
01793         u1 = (uint64)(uint32) (*x)[0];
01794         u1 = u1 * u1;
01795         u2 = u1 >> 32;
01796         u1 = u1 & BIGINTEGER_IMASK;
01797 
01798         u1 += (uint64)(uint32) (*w)[wBase];
01799 
01800         (*w)[wBase] = (int)(uint32) u1;
01801         if (--wBase >= 0)
01802         {
01803                 (*w)[wBase] = (int)(uint32)(u2 + (u1 >> 32) + (uint64)(uint32) (*w)[wBase]);
01804         }
01805         else
01806         {
01807                 ASSERT((uint32)(u2 + (u1 >> 32)) == 0);
01808         }
01809 
01810         return w;
01811 }
01812 
01830 RefCountPtr<BigInteger> BigInteger::ExtEuclid
01831 (
01832         const BigInteger&       a,
01833         const BigInteger&       b,
01834         RefCountPtr<BigInteger> u1Out,
01835         RefCountPtr<BigInteger> u2Out
01836 )
01837 {
01838         BigInteger u1 = One();
01839         BigInteger u3 = a;
01840         BigInteger v1 = Zero();
01841         BigInteger v3 = b;
01842 
01843         while (v3.m_sign > 0)
01844         {
01845                 Array<BigIntegerPtr> q = u3.DivideAndRemainder(v3);
01846 
01847                 BigIntegerPtr tmp = v1.Multiply(*q[0]);
01848                 BigIntegerPtr tn = u1.Subtract(*tmp);
01849                 u1 = v1;
01850                 v1 = *tn;
01851 
01852                 u3 = v3;
01853                 v3 = *q[1];
01854         }
01855 
01856         if (u1Out.Get() != NULL)
01857         {
01858                 u1Out->m_sign = u1.m_sign;
01859                 *u1Out->m_magnitude = *u1.m_magnitude;
01860         }
01861 
01862         if (u2Out.Get() != NULL)
01863         {
01864                 RefCountPtr<BigInteger> tmp = u1.Multiply(a);
01865                 tmp = u3.Subtract(*tmp);
01866                 RefCountPtr<BigInteger> res = tmp->Divide(b);
01867                 u2Out->m_sign = res->m_sign;
01868                 *u2Out->m_magnitude = *res->m_magnitude;
01869         }
01870 
01871         return RefCountPtr<BigInteger>(new BigInteger(u3));
01872 }
01873 
01874 RefCountPtr<BigInteger> BigInteger::ModInverse(const BigInteger& m) const
01875 {
01876         if (m.m_sign < 1)
01877         {
01878                 throw new InvalidArgumentException("Modulus must be positive");
01879         }
01880 
01881         RefCountPtr<BigInteger> x(new BigInteger());
01882         RefCountPtr<BigInteger> nil;
01883         RefCountPtr<BigInteger> modM = Mod(m);
01884         RefCountPtr<BigInteger> gcd = ExtEuclid(*modM, m, x, nil);
01885 
01886         if (!gcd->Equals(One()))
01887         {
01888                 throw new InvalidArgumentException("Numbers not relatively prime.");
01889         }
01890 
01891         if (x->m_sign < 0)
01892         {
01893                 x->m_sign = 1;
01894                 x->m_magnitude = DoSubBigLil(m.m_magnitude, x->m_magnitude);
01895         }
01896 
01897         return x;
01898 }
01899 
01900 RefCountPtr<BigInteger> BigInteger::Mod(const BigInteger &m) const
01901 {
01902         if (m.m_sign < 1)
01903         {
01904                 throw new InvalidArgumentException("Modulus must be positive");
01905         }
01906 
01907         RefCountPtr<BigInteger> biggie = Remainder(m);
01908 
01909         return biggie->m_sign >= 0 ? biggie : biggie->Add(m);
01910 }
01911 
01912 RefCountPtr<BigInteger> BigInteger::ModPow(const BigInteger& exponent, BigInteger& m)
01913 {
01914         if (m.m_sign < 1)
01915         {
01916                 throw new InvalidArgumentException("Modulus must be positive");
01917         }
01918 
01919         if (m.Equals(One()))
01920         {
01921                 return ZeroPtr();
01922         }
01923 
01924         if (exponent.m_sign == 0)
01925         {
01926                 return OnePtr();
01927         }
01928 
01929         if (m_sign == 0)
01930         {
01931                 return ZeroPtr();
01932         }
01933 
01934         RefCountPtr<Array<int32> > zVal;
01935         RefCountPtr<Array<int32> > yAccum;
01936         RefCountPtr<Array<int32> > yVal;
01937 
01938         // Montgomery exponentiation is only possible if the modulus is odd,
01939         // but AFAIK, this is always the case for crypto algo's
01940         bool useMonty = (((*m.m_magnitude)[m.m_magnitude->Length() - 1] & 1) == 1);
01941         int64 mQ = 0;
01942         if (useMonty)
01943         {
01944                 mQ = m.GetMQuote();
01945 
01946                 // tmp = this * R mod m
01947                 RefCountPtr<BigInteger> tmp = ShiftLeft(32 * m.m_magnitude->Length())->Mod(m);
01948                 zVal = tmp->m_magnitude->Clone();
01949 
01950                 useMonty = (zVal->Length() <= m.m_magnitude->Length());
01951 
01952                 if (useMonty)
01953                 {
01954                         yAccum = RefCountPtr<Array<int32> >(new Array<int32>(m.m_magnitude->Length() + 1));
01955                         if (zVal->Length() < m.m_magnitude->Length())
01956                         {
01957                                 Array<int32> *longZ = new Array<int32>(m.m_magnitude->Length());
01958                                 zVal->CopyTo(*longZ, longZ->Length() - zVal->Length());
01959                                 zVal = RefCountPtr<Array<int32> >(longZ);
01960                         }
01961                 }
01962         }
01963 
01964         if (!useMonty)
01965         {
01966                 if (m_magnitude->Length() <= m.m_magnitude->Length())
01967                 {
01968                         //zAccum = new int[m.magnitude.Length * 2];
01969                         zVal = RefCountPtr<Array<int32> >(new Array<int32>(m.m_magnitude->Length()));
01970                         m_magnitude->CopyTo(*zVal, zVal->Length() - m_magnitude->Length());
01971                 }
01972                 else
01973                 {
01974                         //
01975                         // in normal practice we'll never see this...
01976                         //
01977                         RefCountPtr<BigInteger> tmp = Remainder(m);
01978 
01979                         //zAccum = new int[m.magnitude.Length * 2];
01980                         zVal = RefCountPtr<Array<int32> >(new Array<int32>(m.m_magnitude->Length()));
01981                         tmp->m_magnitude->CopyTo(*zVal, zVal->Length() - tmp->m_magnitude->Length());
01982                 }
01983 
01984                 yAccum = RefCountPtr<Array<int32> >(new Array<int32>(m.m_magnitude->Length() * 2));
01985         }
01986 
01987         yVal = RefCountPtr<Array<int32> >(new Array<int32>(m.m_magnitude->Length()));
01988 
01989         //
01990         // from LSW to MSW
01991         //
01992         for (int i = 0; i < exponent.m_magnitude->Length(); i++)
01993         {
01994                 int v = (*exponent.m_magnitude)[i];
01995                 int bits = 0;
01996 
01997                 if (i == 0)
01998                 {
01999                         while (v > 0)
02000                         {
02001                                 v <<= 1;
02002                                 bits++;
02003                         }
02004 
02005                         //
02006                         // first time in initialise y
02007                         //
02008                         zVal->CopyTo(*yVal, 0);
02009 
02010                         v <<= 1;
02011                         bits++;
02012                 }
02013 
02014                 while (v != 0)
02015                 {
02016                         if (useMonty)
02017                         {
02018                                 // Montgomery square algo doesn't exist, and a normal
02019                                 // square followed by a Montgomery reduction proved to
02020                                 // be almost as heavy as a Montgomery mulitply.
02021                                 MultiplyMonty(yAccum, yVal, yVal, m.m_magnitude, mQ);
02022                         }
02023                         else
02024                         {
02025                                 Square(yAccum, yVal);
02026                                 Remainder(yAccum, m.m_magnitude);
02027                                 Array<int32>::Copy(*yAccum, yAccum->Length() - yVal->Length(), *yVal, 0, yVal->Length());
02028                                 yAccum->Clear();
02029                         }
02030                         bits++;
02031 
02032                         if (v < 0)
02033                         {
02034                                 if (useMonty)
02035                                 {
02036                                         MultiplyMonty(yAccum, yVal, zVal, m.m_magnitude, mQ);
02037                                 }
02038                                 else
02039                                 {
02040                                         Multiply(yAccum, yVal, zVal);
02041                                         Remainder(yAccum, m.m_magnitude);
02042                                         Array<int32>::Copy(*yAccum, yAccum->Length() - yVal->Length(), *yVal, 0, yVal->Length());
02043                                         yAccum->Clear();
02044                                 }
02045                         }
02046 
02047                         v <<= 1;
02048                 }
02049 
02050                 while (bits < 32)
02051                 {
02052                         if (useMonty)
02053                         {
02054                                 MultiplyMonty(yAccum, yVal, yVal, m.m_magnitude, mQ);
02055                         }
02056                         else
02057                         {
02058                                 Square(yAccum, yVal);
02059                                 Remainder(yAccum, m.m_magnitude);
02060                                 Array<int32>::Copy(*yAccum, yAccum->Length() - yVal->Length(), *yVal, 0, yVal->Length());
02061                                 yAccum->Clear();
02062                         }
02063                         bits++;
02064                 }
02065         }
02066 
02067         if (useMonty)
02068         {
02069                 // Return y * R^(-1) mod m by doing y * 1 * R^(-1) mod m
02070                 zVal->Clear();
02071                 (*zVal)[zVal->Length() - 1] = 1;
02072                 MultiplyMonty(yAccum, yVal, zVal, m.m_magnitude, mQ);
02073         }
02074 
02075         RefCountPtr<BigInteger> result(new BigInteger(1, yVal, true));
02076 
02077         return exponent.m_sign > 0
02078                 ?       result
02079                 :       result->ModInverse(m);
02080 }
02081 
02082 RefCountPtr<BigInteger> BigInteger::And(const BigInteger& value) const
02083 {
02084         if (m_sign == 0 || value.m_sign == 0)
02085         {
02086                 return ZeroPtr();
02087         }
02088 
02089         const BigInteger& one = One();
02090         
02091         Array<int32> aMag = m_sign > 0
02092                 ? *m_magnitude
02093                 : *Add(one)->m_magnitude;
02094 
02095         Array<int32> bMag = value.m_sign > 0
02096                 ? *value.m_magnitude
02097                 : *value.Add(one)->m_magnitude;
02098 
02099         bool resultNeg = m_sign < 0 && value.m_sign < 0;
02100         int resultLength = Math::Max(aMag.Length(), bMag.Length());
02101         Array<int32> resultMag(resultLength);
02102 
02103         int aStart = resultMag.Length() - aMag.Length();
02104         int bStart = resultMag.Length() - bMag.Length();
02105 
02106         for (int i = 0; i < resultMag.Length(); ++i)
02107         {
02108                 int aWord = i >= aStart ? aMag[i - aStart] : 0;
02109                 int bWord = i >= bStart ? bMag[i - bStart] : 0;
02110 
02111                 if (m_sign < 0)
02112                 {
02113                         aWord = ~aWord;
02114                 }
02115 
02116                 if (value.m_sign < 0)
02117                 {
02118                         bWord = ~bWord;
02119                 }
02120 
02121                 resultMag[i] = aWord & bWord;
02122 
02123                 if (resultNeg)
02124                 {
02125                         resultMag[i] = ~resultMag[i];
02126                 }
02127         }
02128 
02129         RefCountPtr<BigInteger> result(new BigInteger(1, resultMag.Clone(), true));
02130 
02131         // TODO Optimise this case
02132         if (resultNeg)
02133         {
02134                 result = result->Not();
02135         }
02136 
02137         return result;
02138 }
02139 
02140 RefCountPtr<BigInteger> BigInteger::Or(const BigInteger& value) const
02141 {
02142         if (m_sign == 0)
02143                 return RefCountPtr<BigInteger>(new BigInteger(value));
02144 
02145         if (value.m_sign == 0)
02146                 return RefCountPtr<BigInteger>(new BigInteger(*this));
02147 
02148         const BigInteger& one = One();
02149 
02150         Array<int32> aMag = m_sign > 0
02151                 ? *m_magnitude
02152                 : *Add(one)->m_magnitude;
02153 
02154         Array<int32> bMag = value.m_sign > 0
02155                 ? *value.m_magnitude
02156                 : *value.Add(one)->m_magnitude;
02157 
02158         bool resultNeg = m_sign < 0 || value.m_sign < 0;
02159         int resultLength = Math::Max(aMag.Length(), bMag.Length());
02160         Array<int32> resultMag(resultLength);
02161 
02162         int aStart = resultMag.Length() - aMag.Length();
02163         int bStart = resultMag.Length() - bMag.Length();
02164 
02165         for (int i = 0; i < resultMag.Length(); ++i)
02166         {
02167                 int aWord = i >= aStart ? aMag[i - aStart] : 0;
02168                 int bWord = i >= bStart ? bMag[i - bStart] : 0;
02169 
02170                 if (m_sign < 0)
02171                 {
02172                         aWord = ~aWord;
02173                 }
02174 
02175                 if (value.m_sign < 0)
02176                 {
02177                         bWord = ~bWord;
02178                 }
02179 
02180                 resultMag[i] = aWord | bWord;
02181 
02182                 if (resultNeg)
02183                 {
02184                         resultMag[i] = ~resultMag[i];
02185                 }
02186         }
02187 
02188         RefCountPtr<BigInteger> result(new BigInteger(1, resultMag.Clone(), true));
02189 
02190         // TODO Optimise this case
02191         if (resultNeg)
02192         {
02193                 result = result->Not();
02194         }
02195 
02196         return result;
02197 }
02198 
02199 RefCountPtr<BigInteger> BigInteger::Xor(const BigInteger& value) const
02200 {
02201         if (m_sign == 0)
02202                 return RefCountPtr<BigInteger>(new BigInteger(value));
02203 
02204         if (value.m_sign == 0)
02205                 return RefCountPtr<BigInteger>(new BigInteger(*this));
02206 
02207         const BigInteger& one = One();
02208         
02209         Array<int32> aMag = m_sign > 0
02210                 ? *m_magnitude
02211                 : *Add(one)->m_magnitude;
02212 
02213         Array<int32> bMag = value.m_sign > 0
02214                 ? *value.m_magnitude
02215                 : *value.Add(one)->m_magnitude;
02216 
02217         // TODO Can just replace with sign != value.sign?
02218         bool resultNeg = (m_sign < 0 && value.m_sign >= 0) || (m_sign >= 0 && value.m_sign < 0);
02219         int resultLength = Math::Max(aMag.Length(), bMag.Length());
02220         Array<int32> resultMag(resultLength);
02221 
02222         int aStart = resultMag.Length() - aMag.Length();
02223         int bStart = resultMag.Length() - bMag.Length();
02224 
02225         for (int i = 0; i < resultMag.Length(); ++i)
02226         {
02227                 int aWord = i >= aStart ? aMag[i - aStart] : 0;
02228                 int bWord = i >= bStart ? bMag[i - bStart] : 0;
02229 
02230                 if (m_sign < 0)
02231                 {
02232                         aWord = ~aWord;
02233                 }
02234 
02235                 if (value.m_sign < 0)
02236                 {
02237                         bWord = ~bWord;
02238                 }
02239 
02240                 resultMag[i] = aWord ^ bWord;
02241 
02242                 if (resultNeg)
02243                 {
02244                         resultMag[i] = ~resultMag[i];
02245                 }
02246         }
02247 
02248         RefCountPtr<BigInteger> result(new BigInteger(1, resultMag.Clone(), true));
02249 
02250         // TODO Optimise this case
02251         if (resultNeg)
02252         {
02253                 result = result->Not();
02254         }
02255 
02256         return result;
02257 }
02258 
02259 RefCountPtr<BigInteger> BigInteger::SetBit(int n) const
02260 {
02261         if (n < 0)
02262         {
02263                 throw new InvalidArgumentException("Bit address less than zero");
02264         }
02265 
02266         if (TestBit(n))
02267         {
02268                 return RefCountPtr<BigInteger>(new BigInteger(*this));
02269         }
02270 
02271         // TODO Handle negative values and zero
02272         if (m_sign > 0 && n < (GetBitLength() - 1))
02273         {
02274                 return FlipExistingBit(n);
02275         }
02276 
02277         RefCountPtr<BigInteger> ret = One().ShiftLeft(n);
02278         return Or(*ret);
02279 }
02280 
02281 RefCountPtr<BigInteger> BigInteger::ClearBit(int n) const
02282 {
02283         if (n < 0)
02284         {
02285                 throw new InvalidArgumentException("Bit address less than zero");
02286         }
02287 
02288         if (!TestBit(n))
02289         {
02290                 return RefCountPtr<BigInteger>(new BigInteger(*this));
02291         }
02292 
02293         // TODO Handle negative values
02294         if (m_sign > 0 && n < (GetBitLength() - 1))
02295         {
02296                 return FlipExistingBit(n);
02297         }
02298 
02299 
02300         RefCountPtr<BigInteger> ret = One().ShiftLeft(n);
02301         return AndNot(*ret);
02302 }
02303 
02304 RefCountPtr<BigInteger> BigInteger::FlipBit(int n) const
02305 {
02306         if (n < 0)
02307         {
02308                 throw new InvalidArgumentException("Bit address less than zero");
02309         }
02310 
02311         // TODO Handle negative values and zero
02312         if (m_sign > 0 && n < (GetBitLength() - 1))
02313                 return FlipExistingBit(n);
02314 
02315         RefCountPtr<BigInteger> ret = One().ShiftLeft(n);
02316         return Xor(*ret);
02317 }
02318 
02319 RefCountPtr<BigInteger> BigInteger::FlipExistingBit(int n) const
02320 {
02321         ASSERT(m_sign > 0);
02322         ASSERT(n >= 0);
02323         ASSERT(n < GetBitLength() - 1);
02324 
02325         RefCountPtr<Array<int32> > mag = m_magnitude->Clone();
02326         (*mag)[mag->Length() - 1 - (n >> 5)] ^= (1 << (n & 31)); // Flip bit
02327         return RefCountPtr<BigInteger>(new BigInteger(m_sign, mag, false));
02328 }
02329 
02330 RefCountPtr<BigInteger> BigInteger::Gcd(const BigInteger& value) const
02331 {
02332         if (value.m_sign == 0)
02333         {
02334                 return Abs();
02335         }
02336 
02337         if (m_sign == 0)
02338         {
02339                 return value.Abs();
02340         }
02341 
02342         RefCountPtr<BigInteger> r;
02343         BigInteger u = *this;
02344         BigInteger v = value;
02345 
02346         while (v.m_sign != 0)
02347         {
02348                 r = u.Mod(v);
02349                 u = v;
02350                 v = *r;
02351         }
02352 
02353         return RefCountPtr<BigInteger>(new BigInteger(u));
02354 }
02355 
02361 bool BigInteger::IsProbablePrime(int certainty) const
02362 {
02363         if (certainty <= 0)
02364         {
02365                 return true;
02366         }
02367 
02368         RefCountPtr<BigInteger> n = Abs();
02369 
02370         if (!n->TestBit(0))
02371                 return n->Equals(Two());
02372 
02373         if (n->Equals(One()))
02374                 return false;
02375 
02376         return n->CheckProbablePrime(certainty, m_randomSource);
02377 }
02378 
02379 BigInteger::~BigInteger()
02380 {
02381 }
02382 
02383 BigInteger::BigInteger(const BigInteger& toCopy)
02384 :       m_sign(toCopy.m_sign),
02385         m_magnitude(toCopy.m_magnitude->Clone()),
02386         m_nBits(toCopy.m_nBits),
02387         m_nBitLength(toCopy.m_nBitLength),
02388         m_mQuote(toCopy.m_mQuote)
02389 {
02390 }
02391 
02392 BigInteger& BigInteger::operator =(const BigInteger& toAssign)
02393 {
02394         m_sign = toAssign.m_sign;
02395         if (m_magnitude->Length() == toAssign.m_magnitude->Length())
02396         {
02397                 Array<int32>::Copy(*toAssign.m_magnitude, 0, *m_magnitude, 0, m_magnitude->Length());
02398         }
02399         else
02400         {
02401                 m_magnitude = toAssign.m_magnitude->Clone();
02402         }
02403         m_nBits = toAssign.m_nBits;
02404         m_nBitLength = toAssign.m_nBitLength;
02405         m_mQuote = toAssign.m_mQuote;
02406 
02407         return *this;
02408 }
02409 
02410 BigInteger& BigInteger::operator =(const int64 i)
02411 {
02412         *this = *CreateValueOf(i);
02413         return *this;
02414 }
02415 
02416 String BigInteger::ToString() const
02417 {
02418         return "TODO";
02419 }
02420 
02421 BigInteger operator~(const BigInteger& bi)
02422 {
02423         RefCountPtr<Array<int32> > mag = bi.m_magnitude->Clone();
02424         for (int x = 0; x < mag->Length(); x++)
02425         {
02426                 (*mag)[x] = ~(*mag)[x];
02427         }
02428         return BigInteger(bi.m_sign, mag, false);
02429 }
02430 
02431 bool BigInteger::Equals( const IComparable *a ) const
02432 {
02433         return Equals(*a);
02434 }
02435 
02436 int BigInteger::Compare( const IComparable *a ) const
02437 {
02438         return Compare(*a);
02439 }
02440 
02441 bool BigInteger::Equals( const IComparable& a ) const
02442 {
02443         return 0 == Compare(a);
02444 }
02445 
02446 int BigInteger::Compare( const IComparable& a ) const
02447 {
02448         if (a.MajicNumber() != MajicNumber())
02449         {
02450                 return -1;
02451         }
02452 
02453         const BigInteger& value = (const BigInteger&)a;
02454 
02455         return m_sign < value.m_sign ? -1
02456                 : m_sign > value.m_sign ? 1
02457                 : m_sign == 0 ? 0
02458                 : m_sign * CompareNoLeadingZeroes(0, m_magnitude, 0, value.m_magnitude);
02459 }
02460 
02461 bool BigInteger::Equals(int64 i) const
02462 {
02463         return Equals(*ValueOf(i));
02464 }
02465 
02466 int BigInteger::CompareTo
02467 (
02468         int xIndx,
02469         Array<int32>& x,
02470         int yIndx,
02471         Array<int32>& y
02472 )
02473 {
02474         while (xIndx != x.Length() && x[xIndx] == 0)
02475         {
02476                 xIndx++;
02477         }
02478 
02479         while (yIndx != y.Length() && y[yIndx] == 0)
02480         {
02481                 yIndx++;
02482         }
02483 
02484         return CompareNoLeadingZeroes(xIndx, x, yIndx, y);
02485 }
02486 
02487 int BigInteger::CompareNoLeadingZeroes
02488 (
02489         int xIndx,
02490         const Array<int32>& x,
02491         int yIndx,
02492         const Array<int32>& y
02493 )
02494 {
02495         int diff = (x.Length() - y.Length()) - (xIndx - yIndx);
02496 
02497         if (diff != 0)
02498         {
02499                 return diff < 0 ? -1 : 1;
02500         }
02501 
02502         // lengths of magnitudes the same, test the magnitude values
02503 
02504         while (xIndx < x.Length())
02505         {
02506                 uint32 v1 = (uint32)x[xIndx++];
02507                 uint32 v2 = (uint32)y[yIndx++];
02508 
02509                 if (v1 != v2)
02510                 {
02511                         return v1 < v2 ? -1 : 1;
02512                 }
02513         }
02514 
02515         return 0;
02516 }
02517 
02518 int32 BigInteger::MajicNumber() const
02519 {
02520         return BIGINTEGER_MAJIC;
02521 }
02522 
02523 int32 BigInteger::HashCode() const
02524 {
02525         int32 hash = 0;
02526         int count = m_magnitude->Length();
02527 
02528         for(int i = 0; i < count; i++)
02529         {
02530                 hash ^= ~m_magnitude->ElementAt(i);
02531         }
02532 
02533         return hash;
02534 }
02535 
02536 void BigInteger::ToByteArray(Array<byte>& bytes, bool isUnsigned) const
02537 {
02538         if (m_sign == 0)
02539         {
02540                 if (isUnsigned )
02541                 {
02542                         bytes = Array<byte>(0);
02543                 }
02544                 else
02545                 {
02546                         bytes = Array<byte>(1);
02547                         bytes[0] = 0;
02548                 }
02549                 return;
02550         }
02551 
02552         int nBits = (isUnsigned && m_sign > 0)
02553                 ?       GetBitLength()
02554                 :       GetBitLength() + 1;
02555 
02556         int nBytes = GetByteLength(nBits);
02557         if (bytes.Length() != nBytes)
02558         {
02559                 bytes = Array<byte>(nBytes);
02560         }
02561 
02562         int magIndex = m_magnitude->Length();
02563         int bytesIndex = bytes.Length();
02564 
02565         if (m_sign > 0)
02566         {
02567                 while (magIndex > 1)
02568                 {
02569                         uint32 mag = (uint32) (*m_magnitude)[--magIndex];
02570                         bytes[--bytesIndex] = (byte) mag;
02571                         bytes[--bytesIndex] = (byte)(mag >> 8);
02572                         bytes[--bytesIndex] = (byte)(mag >> 16);
02573                         bytes[--bytesIndex] = (byte)(mag >> 24);
02574                 }
02575 
02576                 uint32 lastMag = (uint32) (*m_magnitude)[0];
02577                 while (lastMag > 255)
02578                 {
02579                         bytes[--bytesIndex] = (byte) lastMag;
02580                         lastMag >>= 8;
02581                 }
02582 
02583                 bytes[--bytesIndex] = (byte) lastMag;
02584         }
02585         else // sign < 0
02586         {
02587                 bool carry = true;
02588 
02589                 while (magIndex > 1)
02590                 {
02591                         uint32 mag = ~((uint32)(*m_magnitude)[--magIndex]);
02592 
02593                         if (carry)
02594                         {
02595                                 carry = (++mag == UInt32::MinValue());
02596                         }
02597 
02598                         bytes[--bytesIndex] = (byte) mag;
02599                         bytes[--bytesIndex] = (byte)(mag >> 8);
02600                         bytes[--bytesIndex] = (byte)(mag >> 16);
02601                         bytes[--bytesIndex] = (byte)(mag >> 24);
02602                 }
02603 
02604                 uint32 lastMag = (uint32)(*m_magnitude)[0];
02605 
02606                 if (carry)
02607                 {
02608                         // Never wraps because magnitude[0] != 0
02609                         --lastMag;
02610                 }
02611 
02612                 while (lastMag > 255)
02613                 {
02614                         bytes[--bytesIndex] = (byte) ~lastMag;
02615                         lastMag >>= 8;
02616                 }
02617 
02618                 bytes[--bytesIndex] = (byte) ~lastMag;
02619 
02620                 if (bytesIndex > 0)
02621                 {
02622                         bytes[--bytesIndex] = 255;
02623                 }
02624         }
02625 }
02626 
02627 #if defined(DEBUG) || defined(_DEBUG)
02628 void BigInteger::CheckMem() const
02629 {
02630         m_magnitude.CheckMem();
02631 }
02632 
02633 void BigInteger::ValidateMem() const
02634 {
02635         m_magnitude.ValidateMem();
02636 }
02637 
02638 void BigInteger::CheckMemStatics()
02639 {
02640         m_zero.CheckMem();
02641         m_one.CheckMem();
02642         m_two.CheckMem();
02643 }
02644 
02645 void BigInteger::DebugClearStatics()
02646 {
02647         m_zero = NULL;
02648         m_one = NULL;
02649         m_two = NULL;
02650 }
02651 #endif