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