diff -r 641f389e9157 -r a71299154b21 crypto/weakcrypto/source/bigint/bigint.cpp --- a/crypto/weakcrypto/source/bigint/bigint.cpp Tue Aug 31 17:00:08 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1166 +0,0 @@ -/* -* Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of the License "Eclipse Public License v1.0" -* which accompanies this distribution, and is available -* at the URL "http://www.eclipse.org/legal/epl-v10.html". -* -* Initial Contributors: -* Nokia Corporation - initial contribution. -* -* Contributors: -* -* Description: -* -*/ - - -#include -#include -#include -#include -#include "words.h" -#include "algorithms.h" -#include "windowslider.h" -#include "stackinteger.h" -#include "mont.h" - - -/** -* Creates a new buffer containing the big-endian binary representation of this -* integer. -* -* Note that it does not support the exporting of negative integers. -* -* @return The new buffer. -* -* @leave KErrNegativeExportNotSupported If this instance is a negative integer. -* -*/ -EXPORT_C HBufC8* TInteger::BufferLC() const - { - if(IsNegative()) - { - User::Leave(KErrNegativeExportNotSupported); - } - TUint bytes = ByteCount(); - HBufC8* buf = HBufC8::NewMaxLC(bytes); - TUint8* bufPtr = (TUint8*)(buf->Ptr()); - TUint8* regPtr = (TUint8*)Ptr(); - - // we internally store the number little endian, as a string we want it big - // endian - for(TUint i=0,j=bytes-1; iPtr()); - TUint8* regPtr = (TUint8*)Ptr(); - for(TUint i=0,j=bytes-1; i(KBigintZero); - } - -/** - * Gets the TInteger that represents one - * - * @return The TInteger representing one - */ -EXPORT_C const TInteger& TInteger::One(void) - { - return *reinterpret_cast(KBigintOne); - } - -/** - * Gets the TInteger that represents two - * - * @return The TInteger representing two - */ -EXPORT_C const TInteger& TInteger::Two(void) - { - return *reinterpret_cast(KBigintTwo); - } - -EXPORT_C RInteger TInteger::PlusL(const TInteger& aOperand) const - { - RInteger sum; - if (NotNegative()) - { - if (aOperand.NotNegative()) - sum = PositiveAddL(*this, aOperand); - else - sum = PositiveSubtractL(*this, aOperand); - } - else - { - if (aOperand.NotNegative()) - sum = PositiveSubtractL(aOperand, *this); - else - { - sum = PositiveAddL(*this, aOperand); - sum.SetSign(TInteger::ENegative); - } - } - return sum; - } - -EXPORT_C RInteger TInteger::MinusL(const TInteger& aOperand) const - { - RInteger diff; - if (NotNegative()) - { - if (aOperand.NotNegative()) - diff = PositiveSubtractL(*this, aOperand); - else - diff = PositiveAddL(*this, aOperand); - } - else - { - if (aOperand.NotNegative()) - { - diff = PositiveAddL(*this, aOperand); - diff.SetSign(TInteger::ENegative); - } - else - diff = PositiveSubtractL(aOperand, *this); - } - return diff; - } - -EXPORT_C RInteger TInteger::TimesL(const TInteger& aOperand) const - { - RInteger product = PositiveMultiplyL(*this, aOperand); - - if (NotNegative() != aOperand.NotNegative()) - { - product.Negate(); - } - return product; - } - -EXPORT_C RInteger TInteger::DividedByL(const TInteger& aOperand) const - { - RInteger quotient; - RInteger remainder; - DivideL(remainder, quotient, *this, aOperand); - remainder.Close(); - return quotient; - } - -EXPORT_C RInteger TInteger::DividedByL(TUint aOperand) const - { - TUint remainder; - RInteger quotient; - DivideL(remainder, quotient, *this, aOperand); - return quotient; - } - -EXPORT_C RInteger TInteger::ModuloL(const TInteger& aOperand) const - { - RInteger remainder; - RInteger quotient; - DivideL(remainder, quotient, *this, aOperand); - quotient.Close(); - return remainder; - } - -EXPORT_C TUint TInteger::ModuloL(TUint aOperand) const - { - if(!aOperand) - { - User::Leave(KErrDivideByZero); - } - return Modulo(*this, aOperand); - } - -EXPORT_C RInteger TInteger::SquaredL() const - { - //PositiveMultiplyL optimises for the squaring case already - //Any number squared is positive, no need for negative handling in TimesL - return PositiveMultiplyL(*this, *this); - } - -EXPORT_C RInteger TInteger::ExponentiateL(const TInteger& aExponent) const - { - //See HAC 14.85 - - // 1.1 Precomputation - // g1 <- g - // g2 <- g^2 - RInteger g2 = SquaredL(); - CleanupStack::PushL(g2); - RInteger g1 = RInteger::NewL(*this); - CleanupStack::PushL(g1); - TWindowSlider slider(aExponent); - - // 1.2 - // For i from 1 to (2^(k-1) -1) do g2i+1 <- g2i-1 * g2 - TUint count = (1 << (slider.WindowSize()-1)) - 1; //2^(k-1) -1 - RRArray powerArray(count+1); //+1 because we append g1 - User::LeaveIfError(powerArray.Append(g1)); - CleanupStack::Pop(); //g1 - CleanupClosePushL(powerArray); - for(TUint k=1; k <= count; k++) - { - RInteger g2iplus1 = g2.TimesL(powerArray[k-1]); - //This append can't fail as the granularity is set high enough - //plus we've already called Append once which will alloc to the - //set granularity - powerArray.Append(g2iplus1); - } - - // 2 A <- 1, i <- t - RInteger A = RInteger::NewL(One()); - CleanupStack::PushL(A); - TInt i = aExponent.BitCount() - 1; - - // 3 While i>=0 do: - while( i>=0 ) - { - // 3.1 If ei == 0 then A <- A^2 - if(!aExponent.Bit(i)) - { - A *= A; - i--; - } - // 3.2 Find longest bitstring ei,ei-1,...,el s.t. i-l+1<=k and el==1 - // and do: - // A <- (A^2^(i-l+1)) * g[the index indicated by the bitstring value] - else - { - slider.FindNextWindow(i); - assert(slider.Length() >= 1); - for(TUint j=0; j>1]; - i -= slider.Length(); - } - } - CleanupStack::Pop(&A); - CleanupStack::PopAndDestroy(2, &g2); //powerArray, g2 - return A; - } - -EXPORT_C RInteger TInteger::ModularMultiplyL(const TInteger& aA, const TInteger& aB, - const TInteger& aMod) - { - RInteger product = aA.TimesL(aB); - CleanupStack::PushL(product); - RInteger reduced = product.ModuloL(aMod); - CleanupStack::PopAndDestroy(&product); - return reduced; - } - -EXPORT_C RInteger TInteger::ModularExponentiateL(const TInteger& aBase, - const TInteger& aExp, const TInteger& aMod) - { - CMontgomeryStructure* mont = CMontgomeryStructure::NewLC(aMod); - RInteger result = RInteger::NewL(mont->ExponentiateL(aBase, aExp)); - CleanupStack::PopAndDestroy(mont); - return result; - } - -EXPORT_C RInteger TInteger::GCDL(const TInteger& aOperand) const - { - //Binary GCD algorithm -- see HAC 14.4.1 - //with a slight variation -- our g counts shifts rather than actually - //shifting. We then do one shift at the end. - assert(NotNegative()); - assert(aOperand.NotNegative()); - - RInteger x = RInteger::NewL(*this); - CleanupStack::PushL(x); - RInteger y = RInteger::NewL(aOperand); - CleanupStack::PushL(y); - - // 1 Ensure x >= y - if( x < y ) - { - TClassSwap(x, y); - } - - TUint g = 0; - // 2 while x and y even x <- x/2, y <- y/2 - while( x.IsEven() && y.IsEven() ) - { - x >>= 1; - y >>= 1; - ++g; - } - // 3 while x != 0 - while( x.NotZero() ) - { - // 3.1 while x even x <- x/2 - while( x.IsEven() ) - { - x >>= 1; - } - // 3.2 while y even y <- y/2 - while( y.IsEven() ) - { - y >>= 1; - } - // 3.3 t <- abs(x-y)/2 - RInteger t = x.MinusL(y); - t >>= 1; - t.SetSign(TInteger::EPositive); - - // 3.4 If x>=y then x <- t else y <- t - if( x >= y ) - { - x.Set(t); - } - else - { - y.Set(t); - } - } - - // 4 Return (g*y) (equiv to y<<=g as our g was counting shifts not actually - //shifting) - y <<= g; - CleanupStack::Pop(&y); - CleanupStack::PopAndDestroy(&x); - return y; - } - -EXPORT_C RInteger TInteger::InverseModL(const TInteger& aMod) const - { - assert(aMod.NotNegative()); - - RInteger result; - if(IsNegative() || *this>=aMod) - { - RInteger temp = ModuloL(aMod); - CleanupClosePushL(temp); - result = temp.InverseModL(aMod); - CleanupStack::PopAndDestroy(&temp); - return result; - } - - if(aMod.IsEven()) - { - if( !aMod || IsEven() ) - { - return RInteger::NewL(Zero()); - } - if( *this == One() ) - { - return RInteger::NewL(One()); - } - RInteger u = aMod.InverseModL(*this); - CleanupClosePushL(u); - if(!u) - { - result = RInteger::NewL(Zero()); - } - else - { - //calculates (aMod*(*this-u)+1)/(*this) - result = MinusL(u); - CleanupClosePushL(result); - result *= aMod; - ++result; - result /= *this; - CleanupStack::Pop(&result); - } - CleanupStack::PopAndDestroy(&u); - return result; - } - - result = RInteger::NewEmptyL(aMod.Size()); - CleanupClosePushL(result); - RInteger workspace = RInteger::NewEmptyL(aMod.Size() * 4); - TUint k = AlmostInverse(result.Ptr(), workspace.Ptr(), Ptr(), Size(), - aMod.Ptr(), aMod.Size()); - DivideByPower2Mod(result.Ptr(), result.Ptr(), k, aMod.Ptr(), aMod.Size()); - workspace.Close(); - CleanupStack::Pop(&result); - - return result; - } - -EXPORT_C TInteger& TInteger::operator+=(const TInteger& aOperand) - { - this->Set(PlusL(aOperand)); - return *this; - } - -EXPORT_C TInteger& TInteger::operator-=(const TInteger& aOperand) - { - this->Set(MinusL(aOperand)); - return *this; - } - -EXPORT_C TInteger& TInteger::operator*=(const TInteger& aOperand) - { - this->Set(TimesL(aOperand)); - return *this; - } - -EXPORT_C TInteger& TInteger::operator/=(const TInteger& aOperand) - { - this->Set(DividedByL(aOperand)); - return *this; - } - -EXPORT_C TInteger& TInteger::operator%=(const TInteger& aOperand) - { - this->Set(ModuloL(aOperand)); - return *this; - } - -EXPORT_C TInteger& TInteger::operator+=(TInt aOperand) - { - TStackInteger64 operand(aOperand); - *this += operand; - return *this; - } - -EXPORT_C TInteger& TInteger::operator-=(TInt aOperand) - { - TStackInteger64 operand(aOperand); - *this -= operand; - return *this; - } - -EXPORT_C TInteger& TInteger::operator*=(TInt aOperand) - { - TStackInteger64 operand(aOperand); - *this *= operand; - return *this; - } - -EXPORT_C TInteger& TInteger::operator/=(TInt aOperand) - { - TStackInteger64 operand(aOperand); - *this /= operand; - return *this; - } - -EXPORT_C TInteger& TInteger::operator%=(TInt aOperand) - { - TStackInteger64 operand(aOperand); - assert(operand.NotNegative()); - *this %= operand; - return *this; - } - -EXPORT_C TInteger& TInteger::operator--() - { - if (IsNegative()) - { - if (Increment(Ptr(), Size())) - { - CleanGrowL(2*Size()); - (Ptr())[Size()/2]=1; - } - } - else - { - if (Decrement(Ptr(), Size())) - { - this->CopyL(-1); - } - } - return *this; - } - -EXPORT_C TInteger& TInteger::operator++() - { - if(NotNegative()) - { - if(Increment(Ptr(), Size())) - { - CleanGrowL(2*Size()); - (Ptr())[Size()/2]=1; - } - } - else - { - DecrementNoCarry(Ptr(), Size()); - if(WordCount()==0) - { - this->CopyL(Zero()); - } - } - return *this; - } - -EXPORT_C TInteger& TInteger::operator <<=(TUint aBits) - { - const TUint wordCount = WordCount(); - const TUint shiftWords = aBits / WORD_BITS; - const TUint shiftBits = aBits % WORD_BITS; - - CleanGrowL(wordCount+BitsToWords(aBits)); - ShiftWordsLeftByWords(Ptr(), wordCount + shiftWords, shiftWords); - ShiftWordsLeftByBits(Ptr()+shiftWords, wordCount + BitsToWords(shiftBits), - shiftBits); - return *this; - } - -EXPORT_C TInteger& TInteger::operator >>=(TUint aBits) - { - const TUint wordCount = WordCount(); - const TUint shiftWords = aBits / WORD_BITS; - const TUint shiftBits = aBits % WORD_BITS; - - ShiftWordsRightByWords(Ptr(), wordCount, shiftWords); - if(wordCount > shiftWords) - { - ShiftWordsRightByBits(Ptr(), wordCount - shiftWords, shiftBits); - } - if(IsNegative() && WordCount()==0) // avoid negative 0 - { - SetSign(EPositive); - } - return *this; - } - -EXPORT_C TInt TInteger::UnsignedCompare(const TInteger& aThat) const - { - TUint size = WordCount(); - TUint thatSize = aThat.WordCount(); - - if( size == thatSize ) - return Compare(Ptr(), aThat.Ptr(), size); - else - return size > thatSize ? 1 : -1; - } - -EXPORT_C TInt TInteger::SignedCompare(const TInteger& aThat) const - { - if (NotNegative()) - { - if (aThat.NotNegative()) - return UnsignedCompare(aThat); - else - return 1; - } - else - { - if (aThat.NotNegative()) - return -1; - else - return -UnsignedCompare(aThat); - } - } - -EXPORT_C TBool TInteger::operator!() const - { - //Ptr()[0] is just a quick way of weeding out non-zero numbers without - //doing a full WordCount() == 0. Very good odds that a non-zero number - //will have a bit set in the least significant word - return IsNegative() ? EFalse : (Ptr()[0]==0 && WordCount()==0); - } - -EXPORT_C TInt TInteger::SignedCompare(TInt aInteger) const - { - TStackInteger64 temp(aInteger); - return SignedCompare(temp); - } - -/* TBool IsPrimeL(void) const - * and all primality related functions are implemented in primes.cpp */ - -EXPORT_C TBool TInteger::Bit(TUint aBitPos) const - { - if( aBitPos/WORD_BITS >= Size() ) - { - return 0; - } - else - { - return (((Ptr())[aBitPos/WORD_BITS] >> (aBitPos % WORD_BITS)) & 1); - } - } - -EXPORT_C void TInteger::SetBit(TUint aBitPos) - { - if( aBitPos/WORD_BITS < Size() ) - { - ArraySetBit(Ptr(), aBitPos); - } - } - -EXPORT_C void TInteger::Negate() - { - if(!!(*this)) //don't flip sign if *this==0 - { - SetSign(TSign((~Sign())&KSignMask)); - } - } - -EXPORT_C TInt TInteger::ConvertToLongL(void) const - { - if(!IsConvertableToLong()) - { - User::Leave(KErrTotalLossOfPrecision); - } - return ConvertToLong(); - } - -EXPORT_C void TInteger::CopyL(const TInteger& aInteger, TBool aAllowShrink) - { - if(aAllowShrink) - { - CleanResizeL(aInteger.Size()); - } - else - { - CleanGrowL(aInteger.Size()); - } - Construct(aInteger); - } - -EXPORT_C void TInteger::CopyL(TInt aInteger, TBool aAllowShrink) - { - if(aAllowShrink) - { - CleanResizeL(2); - } - else - { - CleanGrowL(2); - } - Construct(aInteger); - } - -EXPORT_C void TInteger::Set(const RInteger& aInteger) - { - assert(IsHeapBased()); - Mem::FillZ(Ptr(), WordsToBytes(Size())); - User::Free(Ptr()); - iPtr = aInteger.iPtr; - iSize = aInteger.iSize; - } - -RInteger TInteger::PositiveAddL(const TInteger &aA, const TInteger& aB) const - { - RInteger sum = RInteger::NewEmptyL(CryptoMax(aA.Size(), aB.Size())); - const word aSize = aA.Size(); - const word bSize = aB.Size(); - const word* const aReg = aA.Ptr(); - const word* const bReg = aB.Ptr(); - word* const sumReg = sum.Ptr(); - - word carry; - if (aSize == bSize) - carry = Add(sumReg, aReg, bReg, aSize); - else if (aSize > bSize) - { - carry = Add(sumReg, aReg, bReg, bSize); - CopyWords(sumReg+bSize, aReg+bSize, aSize-bSize); - carry = Increment(sumReg+bSize, aSize-bSize, carry); - } - else - { - carry = Add(sumReg, aReg, bReg, aSize); - CopyWords(sumReg+aSize, bReg+aSize, bSize-aSize); - carry = Increment(sumReg+aSize, bSize-aSize, carry); - } - - if (carry) - { - CleanupStack::PushL(sum); - sum.CleanGrowL(2*sum.Size()); - CleanupStack::Pop(&sum); - sum.Ptr()[sum.Size()/2] = 1; - } - sum.SetSign(TInteger::EPositive); - return sum; - } - -RInteger TInteger::PositiveSubtractL(const TInteger &aA, const TInteger& aB) const - { - RInteger diff = RInteger::NewEmptyL(CryptoMax(aA.Size(), aB.Size())); - unsigned aSize = aA.WordCount(); - aSize += aSize%2; - unsigned bSize = aB.WordCount(); - bSize += bSize%2; - const word* const aReg = aA.Ptr(); - const word* const bReg = aB.Ptr(); - word* const diffReg = diff.Ptr(); - - if (aSize == bSize) - { - if (Compare(aReg, bReg, aSize) >= 0) - { - Subtract(diffReg, aReg, bReg, aSize); - diff.SetSign(TInteger::EPositive); - } - else - { - Subtract(diffReg, bReg, aReg, aSize); - diff.SetSign(TInteger::ENegative); - } - } - else if (aSize > bSize) - { - word borrow = Subtract(diffReg, aReg, bReg, bSize); - CopyWords(diffReg+bSize, aReg+bSize, aSize-bSize); - borrow = Decrement(diffReg+bSize, aSize-bSize, borrow); - assert(!borrow); - diff.SetSign(TInteger::EPositive); - } - else - { - word borrow = Subtract(diffReg, bReg, aReg, aSize); - CopyWords(diffReg+aSize, bReg+aSize, bSize-aSize); - borrow = Decrement(diffReg+aSize, bSize-aSize, borrow); - assert(!borrow); - diff.SetSign(TInteger::ENegative); - } - return diff; - } - -RInteger TInteger::PositiveMultiplyL(const TInteger &aA, const TInteger &aB) const - { - unsigned aSize = RoundupSize(aA.WordCount()); - unsigned bSize = RoundupSize(aB.WordCount()); - - RInteger product = RInteger::NewEmptyL(aSize+bSize); - CleanupClosePushL(product); - - RInteger workspace = RInteger::NewEmptyL(aSize + bSize); - AsymmetricMultiply(product.Ptr(), workspace.Ptr(), aA.Ptr(), aSize, aB.Ptr(), - bSize); - workspace.Close(); - CleanupStack::Pop(&product); - return product; - } - -TUint TInteger::Modulo(const TInteger& aDividend, TUint aDivisor) const - { - assert(aDivisor); - TUint i = aDividend.WordCount(); - TUint remainder = 0; - while(i--) - { - remainder = TUint(MAKE_DWORD(aDividend.Ptr()[i], remainder) % aDivisor); - } - return remainder; - } - -void TInteger::PositiveDivide(TUint& aRemainder, TInteger& aQuotient, - const TInteger& aDividend, TUint aDivisor) const - { - assert(aDivisor); - - TUint i = aDividend.WordCount(); - assert(aQuotient.Size() >= RoundupSize(i)); - assert(aQuotient.Sign() == TInteger::EPositive); - aRemainder = 0; - while(i--) - { - aQuotient.Ptr()[i] = - TUint(MAKE_DWORD(aDividend.Ptr()[i], aRemainder) / aDivisor); - aRemainder = - TUint(MAKE_DWORD(aDividend.Ptr()[i], aRemainder) % aDivisor); - } - } - -void TInteger::DivideL(TUint& aRemainder, RInteger& aQuotient, - const TInteger& aDividend, TUint aDivisor) const - { - if(!aDivisor) - { - User::Leave(KErrDivideByZero); - } - - TUint i = aDividend.WordCount(); - aQuotient.CleanNewL(RoundupSize(i)); - PositiveDivide(aRemainder, aQuotient, aDividend, aDivisor); - - if(aDividend.NotNegative()) - { - aQuotient.SetSign(TInteger::EPositive); - } - else - { - aQuotient.SetSign(TInteger::ENegative); - if(aRemainder) - { - --aQuotient; - aRemainder = aDivisor = aRemainder; - } - } - } - -void TInteger::PositiveDivideL(RInteger &aRemainder, RInteger &aQuotient, - const TInteger &aDividend, const TInteger &aDivisor) const - { - unsigned dividendSize = aDividend.WordCount(); - unsigned divisorSize = aDivisor.WordCount(); - - if (!divisorSize) - { - User::Leave(KErrDivideByZero); - } - - if (aDividend.UnsignedCompare(aDivisor) == -1) - { - aRemainder.CreateNewL(aDividend.Size()); - CleanupStack::PushL(aRemainder); - aRemainder.CopyL(aDividend); //set remainder to a - aRemainder.SetSign(TInteger::EPositive); - aQuotient.CleanNewL(2); //Set quotient to zero - CleanupStack::Pop(&aRemainder); - return; - } - - dividendSize += dividendSize%2; // round up to next even number - divisorSize += divisorSize%2; - - aRemainder.CleanNewL(divisorSize); - CleanupStack::PushL(aRemainder); - aQuotient.CleanNewL(dividendSize-divisorSize+2); - CleanupStack::PushL(aQuotient); - - RInteger T = RInteger::NewEmptyL(dividendSize+2*divisorSize+4); - Divide(aRemainder.Ptr(), aQuotient.Ptr(), T.Ptr(), aDividend.Ptr(), - dividendSize, aDivisor.Ptr(), divisorSize); - T.Close(); - CleanupStack::Pop(2, &aRemainder); //aQuotient, aRemainder - } - -void TInteger::DivideL(RInteger& aRemainder, RInteger& aQuotient, - const TInteger& aDividend, const TInteger& aDivisor) const - { - PositiveDivideL(aRemainder, aQuotient, aDividend, aDivisor); - - if (aDividend.IsNegative()) - { - aQuotient.Negate(); - if (aRemainder.NotZero()) - { - --aQuotient; - assert(aRemainder.Size() <= aDivisor.Size()); - Subtract(aRemainder.Ptr(), aDivisor.Ptr(), aRemainder.Ptr(), - aRemainder.Size()); - } - } - - if (aDivisor.IsNegative()) - aQuotient.Negate(); - } - -TInt TInteger::ConvertToLong(void) const - { - TUint value = ConvertToUnsignedLong(); - return Sign() == EPositive ? value : -(static_cast(value)); - } - -TBool TInteger::IsConvertableToLong(void) const - { - if(WordCount() > 1) - { - return EFalse; - } - TUint value = (Ptr())[0]; - if(Sign() == EPositive) - { - return static_cast(value) >= 0; - } - else - { - return -(static_cast(value)) < 0; - } - } - -void TInteger::RandomizeL(TUint aBits, TRandomAttribute aAttr) - { - if(!aBits) - { - return; - } - const TUint bytes = BitsToBytes(aBits); - const TUint words = BitsToWords(aBits); - CleanGrowL(words); - TPtr8 buf((TUint8*)(Ptr()), bytes, WordsToBytes(Size())); - TUint bitpos = aBits % BYTE_BITS; - GenerateRandomBytesL(buf); - //mask with 0 all bits above the num requested in the most significant byte - if(bitpos) - { - buf[bytes-1] = TUint8( buf[bytes-1] & ((1L << bitpos) - 1) ); - } - //set most significant (top) bit - if(aAttr == ETopBitSet || aAttr == ETop2BitsSet) - { - SetBit(aBits-1); //Set bit counts from 0 - assert(BitCount() == aBits); - assert(Bit(aBits-1)); - } - //set 2nd bit from top - if(aAttr == ETop2BitsSet) - { - SetBit(aBits-2); //Set bit counts from 0 - assert(BitCount() == aBits); - assert(Bit(aBits-1)); - assert(Bit(aBits-2)); - } - } - -void TInteger::RandomizeL(const TInteger& aMin, const TInteger& aMax) - { - assert(aMax > aMin); - assert(aMin.NotNegative()); - RInteger range = RInteger::NewL(aMax); - CleanupStack::PushL(range); - range -= aMin; - const TUint bits = range.BitCount(); - - //if we find a number < range then aMin+range < aMax - do - { - RandomizeL(bits, EAllBitsRandom); - } - while(*this > range); - - *this += aMin; - CleanupStack::PopAndDestroy(&range); - } - -/* void PrimeRandomizeL(TUint aBits, TRandomAttribute aAttr) - * and all primality related functions are implemented in primes.cpp */ - -void TInteger::CreateNewL(TUint aNewSize) - { - //should only be called on construction - assert(!iPtr); - - TUint newSize = RoundupSize(aNewSize); - SetPtr((TUint*)User::AllocL(WordsToBytes(newSize))); - SetSize(newSize); - SetHeapBased(); - } - -void TInteger::CleanNewL(TUint aNewSize) - { - CreateNewL(aNewSize); - Mem::FillZ(Ptr(), WordsToBytes(Size())); //clear integer storage - } - -void TInteger::CleanGrowL(TUint aNewSize) - { - assert(IsHeapBased()); - TUint newSize = RoundupSize(aNewSize); - TUint oldSize = Size(); - if(newSize > oldSize) - { - TUint* oldPtr = Ptr(); - //1) allocate new memory and set ptr and size - SetPtr((TUint*)User::AllocL(WordsToBytes(newSize))); - SetSize(newSize); - //2) copy old mem to new mem - Mem::Copy(Ptr(), oldPtr, WordsToBytes(oldSize)); - //3) zero all old memory - Mem::FillZ(oldPtr, WordsToBytes(oldSize)); - //4) give back old memory - User::Free(oldPtr); - //5) zero new memory from end of copy to end of growth - Mem::FillZ(Ptr() + oldSize, WordsToBytes(newSize-oldSize)); - } - } - -void TInteger::CleanResizeL(TUint aNewSize) - { - assert(IsHeapBased()); - TUint newSize = RoundupSize(aNewSize); - TUint oldSize = Size(); - if(newSize > oldSize) - { - CleanGrowL(aNewSize); - } - else if(newSize < oldSize) - { - TUint* oldPtr = Ptr(); - //1) zero memory above newsize - Mem::FillZ(oldPtr+WordsToBytes(aNewSize),WordsToBytes(oldSize-newSize)); - //2) ReAlloc cell. Since our newsize is less than oldsize, it is - //guarenteed not to move. Thus this is just freeing part of our old - //cell to the heap for other uses. - SetPtr((TUint*)User::ReAllocL(Ptr(), WordsToBytes(newSize))); - SetSize(newSize); - } - } - -TInteger::TInteger() : iSize(0), iPtr(0) - { - } - -void TInteger::Construct(const TDesC8& aValue) - { - assert(Size() >= BytesToWords(aValue.Size())); - if(aValue.Size() > 0) - { - //People write numbers with the most significant digits first (big - //endian) but we store our numbers in little endian. Hence we need to - //reverse the string by bytes. - - TUint bytes = aValue.Size(); - TUint8* i = (TUint8*)Ptr(); - TUint8* j = (TUint8*)aValue.Ptr() + bytes; - - //Swap the endianess of the number itself - // (msb) 01 02 03 04 05 06 (lsb) becomes -> - // (lsb) 06 05 04 03 02 01 (msb) - while( j != (TUint8*)aValue.Ptr() ) - { - *i++ = *--j; - } - Mem::FillZ((TUint8*)Ptr() + bytes, WordsToBytes(Size()) - bytes); - } - else - { - //if size is zero, we zero the whole register - Mem::FillZ((TUint8*)Ptr(), WordsToBytes(Size())); - } - SetSign(EPositive); - } - -void TInteger::Construct(const TInteger& aInteger) - { - assert(Size() >= aInteger.Size()); - CopyWords(Ptr(), aInteger.Ptr(), aInteger.Size()); - if(Size() > aInteger.Size()) - { - Mem::FillZ(Ptr()+aInteger.Size(), WordsToBytes(Size()-aInteger.Size())); - } - SetSign(aInteger.Sign()); - } - -void TInteger::Construct(TInt aInteger) - { - Construct((TUint)aInteger); - if(aInteger < 0) - { - SetSign(ENegative); - Ptr()[0] = -aInteger; - } - } - -void TInteger::Construct(TUint aInteger) - { - assert(Size() >= 2); - SetSign(EPositive); - Ptr()[0] = aInteger; - Mem::FillZ(Ptr()+1, WordsToBytes(Size()-1)); - } - -void TInteger::ConstructStack(TUint aWords, TUint aInteger) - { - SetPtr((TUint*)(this)+2); - //SetStackBased(); //Not strictly needed as stackbased is a 0 at bit 1 - SetSize(aWords); - assert(Size() >= 2); - Ptr()[0] = aInteger; - Mem::FillZ(&(Ptr()[1]), WordsToBytes(Size()-1)); - } - -void TInteger::ConstructStack(TUint aWords, const TInteger& aInteger) - { - SetPtr((TUint*)(this)+2); - //SetStackBased(); //Not strictly needed as stackbased is a 0 at bit 1 - SetSize(aWords); - assert( Size() >= RoundupSize(aInteger.WordCount()) ); - CopyWords(Ptr(), aInteger.Ptr(), aInteger.Size()); - Mem::FillZ(Ptr()+aInteger.Size(), WordsToBytes(Size()-aInteger.Size())); - } -