os/security/crypto/weakcryptospi/source/bigint/bigint.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2003-2010 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     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".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 *
    16 */
    17 
    18 
    19 #include <random.h>
    20 #include <bigint.h>
    21 #include <e32std.h>
    22 #include <euserext.h>
    23 #include <securityerr.h>
    24 #include "words.h"
    25 #include "algorithms.h"
    26 #include "windowslider.h"
    27 #include "stackinteger.h"
    28 #include "mont.h"
    29 
    30 
    31 /**
    32 * Creates a new buffer containing the big-endian binary representation of this
    33 * integer.
    34 *
    35 * Note that it does not support the exporting of negative integers.
    36 *
    37 * @return	The new buffer.
    38 * 
    39 * @leave KErrNegativeExportNotSupported	If this instance is a negative integer.
    40 *
    41 */
    42 EXPORT_C HBufC8* TInteger::BufferLC() const
    43 	{
    44 	if(IsNegative())
    45 		{
    46 		User::Leave(KErrNegativeExportNotSupported);
    47 		}
    48 	TUint bytes = ByteCount();
    49 	HBufC8* buf = HBufC8::NewMaxLC(bytes);
    50 	TUint8* bufPtr = (TUint8*)(buf->Ptr());
    51 	TUint8* regPtr = (TUint8*)Ptr();
    52 
    53 	// we internally store the number little endian, as a string we want it big
    54 	// endian
    55 	for(TUint i=0,j=bytes-1; i<bytes; )
    56 		{
    57 		bufPtr[i++] = regPtr[j--];
    58 		}
    59 	return buf;
    60 	}
    61 
    62 EXPORT_C HBufC8* TInteger::BufferWithNoTruncationLC() const
    63  	{
    64  	if(IsNegative())
    65  		{
    66  		User::Leave(KErrNegativeExportNotSupported);
    67  		}
    68  	
    69  	TUint wordCount = Size();
    70  	TUint bytes = (wordCount)*WORD_SIZE;
    71      
    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; )
    76  		{
    77  		bufPtr[i++] = regPtr[j--];
    78  		}
    79   
    80 	return buf;
    81 	}
    82 
    83 /** 
    84 * Gets the number of words required to represent this RInteger.
    85 * 
    86 * @return	The size of the integer in words.
    87 *
    88 */
    89 EXPORT_C TUint TInteger::WordCount() const
    90 	{
    91 	return CountWords(Ptr(), Size());
    92 	}
    93 
    94 /**
    95 * Gets the number of bytes required to represent this RInteger.
    96 * 
    97 * @return	The size of the integer in bytes.
    98 * 
    99 */
   100 EXPORT_C TUint TInteger::ByteCount() const
   101 	{
   102 	TUint wordCount = WordCount();
   103 	if(wordCount)
   104 		{
   105 		return (wordCount-1)*WORD_SIZE + BytePrecision((Ptr())[wordCount-1]);
   106 		}
   107 	else 
   108 		{
   109 		return 0;
   110 		}
   111 	}
   112 
   113 /** 
   114 * Get the number of bits required to represent this RInteger.
   115 * 
   116 * @return	The size of the integer in bits.
   117 * 
   118 */
   119 EXPORT_C TUint TInteger::BitCount() const
   120 	{
   121 	TUint wordCount = WordCount();
   122 	if(wordCount)
   123 		{
   124 		return (wordCount-1)*WORD_BITS + BitPrecision(Ptr()[wordCount-1]);
   125 		}
   126 	else 
   127 		{
   128 		return 0;
   129 		}
   130 	}
   131 
   132 
   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
   136 //modify the ROM ;)
   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};
   146 
   147 /** 
   148  * Gets the TInteger that represents zero
   149  *
   150  * @return	The TInteger representing zero
   151  */
   152 EXPORT_C const TInteger& TInteger::Zero(void)
   153 	{
   154 	return *reinterpret_cast<const TStackInteger64*>(KBigintZero);
   155 	}
   156 
   157 /** 
   158  * Gets the TInteger that represents one
   159  *
   160  * @return	The TInteger representing one
   161  */
   162 EXPORT_C const TInteger& TInteger::One(void)
   163 	{
   164 	return *reinterpret_cast<const TStackInteger64*>(KBigintOne);
   165 	}
   166 	
   167 /** 
   168  * Gets the TInteger that represents two
   169  *
   170  * @return	The TInteger representing two
   171  */
   172 EXPORT_C const TInteger& TInteger::Two(void)
   173 	{
   174 	return *reinterpret_cast<const TStackInteger64*>(KBigintTwo);
   175 	}
   176 
   177 EXPORT_C RInteger TInteger::PlusL(const TInteger& aOperand) const
   178 	{
   179 	RInteger sum;
   180     if (NotNegative())
   181 		{
   182         if (aOperand.NotNegative())
   183             sum = PositiveAddL(*this, aOperand);
   184         else
   185             sum = PositiveSubtractL(*this, aOperand);
   186 		}
   187     else
   188 		{
   189         if (aOperand.NotNegative())
   190             sum = PositiveSubtractL(aOperand, *this);
   191         else
   192 			{
   193             sum = PositiveAddL(*this, aOperand);
   194 			sum.SetSign(TInteger::ENegative);
   195 			}
   196 		}
   197 	return sum;
   198 	}
   199 
   200 EXPORT_C RInteger TInteger::MinusL(const TInteger& aOperand) const
   201 	{
   202 	RInteger diff;
   203     if (NotNegative())
   204 		{
   205         if (aOperand.NotNegative())
   206             diff = PositiveSubtractL(*this, aOperand);
   207         else
   208             diff = PositiveAddL(*this, aOperand);
   209 		}
   210     else
   211 		{
   212         if (aOperand.NotNegative())
   213 			{
   214             diff = PositiveAddL(*this, aOperand);
   215 			diff.SetSign(TInteger::ENegative);
   216 			}
   217         else
   218             diff = PositiveSubtractL(aOperand, *this);
   219 		}
   220 	return diff;
   221 	}
   222 
   223 EXPORT_C RInteger TInteger::TimesL(const TInteger& aOperand) const
   224 	{
   225 	RInteger product = PositiveMultiplyL(*this, aOperand);
   226 
   227 	if (NotNegative() != aOperand.NotNegative())
   228 		{
   229 		product.Negate();
   230 		}
   231 	return product;
   232 	}
   233 
   234 EXPORT_C RInteger TInteger::DividedByL(const TInteger& aOperand) const
   235 	{
   236 	RInteger quotient;
   237 	RInteger remainder;
   238 	DivideL(remainder, quotient, *this, aOperand);
   239 	remainder.Close();
   240 	return quotient;
   241 	}
   242 
   243 EXPORT_C RInteger TInteger::ModuloL(const TInteger& aOperand) const
   244 	{
   245 	RInteger remainder;
   246 	RInteger quotient;
   247 	DivideL(remainder, quotient, *this, aOperand);
   248 	quotient.Close();
   249 	return remainder;
   250 	}
   251 
   252 EXPORT_C TUint TInteger::ModuloL(TUint aOperand) const
   253 	{
   254 	if(!aOperand)
   255 		{
   256 		User::Leave(KErrDivideByZero);
   257 		}
   258 	return Modulo(*this, aOperand);
   259 	}
   260 
   261 EXPORT_C RInteger TInteger::ModularMultiplyL(const TInteger& aA, const TInteger& aB,
   262 	const TInteger& aMod) 
   263 	{
   264 	RInteger product = aA.TimesL(aB);
   265 	CleanupStack::PushL(product);
   266 	RInteger reduced = product.ModuloL(aMod);
   267 	CleanupStack::PopAndDestroy(&product); 
   268 	return reduced;
   269 	}
   270 
   271 EXPORT_C RInteger TInteger::ModularExponentiateL(const TInteger& aBase, 
   272 	const TInteger& aExp, const TInteger& aMod) 
   273 	{
   274 	CMontgomeryStructure* mont = CMontgomeryStructure::NewLC(aMod);
   275 	RInteger result = RInteger::NewL(mont->ExponentiateL(aBase, aExp));
   276 	CleanupStack::PopAndDestroy(mont);
   277 	return result;
   278 	}
   279 
   280 EXPORT_C RInteger TInteger::GCDL(const TInteger& aOperand) const
   281 	{
   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());
   287 
   288 	RInteger x = RInteger::NewL(*this);
   289 	CleanupStack::PushL(x);
   290 	RInteger y = RInteger::NewL(aOperand);
   291 	CleanupStack::PushL(y);
   292 
   293 	// 1 Ensure x >= y
   294 	if( x < y )
   295 		{
   296 		TClassSwap(x, y);
   297 		}
   298 
   299 	TUint g = 0;
   300 	// 2 while x and y even x <- x/2, y <- y/2
   301 	while( x.IsEven() && y.IsEven() )
   302 		{
   303 		x >>= 1;
   304 		y >>= 1;
   305 		++g;
   306 		}
   307 	// 3 while x != 0
   308 	while( x.NotZero() )
   309 		{
   310 		// 3.1 while x even x <- x/2
   311 		while( x.IsEven() )
   312 			{
   313 			x >>= 1;
   314 			}
   315 		// 3.2 while y even y <- y/2
   316 		while( y.IsEven() )
   317 			{
   318 			y >>= 1;
   319 			}
   320 		// 3.3 t <- abs(x-y)/2
   321 		RInteger t = x.MinusL(y);
   322 		t >>= 1;
   323 		t.SetSign(TInteger::EPositive);
   324 
   325 		// 3.4 If x>=y then x <- t else y <- t
   326 		if( x >= y )
   327 			{
   328 			x.Set(t);
   329 			}
   330 		else 
   331 			{
   332 			y.Set(t);
   333 			}
   334 		}
   335 	
   336 	// 4 Return (g*y) (equiv to y<<=g as our g was counting shifts not actually
   337 	//shifting)
   338 	y <<= g;
   339 	CleanupStack::Pop(&y);
   340 	CleanupStack::PopAndDestroy(&x); 
   341 	return y;
   342 	}
   343 
   344 EXPORT_C RInteger TInteger::InverseModL(const TInteger& aMod) const
   345 	{
   346 	assert(aMod.NotNegative());
   347 
   348 	RInteger result;
   349 	if(IsNegative() || *this>=aMod)
   350 		{
   351 		RInteger temp = ModuloL(aMod);
   352 		CleanupClosePushL(temp);
   353 		result = temp.InverseModL(aMod);
   354 		CleanupStack::PopAndDestroy(&temp);
   355 		return result;
   356 		}
   357 
   358 	if(aMod.IsEven())
   359 		{
   360 		if( !aMod || IsEven() )
   361 			{
   362 			return RInteger::NewL(Zero());
   363 			}
   364 		if( *this == One() )
   365 			{
   366 			return RInteger::NewL(One());
   367 			}
   368 		RInteger u = aMod.InverseModL(*this); 
   369 		CleanupClosePushL(u);
   370 		if(!u)
   371 			{
   372 			result = RInteger::NewL(Zero());
   373 			}
   374 		else 
   375 			{
   376 			//calculates (aMod*(*this-u)+1)/(*this) 
   377 			result = MinusL(u);
   378 			CleanupClosePushL(result);
   379 			result *= aMod;
   380 			++result;
   381 			result /= *this;
   382 			CleanupStack::Pop(&result); 
   383 			}
   384 		CleanupStack::PopAndDestroy(&u);
   385 		return result;
   386 		}
   387 
   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());
   394 	workspace.Close();
   395 	CleanupStack::Pop(&result);
   396 
   397 	return result;
   398 	}
   399 
   400 EXPORT_C TInteger& TInteger::operator+=(const TInteger& aOperand)
   401 	{
   402 	this->Set(PlusL(aOperand));
   403     return *this;
   404 	}
   405 
   406 EXPORT_C TInteger& TInteger::operator-=(const TInteger& aOperand)
   407 	{
   408 	this->Set(MinusL(aOperand));
   409     return *this;
   410 	}
   411 
   412 EXPORT_C TInteger& TInteger::operator*=(const TInteger& aOperand)
   413 	{
   414 	this->Set(TimesL(aOperand));
   415 	return *this;
   416 	}
   417 
   418 EXPORT_C TInteger& TInteger::operator/=(const TInteger& aOperand)
   419 	{
   420 	this->Set(DividedByL(aOperand));
   421 	return *this;
   422 	}
   423 
   424 EXPORT_C TInteger& TInteger::operator%=(const TInteger& aOperand)
   425 	{
   426 	this->Set(ModuloL(aOperand));
   427 	return *this;
   428 	}
   429 
   430 EXPORT_C TInteger& TInteger::operator+=(TInt aOperand)
   431 	{
   432 	TStackInteger64 operand(aOperand);
   433 	*this += operand;
   434 	return *this;
   435 	}
   436 
   437 EXPORT_C TInteger& TInteger::operator-=(TInt aOperand)
   438 	{
   439 	TStackInteger64 operand(aOperand);
   440 	*this -= operand;
   441 	return *this;
   442 	}
   443 
   444 EXPORT_C TInteger& TInteger::operator*=(TInt aOperand)
   445 	{
   446 	TStackInteger64 operand(aOperand);
   447 	*this *= operand;
   448 	return *this;
   449 	}
   450 
   451 EXPORT_C TInteger& TInteger::operator--()
   452 	{
   453     if (IsNegative())
   454 		{
   455         if (Increment(Ptr(), Size()))
   456 			{
   457             CleanGrowL(2*Size());
   458             (Ptr())[Size()/2]=1;
   459 			}
   460 		}
   461     else
   462 		{
   463         if (Decrement(Ptr(), Size()))
   464 			{
   465 			this->CopyL(-1);
   466 			}
   467 		}
   468     return *this;	
   469 	}
   470 
   471 EXPORT_C TInteger& TInteger::operator++()
   472 	{
   473 	if(NotNegative())
   474 		{
   475 		if(Increment(Ptr(), Size()))
   476 			{
   477 			CleanGrowL(2*Size());
   478 			(Ptr())[Size()/2]=1;
   479 			}
   480 		}
   481 	else
   482 		{
   483 		DecrementNoCarry(Ptr(), Size());
   484 		if(WordCount()==0)
   485 			{
   486 			this->CopyL(Zero());
   487 			}
   488 		}
   489 	return *this;
   490 	}
   491 
   492 EXPORT_C TInteger& TInteger::operator <<=(TUint aBits)
   493 	{
   494 	const TUint wordCount = WordCount();
   495 	const TUint shiftWords = aBits / WORD_BITS;
   496 	const TUint shiftBits = aBits % WORD_BITS;
   497 
   498 	CleanGrowL(wordCount+BitsToWords(aBits));
   499 	ShiftWordsLeftByWords(Ptr(), wordCount + shiftWords, shiftWords);
   500 	ShiftWordsLeftByBits(Ptr()+shiftWords, wordCount + BitsToWords(shiftBits), 
   501 		shiftBits);
   502 	return *this;
   503 	}
   504 
   505 EXPORT_C TInteger& TInteger::operator >>=(TUint aBits)
   506 	{
   507 	const TUint wordCount = WordCount();
   508 	const TUint shiftWords = aBits / WORD_BITS;
   509 	const TUint shiftBits = aBits % WORD_BITS;
   510 
   511 	ShiftWordsRightByWords(Ptr(), wordCount, shiftWords);
   512 	if(wordCount > shiftWords)
   513 		{
   514 		ShiftWordsRightByBits(Ptr(), wordCount - shiftWords, shiftBits);
   515 		}
   516 	if(IsNegative() && WordCount()==0) // avoid negative 0
   517 		{
   518 		SetSign(EPositive);
   519 		}
   520 	return *this;
   521 	}
   522 
   523 EXPORT_C TInt TInteger::UnsignedCompare(const TInteger& aThat) const
   524 	{
   525 	TUint size = WordCount();
   526 	TUint thatSize = aThat.WordCount();
   527 
   528 	if( size == thatSize )
   529 		return Compare(Ptr(), aThat.Ptr(), size);
   530 	else
   531 		return size > thatSize ? 1 : -1;
   532 	}
   533 
   534 EXPORT_C TInt TInteger::SignedCompare(const TInteger& aThat) const
   535 	{
   536     if (NotNegative())
   537 		{
   538         if (aThat.NotNegative())
   539             return UnsignedCompare(aThat);
   540         else
   541             return 1;
   542 		}
   543     else
   544 		{
   545         if (aThat.NotNegative())
   546             return -1;
   547         else
   548             return -UnsignedCompare(aThat);
   549 		}
   550 	}
   551 
   552 EXPORT_C TBool TInteger::operator!() const
   553 	{
   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);
   558 	}
   559 
   560 EXPORT_C TInt TInteger::SignedCompare(TInt aInteger) const
   561 	{
   562 	TStackInteger64 temp(aInteger);
   563 	return SignedCompare(temp);
   564 	}
   565 
   566 /* TBool IsPrimeL(void) const 
   567  * and all primality related functions are implemented in primes.cpp */
   568 
   569 EXPORT_C TBool TInteger::Bit(TUint aBitPos) const
   570 	{
   571 	if( aBitPos/WORD_BITS >= Size() )
   572 		{
   573 		return 0;
   574 		}
   575 	else 
   576 		{
   577 		return (((Ptr())[aBitPos/WORD_BITS] >> (aBitPos % WORD_BITS)) & 1);
   578 		}
   579 	}
   580 
   581 EXPORT_C void TInteger::SetBit(TUint aBitPos) 
   582 	{
   583 	if( aBitPos/WORD_BITS < Size() )
   584 		{
   585 		ArraySetBit(Ptr(), aBitPos);
   586 		}
   587 	}
   588 
   589 EXPORT_C void TInteger::Negate() 
   590 	{
   591 	if(!!(*this)) //don't flip sign if *this==0
   592 		{
   593 		SetSign(TSign((~Sign())&KSignMask));
   594 		}
   595 	}
   596 
   597 EXPORT_C void TInteger::CopyL(const TInteger& aInteger, TBool aAllowShrink)
   598 	{
   599 	if(aAllowShrink)
   600 		{
   601 		CleanResizeL(aInteger.Size());
   602 		}
   603 	else
   604 		{
   605 		CleanGrowL(aInteger.Size());
   606 		}
   607 	Construct(aInteger);
   608 	}
   609 
   610 EXPORT_C void TInteger::CopyL(TInt aInteger, TBool aAllowShrink)
   611 	{
   612 	if(aAllowShrink)
   613 		{
   614 		CleanResizeL(2);
   615 		}
   616 	else
   617 		{
   618 		CleanGrowL(2);
   619 		}
   620 	Construct(aInteger);
   621 	}
   622 
   623 EXPORT_C void TInteger::Set(const RInteger& aInteger)
   624 	{
   625 	assert(IsHeapBased());
   626 	Mem::FillZ(Ptr(), WordsToBytes(Size()));
   627 	User::Free(Ptr());
   628 	iPtr = aInteger.iPtr;
   629 	iSize = aInteger.iSize;
   630 	}
   631 
   632 RInteger TInteger::PositiveAddL(const TInteger &aA, const TInteger& aB) const
   633 	{
   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();
   640 
   641 	word carry;
   642 	if (aSize == bSize)
   643 		carry = Add(sumReg, aReg, bReg, aSize);
   644 	else if (aSize > bSize)
   645 		{
   646 		carry = Add(sumReg, aReg, bReg, bSize);
   647 		CopyWords(sumReg+bSize, aReg+bSize, aSize-bSize);
   648 		carry = Increment(sumReg+bSize, aSize-bSize, carry);
   649 		}
   650 	else
   651 		{
   652 		carry = Add(sumReg, aReg, bReg, aSize);
   653 		CopyWords(sumReg+aSize, bReg+aSize, bSize-aSize);
   654 		carry = Increment(sumReg+aSize, bSize-aSize, carry);
   655 		}
   656 
   657 	if (carry)
   658 		{
   659 		CleanupStack::PushL(sum);
   660 		sum.CleanGrowL(2*sum.Size());
   661 		CleanupStack::Pop(&sum);
   662 		sum.Ptr()[sum.Size()/2] = 1;
   663 		}
   664 	sum.SetSign(TInteger::EPositive);
   665 	return sum;
   666 	}
   667 
   668 RInteger TInteger::PositiveSubtractL(const TInteger &aA, const TInteger& aB) const
   669 	{
   670 	RInteger diff = RInteger::NewEmptyL(CryptoMax(aA.Size(), aB.Size()));
   671 	unsigned aSize = aA.WordCount();
   672 	aSize += aSize%2;
   673 	unsigned bSize = aB.WordCount();
   674 	bSize += bSize%2;
   675 	const word* const aReg = aA.Ptr();
   676 	const word* const bReg = aB.Ptr();
   677 	word* const diffReg = diff.Ptr();
   678 
   679 	if (aSize == bSize)
   680 		{
   681 		if (Compare(aReg, bReg, aSize) >= 0)
   682 			{
   683 			Subtract(diffReg, aReg, bReg, aSize);
   684 			diff.SetSign(TInteger::EPositive);
   685 			}
   686 		else
   687 			{
   688 			Subtract(diffReg, bReg, aReg, aSize);
   689 			diff.SetSign(TInteger::ENegative);
   690 			}
   691 		}
   692 	else if (aSize > bSize)
   693 		{
   694 		word borrow = Subtract(diffReg, aReg, bReg, bSize);
   695 		CopyWords(diffReg+bSize, aReg+bSize, aSize-bSize);
   696 		borrow = Decrement(diffReg+bSize, aSize-bSize, borrow);
   697 		assert(!borrow);
   698 		diff.SetSign(TInteger::EPositive);
   699 		}
   700 	else
   701 		{
   702 		word borrow = Subtract(diffReg, bReg, aReg, aSize);
   703 		CopyWords(diffReg+aSize, bReg+aSize, bSize-aSize);
   704 		borrow = Decrement(diffReg+aSize, bSize-aSize, borrow);
   705 		assert(!borrow);
   706 		diff.SetSign(TInteger::ENegative);
   707 		}
   708 	return diff;
   709 	}
   710 
   711 RInteger TInteger::PositiveMultiplyL(const TInteger &aA, const TInteger &aB) const
   712 	{
   713 	unsigned aSize = RoundupSize(aA.WordCount());
   714 	unsigned bSize = RoundupSize(aB.WordCount());
   715 
   716 	RInteger product = RInteger::NewEmptyL(aSize+bSize);
   717 	CleanupClosePushL(product);
   718 
   719 	RInteger workspace = RInteger::NewEmptyL(aSize + bSize);
   720 	AsymmetricMultiply(product.Ptr(), workspace.Ptr(), aA.Ptr(), aSize, aB.Ptr(), 
   721 		bSize);
   722 	workspace.Close();
   723 	CleanupStack::Pop(&product);
   724 	return product;
   725 	}
   726 
   727 TUint TInteger::Modulo(const TInteger& aDividend, TUint aDivisor) const
   728 	{
   729 	assert(aDivisor);
   730 	TUint i = aDividend.WordCount();
   731 	TUint remainder = 0;
   732 	while(i--)
   733 		{
   734 		remainder = TUint(MAKE_DWORD(aDividend.Ptr()[i], remainder) % aDivisor);
   735 		}
   736 	return remainder;
   737 	}
   738 
   739 void TInteger::PositiveDivideL(RInteger &aRemainder, RInteger &aQuotient,
   740 	const TInteger &aDividend, const TInteger &aDivisor) const
   741 	{
   742 	unsigned dividendSize = aDividend.WordCount();
   743 	unsigned divisorSize = aDivisor.WordCount();
   744 
   745 	if (!divisorSize)
   746 		{
   747 		User::Leave(KErrDivideByZero);
   748 		}
   749 
   750 	if (aDividend.UnsignedCompare(aDivisor) == -1)
   751 		{
   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);
   758 		return;
   759 		}
   760 
   761 	dividendSize += dividendSize%2;	// round up to next even number
   762 	divisorSize += divisorSize%2;
   763 
   764 	aRemainder.CleanNewL(divisorSize);
   765 	CleanupStack::PushL(aRemainder);
   766 	aQuotient.CleanNewL(dividendSize-divisorSize+2);
   767 	CleanupStack::PushL(aQuotient);
   768 
   769 	RInteger T = RInteger::NewEmptyL(dividendSize+2*divisorSize+4);
   770 	Divide(aRemainder.Ptr(), aQuotient.Ptr(), T.Ptr(), aDividend.Ptr(), 
   771 		dividendSize, aDivisor.Ptr(), divisorSize);
   772 	T.Close();
   773 	CleanupStack::Pop(2, &aRemainder); //aQuotient, aRemainder
   774 	}
   775 
   776 void TInteger::DivideL(RInteger& aRemainder, RInteger& aQuotient, 
   777 	const TInteger& aDividend, const TInteger& aDivisor) const
   778     {
   779     PositiveDivideL(aRemainder, aQuotient, aDividend, aDivisor);
   780 
   781     if (aDividend.IsNegative())
   782         {
   783         aQuotient.Negate();
   784         if (aRemainder.NotZero())
   785             {
   786             --aQuotient;
   787 			assert(aRemainder.Size() <= aDivisor.Size());
   788 			Subtract(aRemainder.Ptr(), aDivisor.Ptr(), aRemainder.Ptr(), 
   789 				aRemainder.Size());
   790             }
   791         }
   792 
   793     if (aDivisor.IsNegative())
   794         aQuotient.Negate();
   795     }
   796 
   797 void TInteger::RandomizeL(TUint aBits, TRandomAttribute aAttr)
   798 	{
   799 	if(!aBits)
   800 		{
   801 		return;
   802 		}
   803 	const TUint bytes = BitsToBytes(aBits);
   804 	const TUint words = BitsToWords(aBits);
   805 	CleanGrowL(words);
   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))
   810 	    User::Leave(err);
   811 	//mask with 0 all bits above the num requested in the most significant byte
   812 	if(bitpos)
   813 		{
   814 		buf[bytes-1] = TUint8( buf[bytes-1] & ((1L << bitpos) - 1) );
   815 		}
   816 	//set most significant (top) bit 
   817 	if(aAttr == ETopBitSet || aAttr == ETop2BitsSet)
   818 		{
   819 		SetBit(aBits-1); //Set bit counts from 0
   820 		assert(BitCount() == aBits);
   821 		assert(Bit(aBits-1));
   822 		}
   823 	//set 2nd bit from top
   824 	if(aAttr == ETop2BitsSet)
   825 		{
   826 		SetBit(aBits-2); //Set bit counts from 0
   827 		assert(BitCount() == aBits);
   828 		assert(Bit(aBits-1));
   829 		assert(Bit(aBits-2));
   830 		}
   831 	}
   832 
   833 void TInteger::RandomizeL(const TInteger& aMin, const TInteger& aMax)
   834 	{
   835 	assert(aMax > aMin);
   836 	assert(aMin.NotNegative());
   837 	RInteger range = RInteger::NewL(aMax);
   838 	CleanupStack::PushL(range);
   839 	range -= aMin;
   840 	const TUint bits = range.BitCount();
   841 
   842 	//if we find a number < range then aMin+range < aMax 
   843 	do
   844 		{
   845 		RandomizeL(bits, EAllBitsRandom);
   846 		} 
   847 	while(*this > range);
   848 
   849 	*this += aMin;
   850 	CleanupStack::PopAndDestroy(&range);
   851 	}
   852 
   853 /* void PrimeRandomizeL(TUint aBits, TRandomAttribute aAttr)
   854  * and all primality related functions are implemented in primes.cpp */
   855 
   856 void TInteger::CreateNewL(TUint aNewSize)
   857 	{
   858 	//should only be called on construction
   859 	assert(!iPtr);
   860 	
   861 	TUint newSize = RoundupSize(aNewSize);
   862 	SetPtr((TUint*)User::AllocL(WordsToBytes(newSize)));
   863 	SetSize(newSize);
   864 	SetHeapBased();
   865 	}
   866 
   867 void TInteger::CleanNewL(TUint aNewSize)
   868 	{
   869 	CreateNewL(aNewSize);
   870 	Mem::FillZ(Ptr(), WordsToBytes(Size())); //clear integer storage
   871 	}
   872 
   873 void TInteger::CleanGrowL(TUint aNewSize)
   874 	{
   875 	assert(IsHeapBased());
   876 	TUint newSize = RoundupSize(aNewSize);
   877 	TUint oldSize = Size();
   878 	if(newSize > oldSize)
   879 		{
   880 		TUint* oldPtr = Ptr();
   881 		//1) allocate new memory and set ptr and size
   882 		SetPtr((TUint*)User::AllocL(WordsToBytes(newSize)));
   883 		SetSize(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
   889 		User::Free(oldPtr);
   890 		//5) zero new memory from end of copy to end of growth
   891 		Mem::FillZ(Ptr() + oldSize, WordsToBytes(newSize-oldSize));
   892 		}
   893 	}
   894 
   895 void TInteger::CleanResizeL(TUint aNewSize)
   896 	{
   897 	assert(IsHeapBased());
   898 	TUint newSize = RoundupSize(aNewSize);
   899 	TUint oldSize = Size();
   900 	if(newSize > oldSize)
   901 		{
   902 		CleanGrowL(aNewSize);
   903 		}
   904 	else if(newSize < oldSize)
   905 		{
   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)));
   913 		SetSize(newSize);
   914 		}
   915 	}
   916 
   917 EXPORT_C TInteger::TInteger() : iSize(0), iPtr(0)
   918 	{
   919 	}
   920 
   921 void TInteger::Construct(const TDesC8& aValue)
   922 	{
   923 	assert(Size() >= BytesToWords(aValue.Size()));
   924 	if(aValue.Size() > 0)
   925 		{
   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.
   929 
   930 		TUint bytes = aValue.Size();
   931 		TUint8* i = (TUint8*)Ptr();
   932 		TUint8* j = (TUint8*)aValue.Ptr() + bytes;
   933 
   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() )
   938 			{
   939 			*i++ = *--j;
   940 			}
   941 		Mem::FillZ((TUint8*)Ptr() + bytes, WordsToBytes(Size()) - bytes);
   942 		}
   943 	else
   944 		{
   945 		//if size is zero, we zero the whole register
   946 		Mem::FillZ((TUint8*)Ptr(), WordsToBytes(Size()));
   947 		}
   948 	SetSign(EPositive);
   949 	}
   950 
   951 void TInteger::Construct(const TInteger& aInteger)
   952 	{
   953 	assert(Size() >= aInteger.Size());
   954 	CopyWords(Ptr(), aInteger.Ptr(), aInteger.Size());
   955 	if(Size() > aInteger.Size())
   956 		{
   957 		Mem::FillZ(Ptr()+aInteger.Size(), WordsToBytes(Size()-aInteger.Size()));
   958 		}
   959 	SetSign(aInteger.Sign());
   960 	}
   961 
   962 void TInteger::Construct(TInt aInteger)
   963 	{
   964 	Construct((TUint)aInteger);
   965 	if(aInteger < 0)
   966 		{
   967 		SetSign(ENegative);
   968 		Ptr()[0] = -aInteger;
   969 		}
   970 	}
   971 
   972 void TInteger::Construct(TUint aInteger)
   973 	{
   974 	assert(Size() >= 2);
   975 	SetSign(EPositive);
   976 	Ptr()[0] = aInteger;
   977 	Mem::FillZ(Ptr()+1, WordsToBytes(Size()-1));
   978 	}
   979 
   980 void TInteger::ConstructStack(TUint aWords, TUint aInteger)
   981 	{
   982 	SetPtr((TUint*)(this)+2);
   983 	//SetStackBased(); //Not strictly needed as stackbased is a 0 at bit 1
   984 	SetSize(aWords);
   985 	assert(Size() >= 2);
   986 	Ptr()[0] = aInteger;
   987 	Mem::FillZ(&(Ptr()[1]), WordsToBytes(Size()-1));
   988 	}
   989 
   990 void TInteger::ConstructStack(TUint aWords, const TInteger& aInteger)
   991 	{
   992 	SetPtr((TUint*)(this)+2);
   993 	//SetStackBased(); //Not strictly needed as stackbased is a 0 at bit 1
   994 	SetSize(aWords);
   995 	assert( Size() >= RoundupSize(aInteger.WordCount()) );
   996 	CopyWords(Ptr(), aInteger.Ptr(), aInteger.Size());
   997 	Mem::FillZ(Ptr()+aInteger.Size(), WordsToBytes(Size()-aInteger.Size()));
   998 	}
   999 
  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
  1006 #endif
  1007 
  1008 EXPORT_C TInteger& TInteger::operator/=(TInt aOperand)
  1009 	{
  1010 	TStackInteger64 operand(aOperand);
  1011 	*this /= operand;
  1012 	return *this;
  1013 	}
  1014 
  1015 EXPORT_C TInteger& TInteger::operator%=(TInt aOperand)
  1016 	{
  1017 	TStackInteger64 operand(aOperand);
  1018 	assert(operand.NotNegative());
  1019 	*this %= operand;
  1020 	return *this;
  1021 	}
  1022 
  1023 EXPORT_C TInt TInteger::ConvertToLongL(void) const
  1024 	{
  1025 	if(!IsConvertableToLong())
  1026 		{
  1027 		User::Leave(KErrTotalLossOfPrecision);
  1028 		}
  1029 	return ConvertToLong();
  1030 	}
  1031 
  1032 TInt TInteger::ConvertToLong(void) const
  1033 	{
  1034 	TUint value = ConvertToUnsignedLong();
  1035 	return Sign() == EPositive ? value : -(static_cast<TInt>(value));
  1036 	}
  1037 
  1038 TBool TInteger::IsConvertableToLong(void) const
  1039 	{
  1040 	if(WordCount() > 1)
  1041 		{
  1042 		return EFalse;
  1043 		}
  1044 	TUint value = (Ptr())[0];
  1045 	if(Sign() == EPositive)
  1046 		{
  1047 		return static_cast<TInt>(value) >= 0;
  1048 		}
  1049 	else
  1050 		{
  1051 		return -(static_cast<TInt>(value)) < 0;
  1052 		}
  1053 	}
  1054 
  1055 EXPORT_C RInteger TInteger::SquaredL() const
  1056 	{
  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);
  1060 	}
  1061 
  1062 EXPORT_C RInteger TInteger::DividedByL(TUint aOperand) const
  1063 	{
  1064 	TUint remainder;
  1065 	RInteger quotient;
  1066 	DivideL(remainder, quotient, *this, aOperand);
  1067 	return quotient;
  1068 	}
  1069 
  1070 EXPORT_C RInteger TInteger::ExponentiateL(const TInteger& aExponent) const
  1071 	{
  1072 	//See HAC 14.85
  1073 
  1074 	// 1.1 Precomputation
  1075 	// g1 <- g
  1076 	// g2 <- g^2
  1077 	RInteger g2 = SquaredL();
  1078 	CleanupStack::PushL(g2);
  1079 	RInteger g1 = RInteger::NewL(*this);
  1080 	CleanupStack::PushL(g1);
  1081 	TWindowSlider slider(aExponent);
  1082 
  1083 	// 1.2 
  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++)
  1091 		{
  1092 		RInteger g2iplus1 = g2.TimesL(powerArray[k-1]);
  1093 		powerArray.AppendL(g2iplus1);
  1094 		}
  1095 
  1096 	// 2 A <- 1, i <- t
  1097 	RInteger A = RInteger::NewL(One());
  1098 	CleanupStack::PushL(A);
  1099 	TInt i = aExponent.BitCount() - 1;
  1100 
  1101 	// 3 While i>=0 do:
  1102 	while( i>=0 )
  1103 		{
  1104 		// 3.1 If ei == 0 then A <- A^2
  1105 		if(!aExponent.Bit(i))
  1106 			{
  1107 			A *= A;
  1108 			i--;
  1109 			}
  1110 		// 3.2 Find longest bitstring ei,ei-1,...,el s.t. i-l+1<=k and el==1
  1111 		// and do:
  1112 		// A <- (A^2^(i-l+1)) * g[the index indicated by the bitstring value]
  1113 		else
  1114 			{
  1115 			slider.FindNextWindow(i);
  1116 			assert(slider.Length() >= 1);
  1117 			for(TUint j=0; j<slider.Length(); j++)
  1118 				{
  1119 				A *= A;
  1120 				}
  1121 			A *= powerArray[slider.Value()>>1];
  1122 			i -= slider.Length();
  1123 			}
  1124 		}
  1125 	CleanupStack::Pop(&A);
  1126 	CleanupStack::PopAndDestroy(2, &g2); //powerArray, g2
  1127 	return A;
  1128 	}
  1129 
  1130 void TInteger::DivideL(TUint& aRemainder, RInteger& aQuotient,
  1131 	const TInteger& aDividend, TUint aDivisor) const
  1132 	{
  1133 	if(!aDivisor)
  1134 		{
  1135 		User::Leave(KErrDivideByZero);
  1136 		}
  1137 	
  1138 	TUint i = aDividend.WordCount();
  1139 	aQuotient.CleanNewL(RoundupSize(i));
  1140 	PositiveDivide(aRemainder, aQuotient, aDividend, aDivisor);
  1141 
  1142 	if(aDividend.NotNegative())
  1143 		{
  1144 		aQuotient.SetSign(TInteger::EPositive);
  1145 		}
  1146 	else
  1147 		{
  1148 		aQuotient.SetSign(TInteger::ENegative);
  1149 		if(aRemainder)
  1150 			{
  1151 			--aQuotient;
  1152 			aRemainder = aDivisor = aRemainder;
  1153 			}
  1154 		}
  1155 	}
  1156 
  1157 void TInteger::PositiveDivide(TUint& aRemainder, TInteger& aQuotient, 
  1158 	const TInteger& aDividend, TUint aDivisor) const
  1159 	{
  1160 	assert(aDivisor);
  1161 
  1162 	TUint i = aDividend.WordCount();
  1163 	assert(aQuotient.Size() >= RoundupSize(i));
  1164 	assert(aQuotient.Sign() == TInteger::EPositive);
  1165 	aRemainder = 0;
  1166 	while(i--)
  1167 		{
  1168 		aQuotient.Ptr()[i] = 
  1169 			TUint(MAKE_DWORD(aDividend.Ptr()[i], aRemainder) / aDivisor);
  1170 		aRemainder = 
  1171 			TUint(MAKE_DWORD(aDividend.Ptr()[i], aRemainder) % aDivisor);
  1172 		}
  1173 	}