os/security/crypto/weakcryptospi/test/tbigint/tbasicmathsfb.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * Copyright (c) 2002-2009 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 "tbasicmathsfb.h"
    20 #include "t_input.h"
    21 #include "t_output.h"
    22 #include <bigint.h>
    23 #include <random.h>
    24 
    25 CTestAction* CBasicMathsFB::NewL(RFs& aFs, CConsoleBase& aConsole, 
    26 	Output& aOut, const TTestActionSpec& aTestActionSpec)
    27 	{
    28 	CTestAction* self = CBasicMathsFB::NewLC(aFs, aConsole,
    29 		aOut, aTestActionSpec);
    30 	CleanupStack::Pop();
    31 	return self;
    32 	}
    33 
    34 CTestAction* CBasicMathsFB::NewLC(RFs& aFs, CConsoleBase& aConsole, 
    35 	Output& aOut, const TTestActionSpec& aTestActionSpec)
    36 	{
    37 	CBasicMathsFB* self = new(ELeave) CBasicMathsFB(aFs, aConsole, aOut);
    38 	CleanupStack::PushL(self);
    39 	self->ConstructL(aTestActionSpec);
    40 	return self;
    41 	}
    42 
    43 CBasicMathsFB::~CBasicMathsFB()
    44 	{
    45 	delete iBody;
    46 	}
    47 
    48 CBasicMathsFB::CBasicMathsFB(RFs& aFs, CConsoleBase& aConsole, Output& aOut)
    49 	: CTestAction(aConsole, aOut), iFs(aFs)
    50 	{
    51 	}
    52 
    53 void CBasicMathsFB::ConstructL(const TTestActionSpec& aTestActionSpec)
    54 	{
    55 	CTestAction::ConstructL(aTestActionSpec);
    56 
    57 	iBody = HBufC8::NewL(aTestActionSpec.iActionBody.Length());
    58 	iBody->Des().Copy(aTestActionSpec.iActionBody);
    59 
    60 	//HBufC8* length = Input::ParseElementHexL(*iBody, _L8("<bits>"));
    61 	TUint bits = Input::ParseIntElement(*iBody, _L8("<bits>"), _L8("</bits>"));
    62 	// the final /7 gives the number of times we have to increment by 7 to get
    63 	// to that number of bytes and hence bits.
    64 	iIterations = ((bits+7)/8)/7 + 1;
    65 	}
    66 
    67 void CBasicMathsFB::DoPerformPrerequisite(TRequestStatus& aStatus)
    68 	{
    69 	TRequestStatus* status = &aStatus;
    70 	User::RequestComplete(status, KErrNone);
    71 	iActionState = CTestAction::EAction;
    72 	}
    73 
    74 void CBasicMathsFB::DoPerformPostrequisite(TRequestStatus& aStatus)
    75 	{
    76 	TRequestStatus* status = &aStatus;
    77 	iFinished = ETrue;
    78 	User::RequestComplete(status, KErrNone);
    79 	}
    80 
    81 void CBasicMathsFB::DoReportAction(void)
    82 	{
    83 	}
    84 
    85 void CBasicMathsFB::DoCheckResult(TInt)
    86 	{
    87 	}
    88 
    89 void CBasicMathsFB::PerformAction(TRequestStatus& aStatus)
    90 	{
    91 	__UHEAP_MARK;
    92 	TRequestStatus* status = &aStatus;
    93 	iResult = ETrue;
    94 
    95 	//min max values for NewRandomLC call
    96 	RInteger min = RInteger::NewL(10);
    97 	CleanupStack::PushL(min);
    98 	RInteger max = RInteger::NewL(100);
    99 	CleanupStack::PushL(max);
   100 	
   101 	//Generate iIterations*7 byte random sequences we are using 7 as it's a generator
   102 	//mod 8.  Thus we'll cycle through every value (0-7) every 8 iterations.
   103 	//This gives us a better feeling that certain byte lengths (and thus bit
   104 	//lengths as the byte is chosen randomly) don't have errors.
   105 	for(TUint i=1; i<iIterations; i++)
   106 		{ 
   107 		HBufC8* buf = HBufC8::NewMaxLC(i*7);
   108 		TPtr8 ptr = buf->Des();
   109 		TRandom::RandomL(ptr);
   110 
   111 		//This is this iteration's random number
   112 		RInteger initial = RInteger::NewL(ptr);
   113 		CleanupStack::PushL(initial);
   114 
   115 		//get a number x | 10 < x < 100
   116 		RInteger crange = RInteger::NewRandomL(min, max);
   117 		CleanupStack::PushL(crange);
   118 		TUint range = crange.ConvertToLongL();
   119 		CleanupStack::PopAndDestroy(); //crange
   120 
   121 		AddSub(initial, range);
   122 		MulDiv(initial, range);
   123 		//GCD
   124 		CleanupStack::PopAndDestroy(); //initial
   125 		CleanupStack::PopAndDestroy();//buf
   126 		iConsole.Printf(_L("."));
   127 		}
   128 	
   129 	//Test a single iteration where the initial random number is less than a
   130 	//word so the division and modulo routines that take words rather than
   131 	//TIntegers can run.
   132 	//do
   133 		{
   134 		//This is this iteration's random number
   135 		RInteger initial = RInteger::NewRandomL(31);
   136 		CleanupStack::PushL(initial);
   137 		//get a number x | 10 < x < 100
   138 		RInteger crange = RInteger::NewRandomL(min, max);
   139 		CleanupStack::PushL(crange);
   140 		TUint range = crange.ConvertToLongL();
   141 		CleanupStack::PopAndDestroy(&crange); //crange
   142 
   143 		AddSub(initial, range);
   144 		MulDiv(initial, range);
   145 		CleanupStack::PopAndDestroy(&initial); //initial
   146 		iConsole.Printf(_L("."));
   147 		} //while (0);
   148 
   149 	CleanupStack::PopAndDestroy();//max
   150 	CleanupStack::PopAndDestroy(); //min
   151 	
   152 	MiscDivL();
   153 	
   154 	User::RequestComplete(status, KErrNone);
   155 	iActionState = CTestAction::EPostrequisite;
   156 	__UHEAP_MARK;
   157 	}
   158 
   159 void CBasicMathsFB::AddSub(const TInteger& aInitial, TUint aRange)
   160 	{
   161 	__UHEAP_MARK;
   162 	//This is the copy we are going to do stuff to
   163 	RInteger a = RInteger::NewL(aInitial);
   164 	CleanupStack::PushL(a);
   165 
   166 	// compute a*aRange using doubling
   167 	TUint j=1;
   168 	for(; j<aRange; j++)
   169 		{
   170 		a += aInitial;
   171 		}
   172 
   173 	//b = a*aRange;
   174 	RInteger b = RInteger::NewL(a);
   175 	CleanupStack::PushL(b);
   176 	//compute (a*aRange)/aRange using subtraction
   177 	for(j=1; j<aRange; j++)
   178 		{
   179 		b -= aInitial;
   180 		}
   181 	// b should be the same as the initial value
   182 	if( b != aInitial )
   183 		{
   184 		iResult = EFalse;
   185 		iOut.writeString(_L("AddSub Failure:"));
   186 		iOut.writeNewLine();
   187 		}
   188 
   189 	RInteger c = RInteger::NewL(aInitial);
   190 	CleanupStack::PushL(c);
   191 	// compute a*aRange using normal multiplication
   192 	c *= aRange;
   193 	
   194 	// c and a should now be the same
   195 	if( c != a )
   196 		{ 
   197 		iResult = EFalse;
   198 		}
   199 
   200 	RInteger d = RInteger::NewL(a);
   201 	CleanupStack::PushL(d);
   202 	//compute (a*aRange)/aRange using normal division
   203 	d /= aRange;
   204 	if( d != aInitial )
   205 		{
   206 		iResult = EFalse;
   207 		}
   208 	RInteger e = RInteger::NewL(a);
   209 	CleanupStack::PushL(e);
   210 	e %= aRange;
   211 	// (a*aRange)%aRange == 0
   212 	if( e != 0 )
   213 		{
   214 		iResult = EFalse;
   215 		}
   216 	CleanupStack::PopAndDestroy(5); //e,d,c,b,a
   217 	__UHEAP_MARKEND;
   218 	}
   219 
   220 void CBasicMathsFB::MulDiv(const TInteger& aInitial, TUint aRange)
   221 	{
   222 	__UHEAP_MARK;
   223 	//This is the copy we are going to do stuff to
   224 	RInteger a = RInteger::NewL(aInitial);
   225 	CleanupStack::PushL(a);
   226 
   227 	//compute a = aInitial^aRange using repeated multiplication
   228 	TUint j=1;
   229 	for(; j<aRange; j++)
   230 		{
   231 		a *= aInitial;
   232 		}
   233 
   234 	//b = a
   235 	RInteger b = RInteger::NewL(a);
   236 	CleanupStack::PushL(b);
   237 	//try to find aInitial by repeatedly dividing b by aInitial aRange times
   238 	for(j=1; j<aRange; j++)
   239 		{
   240 		TRAPD(res, b /= aInitial);
   241 		//the first time through aInitial is 0 so this is expected
   242 		if(res == KErrDivideByZero && aInitial.IsZero())
   243 			{
   244 			break;
   245 			}
   246 		else if(res == KErrDivideByZero && aInitial.NotZero())
   247 			{
   248 			iResult = EFalse;
   249 			}
   250 		else if(res != KErrNone)
   251 			{
   252 			User::Leave(res);
   253 			}
   254 		}
   255 	// b should be the same as the initial value
   256 	if( b != aInitial )
   257 		{
   258 		iResult = EFalse;
   259 		}
   260 
   261 	//tests division by something smaller than a word
   262 	if(aInitial.WordCount() <= 1)
   263 		{
   264 		RInteger dividend = RInteger::NewL(a);
   265 		CleanupStack::PushL(dividend);
   266 		for(j=1; j<aRange; j++)
   267 			{
   268 			RInteger quotient;
   269 			//try to find aInitial by repeatedly dividing dividend by aInitial aRange times 
   270 			TRAPD(res, quotient = dividend.DividedByL(aInitial.ConvertToLongL()));
   271 			//the first time through aInitial is 0 so this is expected
   272 			if(res == KErrDivideByZero && aInitial.IsZero())
   273 				{
   274 				break;
   275 				}
   276 			else if(res == KErrDivideByZero && aInitial.NotZero())
   277 				{
   278 				iResult = EFalse;
   279 				}
   280 			else if(res != KErrNone)
   281 				{
   282 				User::Leave(res);
   283 				}
   284 			dividend.Set(quotient);
   285 			}
   286 		if( dividend != aInitial )
   287 			{
   288 			iResult = EFalse;
   289 			}
   290 
   291 		TUint remainder=1;
   292 		TRAPD(res, remainder = a.ModuloL(aInitial.ConvertToLongL()));
   293 		//the first time through aInitial is 0
   294 		if(res != KErrDivideByZero && res != KErrNone)
   295 			{
   296 			User::Leave(res);
   297 			}
   298 		else if(res == KErrDivideByZero && aInitial.NotZero())
   299 			{
   300 			iResult = EFalse;
   301 			}
   302 		//else we have an expected divide by zero, ignore it.
   303 		if(remainder != 0)
   304 			{
   305 			iResult = EFalse;
   306 			}
   307 
   308 		CleanupStack::PopAndDestroy(&dividend);
   309 		}
   310 
   311 	RInteger c = RInteger::NewL(aRange);
   312 	CleanupStack::PushL(c);
   313 	RInteger d = aInitial.ExponentiateL(c);
   314 	CleanupStack::PushL(d);
   315 	// c and a should now be the same
   316 	if( d != a )
   317 		{ 
   318 		iResult = EFalse;
   319 		}
   320 
   321 	RInteger e = RInteger::NewL(a);
   322 	CleanupStack::PushL(e);
   323 	TRAPD(res, e %= aInitial);
   324 	//the first time through aInitial is 0
   325 	if(res != KErrDivideByZero && res != KErrNone)
   326 		{
   327 		User::Leave(res);
   328 		}
   329 	else if(res == KErrDivideByZero && aInitial.NotZero())
   330 		{
   331 		iResult = EFalse;
   332 		}
   333 	//else we have an expected divide by zero, ignore it.
   334 
   335 	// (aInitial^aRange)%aInitial == 0
   336 	if( e != 0 )
   337 		{
   338 		iResult = EFalse;
   339 		}
   340 	CleanupStack::PopAndDestroy(5);//e,d,c,b,a
   341 	__UHEAP_MARKEND;
   342 	}
   343 
   344 void CBasicMathsFB::MiscDivL()
   345 	{
   346 	__UHEAP_MARK;
   347 		
   348 	TUint seed = 10;
   349 	TUint diviser = 2;
   350 	TInt dividendInt = 10;
   351 	
   352 	RInteger dividend = RInteger::NewL(seed);
   353 	CleanupStack::PushL(dividend);
   354 	
   355 	TInt longInt = dividend.ConvertToLongL();
   356 
   357 	// Test for inequality FALSE
   358 	TBool res0 = dividend != dividendInt;
   359 	if (res0)
   360 		{
   361 		iResult = EFalse;
   362 		}
   363 	
   364 	// Test for inequality TRUE
   365 	res0 = dividend != TInt(diviser);
   366 	if (!res0)
   367 		{
   368 		iResult = EFalse;
   369 		}
   370 	
   371 	// Test for equality TRUE
   372 	res0 = dividend >= dividend; 
   373 	if (!res0)
   374 		{
   375 		iResult = EFalse;
   376 		}
   377 	
   378 	RInteger quotient;
   379 	CleanupStack::PushL(quotient);
   380 	// 10 / 2 = 5
   381 	TRAPD(res, quotient = dividend.DividedByL(diviser));
   382 	if (res != KErrNone)
   383 		{
   384 		User::Leave(res);
   385 		}
   386 	else if (quotient != (dividendInt/diviser))
   387 		{
   388 		iResult = EFalse;
   389 		}
   390 
   391 	// Test for greater value TRUE and equality FALSE
   392 	res0 = dividend >= quotient; 
   393 	if (!res0)
   394 		{
   395 		iResult = EFalse;
   396 		}
   397 	
   398 	// Test for greater value FALSE and equality FALSE
   399 	res0 = quotient >= dividend; 
   400 	if (res0)
   401 		{
   402 		iResult = EFalse;
   403 		}
   404 	
   405 	// 10 / 10 = 1
   406 	TRAPD(res1, dividend /= dividendInt);
   407 	if (res1 != KErrNone)
   408 		{
   409 		User::Leave(res);
   410 		}	
   411 	else if (dividend != (dividendInt/seed))
   412 		{
   413 		iResult = EFalse;
   414 		}
   415 	
   416 	// 1 % 10 = 1 (dividend = 1, due to last step) 
   417 	TRAPD(res2, dividend %= dividendInt);
   418 	if (res2 != KErrNone)
   419 		{
   420 		User::Leave(res);
   421 		}	
   422 	else if (dividend != (dividendInt/seed))
   423 		{
   424 		iResult = EFalse;
   425 		}
   426 	
   427 	// 1 x 1 = 1 (dividend = 1, due to last step)
   428 	RInteger squaredInt = dividend.SquaredL();
   429 	CleanupStack::PushL(squaredInt);
   430 	if ( squaredInt != (dividendInt/seed))
   431 		{
   432 		iResult = EFalse;
   433 		}
   434 	
   435 	RInteger expSeed = RInteger::NewL(10);
   436 	CleanupStack::PushL(expSeed);
   437 	RInteger exponent = RInteger::NewL(3);
   438 	CleanupStack::PushL(exponent);
   439 	RInteger expResult;
   440 	CleanupStack::PushL(expResult);
   441 	TRAPD(res3, expResult = expSeed.ExponentiateL(exponent));
   442 		if (res3 != KErrNone)
   443 			{
   444 			User::Leave(res);
   445 			}
   446 		else if (expResult != (10*10*10))
   447 			{
   448 			iResult = EFalse;
   449 			}
   450 		
   451 	CleanupStack::PopAndDestroy(6, &dividend); // dividend, quotient, squardInt, expSeed, exponent, expResult
   452 	__UHEAP_MARKEND;
   453 	}