crypto/weakcrypto/test/tsymmetric/tperformancetest.cpp
changeset 72 de46a57f75fb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/weakcrypto/test/tsymmetric/tperformancetest.cpp	Thu Jun 24 15:39:07 2010 +0530
@@ -0,0 +1,632 @@
+/*
+* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+#include "tperformancetest.h"
+#include "symmetric.h"
+#include <t_output.h>
+
+#ifndef _DEBUG
+_LIT(KPerfEFormat, "\tPerformance (encryption) : %f us/iteration (%i iterations in %iL us)\r\n");
+_LIT(KPerfDFormat, "\tPerformance (decryption) : %f us/iteration (%i iterations in %iL us)\r\n");
+_LIT(KTotalFormat, "\tPerformance (total) : %f us/iteration (%i iterations in %iL us)\r\n");
+_LIT(KPerfThroughput, "\tThroughput (total): %f MB/s\r\n");
+_LIT(KPerfThroughputAfterSetup, "\tThroughput after setup: %f MB/s\r\n");
+_LIT(KPerfEncryptorCreate, "\tPerformance (encryptor create) : %f us/iteration (%i iterations in %iL us)\r\n");
+_LIT(KPerfDecryptorCreate, "\tPerformance (decryptor create) : %f us/iteration (%i iterations in %iL us)\r\n");
+_LIT(KDataSize,"\tData input size : %i B\r\n");
+#endif
+
+CTestAction* CPerformanceTest::NewL(RFs& aFs,
+									   CConsoleBase& aConsole,
+									   Output& aOut, 
+									   const TTestActionSpec& aTestActionSpec)
+	{
+	CTestAction* self = CPerformanceTest::NewLC(aFs, aConsole,
+		aOut, aTestActionSpec);
+	CleanupStack::Pop();
+	return self;
+	}
+
+CTestAction* CPerformanceTest::NewLC(RFs& aFs,
+										CConsoleBase& aConsole,
+										Output& aOut, 
+										const TTestActionSpec& aTestActionSpec)
+	{
+	CPerformanceTest* self = new(ELeave) CPerformanceTest(aFs, aConsole, aOut);
+	CleanupStack::PushL(self);
+	self->ConstructL(aTestActionSpec);
+	return self;
+	}
+
+CPerformanceTest::~CPerformanceTest()
+{
+	delete iEncryptor;
+	delete iDecryptor;
+}
+
+CPerformanceTest::CPerformanceTest(RFs& aFs, 
+								 CConsoleBase& aConsole,
+								 Output& aOut)
+								 
+: CCryptoTestAction(aFs, aConsole, aOut)
+{}
+
+void CPerformanceTest::DoPerformPrerequisiteL()
+{
+#ifndef _DEBUG
+	TInt err = KErrNone;
+	TInt pos = 0;
+	TPtrC8 vector = Input::ParseElement(*iBody, KVectorStart, KVectorEnd, pos, err);
+
+	DoInputParseL(vector);
+
+	CBlockTransformation* encryptor = 0;
+	CBlockTransformation* decryptor = 0;
+
+	switch (iCipherType)
+	{
+		case (EDESECB):
+		{//	Time the length of time it takes to set up the key schedule,
+		//	save it and add to encrypt time, to be consistent with old API
+		//	for comparison purposes (old API does both set up and encrypt/decrypt
+		//	in a single operation).
+			TTime startTime;
+			TTime endTime;
+			TTimeIntervalSeconds diff(0);
+			const TTimeIntervalSeconds iterationTime(iIterationTime);
+			
+			encryptor = CDESEncryptor::NewL(iKey->Des());
+			iEncryptIterations = 0;
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				encryptor->Reset();
+				iEncryptIterations++;
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iEncryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+
+			delete encryptor;
+			
+			decryptor = CDESDecryptor::NewL(iKey->Des());
+			
+			diff = 0;
+			iDecryptIterations = 0;
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				decryptor->Reset();
+				iDecryptIterations++;
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iDecryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+
+			delete decryptor;
+
+			encryptor = CDESEncryptor::NewLC(iKey->Des());
+			decryptor = CDESDecryptor::NewL(iKey->Des());
+			CleanupStack::Pop(encryptor);
+		}
+		break;
+		case(EDESCBC):
+		{
+			CBlockTransformation* desEncryptor = NULL;
+			CBlockTransformation* desDecryptor = NULL;
+
+			desEncryptor = CDESEncryptor::NewLC(iKey->Des());								
+			encryptor = CModeCBCEncryptor::NewL(desEncryptor, iIV->Des());				
+			
+			TTime startTime;
+			TTime endTime;
+			TTimeIntervalSeconds diff(0);
+			const TTimeIntervalSeconds iterationTime(iIterationTime);
+
+			iEncryptIterations = 0;
+			startTime.UniversalTime();
+			while (diff < iterationTime)
+				{
+				iEncryptIterations++;
+				encryptor->Reset();
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iEncryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+
+			CleanupStack::Pop(1);
+			delete encryptor;
+
+			desDecryptor = CDESDecryptor::NewLC(iKey->Des());
+			decryptor = CModeCBCDecryptor::NewL(desDecryptor, iIV->Des());
+			
+			diff = 0;
+			iDecryptIterations = 0;
+			startTime.UniversalTime();
+			while (diff < iterationTime)
+				{
+				decryptor->Reset();
+				iDecryptIterations++;
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iDecryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+
+			CleanupStack::Pop(1);
+			delete decryptor;				
+
+			desEncryptor = CDESEncryptor::NewLC(iKey->Des());
+			desDecryptor = CDESDecryptor::NewLC(iKey->Des());
+			
+			encryptor = CModeCBCEncryptor::NewL(desEncryptor, iIV->Des());
+			CleanupStack::PushL(encryptor);
+			decryptor = CModeCBCDecryptor::NewL(desDecryptor, iIV->Des());					
+			CleanupStack::Pop(3);
+		}
+		break;
+		case (E3DESECB):
+		{
+			encryptor = C3DESEncryptor::NewL(iKey->Des());
+			TTime startTime;
+			TTime endTime;
+			TTimeIntervalSeconds diff(0);
+			const TTimeIntervalSeconds iterationTime(iIterationTime);
+
+			iEncryptIterations = 0;
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				iEncryptIterations++;
+				encryptor->Reset();
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iEncryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+
+			delete encryptor;
+
+			diff = 0;
+			iDecryptIterations = 0;
+			decryptor = C3DESDecryptor::NewL(iKey->Des());
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				decryptor->Reset();
+				iDecryptIterations++;
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iDecryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+			delete decryptor;
+
+			encryptor = C3DESEncryptor::NewLC(iKey->Des());
+			decryptor = C3DESDecryptor::NewL(iKey->Des());
+			CleanupStack::Pop(encryptor);
+		}
+		break;
+		case (E3DESCBC):
+		{
+			CBlockTransformation* the3DESencryptor = NULL;
+			CBlockTransformation* the3DESdecryptor = NULL;
+
+			the3DESencryptor = C3DESEncryptor::NewLC(iKey->Des());
+			encryptor = CModeCBCEncryptor::NewL(the3DESencryptor, iIV->Des());
+
+			TTime startTime;
+			TTime endTime;
+			TTimeIntervalSeconds diff(0);
+			const TTimeIntervalSeconds iterationTime(iIterationTime);
+
+			iEncryptIterations = 0;
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				iEncryptIterations++;
+				encryptor->Reset();
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iEncryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+
+			CleanupStack::Pop(1);
+			delete encryptor;				
+
+			the3DESdecryptor = C3DESDecryptor::NewLC(iKey->Des());
+			decryptor = CModeCBCDecryptor::NewL(the3DESdecryptor, iIV->Des());		
+
+			diff = 0;
+			iDecryptIterations = 0;
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				decryptor->Reset();
+				iDecryptIterations++;
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iDecryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+			CleanupStack::Pop(1);
+			delete decryptor;
+
+			the3DESencryptor = C3DESEncryptor::NewLC(iKey->Des());
+			the3DESdecryptor = C3DESDecryptor::NewLC(iKey->Des());
+			
+			encryptor = CModeCBCEncryptor::NewL(the3DESencryptor, iIV->Des());
+			CleanupStack::PushL(encryptor);
+			decryptor = CModeCBCDecryptor::NewL(the3DESdecryptor, iIV->Des());		
+			CleanupStack::Pop(3);
+		}
+		break;
+		case (EAESECB):
+		{
+			TTime startTime;
+			TTime endTime;
+			TTimeIntervalSeconds diff(0);
+			const TTimeIntervalSeconds iterationTime(iIterationTime);
+
+			iEncryptIterations = 0;
+			encryptor = CAESEncryptor::NewL(iKey->Des());
+			startTime.UniversalTime();
+			while (diff < iterationTime)
+				{
+				iEncryptIterations++;
+				encryptor->Reset();
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iEncryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+			delete encryptor;
+
+			diff = 0;
+			iDecryptIterations = 0;
+			decryptor = CAESDecryptor::NewL(iKey->Des());
+			startTime.UniversalTime();
+			while (diff < iterationTime)
+				{
+				decryptor->Reset();
+				iDecryptIterations++;
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iDecryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+			delete decryptor;
+			
+			encryptor = CAESEncryptor::NewLC(iKey->Des());
+			decryptor = CAESDecryptor::NewL(iKey->Des());
+			CleanupStack::Pop(encryptor);
+		}
+		break;	
+		case (ERC2ECB):
+		{
+			TTime startTime;
+			TTime endTime;
+			TTimeIntervalSeconds diff(0);
+			const TTimeIntervalSeconds iterationTime(iIterationTime);
+
+			iEncryptIterations = 0;
+			encryptor = CRC2Encryptor::NewL(iKey->Des(), iEffectiveKeyLen);
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				iEncryptIterations++;
+				encryptor->Reset();
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iEncryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+			delete encryptor;
+			
+			diff = 0;
+			decryptor = CRC2Decryptor::NewL(iKey->Des(), iEffectiveKeyLen);
+			iDecryptIterations = 0;
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				decryptor->Reset();
+				iDecryptIterations++;
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iDecryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+			delete decryptor;
+
+			encryptor = CRC2Encryptor::NewLC(iKey->Des(), iEffectiveKeyLen);
+			decryptor = CRC2Decryptor::NewL(iKey->Des(), iEffectiveKeyLen);
+			CleanupStack::Pop(encryptor);
+		}
+		break;
+		case (ERC2CBC):
+		{
+			CBlockTransformation* theRC2encryptor = NULL;
+			CBlockTransformation* theRC2decryptor = NULL;
+
+			theRC2encryptor = CRC2Encryptor::NewLC(iKey->Des(), iEffectiveKeyLen);
+			encryptor = CModeCBCEncryptor::NewL(theRC2encryptor, iIV->Des());
+
+			TTime startTime;
+			TTime endTime;
+			TTimeIntervalSeconds diff(0);
+			const TTimeIntervalSeconds iterationTime(iIterationTime);
+
+			iEncryptIterations = 0;
+			startTime.UniversalTime();
+			while (diff < iterationTime)
+				{
+				iEncryptIterations++;
+				encryptor->Reset();
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iEncryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+			CleanupStack::Pop(1);
+			delete encryptor;
+
+			diff = 0;
+			iDecryptIterations = 0;
+			theRC2decryptor = CRC2Decryptor::NewLC(iKey->Des(), iEffectiveKeyLen);
+			decryptor = CModeCBCDecryptor::NewL(theRC2decryptor, iIV->Des());		
+			startTime.UniversalTime();
+			while (diff < iterationTime)
+				{
+				decryptor->Reset();
+				iDecryptIterations++;
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iDecryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+			CleanupStack::Pop(1);
+			delete decryptor;
+
+			theRC2encryptor = CRC2Encryptor::NewLC(iKey->Des(), iEffectiveKeyLen);
+			theRC2decryptor = CRC2Decryptor::NewLC(iKey->Des(), iEffectiveKeyLen);
+			
+			encryptor = CModeCBCEncryptor::NewL(theRC2encryptor, iIV->Des());
+			CleanupStack::PushL(encryptor);
+			decryptor = CModeCBCDecryptor::NewL(theRC2decryptor, iIV->Des());		
+			CleanupStack::Pop(3);
+		}
+		break;
+		case (ERC4):
+		{
+			iEncryptor = CARC4::NewL(*iKey);
+			TTime startTime;
+			TTime endTime;
+			TTimeIntervalSeconds diff(0);
+			const TTimeIntervalSeconds iterationTime(iIterationTime);
+
+			iEncryptIterations = 0;
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				iEncryptIterations++;
+				iEncryptor->Reset();
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iEncryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+
+			diff = 0;			
+			iDecryptIterations = 0;
+			iDecryptor = CARC4::NewL(*iKey);
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				iDecryptor->Reset();
+				iDecryptIterations++;
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iDecryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+		}
+		break;
+		case (ECipherNull):
+		{
+			iEncryptor = CNullCipher::NewL();
+			TTime startTime;
+			TTime endTime;
+			TTimeIntervalSeconds diff(0);
+			const TTimeIntervalSeconds iterationTime(iIterationTime);
+
+			iEncryptIterations = 0;
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				iEncryptIterations++;
+				iEncryptor->Reset();
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iEncryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+			
+			diff = 0;
+			iDecryptIterations = 0;
+			iDecryptor = CNullCipher::NewL();
+			startTime.UniversalTime();	
+			while (diff < iterationTime)
+				{
+				iDecryptor->Reset();
+				iDecryptIterations++;
+				endTime.UniversalTime();
+				endTime.SecondsFrom(startTime, diff);
+				}
+			endTime.UniversalTime();
+			iDecryptorCreateTime = endTime.MicroSecondsFrom(startTime);
+		}
+		break;
+			
+		default:
+		{
+			ASSERT(0);
+			User::Leave(KErrNotSupported);
+		}
+	}
+	
+	if( encryptor && decryptor )
+		{
+		CleanupStack::PushL(encryptor);
+		CleanupStack::PushL(decryptor);
+		
+		CPaddingSSLv3* ePadding = CPaddingSSLv3::NewLC(encryptor->BlockSize());
+		iEncryptor = CBufferedEncryptor::NewL(encryptor, ePadding);	
+		CleanupStack::Pop(ePadding);	
+		
+		CPaddingSSLv3* dPadding = CPaddingSSLv3::NewLC(decryptor->BlockSize());
+		iDecryptor = CBufferedDecryptor::NewL(decryptor, dPadding);
+		CleanupStack::Pop(dPadding);
+		CleanupStack::Pop(decryptor);
+		CleanupStack::Pop(encryptor);
+		}
+
+	// clear the default input and output fields and fill with random data
+	// since for performance testing we do not care about validating
+	// correct output
+	delete iInput;	
+	iInput = NULL;
+	iInput = HBufC8::NewMaxL(iRandDataSize);
+	TPtr8 tempPtr = iInput->Des();
+	TRandom::Random(tempPtr);	
+	TBuf<128> tempbuf;
+	tempbuf.Format(KDataSize, (iInput->Length()));
+	iOut.writeString(tempbuf);	
+	delete iOutput;
+	iOutput = NULL;
+	iOutput = HBufC8::NewMaxL(iRandDataSize);
+	TPtr8 tempPtr2 = iOutput->Des();
+	TRandom::Random(tempPtr2);	
+		
+	iEResult = HBufC8::NewMaxL(iEncryptor->MaxOutputLength(iInput->Length()));
+	iDResult = HBufC8::NewMaxL(iDecryptor->MaxOutputLength(iEResult->Size()));
+#endif
+}
+
+void CPerformanceTest::DoPerformActionL()
+{
+	iResult = ETrue;
+#ifndef _DEBUG
+	TBuf<128> buf;
+	TReal rate = I64REAL(iEncryptorCreateTime.Int64()) / iEncryptIterations;
+	buf.Format(KPerfEncryptorCreate, rate, iEncryptIterations, iEncryptorCreateTime.Int64());
+	iOut.writeString(buf);
+
+	TTime startTime;
+	TTime endTime;
+	TTimeIntervalSeconds diff(0);
+	const TTimeIntervalSeconds iterationTime(iIterationTime);
+	
+	iEncryptIterations = 0;
+	startTime.UniversalTime();
+	while (diff < iterationTime)
+		{
+		TPtr8 iEResultTemp(iEResult->Des());
+		iEResultTemp.Zero();
+
+		iEncryptor->Process(*iInput, iEResultTemp);
+		iEncryptIterations++;
+		endTime.UniversalTime();
+		endTime.SecondsFrom(startTime, diff);
+		}
+	endTime.UniversalTime();
+
+	TTimeIntervalMicroSeconds time = endTime.MicroSecondsFrom(startTime);
+	rate = I64REAL(time.Int64()) / iEncryptIterations;
+	buf.Format(KPerfEFormat, rate, iEncryptIterations, time.Int64());
+	iOut.writeString(buf);
+
+	rate = (static_cast<TReal>(iEncryptIterations) * iInput->Size() * 1000 * 1000) / (I64REAL(time.Int64()) * 1024 * 1024);	// Throughput in MB/s
+	buf.FillZ();
+	buf.Zero();
+	buf.Format(KPerfThroughputAfterSetup, rate);
+	iOut.writeString(buf);
+
+	TInt64 totalEncryptTime = time.Int64();
+	totalEncryptTime+=iEncryptorCreateTime.Int64();
+	rate = I64REAL(totalEncryptTime) / iEncryptIterations;
+	buf.FillZ();
+	buf.Zero();
+	buf.Format(KTotalFormat, rate, iEncryptIterations, totalEncryptTime);
+	iOut.writeString(buf);
+
+	rate = (static_cast<TReal>(iEncryptIterations) * iInput->Size() * 1000 * 1000) / (I64REAL(totalEncryptTime) * 1024 * 1024);	// Throughput in MB/s
+	buf.Zero();
+	buf.Format(KPerfThroughput, rate);
+	iOut.writeString(buf);
+
+//	Test decryption
+	rate = I64REAL(iDecryptorCreateTime.Int64()) / iDecryptIterations;
+	buf.Format(KPerfDecryptorCreate, rate, iDecryptIterations, iDecryptorCreateTime.Int64());
+	iOut.writeString(buf);
+	
+	diff = 0;
+	iDecryptIterations = 0;
+	startTime.UniversalTime();	
+	while (diff < iterationTime)
+		{
+		TPtr8 iDResultTemp(iDResult->Des());
+		iDResultTemp.Zero();
+		iDecryptor->Process(*iOutput, iDResultTemp);
+		iDecryptIterations++;
+		endTime.UniversalTime();
+		endTime.SecondsFrom(startTime, diff);
+		}
+	endTime.UniversalTime();
+
+	time = endTime.MicroSecondsFrom(startTime);	
+	rate = I64REAL(time.Int64()) / iDecryptIterations;
+	buf.FillZ();
+	buf.Zero();
+	buf.Format(KPerfDFormat, rate, iDecryptIterations, time.Int64());
+	iOut.writeString(buf);
+
+	rate = (static_cast<TReal>(iDecryptIterations) * iInput->Size() * 1000 * 1000) / (I64REAL(time.Int64()) * 1024 * 1024);	// Throughput in MB/s
+	buf.Zero();
+	buf.Format(KPerfThroughputAfterSetup, rate);
+	iOut.writeString(buf);
+
+	TInt64 totalDecryptTime = time.Int64();
+	totalDecryptTime+=iDecryptorCreateTime.Int64();
+	rate = I64REAL(totalDecryptTime) / iDecryptIterations;
+	buf.FillZ();
+	buf.Zero();
+	buf.Format(KTotalFormat, rate, iDecryptIterations, totalDecryptTime);
+	iOut.writeString(buf);
+	
+	rate = (static_cast<TReal>(iDecryptIterations) * iInput->Size() * 1000 * 1000) / (I64REAL(totalDecryptTime) * 1024 * 1024);	// Throughput in MB/s
+	buf.Zero();
+	buf.Format(KPerfThroughput, rate);
+	iOut.writeString(buf);
+	
+#endif
+}
+