williamr@4: /* williamr@4: * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). williamr@4: * All rights reserved. williamr@4: * This component and the accompanying materials are made available williamr@4: * under the terms of the License "Eclipse Public License v1.0" williamr@4: * which accompanies this distribution, and is available williamr@4: * at the URL "http://www.eclipse.org/legal/epl-v10.html". williamr@4: * williamr@4: * Initial Contributors: williamr@4: * Nokia Corporation - initial contribution. williamr@4: * williamr@4: * Contributors: williamr@4: * williamr@4: * Description: williamr@4: * ** IMPORTANT ** PublishedPartner API's in this file are published to 3rd party developers via the williamr@4: * Symbian website. Changes to these API's should be treated as PublishedAll API changes and the Security TA should be consulted. williamr@4: * williamr@4: */ williamr@4: williamr@4: williamr@4: /** williamr@4: @file williamr@4: @publishedAll williamr@4: @released williamr@4: */ williamr@4: williamr@4: #ifndef __BIGINT_H__ williamr@4: #define __BIGINT_H__ williamr@4: williamr@4: #include williamr@4: williamr@4: williamr@4: const TUint KSignMask = 0x1L; williamr@4: const TUint KHeapBasedMask = 0x2L; williamr@4: const TUint KPtrMask = 0xFFFFFFFCL; williamr@4: williamr@4: class RInteger; williamr@4: williamr@4: /** williamr@4: * Abstract base class defining the interface for handling and manipulating big williamr@4: * integers. williamr@4: * williamr@4: * TInteger is capable of representing both negative and positive integers williamr@4: * with an absolute value of less than 2^32^(2^32). To create an integer williamr@4: * look at RInteger. williamr@4: * TInteger defines an interface for the RInteger implementation - it is not williamr@4: * intended that TIntegers be copied or assigned from other TIntegers. On EKA1 williamr@4: * platforms, this is possible, but it should be avoided. williamr@4: * williamr@4: * williamr@4: * @see RInteger williamr@4: */ williamr@4: class TInteger williamr@4: { williamr@4: public: williamr@4: /** @internalComponent */ williamr@4: enum TRandomAttribute {EAllBitsRandom=0, ETopBitSet=1, ETop2BitsSet=2}; williamr@4: williamr@4: IMPORT_C HBufC8* BufferLC() const; williamr@4: IMPORT_C TUint WordCount(void) const; williamr@4: IMPORT_C TUint ByteCount(void) const; williamr@4: IMPORT_C TUint BitCount(void) const; williamr@4: williamr@4: IMPORT_C static const TInteger& Zero(void); williamr@4: IMPORT_C static const TInteger& One(void); williamr@4: IMPORT_C static const TInteger& Two(void); williamr@4: williamr@4: IMPORT_C RInteger PlusL(const TInteger& aOperand) const; williamr@4: IMPORT_C RInteger MinusL(const TInteger& aOperand) const; williamr@4: IMPORT_C RInteger TimesL(const TInteger& aOperand) const; williamr@4: IMPORT_C RInteger DividedByL(const TInteger& aOperand) const; williamr@4: IMPORT_C RInteger DividedByL(TUint aOperand) const; williamr@4: IMPORT_C RInteger ModuloL(const TInteger& aOperand) const; williamr@4: IMPORT_C TUint ModuloL(TUint aOperand) const; williamr@4: williamr@4: IMPORT_C RInteger SquaredL(void) const; williamr@4: IMPORT_C RInteger ExponentiateL(const TInteger& aExponent) const; williamr@4: IMPORT_C static RInteger ModularMultiplyL(const TInteger& aA, const TInteger& aB, williamr@4: const TInteger& aModulus); williamr@4: IMPORT_C static RInteger ModularExponentiateL(const TInteger& aBase, williamr@4: const TInteger& aExp, const TInteger& aMod); williamr@4: IMPORT_C RInteger GCDL(const TInteger& aOperand) const; williamr@4: IMPORT_C RInteger InverseModL(const TInteger& aMod) const; williamr@4: williamr@4: // These overloaded operator functions leave williamr@4: IMPORT_C TInteger& operator += (const TInteger& aOperand); williamr@4: IMPORT_C TInteger& operator -= (const TInteger& aOperand); williamr@4: IMPORT_C TInteger& operator *= (const TInteger& aOperand); williamr@4: IMPORT_C TInteger& operator /= (const TInteger& aOperand); williamr@4: IMPORT_C TInteger& operator %= (const TInteger& aOperand); williamr@4: williamr@4: IMPORT_C TInteger& operator += (TInt aOperand); williamr@4: IMPORT_C TInteger& operator -= (TInt aOperand); williamr@4: IMPORT_C TInteger& operator *= (TInt aOperand); williamr@4: IMPORT_C TInteger& operator /= (TInt aOperand); williamr@4: IMPORT_C TInteger& operator %= (TInt aOperand); williamr@4: IMPORT_C TInteger& operator -- (); williamr@4: IMPORT_C TInteger& operator ++ (); williamr@4: williamr@4: IMPORT_C TInteger& operator <<= (TUint aBits); williamr@4: // End of leaving overloaded operator functions williamr@4: IMPORT_C TInteger& operator >>= (TUint aBits); williamr@4: williamr@4: IMPORT_C TInt UnsignedCompare(const TInteger& aThat) const; williamr@4: IMPORT_C TInt SignedCompare(const TInteger& aThat) const; williamr@4: IMPORT_C TBool operator ! () const; williamr@4: inline TBool operator == (const TInteger& aInteger) const; williamr@4: inline TBool operator != (const TInteger& aInteger) const; williamr@4: inline TBool operator <= (const TInteger& aInteger) const; williamr@4: inline TBool operator >= (const TInteger& aInteger) const; williamr@4: inline TBool operator < (const TInteger& aInteger) const; williamr@4: inline TBool operator > (const TInteger& aInteger) const; williamr@4: williamr@4: IMPORT_C TInt SignedCompare(TInt aThat) const; williamr@4: inline TBool operator == (TInt aInteger) const; williamr@4: inline TBool operator != (TInt aInteger) const; williamr@4: inline TBool operator <= (TInt aInteger) const; williamr@4: inline TBool operator >= (TInt aInteger) const; williamr@4: inline TBool operator < (TInt aInteger) const; williamr@4: inline TBool operator > (TInt aInteger) const; williamr@4: williamr@4: inline TBool IsZero() const {return !*this;} williamr@4: inline TBool NotZero() const {return !IsZero();} williamr@4: inline TBool IsNegative() const {return Sign() == ENegative;} williamr@4: inline TBool NotNegative() const {return !IsNegative();} williamr@4: inline TBool IsPositive() const {return NotNegative() && NotZero();} williamr@4: inline TBool NotPositive() const {return !IsPositive();} williamr@4: inline TBool IsEven() const {return Bit(0) == EFalse;} williamr@4: inline TBool IsOdd() const {return Bit(0);} williamr@4: williamr@4: IMPORT_C TBool IsPrimeL(void) const; williamr@4: williamr@4: IMPORT_C TBool Bit(TUint aBitPos) const; williamr@4: IMPORT_C void SetBit(TUint aBitPos); williamr@4: IMPORT_C void Negate(void); williamr@4: williamr@4: IMPORT_C TInt ConvertToLongL(void) const; williamr@4: williamr@4: IMPORT_C void CopyL(const TInteger& aInteger, TBool aAllowShrink=ETrue); williamr@4: IMPORT_C void CopyL(const TInt aInteger, TBool aAllowShrink=ETrue); williamr@4: IMPORT_C void Set(const RInteger& aInteger); williamr@4: IMPORT_C HBufC8* BufferWithNoTruncationLC() const; williamr@4: williamr@4: protected: //Interface functions to algorthims williamr@4: /** @internalComponent */ williamr@4: RInteger PositiveAddL(const TInteger& aA, const TInteger& aB) const; williamr@4: /** @internalComponent */ williamr@4: RInteger PositiveSubtractL(const TInteger& aA, const TInteger& aB) const; williamr@4: /** @internalComponent */ williamr@4: RInteger PositiveMultiplyL(const TInteger& aA, const TInteger& aB) const; williamr@4: /** @internalComponent */ williamr@4: void PositiveDivideL(RInteger& aRemainder, RInteger& aQuotient, williamr@4: const TInteger& aDividend, const TInteger& aDivisor) const; williamr@4: /** @internalComponent */ williamr@4: void DivideL(RInteger& aRemainder, RInteger& aQuotient, williamr@4: const TInteger& aDividend, const TInteger& aDivisor) const; williamr@4: /** @internalComponent */ williamr@4: void PositiveDivide(TUint& aRemainder, TInteger& aQoutient, williamr@4: const TInteger& aDividend, TUint aDivisor) const; williamr@4: /** @internalComponent */ williamr@4: void DivideL(TUint& aRemainder, RInteger& aQoutient, williamr@4: const TInteger& aDividend, TUint aDivisor) const; williamr@4: /** @internalComponent */ williamr@4: TUint Modulo(const TInteger& aDividend, TUint aDivisor) const; williamr@4: williamr@4: protected: //Utility functions williamr@4: /** @internalComponent */ williamr@4: TInt ConvertToLong(void) const; williamr@4: inline TUint ConvertToUnsignedLong(void) const {return Ptr()[0];} williamr@4: /** @internalComponent */ williamr@4: TBool IsConvertableToLong(void) const; williamr@4: /** @internalComponent */ williamr@4: void RandomizeL(TUint aBits, TRandomAttribute aAttr); williamr@4: /** @internalComponent */ williamr@4: void RandomizeL(const TInteger& aMin, const TInteger& aMax); williamr@4: /** @internalComponent */ williamr@4: void PrimeRandomizeL(TUint aBits, TRandomAttribute aAttr); williamr@4: /** @internalComponent */ williamr@4: TBool SmallPrimeRandomizeL(void); williamr@4: williamr@4: protected: //Memory Handling williamr@4: /** @internalComponent */ williamr@4: void CreateNewL(TUint aNewSize); williamr@4: /** @internalComponent */ williamr@4: void CleanNewL(TUint aNewSize); williamr@4: /** @internalComponent */ williamr@4: void CleanGrowL(TUint aNewSize); williamr@4: /** @internalComponent */ williamr@4: void CleanResizeL(TUint aNewSize); williamr@4: williamr@4: protected: //Construction functions williamr@4: IMPORT_C TInteger(void); williamr@4: /** @internalComponent */ williamr@4: void Construct(const TDesC8& aValue); williamr@4: /** @internalComponent */ williamr@4: void Construct(const TInteger& aInteger); williamr@4: /** @internalComponent */ williamr@4: void Construct(TInt aInteger); williamr@4: /** @internalComponent */ williamr@4: void Construct(TUint aInteger); williamr@4: protected: //Construction functions for stack based integers williamr@4: /** @internalComponent */ williamr@4: void ConstructStack(TUint aWords, TUint aInteger); williamr@4: /** @internalComponent */ williamr@4: void ConstructStack(TUint aWords, const TInteger& aInteger); williamr@4: williamr@4: williamr@4: protected: //Member data williamr@4: enum TSign {EPositive=0, ENegative=1}; williamr@4: TUint iSize; williamr@4: TUint iPtr; williamr@4: williamr@4: protected: //Hackish functions williamr@4: /* Memory Layout williamr@4: * Word 0: Size -- Must be power of 2 (algorithms assume this) williamr@4: * Word 1: Pointer to storage location plus 2 flag bits in lsb williamr@4: * Word 1 (bit 0): Sign of the integer (+ve == 0, -ve == 1) williamr@4: * Word 1 (bit 1): Heap based flag bit (stack== 0, heap==1) williamr@4: */ williamr@4: inline TSign Sign(void) const {return (TSign)(iPtr&KSignMask);} williamr@4: inline TUint Size(void) const {return iSize;} williamr@4: inline void SetSize(TUint aSize) {iSize = aSize;} williamr@4: inline TUint* const Ptr(void) const {return (TUint*)(iPtr&KPtrMask);} williamr@4: inline TBool IsStackBased(void) const {return !IsHeapBased();} williamr@4: inline TBool IsHeapBased(void) const {return iPtr&KHeapBasedMask;} williamr@4: inline void SetPtr(TUint* aPtr) {iPtr &= ~KPtrMask; iPtr |= (TUint)aPtr;} williamr@4: inline void SetHeapBased(void) {iPtr |= KHeapBasedMask;} williamr@4: inline void SetStackBased(void) {iPtr &= ~KHeapBasedMask;} williamr@4: inline void SetSign(TSign aSign) {iPtr &= ~KSignMask; iPtr |= (TUint)aSign;} williamr@4: williamr@4: private: williamr@4: // disable default copy constructor and assignment operator williamr@4: TInteger(const TInteger& aInteger); williamr@4: TInteger& operator=(const TInteger& aInteger); williamr@4: williamr@4: friend class CMontgomeryStructure; williamr@4: friend class RInteger; //in order to have access to Size() for an argument williamr@4: }; williamr@4: williamr@4: // Inline methods for TInteger williamr@4: williamr@4: inline TBool TInteger::operator == (const TInteger& aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) == 0; williamr@4: } williamr@4: williamr@4: inline TBool TInteger::operator != (const TInteger& aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) != 0; williamr@4: } williamr@4: williamr@4: inline TBool TInteger::operator <= (const TInteger& aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) <= 0; williamr@4: } williamr@4: williamr@4: inline TBool TInteger::operator >= (const TInteger& aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) >= 0; williamr@4: } williamr@4: williamr@4: inline TBool TInteger::operator < (const TInteger& aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) < 0; williamr@4: } williamr@4: williamr@4: TBool TInteger::operator > (const TInteger& aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) > 0; williamr@4: } williamr@4: williamr@4: inline TBool TInteger::operator == (TInt aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) == 0; williamr@4: } williamr@4: williamr@4: inline TBool TInteger::operator != (TInt aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) != 0; williamr@4: } williamr@4: williamr@4: inline TBool TInteger::operator <= (TInt aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) <= 0; williamr@4: } williamr@4: williamr@4: inline TBool TInteger::operator >= (TInt aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) >= 0; williamr@4: } williamr@4: williamr@4: inline TBool TInteger::operator < (TInt aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) < 0; williamr@4: } williamr@4: williamr@4: inline TBool TInteger::operator > (TInt aInteger) const williamr@4: { williamr@4: return SignedCompare(aInteger) > 0; williamr@4: } williamr@4: williamr@4: williamr@4: /** williamr@4: * A TInteger derived class allowing the construction of variable length big integers. williamr@4: * See the Cryptography API guide for further information. williamr@4: * williamr@4: * williamr@4: * @see TInteger williamr@4: */ williamr@4: class RInteger : public TInteger williamr@4: { williamr@4: public: williamr@4: IMPORT_C static RInteger NewL(void); williamr@4: IMPORT_C static RInteger NewL(const TDesC8& aValue); williamr@4: IMPORT_C static RInteger NewL(const TInteger& aInteger); williamr@4: IMPORT_C static RInteger NewL(TInt aInteger); williamr@4: IMPORT_C static RInteger NewL(TUint aInteger); williamr@4: IMPORT_C static RInteger NewEmptyL(TUint aNumWords); williamr@4: williamr@4: IMPORT_C static RInteger NewRandomL(TUint aBits, williamr@4: TRandomAttribute aAttr=EAllBitsRandom); williamr@4: IMPORT_C static RInteger NewRandomL(const TInteger& aMin, williamr@4: const TInteger& aMax); williamr@4: IMPORT_C static RInteger NewPrimeL(TUint aBits, williamr@4: TRandomAttribute aAttr=EAllBitsRandom); williamr@4: williamr@4: IMPORT_C RInteger(void); williamr@4: IMPORT_C RInteger(const RInteger& aInteger); williamr@4: IMPORT_C RInteger& operator=(const RInteger& aInteger); williamr@4: williamr@4: IMPORT_C operator TCleanupItem(); williamr@4: IMPORT_C static void CallClose(TAny* aPtr); williamr@4: IMPORT_C void Close(void); williamr@4: }; williamr@4: williamr@4: #endif // __BIGINT_H__