First public contribution.
2 * Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
23 #include <securityerr.h>
25 #include "algorithms.h"
26 #include "windowslider.h"
27 #include "stackinteger.h"
32 * Creates a new buffer containing the big-endian binary representation of this
35 * Note that it does not support the exporting of negative integers.
37 * @return The new buffer.
39 * @leave KErrNegativeExportNotSupported If this instance is a negative integer.
42 EXPORT_C HBufC8* TInteger::BufferLC() const
46 User::Leave(KErrNegativeExportNotSupported);
48 TUint bytes = ByteCount();
49 HBufC8* buf = HBufC8::NewMaxLC(bytes);
50 TUint8* bufPtr = (TUint8*)(buf->Ptr());
51 TUint8* regPtr = (TUint8*)Ptr();
53 // we internally store the number little endian, as a string we want it big
55 for(TUint i=0,j=bytes-1; i<bytes; )
57 bufPtr[i++] = regPtr[j--];
62 EXPORT_C HBufC8* TInteger::BufferWithNoTruncationLC() const
66 User::Leave(KErrNegativeExportNotSupported);
69 TUint wordCount = Size();
70 TUint bytes = (wordCount)*WORD_SIZE;
72 HBufC8* buf = HBufC8::NewMaxLC(bytes);
73 TUint8* bufPtr = (TUint8*)(buf->Ptr());
74 TUint8* regPtr = (TUint8*)Ptr();
75 for(TUint i=0,j=bytes-1; i<bytes; )
77 bufPtr[i++] = regPtr[j--];
84 * Gets the number of words required to represent this RInteger.
86 * @return The size of the integer in words.
89 EXPORT_C TUint TInteger::WordCount() const
91 return CountWords(Ptr(), Size());
95 * Gets the number of bytes required to represent this RInteger.
97 * @return The size of the integer in bytes.
100 EXPORT_C TUint TInteger::ByteCount() const
102 TUint wordCount = WordCount();
105 return (wordCount-1)*WORD_SIZE + BytePrecision((Ptr())[wordCount-1]);
114 * Get the number of bits required to represent this RInteger.
116 * @return The size of the integer in bits.
119 EXPORT_C TUint TInteger::BitCount() const
121 TUint wordCount = WordCount();
124 return (wordCount-1)*WORD_BITS + BitPrecision(Ptr()[wordCount-1]);
133 //These 3 declarations instantiate a constant 0, 1, 2 for ease of use and
134 //quick construction elsewhere in the code. Note that the functions
135 //returning references to this static data return const references as you can't
137 //word 0: Size of storage in words
138 //word 1: Pointer to storage
139 //word 2: LSW of storage
140 //word 3: MSW of storage
141 //Note that the flag bits in word 1 (Ptr()) are zero in the case of a positive
142 //stack based integer (SignBit == 0, IsHeapBasedBit == 0)
143 const TUint KBigintZero[4] = {2, (TUint)(KBigintZero+2), 0, 0};
144 const TUint KBigintOne[4] = {2, (TUint)(KBigintOne+2), 1, 0};
145 const TUint KBigintTwo[4] = {2, (TUint)(KBigintTwo+2), 2, 0};
148 * Gets the TInteger that represents zero
150 * @return The TInteger representing zero
152 EXPORT_C const TInteger& TInteger::Zero(void)
154 return *reinterpret_cast<const TStackInteger64*>(KBigintZero);
158 * Gets the TInteger that represents one
160 * @return The TInteger representing one
162 EXPORT_C const TInteger& TInteger::One(void)
164 return *reinterpret_cast<const TStackInteger64*>(KBigintOne);
168 * Gets the TInteger that represents two
170 * @return The TInteger representing two
172 EXPORT_C const TInteger& TInteger::Two(void)
174 return *reinterpret_cast<const TStackInteger64*>(KBigintTwo);
177 EXPORT_C RInteger TInteger::PlusL(const TInteger& aOperand) const
182 if (aOperand.NotNegative())
183 sum = PositiveAddL(*this, aOperand);
185 sum = PositiveSubtractL(*this, aOperand);
189 if (aOperand.NotNegative())
190 sum = PositiveSubtractL(aOperand, *this);
193 sum = PositiveAddL(*this, aOperand);
194 sum.SetSign(TInteger::ENegative);
200 EXPORT_C RInteger TInteger::MinusL(const TInteger& aOperand) const
205 if (aOperand.NotNegative())
206 diff = PositiveSubtractL(*this, aOperand);
208 diff = PositiveAddL(*this, aOperand);
212 if (aOperand.NotNegative())
214 diff = PositiveAddL(*this, aOperand);
215 diff.SetSign(TInteger::ENegative);
218 diff = PositiveSubtractL(aOperand, *this);
223 EXPORT_C RInteger TInteger::TimesL(const TInteger& aOperand) const
225 RInteger product = PositiveMultiplyL(*this, aOperand);
227 if (NotNegative() != aOperand.NotNegative())
234 EXPORT_C RInteger TInteger::DividedByL(const TInteger& aOperand) const
238 DivideL(remainder, quotient, *this, aOperand);
243 EXPORT_C RInteger TInteger::ModuloL(const TInteger& aOperand) const
247 DivideL(remainder, quotient, *this, aOperand);
252 EXPORT_C TUint TInteger::ModuloL(TUint aOperand) const
256 User::Leave(KErrDivideByZero);
258 return Modulo(*this, aOperand);
261 EXPORT_C RInteger TInteger::ModularMultiplyL(const TInteger& aA, const TInteger& aB,
262 const TInteger& aMod)
264 RInteger product = aA.TimesL(aB);
265 CleanupStack::PushL(product);
266 RInteger reduced = product.ModuloL(aMod);
267 CleanupStack::PopAndDestroy(&product);
271 EXPORT_C RInteger TInteger::ModularExponentiateL(const TInteger& aBase,
272 const TInteger& aExp, const TInteger& aMod)
274 CMontgomeryStructure* mont = CMontgomeryStructure::NewLC(aMod);
275 RInteger result = RInteger::NewL(mont->ExponentiateL(aBase, aExp));
276 CleanupStack::PopAndDestroy(mont);
280 EXPORT_C RInteger TInteger::GCDL(const TInteger& aOperand) const
282 //Binary GCD algorithm -- see HAC 14.4.1
283 //with a slight variation -- our g counts shifts rather than actually
284 //shifting. We then do one shift at the end.
285 assert(NotNegative());
286 assert(aOperand.NotNegative());
288 RInteger x = RInteger::NewL(*this);
289 CleanupStack::PushL(x);
290 RInteger y = RInteger::NewL(aOperand);
291 CleanupStack::PushL(y);
300 // 2 while x and y even x <- x/2, y <- y/2
301 while( x.IsEven() && y.IsEven() )
310 // 3.1 while x even x <- x/2
315 // 3.2 while y even y <- y/2
320 // 3.3 t <- abs(x-y)/2
321 RInteger t = x.MinusL(y);
323 t.SetSign(TInteger::EPositive);
325 // 3.4 If x>=y then x <- t else y <- t
336 // 4 Return (g*y) (equiv to y<<=g as our g was counting shifts not actually
339 CleanupStack::Pop(&y);
340 CleanupStack::PopAndDestroy(&x);
344 EXPORT_C RInteger TInteger::InverseModL(const TInteger& aMod) const
346 assert(aMod.NotNegative());
349 if(IsNegative() || *this>=aMod)
351 RInteger temp = ModuloL(aMod);
352 CleanupClosePushL(temp);
353 result = temp.InverseModL(aMod);
354 CleanupStack::PopAndDestroy(&temp);
360 if( !aMod || IsEven() )
362 return RInteger::NewL(Zero());
366 return RInteger::NewL(One());
368 RInteger u = aMod.InverseModL(*this);
369 CleanupClosePushL(u);
372 result = RInteger::NewL(Zero());
376 //calculates (aMod*(*this-u)+1)/(*this)
378 CleanupClosePushL(result);
382 CleanupStack::Pop(&result);
384 CleanupStack::PopAndDestroy(&u);
388 result = RInteger::NewEmptyL(aMod.Size());
389 CleanupClosePushL(result);
390 RInteger workspace = RInteger::NewEmptyL(aMod.Size() * 4);
391 TUint k = AlmostInverse(result.Ptr(), workspace.Ptr(), Ptr(), Size(),
392 aMod.Ptr(), aMod.Size());
393 DivideByPower2Mod(result.Ptr(), result.Ptr(), k, aMod.Ptr(), aMod.Size());
395 CleanupStack::Pop(&result);
400 EXPORT_C TInteger& TInteger::operator+=(const TInteger& aOperand)
402 this->Set(PlusL(aOperand));
406 EXPORT_C TInteger& TInteger::operator-=(const TInteger& aOperand)
408 this->Set(MinusL(aOperand));
412 EXPORT_C TInteger& TInteger::operator*=(const TInteger& aOperand)
414 this->Set(TimesL(aOperand));
418 EXPORT_C TInteger& TInteger::operator/=(const TInteger& aOperand)
420 this->Set(DividedByL(aOperand));
424 EXPORT_C TInteger& TInteger::operator%=(const TInteger& aOperand)
426 this->Set(ModuloL(aOperand));
430 EXPORT_C TInteger& TInteger::operator+=(TInt aOperand)
432 TStackInteger64 operand(aOperand);
437 EXPORT_C TInteger& TInteger::operator-=(TInt aOperand)
439 TStackInteger64 operand(aOperand);
444 EXPORT_C TInteger& TInteger::operator*=(TInt aOperand)
446 TStackInteger64 operand(aOperand);
451 EXPORT_C TInteger& TInteger::operator--()
455 if (Increment(Ptr(), Size()))
457 CleanGrowL(2*Size());
463 if (Decrement(Ptr(), Size()))
471 EXPORT_C TInteger& TInteger::operator++()
475 if(Increment(Ptr(), Size()))
477 CleanGrowL(2*Size());
483 DecrementNoCarry(Ptr(), Size());
492 EXPORT_C TInteger& TInteger::operator <<=(TUint aBits)
494 const TUint wordCount = WordCount();
495 const TUint shiftWords = aBits / WORD_BITS;
496 const TUint shiftBits = aBits % WORD_BITS;
498 CleanGrowL(wordCount+BitsToWords(aBits));
499 ShiftWordsLeftByWords(Ptr(), wordCount + shiftWords, shiftWords);
500 ShiftWordsLeftByBits(Ptr()+shiftWords, wordCount + BitsToWords(shiftBits),
505 EXPORT_C TInteger& TInteger::operator >>=(TUint aBits)
507 const TUint wordCount = WordCount();
508 const TUint shiftWords = aBits / WORD_BITS;
509 const TUint shiftBits = aBits % WORD_BITS;
511 ShiftWordsRightByWords(Ptr(), wordCount, shiftWords);
512 if(wordCount > shiftWords)
514 ShiftWordsRightByBits(Ptr(), wordCount - shiftWords, shiftBits);
516 if(IsNegative() && WordCount()==0) // avoid negative 0
523 EXPORT_C TInt TInteger::UnsignedCompare(const TInteger& aThat) const
525 TUint size = WordCount();
526 TUint thatSize = aThat.WordCount();
528 if( size == thatSize )
529 return Compare(Ptr(), aThat.Ptr(), size);
531 return size > thatSize ? 1 : -1;
534 EXPORT_C TInt TInteger::SignedCompare(const TInteger& aThat) const
538 if (aThat.NotNegative())
539 return UnsignedCompare(aThat);
545 if (aThat.NotNegative())
548 return -UnsignedCompare(aThat);
552 EXPORT_C TBool TInteger::operator!() const
554 //Ptr()[0] is just a quick way of weeding out non-zero numbers without
555 //doing a full WordCount() == 0. Very good odds that a non-zero number
556 //will have a bit set in the least significant word
557 return IsNegative() ? EFalse : (Ptr()[0]==0 && WordCount()==0);
560 EXPORT_C TInt TInteger::SignedCompare(TInt aInteger) const
562 TStackInteger64 temp(aInteger);
563 return SignedCompare(temp);
566 /* TBool IsPrimeL(void) const
567 * and all primality related functions are implemented in primes.cpp */
569 EXPORT_C TBool TInteger::Bit(TUint aBitPos) const
571 if( aBitPos/WORD_BITS >= Size() )
577 return (((Ptr())[aBitPos/WORD_BITS] >> (aBitPos % WORD_BITS)) & 1);
581 EXPORT_C void TInteger::SetBit(TUint aBitPos)
583 if( aBitPos/WORD_BITS < Size() )
585 ArraySetBit(Ptr(), aBitPos);
589 EXPORT_C void TInteger::Negate()
591 if(!!(*this)) //don't flip sign if *this==0
593 SetSign(TSign((~Sign())&KSignMask));
597 EXPORT_C void TInteger::CopyL(const TInteger& aInteger, TBool aAllowShrink)
601 CleanResizeL(aInteger.Size());
605 CleanGrowL(aInteger.Size());
610 EXPORT_C void TInteger::CopyL(TInt aInteger, TBool aAllowShrink)
623 EXPORT_C void TInteger::Set(const RInteger& aInteger)
625 assert(IsHeapBased());
626 Mem::FillZ(Ptr(), WordsToBytes(Size()));
628 iPtr = aInteger.iPtr;
629 iSize = aInteger.iSize;
632 RInteger TInteger::PositiveAddL(const TInteger &aA, const TInteger& aB) const
634 RInteger sum = RInteger::NewEmptyL(CryptoMax(aA.Size(), aB.Size()));
635 const word aSize = aA.Size();
636 const word bSize = aB.Size();
637 const word* const aReg = aA.Ptr();
638 const word* const bReg = aB.Ptr();
639 word* const sumReg = sum.Ptr();
643 carry = Add(sumReg, aReg, bReg, aSize);
644 else if (aSize > bSize)
646 carry = Add(sumReg, aReg, bReg, bSize);
647 CopyWords(sumReg+bSize, aReg+bSize, aSize-bSize);
648 carry = Increment(sumReg+bSize, aSize-bSize, carry);
652 carry = Add(sumReg, aReg, bReg, aSize);
653 CopyWords(sumReg+aSize, bReg+aSize, bSize-aSize);
654 carry = Increment(sumReg+aSize, bSize-aSize, carry);
659 CleanupStack::PushL(sum);
660 sum.CleanGrowL(2*sum.Size());
661 CleanupStack::Pop(&sum);
662 sum.Ptr()[sum.Size()/2] = 1;
664 sum.SetSign(TInteger::EPositive);
668 RInteger TInteger::PositiveSubtractL(const TInteger &aA, const TInteger& aB) const
670 RInteger diff = RInteger::NewEmptyL(CryptoMax(aA.Size(), aB.Size()));
671 unsigned aSize = aA.WordCount();
673 unsigned bSize = aB.WordCount();
675 const word* const aReg = aA.Ptr();
676 const word* const bReg = aB.Ptr();
677 word* const diffReg = diff.Ptr();
681 if (Compare(aReg, bReg, aSize) >= 0)
683 Subtract(diffReg, aReg, bReg, aSize);
684 diff.SetSign(TInteger::EPositive);
688 Subtract(diffReg, bReg, aReg, aSize);
689 diff.SetSign(TInteger::ENegative);
692 else if (aSize > bSize)
694 word borrow = Subtract(diffReg, aReg, bReg, bSize);
695 CopyWords(diffReg+bSize, aReg+bSize, aSize-bSize);
696 borrow = Decrement(diffReg+bSize, aSize-bSize, borrow);
698 diff.SetSign(TInteger::EPositive);
702 word borrow = Subtract(diffReg, bReg, aReg, aSize);
703 CopyWords(diffReg+aSize, bReg+aSize, bSize-aSize);
704 borrow = Decrement(diffReg+aSize, bSize-aSize, borrow);
706 diff.SetSign(TInteger::ENegative);
711 RInteger TInteger::PositiveMultiplyL(const TInteger &aA, const TInteger &aB) const
713 unsigned aSize = RoundupSize(aA.WordCount());
714 unsigned bSize = RoundupSize(aB.WordCount());
716 RInteger product = RInteger::NewEmptyL(aSize+bSize);
717 CleanupClosePushL(product);
719 RInteger workspace = RInteger::NewEmptyL(aSize + bSize);
720 AsymmetricMultiply(product.Ptr(), workspace.Ptr(), aA.Ptr(), aSize, aB.Ptr(),
723 CleanupStack::Pop(&product);
727 TUint TInteger::Modulo(const TInteger& aDividend, TUint aDivisor) const
730 TUint i = aDividend.WordCount();
734 remainder = TUint(MAKE_DWORD(aDividend.Ptr()[i], remainder) % aDivisor);
739 void TInteger::PositiveDivideL(RInteger &aRemainder, RInteger &aQuotient,
740 const TInteger &aDividend, const TInteger &aDivisor) const
742 unsigned dividendSize = aDividend.WordCount();
743 unsigned divisorSize = aDivisor.WordCount();
747 User::Leave(KErrDivideByZero);
750 if (aDividend.UnsignedCompare(aDivisor) == -1)
752 aRemainder.CreateNewL(aDividend.Size());
753 CleanupStack::PushL(aRemainder);
754 aRemainder.CopyL(aDividend); //set remainder to a
755 aRemainder.SetSign(TInteger::EPositive);
756 aQuotient.CleanNewL(2); //Set quotient to zero
757 CleanupStack::Pop(&aRemainder);
761 dividendSize += dividendSize%2; // round up to next even number
762 divisorSize += divisorSize%2;
764 aRemainder.CleanNewL(divisorSize);
765 CleanupStack::PushL(aRemainder);
766 aQuotient.CleanNewL(dividendSize-divisorSize+2);
767 CleanupStack::PushL(aQuotient);
769 RInteger T = RInteger::NewEmptyL(dividendSize+2*divisorSize+4);
770 Divide(aRemainder.Ptr(), aQuotient.Ptr(), T.Ptr(), aDividend.Ptr(),
771 dividendSize, aDivisor.Ptr(), divisorSize);
773 CleanupStack::Pop(2, &aRemainder); //aQuotient, aRemainder
776 void TInteger::DivideL(RInteger& aRemainder, RInteger& aQuotient,
777 const TInteger& aDividend, const TInteger& aDivisor) const
779 PositiveDivideL(aRemainder, aQuotient, aDividend, aDivisor);
781 if (aDividend.IsNegative())
784 if (aRemainder.NotZero())
787 assert(aRemainder.Size() <= aDivisor.Size());
788 Subtract(aRemainder.Ptr(), aDivisor.Ptr(), aRemainder.Ptr(),
793 if (aDivisor.IsNegative())
797 void TInteger::RandomizeL(TUint aBits, TRandomAttribute aAttr)
803 const TUint bytes = BitsToBytes(aBits);
804 const TUint words = BitsToWords(aBits);
806 TPtr8 buf((TUint8*)(Ptr()), bytes, WordsToBytes(Size()));
807 TUint bitpos = aBits % BYTE_BITS;
808 TRAPD(err, GenerateRandomBytesL(buf));
809 if((err != KErrNone) && (err != KErrNotSecure))
811 //mask with 0 all bits above the num requested in the most significant byte
814 buf[bytes-1] = TUint8( buf[bytes-1] & ((1L << bitpos) - 1) );
816 //set most significant (top) bit
817 if(aAttr == ETopBitSet || aAttr == ETop2BitsSet)
819 SetBit(aBits-1); //Set bit counts from 0
820 assert(BitCount() == aBits);
821 assert(Bit(aBits-1));
823 //set 2nd bit from top
824 if(aAttr == ETop2BitsSet)
826 SetBit(aBits-2); //Set bit counts from 0
827 assert(BitCount() == aBits);
828 assert(Bit(aBits-1));
829 assert(Bit(aBits-2));
833 void TInteger::RandomizeL(const TInteger& aMin, const TInteger& aMax)
836 assert(aMin.NotNegative());
837 RInteger range = RInteger::NewL(aMax);
838 CleanupStack::PushL(range);
840 const TUint bits = range.BitCount();
842 //if we find a number < range then aMin+range < aMax
845 RandomizeL(bits, EAllBitsRandom);
847 while(*this > range);
850 CleanupStack::PopAndDestroy(&range);
853 /* void PrimeRandomizeL(TUint aBits, TRandomAttribute aAttr)
854 * and all primality related functions are implemented in primes.cpp */
856 void TInteger::CreateNewL(TUint aNewSize)
858 //should only be called on construction
861 TUint newSize = RoundupSize(aNewSize);
862 SetPtr((TUint*)User::AllocL(WordsToBytes(newSize)));
867 void TInteger::CleanNewL(TUint aNewSize)
869 CreateNewL(aNewSize);
870 Mem::FillZ(Ptr(), WordsToBytes(Size())); //clear integer storage
873 void TInteger::CleanGrowL(TUint aNewSize)
875 assert(IsHeapBased());
876 TUint newSize = RoundupSize(aNewSize);
877 TUint oldSize = Size();
878 if(newSize > oldSize)
880 TUint* oldPtr = Ptr();
881 //1) allocate new memory and set ptr and size
882 SetPtr((TUint*)User::AllocL(WordsToBytes(newSize)));
884 //2) copy old mem to new mem
885 Mem::Copy(Ptr(), oldPtr, WordsToBytes(oldSize));
886 //3) zero all old memory
887 Mem::FillZ(oldPtr, WordsToBytes(oldSize));
888 //4) give back old memory
890 //5) zero new memory from end of copy to end of growth
891 Mem::FillZ(Ptr() + oldSize, WordsToBytes(newSize-oldSize));
895 void TInteger::CleanResizeL(TUint aNewSize)
897 assert(IsHeapBased());
898 TUint newSize = RoundupSize(aNewSize);
899 TUint oldSize = Size();
900 if(newSize > oldSize)
902 CleanGrowL(aNewSize);
904 else if(newSize < oldSize)
906 TUint* oldPtr = Ptr();
907 //1) zero memory above newsize
908 Mem::FillZ(oldPtr+WordsToBytes(aNewSize),WordsToBytes(oldSize-newSize));
909 //2) ReAlloc cell. Since our newsize is less than oldsize, it is
910 //guarenteed not to move. Thus this is just freeing part of our old
911 //cell to the heap for other uses.
912 SetPtr((TUint*)User::ReAllocL(Ptr(), WordsToBytes(newSize)));
917 EXPORT_C TInteger::TInteger() : iSize(0), iPtr(0)
921 void TInteger::Construct(const TDesC8& aValue)
923 assert(Size() >= BytesToWords(aValue.Size()));
924 if(aValue.Size() > 0)
926 //People write numbers with the most significant digits first (big
927 //endian) but we store our numbers in little endian. Hence we need to
928 //reverse the string by bytes.
930 TUint bytes = aValue.Size();
931 TUint8* i = (TUint8*)Ptr();
932 TUint8* j = (TUint8*)aValue.Ptr() + bytes;
934 //Swap the endianess of the number itself
935 // (msb) 01 02 03 04 05 06 (lsb) becomes ->
936 // (lsb) 06 05 04 03 02 01 (msb)
937 while( j != (TUint8*)aValue.Ptr() )
941 Mem::FillZ((TUint8*)Ptr() + bytes, WordsToBytes(Size()) - bytes);
945 //if size is zero, we zero the whole register
946 Mem::FillZ((TUint8*)Ptr(), WordsToBytes(Size()));
951 void TInteger::Construct(const TInteger& aInteger)
953 assert(Size() >= aInteger.Size());
954 CopyWords(Ptr(), aInteger.Ptr(), aInteger.Size());
955 if(Size() > aInteger.Size())
957 Mem::FillZ(Ptr()+aInteger.Size(), WordsToBytes(Size()-aInteger.Size()));
959 SetSign(aInteger.Sign());
962 void TInteger::Construct(TInt aInteger)
964 Construct((TUint)aInteger);
968 Ptr()[0] = -aInteger;
972 void TInteger::Construct(TUint aInteger)
977 Mem::FillZ(Ptr()+1, WordsToBytes(Size()-1));
980 void TInteger::ConstructStack(TUint aWords, TUint aInteger)
982 SetPtr((TUint*)(this)+2);
983 //SetStackBased(); //Not strictly needed as stackbased is a 0 at bit 1
987 Mem::FillZ(&(Ptr()[1]), WordsToBytes(Size()-1));
990 void TInteger::ConstructStack(TUint aWords, const TInteger& aInteger)
992 SetPtr((TUint*)(this)+2);
993 //SetStackBased(); //Not strictly needed as stackbased is a 0 at bit 1
995 assert( Size() >= RoundupSize(aInteger.WordCount()) );
996 CopyWords(Ptr(), aInteger.Ptr(), aInteger.Size());
997 Mem::FillZ(Ptr()+aInteger.Size(), WordsToBytes(Size()-aInteger.Size()));
1000 // Methods are excluded from coverage due to the problem with BullsEye on ONB.
1001 // Manually verified that these methods are functionally covered.
1002 #ifdef _BullseyeCoverage
1003 #pragma suppress_warnings on
1004 #pragma BullseyeCoverage off
1005 #pragma suppress_warnings off
1008 EXPORT_C TInteger& TInteger::operator/=(TInt aOperand)
1010 TStackInteger64 operand(aOperand);
1015 EXPORT_C TInteger& TInteger::operator%=(TInt aOperand)
1017 TStackInteger64 operand(aOperand);
1018 assert(operand.NotNegative());
1023 EXPORT_C TInt TInteger::ConvertToLongL(void) const
1025 if(!IsConvertableToLong())
1027 User::Leave(KErrTotalLossOfPrecision);
1029 return ConvertToLong();
1032 TInt TInteger::ConvertToLong(void) const
1034 TUint value = ConvertToUnsignedLong();
1035 return Sign() == EPositive ? value : -(static_cast<TInt>(value));
1038 TBool TInteger::IsConvertableToLong(void) const
1044 TUint value = (Ptr())[0];
1045 if(Sign() == EPositive)
1047 return static_cast<TInt>(value) >= 0;
1051 return -(static_cast<TInt>(value)) < 0;
1055 EXPORT_C RInteger TInteger::SquaredL() const
1057 //PositiveMultiplyL optimises for the squaring case already
1058 //Any number squared is positive, no need for negative handling in TimesL
1059 return PositiveMultiplyL(*this, *this);
1062 EXPORT_C RInteger TInteger::DividedByL(TUint aOperand) const
1066 DivideL(remainder, quotient, *this, aOperand);
1070 EXPORT_C RInteger TInteger::ExponentiateL(const TInteger& aExponent) const
1074 // 1.1 Precomputation
1077 RInteger g2 = SquaredL();
1078 CleanupStack::PushL(g2);
1079 RInteger g1 = RInteger::NewL(*this);
1080 CleanupStack::PushL(g1);
1081 TWindowSlider slider(aExponent);
1084 // For i from 1 to (2^(k-1) -1) do g2i+1 <- g2i-1 * g2
1085 TUint count = (1 << (slider.WindowSize()-1)) - 1; //2^(k-1) -1
1086 RRArray<RInteger> powerArray(count+1); //+1 because we append g1
1087 powerArray.AppendL(g1);
1088 CleanupStack::Pop(); //g1
1089 CleanupClosePushL(powerArray);
1090 for(TUint k=1; k <= count; k++)
1092 RInteger g2iplus1 = g2.TimesL(powerArray[k-1]);
1093 powerArray.AppendL(g2iplus1);
1097 RInteger A = RInteger::NewL(One());
1098 CleanupStack::PushL(A);
1099 TInt i = aExponent.BitCount() - 1;
1104 // 3.1 If ei == 0 then A <- A^2
1105 if(!aExponent.Bit(i))
1110 // 3.2 Find longest bitstring ei,ei-1,...,el s.t. i-l+1<=k and el==1
1112 // A <- (A^2^(i-l+1)) * g[the index indicated by the bitstring value]
1115 slider.FindNextWindow(i);
1116 assert(slider.Length() >= 1);
1117 for(TUint j=0; j<slider.Length(); j++)
1121 A *= powerArray[slider.Value()>>1];
1122 i -= slider.Length();
1125 CleanupStack::Pop(&A);
1126 CleanupStack::PopAndDestroy(2, &g2); //powerArray, g2
1130 void TInteger::DivideL(TUint& aRemainder, RInteger& aQuotient,
1131 const TInteger& aDividend, TUint aDivisor) const
1135 User::Leave(KErrDivideByZero);
1138 TUint i = aDividend.WordCount();
1139 aQuotient.CleanNewL(RoundupSize(i));
1140 PositiveDivide(aRemainder, aQuotient, aDividend, aDivisor);
1142 if(aDividend.NotNegative())
1144 aQuotient.SetSign(TInteger::EPositive);
1148 aQuotient.SetSign(TInteger::ENegative);
1152 aRemainder = aDivisor = aRemainder;
1157 void TInteger::PositiveDivide(TUint& aRemainder, TInteger& aQuotient,
1158 const TInteger& aDividend, TUint aDivisor) const
1162 TUint i = aDividend.WordCount();
1163 assert(aQuotient.Size() >= RoundupSize(i));
1164 assert(aQuotient.Sign() == TInteger::EPositive);
1168 aQuotient.Ptr()[i] =
1169 TUint(MAKE_DWORD(aDividend.Ptr()[i], aRemainder) / aDivisor);
1171 TUint(MAKE_DWORD(aDividend.Ptr()[i], aRemainder) % aDivisor);