00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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
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
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
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
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
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
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
00339 b[0] &= mask;
00340
00341
00342 b[0] |= (byte)(1 << (7 - xBits));
00343
00344
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
00420 if ((lsw & -lsw) == lsw)
00421 {
00422 n->m_nBits = 1;
00423 }
00424
00425 return n;
00426 }
00427
00428
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
00441 int firstSignificant;
00442 for (firstSignificant = offset; firstSignificant < end && bytes[firstSignificant] == 0; firstSignificant++)
00443 {
00444 }
00445
00446 if (firstSignificant >= end)
00447 {
00448
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
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
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
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
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
00539
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;
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
00585 int bitLength = 32 * ((mag.Length() - indx) - 1);
00586
00587
00588 int firstMag = mag.ElementAt(indx);
00589 bitLength += BitLen(firstMag);
00590
00591
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
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
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
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
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
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;
01109 }
01110
01111 if (m_magnitude->Length() == 0 || ((*m_magnitude)[m_magnitude->Length() - 1] & 1) == 0)
01112 {
01113 return -1;
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 ;
01230 }
01231
01232
01233 xBitLength = 32 * (x->Length() - xStart - 1) + BitLen((*x)[xStart]);
01234
01235 if (xBitLength <= yBitLength)
01236 {
01237 if (xBitLength < yBitLength)
01238 {
01239 return ;
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
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
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 ;
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
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
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())
01346 {
01347
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
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
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
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
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())
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())
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())
01562 {
01563 RefCountPtr<BigInteger> result = ShiftLeft(val.Abs()->GetBitLength() - 1);
01564 return val.m_sign > 0 ? result : result->Negate();
01565 }
01566
01567 if (QuickPow2Check())
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
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
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
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
01699 a.Clear(0, n + 1);
01700
01701
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
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;
01721 }
01722 carry += (a[0] & BIGINTEGER_IMASK);
01723 a[1] = (int)carry;
01724 a[0] = (int)((uint64)carry >> 32);
01725 }
01726
01727
01728 if (CompareTo(0, a, 0, m) >= 0)
01729 {
01730 Subtract(0, a, 0, m);
01731 }
01732
01733
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
01747
01748
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;
01772 u1 = (uint32)(u1 << 1);
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
01939
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
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
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
01976
01977 RefCountPtr<BigInteger> tmp = Remainder(m);
01978
01979
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
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
02007
02008 zVal->CopyTo(*yVal, 0);
02009
02010 v <<= 1;
02011 bits++;
02012 }
02013
02014 while (v != 0)
02015 {
02016 if (useMonty)
02017 {
02018
02019
02020
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
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
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
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
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
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
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
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
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));
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
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
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
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