crypto/weakcrypto/test/tbigint/tbasicmathsfb.cpp
changeset 0 2c201484c85f
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     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 
       
   124 		//GCD
       
   125 		CleanupStack::PopAndDestroy(); //initial
       
   126 		CleanupStack::PopAndDestroy();//buf
       
   127 		iConsole.Printf(_L("."));
       
   128 		}
       
   129 	
       
   130 	//Test a single iteration where the initial random number is less than a
       
   131 	//word so the division and modulo routines that take words rather than
       
   132 	//TIntegers can run.
       
   133 	//do
       
   134 		{
       
   135 		//This is this iteration's random number
       
   136 		RInteger initial = RInteger::NewRandomL(31);
       
   137 		CleanupStack::PushL(initial);
       
   138 		//get a number x | 10 < x < 100
       
   139 		RInteger crange = RInteger::NewRandomL(min, max);
       
   140 		CleanupStack::PushL(crange);
       
   141 		TUint range = crange.ConvertToLongL();
       
   142 		CleanupStack::PopAndDestroy(&crange); //crange
       
   143 
       
   144 		AddSub(initial, range);
       
   145 		MulDiv(initial, range);
       
   146 		CleanupStack::PopAndDestroy(&initial); //initial
       
   147 		iConsole.Printf(_L("."));
       
   148 		} //while (0);
       
   149 
       
   150 	CleanupStack::PopAndDestroy();//max
       
   151 	CleanupStack::PopAndDestroy(); //min
       
   152 
       
   153 	User::RequestComplete(status, KErrNone);
       
   154 	iActionState = CTestAction::EPostrequisite;
       
   155 	__UHEAP_MARK;
       
   156 	}
       
   157 
       
   158 void CBasicMathsFB::AddSub(const TInteger& aInitial, TUint aRange)
       
   159 	{
       
   160 	__UHEAP_MARK;
       
   161 	//This is the copy we are going to do stuff to
       
   162 	RInteger a = RInteger::NewL(aInitial);
       
   163 	CleanupStack::PushL(a);
       
   164 
       
   165 	// compute a*aRange using doubling
       
   166 	TUint j=1;
       
   167 	for(; j<aRange; j++)
       
   168 		{
       
   169 		a += aInitial;
       
   170 		}
       
   171 
       
   172 	//b = a*aRange;
       
   173 	RInteger b = RInteger::NewL(a);
       
   174 	CleanupStack::PushL(b);
       
   175 	//compute (a*aRange)/aRange using subtraction
       
   176 	for(j=1; j<aRange; j++)
       
   177 		{
       
   178 		b -= aInitial;
       
   179 		}
       
   180 	// b should be the same as the initial value
       
   181 	if( b != aInitial )
       
   182 		{
       
   183 		iResult = EFalse;
       
   184 		iOut.writeString(_L("AddSub Failure:"));
       
   185 		iOut.writeNewLine();
       
   186 		}
       
   187 
       
   188 	RInteger c = RInteger::NewL(aInitial);
       
   189 	CleanupStack::PushL(c);
       
   190 	// compute a*aRange using normal multiplication
       
   191 	c *= aRange;
       
   192 	
       
   193 	// c and a should now be the same
       
   194 	if( c != a )
       
   195 		{ 
       
   196 		iResult = EFalse;
       
   197 		}
       
   198 
       
   199 	RInteger d = RInteger::NewL(a);
       
   200 	CleanupStack::PushL(d);
       
   201 	//compute (a*aRange)/aRange using normal division
       
   202 	d /= aRange;
       
   203 	if( d != aInitial )
       
   204 		{
       
   205 		iResult = EFalse;
       
   206 		}
       
   207 	RInteger e = RInteger::NewL(a);
       
   208 	CleanupStack::PushL(e);
       
   209 	e %= aRange;
       
   210 	// (a*aRange)%aRange == 0
       
   211 	if( e != 0 )
       
   212 		{
       
   213 		iResult = EFalse;
       
   214 		}
       
   215 	CleanupStack::PopAndDestroy(5); //e,d,c,b,a
       
   216 	__UHEAP_MARKEND;
       
   217 	}
       
   218 
       
   219 void CBasicMathsFB::MulDiv(const TInteger& aInitial, TUint aRange)
       
   220 	{
       
   221 	__UHEAP_MARK;
       
   222 	//This is the copy we are going to do stuff to
       
   223 	RInteger a = RInteger::NewL(aInitial);
       
   224 	CleanupStack::PushL(a);
       
   225 
       
   226 	//compute a = aInitial^aRange using repeated multiplication
       
   227 	TUint j=1;
       
   228 	for(; j<aRange; j++)
       
   229 		{
       
   230 		a *= aInitial;
       
   231 		}
       
   232 
       
   233 	//b = a
       
   234 	RInteger b = RInteger::NewL(a);
       
   235 	CleanupStack::PushL(b);
       
   236 	//try to find aInitial by repeatedly dividing b by aInitial aRange times
       
   237 	for(j=1; j<aRange; j++)
       
   238 		{
       
   239 		TRAPD(res, b /= aInitial);
       
   240 		//the first time through aInitial is 0 so this is expected
       
   241 		if(res == KErrDivideByZero && aInitial.IsZero())
       
   242 			{
       
   243 			break;
       
   244 			}
       
   245 		else if(res == KErrDivideByZero && aInitial.NotZero())
       
   246 			{
       
   247 			iResult = EFalse;
       
   248 			}
       
   249 		else if(res != KErrNone)
       
   250 			{
       
   251 			User::Leave(res);
       
   252 			}
       
   253 		}
       
   254 	// b should be the same as the initial value
       
   255 	if( b != aInitial )
       
   256 		{
       
   257 		iResult = EFalse;
       
   258 		}
       
   259 
       
   260 	//tests division by something smaller than a word
       
   261 	if(aInitial.WordCount() <= 1)
       
   262 		{
       
   263 		RInteger dividend = RInteger::NewL(a);
       
   264 		CleanupStack::PushL(dividend);
       
   265 		for(j=1; j<aRange; j++)
       
   266 			{
       
   267 			RInteger quotient;
       
   268 			//try to find aInitial by repeatedly dividing dividend by aInitial aRange times 
       
   269 			TRAPD(res, quotient = dividend.DividedByL(aInitial.ConvertToLongL()));
       
   270 			//the first time through aInitial is 0 so this is expected
       
   271 			if(res == KErrDivideByZero && aInitial.IsZero())
       
   272 				{
       
   273 				break;
       
   274 				}
       
   275 			else if(res == KErrDivideByZero && aInitial.NotZero())
       
   276 				{
       
   277 				iResult = EFalse;
       
   278 				}
       
   279 			else if(res != KErrNone)
       
   280 				{
       
   281 				User::Leave(res);
       
   282 				}
       
   283 			dividend.Set(quotient);
       
   284 			}
       
   285 		if( dividend != aInitial )
       
   286 			{
       
   287 			iResult = EFalse;
       
   288 			}
       
   289 
       
   290 		TUint remainder=1;
       
   291 		TRAPD(res, remainder = a.ModuloL(aInitial.ConvertToLongL()));
       
   292 		//the first time through aInitial is 0
       
   293 		if(res != KErrDivideByZero && res != KErrNone)
       
   294 			{
       
   295 			User::Leave(res);
       
   296 			}
       
   297 		else if(res == KErrDivideByZero && aInitial.NotZero())
       
   298 			{
       
   299 			iResult = EFalse;
       
   300 			}
       
   301 		//else we have an expected divide by zero, ignore it.
       
   302 		if(remainder != 0)
       
   303 			{
       
   304 			iResult = EFalse;
       
   305 			}
       
   306 
       
   307 		CleanupStack::PopAndDestroy(&dividend);
       
   308 		}
       
   309 
       
   310 	RInteger c = RInteger::NewL(aRange);
       
   311 	CleanupStack::PushL(c);
       
   312 	RInteger d = aInitial.ExponentiateL(c);
       
   313 	CleanupStack::PushL(d);
       
   314 	// c and a should now be the same
       
   315 	if( d != a )
       
   316 		{ 
       
   317 		iResult = EFalse;
       
   318 		}
       
   319 
       
   320 	RInteger e = RInteger::NewL(a);
       
   321 	CleanupStack::PushL(e);
       
   322 	TRAPD(res, e %= aInitial);
       
   323 	//the first time through aInitial is 0
       
   324 	if(res != KErrDivideByZero && res != KErrNone)
       
   325 		{
       
   326 		User::Leave(res);
       
   327 		}
       
   328 	else if(res == KErrDivideByZero && aInitial.NotZero())
       
   329 		{
       
   330 		iResult = EFalse;
       
   331 		}
       
   332 	//else we have an expected divide by zero, ignore it.
       
   333 
       
   334 	// (aInitial^aRange)%aInitial == 0
       
   335 	if( e != 0 )
       
   336 		{
       
   337 		iResult = EFalse;
       
   338 		}
       
   339 	CleanupStack::PopAndDestroy(5);//e,d,c,b,a
       
   340 	__UHEAP_MARKEND;
       
   341 	}