crypto/weakcryptospi/test/tbigint/tbasicmathsfb.cpp
changeset 8 35751d3474b7
equal deleted inserted replaced
2:675a964f4eb5 8:35751d3474b7
       
     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 	}