--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/weakcryptospi/test/tbigint/tbasicmathsfb.cpp Thu Sep 10 14:01:51 2009 +0300
@@ -0,0 +1,453 @@
+/*
+* Copyright (c) 2002-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 "tbasicmathsfb.h"
+#include "t_input.h"
+#include "t_output.h"
+#include <bigint.h>
+#include <random.h>
+
+CTestAction* CBasicMathsFB::NewL(RFs& aFs, CConsoleBase& aConsole,
+ Output& aOut, const TTestActionSpec& aTestActionSpec)
+ {
+ CTestAction* self = CBasicMathsFB::NewLC(aFs, aConsole,
+ aOut, aTestActionSpec);
+ CleanupStack::Pop();
+ return self;
+ }
+
+CTestAction* CBasicMathsFB::NewLC(RFs& aFs, CConsoleBase& aConsole,
+ Output& aOut, const TTestActionSpec& aTestActionSpec)
+ {
+ CBasicMathsFB* self = new(ELeave) CBasicMathsFB(aFs, aConsole, aOut);
+ CleanupStack::PushL(self);
+ self->ConstructL(aTestActionSpec);
+ return self;
+ }
+
+CBasicMathsFB::~CBasicMathsFB()
+ {
+ delete iBody;
+ }
+
+CBasicMathsFB::CBasicMathsFB(RFs& aFs, CConsoleBase& aConsole, Output& aOut)
+ : CTestAction(aConsole, aOut), iFs(aFs)
+ {
+ }
+
+void CBasicMathsFB::ConstructL(const TTestActionSpec& aTestActionSpec)
+ {
+ CTestAction::ConstructL(aTestActionSpec);
+
+ iBody = HBufC8::NewL(aTestActionSpec.iActionBody.Length());
+ iBody->Des().Copy(aTestActionSpec.iActionBody);
+
+ //HBufC8* length = Input::ParseElementHexL(*iBody, _L8("<bits>"));
+ TUint bits = Input::ParseIntElement(*iBody, _L8("<bits>"), _L8("</bits>"));
+ // the final /7 gives the number of times we have to increment by 7 to get
+ // to that number of bytes and hence bits.
+ iIterations = ((bits+7)/8)/7 + 1;
+ }
+
+void CBasicMathsFB::DoPerformPrerequisite(TRequestStatus& aStatus)
+ {
+ TRequestStatus* status = &aStatus;
+ User::RequestComplete(status, KErrNone);
+ iActionState = CTestAction::EAction;
+ }
+
+void CBasicMathsFB::DoPerformPostrequisite(TRequestStatus& aStatus)
+ {
+ TRequestStatus* status = &aStatus;
+ iFinished = ETrue;
+ User::RequestComplete(status, KErrNone);
+ }
+
+void CBasicMathsFB::DoReportAction(void)
+ {
+ }
+
+void CBasicMathsFB::DoCheckResult(TInt)
+ {
+ }
+
+void CBasicMathsFB::PerformAction(TRequestStatus& aStatus)
+ {
+ __UHEAP_MARK;
+ TRequestStatus* status = &aStatus;
+ iResult = ETrue;
+
+ //min max values for NewRandomLC call
+ RInteger min = RInteger::NewL(10);
+ CleanupStack::PushL(min);
+ RInteger max = RInteger::NewL(100);
+ CleanupStack::PushL(max);
+
+ //Generate iIterations*7 byte random sequences we are using 7 as it's a generator
+ //mod 8. Thus we'll cycle through every value (0-7) every 8 iterations.
+ //This gives us a better feeling that certain byte lengths (and thus bit
+ //lengths as the byte is chosen randomly) don't have errors.
+ for(TUint i=1; i<iIterations; i++)
+ {
+ HBufC8* buf = HBufC8::NewMaxLC(i*7);
+ TPtr8 ptr = buf->Des();
+ TRandom::RandomL(ptr);
+
+ //This is this iteration's random number
+ RInteger initial = RInteger::NewL(ptr);
+ CleanupStack::PushL(initial);
+
+ //get a number x | 10 < x < 100
+ RInteger crange = RInteger::NewRandomL(min, max);
+ CleanupStack::PushL(crange);
+ TUint range = crange.ConvertToLongL();
+ CleanupStack::PopAndDestroy(); //crange
+
+ AddSub(initial, range);
+ MulDiv(initial, range);
+ //GCD
+ CleanupStack::PopAndDestroy(); //initial
+ CleanupStack::PopAndDestroy();//buf
+ iConsole.Printf(_L("."));
+ }
+
+ //Test a single iteration where the initial random number is less than a
+ //word so the division and modulo routines that take words rather than
+ //TIntegers can run.
+ //do
+ {
+ //This is this iteration's random number
+ RInteger initial = RInteger::NewRandomL(31);
+ CleanupStack::PushL(initial);
+ //get a number x | 10 < x < 100
+ RInteger crange = RInteger::NewRandomL(min, max);
+ CleanupStack::PushL(crange);
+ TUint range = crange.ConvertToLongL();
+ CleanupStack::PopAndDestroy(&crange); //crange
+
+ AddSub(initial, range);
+ MulDiv(initial, range);
+ CleanupStack::PopAndDestroy(&initial); //initial
+ iConsole.Printf(_L("."));
+ } //while (0);
+
+ CleanupStack::PopAndDestroy();//max
+ CleanupStack::PopAndDestroy(); //min
+
+ MiscDivL();
+
+ User::RequestComplete(status, KErrNone);
+ iActionState = CTestAction::EPostrequisite;
+ __UHEAP_MARK;
+ }
+
+void CBasicMathsFB::AddSub(const TInteger& aInitial, TUint aRange)
+ {
+ __UHEAP_MARK;
+ //This is the copy we are going to do stuff to
+ RInteger a = RInteger::NewL(aInitial);
+ CleanupStack::PushL(a);
+
+ // compute a*aRange using doubling
+ TUint j=1;
+ for(; j<aRange; j++)
+ {
+ a += aInitial;
+ }
+
+ //b = a*aRange;
+ RInteger b = RInteger::NewL(a);
+ CleanupStack::PushL(b);
+ //compute (a*aRange)/aRange using subtraction
+ for(j=1; j<aRange; j++)
+ {
+ b -= aInitial;
+ }
+ // b should be the same as the initial value
+ if( b != aInitial )
+ {
+ iResult = EFalse;
+ iOut.writeString(_L("AddSub Failure:"));
+ iOut.writeNewLine();
+ }
+
+ RInteger c = RInteger::NewL(aInitial);
+ CleanupStack::PushL(c);
+ // compute a*aRange using normal multiplication
+ c *= aRange;
+
+ // c and a should now be the same
+ if( c != a )
+ {
+ iResult = EFalse;
+ }
+
+ RInteger d = RInteger::NewL(a);
+ CleanupStack::PushL(d);
+ //compute (a*aRange)/aRange using normal division
+ d /= aRange;
+ if( d != aInitial )
+ {
+ iResult = EFalse;
+ }
+ RInteger e = RInteger::NewL(a);
+ CleanupStack::PushL(e);
+ e %= aRange;
+ // (a*aRange)%aRange == 0
+ if( e != 0 )
+ {
+ iResult = EFalse;
+ }
+ CleanupStack::PopAndDestroy(5); //e,d,c,b,a
+ __UHEAP_MARKEND;
+ }
+
+void CBasicMathsFB::MulDiv(const TInteger& aInitial, TUint aRange)
+ {
+ __UHEAP_MARK;
+ //This is the copy we are going to do stuff to
+ RInteger a = RInteger::NewL(aInitial);
+ CleanupStack::PushL(a);
+
+ //compute a = aInitial^aRange using repeated multiplication
+ TUint j=1;
+ for(; j<aRange; j++)
+ {
+ a *= aInitial;
+ }
+
+ //b = a
+ RInteger b = RInteger::NewL(a);
+ CleanupStack::PushL(b);
+ //try to find aInitial by repeatedly dividing b by aInitial aRange times
+ for(j=1; j<aRange; j++)
+ {
+ TRAPD(res, b /= aInitial);
+ //the first time through aInitial is 0 so this is expected
+ if(res == KErrDivideByZero && aInitial.IsZero())
+ {
+ break;
+ }
+ else if(res == KErrDivideByZero && aInitial.NotZero())
+ {
+ iResult = EFalse;
+ }
+ else if(res != KErrNone)
+ {
+ User::Leave(res);
+ }
+ }
+ // b should be the same as the initial value
+ if( b != aInitial )
+ {
+ iResult = EFalse;
+ }
+
+ //tests division by something smaller than a word
+ if(aInitial.WordCount() <= 1)
+ {
+ RInteger dividend = RInteger::NewL(a);
+ CleanupStack::PushL(dividend);
+ for(j=1; j<aRange; j++)
+ {
+ RInteger quotient;
+ //try to find aInitial by repeatedly dividing dividend by aInitial aRange times
+ TRAPD(res, quotient = dividend.DividedByL(aInitial.ConvertToLongL()));
+ //the first time through aInitial is 0 so this is expected
+ if(res == KErrDivideByZero && aInitial.IsZero())
+ {
+ break;
+ }
+ else if(res == KErrDivideByZero && aInitial.NotZero())
+ {
+ iResult = EFalse;
+ }
+ else if(res != KErrNone)
+ {
+ User::Leave(res);
+ }
+ dividend.Set(quotient);
+ }
+ if( dividend != aInitial )
+ {
+ iResult = EFalse;
+ }
+
+ TUint remainder=1;
+ TRAPD(res, remainder = a.ModuloL(aInitial.ConvertToLongL()));
+ //the first time through aInitial is 0
+ if(res != KErrDivideByZero && res != KErrNone)
+ {
+ User::Leave(res);
+ }
+ else if(res == KErrDivideByZero && aInitial.NotZero())
+ {
+ iResult = EFalse;
+ }
+ //else we have an expected divide by zero, ignore it.
+ if(remainder != 0)
+ {
+ iResult = EFalse;
+ }
+
+ CleanupStack::PopAndDestroy(÷nd);
+ }
+
+ RInteger c = RInteger::NewL(aRange);
+ CleanupStack::PushL(c);
+ RInteger d = aInitial.ExponentiateL(c);
+ CleanupStack::PushL(d);
+ // c and a should now be the same
+ if( d != a )
+ {
+ iResult = EFalse;
+ }
+
+ RInteger e = RInteger::NewL(a);
+ CleanupStack::PushL(e);
+ TRAPD(res, e %= aInitial);
+ //the first time through aInitial is 0
+ if(res != KErrDivideByZero && res != KErrNone)
+ {
+ User::Leave(res);
+ }
+ else if(res == KErrDivideByZero && aInitial.NotZero())
+ {
+ iResult = EFalse;
+ }
+ //else we have an expected divide by zero, ignore it.
+
+ // (aInitial^aRange)%aInitial == 0
+ if( e != 0 )
+ {
+ iResult = EFalse;
+ }
+ CleanupStack::PopAndDestroy(5);//e,d,c,b,a
+ __UHEAP_MARKEND;
+ }
+
+void CBasicMathsFB::MiscDivL()
+ {
+ __UHEAP_MARK;
+
+ TUint seed = 10;
+ TUint diviser = 2;
+ TInt dividendInt = 10;
+
+ RInteger dividend = RInteger::NewL(seed);
+ CleanupStack::PushL(dividend);
+
+ TInt longInt = dividend.ConvertToLongL();
+
+ // Test for inequality FALSE
+ TBool res0 = dividend != dividendInt;
+ if (res0)
+ {
+ iResult = EFalse;
+ }
+
+ // Test for inequality TRUE
+ res0 = dividend != TInt(diviser);
+ if (!res0)
+ {
+ iResult = EFalse;
+ }
+
+ // Test for equality TRUE
+ res0 = dividend >= dividend;
+ if (!res0)
+ {
+ iResult = EFalse;
+ }
+
+ RInteger quotient;
+ CleanupStack::PushL(quotient);
+ // 10 / 2 = 5
+ TRAPD(res, quotient = dividend.DividedByL(diviser));
+ if (res != KErrNone)
+ {
+ User::Leave(res);
+ }
+ else if (quotient != (dividendInt/diviser))
+ {
+ iResult = EFalse;
+ }
+
+ // Test for greater value TRUE and equality FALSE
+ res0 = dividend >= quotient;
+ if (!res0)
+ {
+ iResult = EFalse;
+ }
+
+ // Test for greater value FALSE and equality FALSE
+ res0 = quotient >= dividend;
+ if (res0)
+ {
+ iResult = EFalse;
+ }
+
+ // 10 / 10 = 1
+ TRAPD(res1, dividend /= dividendInt);
+ if (res1 != KErrNone)
+ {
+ User::Leave(res);
+ }
+ else if (dividend != (dividendInt/seed))
+ {
+ iResult = EFalse;
+ }
+
+ // 1 % 10 = 1 (dividend = 1, due to last step)
+ TRAPD(res2, dividend %= dividendInt);
+ if (res2 != KErrNone)
+ {
+ User::Leave(res);
+ }
+ else if (dividend != (dividendInt/seed))
+ {
+ iResult = EFalse;
+ }
+
+ // 1 x 1 = 1 (dividend = 1, due to last step)
+ RInteger squaredInt = dividend.SquaredL();
+ CleanupStack::PushL(squaredInt);
+ if ( squaredInt != (dividendInt/seed))
+ {
+ iResult = EFalse;
+ }
+
+ RInteger expSeed = RInteger::NewL(10);
+ CleanupStack::PushL(expSeed);
+ RInteger exponent = RInteger::NewL(3);
+ CleanupStack::PushL(exponent);
+ RInteger expResult;
+ CleanupStack::PushL(expResult);
+ TRAPD(res3, expResult = expSeed.ExponentiateL(exponent));
+ if (res3 != KErrNone)
+ {
+ User::Leave(res);
+ }
+ else if (expResult != (10*10*10))
+ {
+ iResult = EFalse;
+ }
+
+ CleanupStack::PopAndDestroy(6, ÷nd); // dividend, quotient, squardInt, expSeed, exponent, expResult
+ __UHEAP_MARKEND;
+ }