kerneltest/e32utils/nistsecurerng/src/utilities.cpp
branchRCL_3
changeset 294 039a3e647356
parent 268 345b1ca54e88
child 295 5460f47b94ad
equal deleted inserted replaced
268:345b1ca54e88 294:039a3e647356
     1 /*
       
     2 * Portions Copyright (c) 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 "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 * The original NIST Statistical Test Suite code is placed in public domain.
       
    16 * (http://csrc.nist.gov/groups/ST/toolkit/rng/documentation_software.html) 
       
    17 * 
       
    18 * This software was developed at the National Institute of Standards and Technology by 
       
    19 * employees of the Federal Government in the course of their official duties. Pursuant
       
    20 * to title 17 Section 105 of the United States Code this software is not subject to 
       
    21 * copyright protection and is in the public domain. The NIST Statistical Test Suite is
       
    22 * an experimental system. NIST assumes no responsibility whatsoever for its use by other 
       
    23 * parties, and makes no guarantees, expressed or implied, about its quality, reliability, 
       
    24 * or any other characteristic. We would appreciate acknowledgment if the software is used.
       
    25 */
       
    26 
       
    27 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
       
    28 U T I L I T I E S
       
    29 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
       
    30 
       
    31 #include "openc.h"
       
    32 #include "../include/externs.h"
       
    33 #include "../include/utilities.h"
       
    34 #include "../include/generators.h"
       
    35 #include "../include/stat_fncs.h"
       
    36 
       
    37 
       
    38 TBuf8<KMaxFileName> gLogFilePath;
       
    39 TInt                gTemplateIndex = 1;
       
    40 
       
    41 bool ConvertToAperiodicBits(BitSequence aSequence[32], long value);
       
    42 
       
    43 
       
    44 int
       
    45 displayGeneratorOptions()
       
    46 {
       
    47 	int		option = 0;
       
    48 
       
    49 	printf("           G E N E R A T O R    S E L E C T I O N \n");
       
    50 	printf("           ______________________________________\n\n");
       
    51 	printf("    [0] Input File                 [1] Linear Congruential\n");
       
    52 	printf("    [2] Quadratic Congruential I   [3] Quadratic Congruential II\n");
       
    53 	printf("    [4] Cubic Congruential         [5] XOR\n");
       
    54 	printf("    [6] Modular Exponentiation     [7] Blum-Blum-Shub\n");
       
    55 	printf("    [8] Micali-Schnorr             [9] G Using SHA-1\n\n");
       
    56 	printf("   Enter Choice: ");
       
    57 	scanf("%d", &option);
       
    58 	printf("\n\n");
       
    59 
       
    60 	return option;
       
    61 }
       
    62 
       
    63 
       
    64 int
       
    65 generatorOptions(char** streamFile)
       
    66 {
       
    67 	char	file[200];
       
    68 	int		option = NUMOFGENERATORS+1; 
       
    69 	
       
    70 	while ( (option < 0) || (option > NUMOFGENERATORS) ) {
       
    71 		option = displayGeneratorOptions();
       
    72 		switch( option ) {
       
    73 			case 0:
       
    74 				printf("\t\tUser Prescribed Input File: ");
       
    75 				scanf("%s", file);
       
    76 				*streamFile = (char*)calloc(200, sizeof(char));
       
    77 				sprintf(*streamFile, "%s", file);
       
    78 				printf("\n");
       
    79 				break;
       
    80 			case 1:
       
    81 				*streamFile = "Linear-Congruential";
       
    82 				break;
       
    83 			case 2:
       
    84 				*streamFile = "Quadratic-Congruential-1";
       
    85 				break;
       
    86 			case 3:
       
    87 				*streamFile = "Quadratic-Congruential-2";
       
    88 				break;
       
    89 			case 4:
       
    90 				*streamFile = "Cubic-Congruential";
       
    91 				break;
       
    92 			case 5:
       
    93 				*streamFile = "XOR";
       
    94 				break;
       
    95 			case 6:
       
    96 				*streamFile = "Modular-Exponentiation";
       
    97 				break;
       
    98 			case 7:
       
    99 				*streamFile = "Blum-Blum-Shub";
       
   100 				break;
       
   101 			case 8:
       
   102 				*streamFile = "Micali-Schnorr";
       
   103 				break;
       
   104 			case 9:
       
   105 				*streamFile = "G using SHA-1";
       
   106 				break;
       
   107 				
       
   108 			/* INTRODUCE NEW PRNG NAMES HERE */
       
   109 			/*
       
   110 			case 10:  *streamFile = "myNewPRNG";
       
   111 				break;
       
   112 			*/
       
   113 			default:
       
   114 				printf("Error:  Out of range - Try again!\n");
       
   115 				break;
       
   116 		}
       
   117 	}
       
   118 	return option;
       
   119 }
       
   120 
       
   121 
       
   122 void
       
   123 chooseTests()
       
   124 {
       
   125 	int		i;
       
   126 	
       
   127 	printf("                S T A T I S T I C A L   T E S T S\n");
       
   128 	printf("                _________________________________\n\n");
       
   129 	printf("    [01] Frequency                       [02] Block Frequency\n");
       
   130 	printf("    [03] Cumulative Sums                 [04] Runs\n");
       
   131 	printf("    [05] Longest Run of Ones             [06] Rank\n");
       
   132 	printf("    [07] Discrete Fourier Transform      [08] Nonperiodic Template Matchings\n");
       
   133 	printf("    [09] Overlapping Template Matchings  [10] Universal Statistical\n");
       
   134 	printf("    [11] Approximate Entropy             [12] Random Excursions\n");
       
   135 	printf("    [13] Random Excursions Variant       [14] Serial\n");
       
   136 	printf("    [15] Linear Complexity\n\n");
       
   137 	printf("         INSTRUCTIONS\n");
       
   138 	printf("            Enter 0 if you DO NOT want to apply all of the\n");
       
   139 	printf("            statistical tests to each sequence and 1 if you DO.\n\n");
       
   140 	printf("   Enter Choice: ");
       
   141 	scanf("%d", &testVector[0]);
       
   142 	printf("\n");
       
   143 	if ( testVector[0] == 1 )
       
   144 	    {
       
   145 		for( i=1; i<=NUMOFTESTS; i++ )
       
   146 			testVector[i] = 1;
       
   147 		
       
   148 		// Disable Fast Fourier Transform Test.
       
   149 		// NIST has discovered a problem with the Fast Fourier Transform test. 
       
   150 		// At this time NIST advises disregarding the results of this test until 
       
   151 		// a further update is posted.
       
   152 		// Link: http://csrc.nist.gov/groups/ST/toolkit/rng/documentation_software.html
       
   153 		//
       
   154 		// When the FFT test is fixed remove the following 5 lines.
       
   155 		printf(" Please Note: \n");
       
   156 		printf(" NIST has discovered a problem with the DFT test and hence the DFT results are invalid currently.\n");
       
   157 		printf(" DFT test will be disabled at the momemt in the NIST test suite run \n \n");        
       
   158 		testVector[TEST_FFT] = 0; 
       
   159 		testVector[0] = 0; 
       
   160 	    }
       
   161 	else {
       
   162 		printf("         INSTRUCTIONS\n");
       
   163 		printf("            Enter a 0 or 1 to indicate whether or not the numbered statistical\n");
       
   164 		printf("            test should be applied to each sequence.\n\n");
       
   165 		printf("      123456789111111\n");
       
   166 		printf("               012345\n");
       
   167 		printf("      ");
       
   168         for ( i=1; i<=NUMOFTESTS; i++ ) 
       
   169             scanf("%1d", &testVector[i]);
       
   170         printf("\n\n");
       
   171     }
       
   172 }
       
   173 
       
   174 
       
   175 void
       
   176 fixParameters()
       
   177 {
       
   178 	int		counter, testid;
       
   179 	
       
   180 	//  Check to see if any parameterized tests are selected
       
   181 	if ( (testVector[TEST_BLOCK_FREQUENCY] != 1) && (testVector[TEST_NONPERIODIC] != 1) && 
       
   182 		 (testVector[TEST_OVERLAPPING] != 1) && (testVector[TEST_APEN] != 1) &&
       
   183 		 (testVector[TEST_SERIAL] != 1) && (testVector[TEST_LINEARCOMPLEXITY] != 1) )
       
   184 			return;
       
   185 		
       
   186 	do {
       
   187 		counter = 1;
       
   188 		printf("        P a r a m e t e r   A d j u s t m e n t s\n");
       
   189 		printf("        -----------------------------------------\n");
       
   190 		if ( testVector[TEST_BLOCK_FREQUENCY] == 1 )
       
   191 			printf("    [%d] Block Frequency Test - block length(M):         %d\n", counter++, tp.blockFrequencyBlockLength);
       
   192 		if ( testVector[TEST_NONPERIODIC] == 1 )
       
   193 			printf("    [%d] NonOverlapping Template Test - block length(m): %d\n", counter++, tp.nonOverlappingTemplateBlockLength);
       
   194 		if ( testVector[TEST_OVERLAPPING] == 1 )
       
   195 			printf("    [%d] Overlapping Template Test - block length(m):    %d\n", counter++, tp.overlappingTemplateBlockLength);
       
   196 		if ( testVector[TEST_APEN] == 1 )
       
   197 			printf("    [%d] Approximate Entropy Test - block length(m):     %d\n", counter++, tp.approximateEntropyBlockLength);
       
   198 		if ( testVector[TEST_SERIAL] == 1 )
       
   199 			printf("    [%d] Serial Test - block length(m):                  %d\n", counter++, tp.serialBlockLength);
       
   200 		if ( testVector[TEST_LINEARCOMPLEXITY] == 1 )
       
   201 			printf("    [%d] Linear Complexity Test - block length(M):       %d\n", counter++, tp.linearComplexitySequenceLength);
       
   202 		printf("\n");
       
   203 		printf("   Select Test (0 to continue): ");
       
   204 		scanf("%1d", &testid);
       
   205 		printf("\n");
       
   206 		
       
   207 		counter = 0;
       
   208 		if ( testVector[TEST_BLOCK_FREQUENCY] == 1 ) {
       
   209 			counter++;
       
   210 			if ( counter == testid ) {
       
   211 				printf("   Enter Block Frequency Test block length: ");
       
   212 				scanf("%d", &tp.blockFrequencyBlockLength);
       
   213 				printf("\n");
       
   214 				continue;
       
   215 			}
       
   216 		}
       
   217 		if ( testVector[TEST_NONPERIODIC] == 1 ) {
       
   218 			counter++;
       
   219 			if ( counter == testid ) {
       
   220 				printf("   Enter NonOverlapping Template Test block Length: ");
       
   221 				scanf("%d", &tp.nonOverlappingTemplateBlockLength);
       
   222 				printf("\n");
       
   223 				continue;
       
   224 			}
       
   225 		}
       
   226 		if ( testVector[TEST_OVERLAPPING] == 1 ) {
       
   227 			counter++;
       
   228 			if ( counter == testid ) {
       
   229 				printf("   Enter Overlapping Template Test block Length: ");
       
   230 				scanf("%d", &tp.overlappingTemplateBlockLength);
       
   231 				printf("\n");
       
   232 				continue;
       
   233 			}
       
   234 		}
       
   235 		if ( testVector[TEST_APEN] == 1 ) {
       
   236 			counter++;
       
   237 			if ( counter == testid ) {
       
   238 				printf("   Enter Approximate Entropy Test block Length: ");
       
   239 				scanf("%d", &tp.approximateEntropyBlockLength);
       
   240 				printf("\n");
       
   241 				continue;
       
   242 			}
       
   243 		}
       
   244 		if ( testVector[TEST_SERIAL] == 1 ) {
       
   245 			counter++;
       
   246 			if ( counter == testid ) {
       
   247 				printf("   Enter Serial Test block Length: ");
       
   248 				scanf("%d", &tp.serialBlockLength);
       
   249 				printf("\n");
       
   250 				continue;
       
   251 			}
       
   252 		}
       
   253 		if ( testVector[TEST_LINEARCOMPLEXITY] == 1 ) {
       
   254 			counter++;
       
   255 			if ( counter == testid ) {
       
   256 				printf("   Enter Linear Complexity Test block Length: ");
       
   257 				scanf("%d", &tp.linearComplexitySequenceLength);
       
   258 				printf("\n");
       
   259 				continue;
       
   260 			}
       
   261 		}
       
   262 	} while ( testid != 0 );
       
   263 }
       
   264 
       
   265 
       
   266 void
       
   267 fileBasedBitStreams(char *streamFile)
       
   268 {
       
   269 	FILE	*fp;
       
   270 	int		mode;
       
   271 	
       
   272 	printf("   Input File Format:\n");
       
   273 	printf("    [0] ASCII - A sequence of ASCII 0's and 1's\n");
       
   274 	printf("    [1] Binary - Each byte in data file contains 8 bits of data\n\n");
       
   275 	printf("   Select input mode:  ");
       
   276 	scanf("%1d", &mode);
       
   277 	printf("\n");
       
   278 	if ( mode == 0 ) {
       
   279 		if ( (fp = fopen(streamFile, "r")) == NULL ) {
       
   280 			printf("ERROR IN FUNCTION fileBasedBitStreams:  file %s could not be opened.\n",  streamFile);
       
   281 			exit(-1);
       
   282 		}
       
   283 		readBinaryDigitsInASCIIFormat(fp, streamFile);
       
   284 		fclose(fp);
       
   285 	}
       
   286 	else if ( mode == 1 ) {
       
   287 		if ( (fp = fopen(streamFile, "rb")) == NULL ) {
       
   288 			printf("ERROR IN FUNCTION fileBasedBitStreams:  file %s could not be opened.\n", streamFile);
       
   289 			exit(-1);
       
   290 		}
       
   291 		readHexDigitsInBinaryFormat(fp);
       
   292 		fclose(fp);
       
   293 	}
       
   294 }
       
   295 
       
   296 
       
   297 void
       
   298 readBinaryDigitsInASCIIFormat(FILE *fp, char *streamFile)
       
   299 {
       
   300 	int		i, j, num_0s, num_1s, bitsRead, bit;
       
   301 	
       
   302 	if ( (epsilon = (BitSequence *) calloc(tp.n, sizeof(BitSequence))) == NULL ) {
       
   303 		printf("BITSTREAM DEFINITION:  Insufficient memory available.\n");
       
   304 		printf("Statistical Testing Aborted!\n");
       
   305 		return;
       
   306 	}
       
   307 	printf("     Statistical Testing In Progress.........\n\n");   
       
   308 	for ( i=0; i<tp.numOfBitStreams; i++ ) {
       
   309 		num_0s = 0;
       
   310 		num_1s = 0;
       
   311 		bitsRead = 0;
       
   312 		for ( j=0; j<tp.n; j++ ) {
       
   313 			if ( fscanf(fp, "%1d", &bit) == EOF ) {
       
   314 				printf("ERROR:  Insufficient data in file %s.  %d bits were read.\n", streamFile, bitsRead);
       
   315 				fclose(fp);
       
   316 				free(epsilon);
       
   317 				return;
       
   318 			}
       
   319 			else {
       
   320 				bitsRead++;
       
   321 				if ( bit == 0 ) 
       
   322 					num_0s++;
       
   323 				else 
       
   324 					num_1s++;
       
   325 				epsilon[j] = (BitSequence)bit;
       
   326 			}
       
   327 		}
       
   328 		fprintf(freqfp, "\t\tBITSREAD = %d 0s = %d 1s = %d\n", bitsRead, num_0s, num_1s);
       
   329 		nist_test_suite();
       
   330 	}
       
   331 	free(epsilon);
       
   332 }
       
   333 
       
   334 
       
   335 void
       
   336 readHexDigitsInBinaryFormat(FILE *fp)
       
   337 {
       
   338 	int		i, done, num_0s, num_1s, bitsRead;
       
   339 	BYTE	buffer[4];
       
   340 	
       
   341 	if ( (epsilon = (BitSequence *) calloc(tp.n,sizeof(BitSequence))) == NULL ) {
       
   342 		printf("BITSTREAM DEFINITION:  Insufficient memory available.\n");
       
   343 		return;
       
   344 	}
       
   345 
       
   346 	printf("     Statistical Testing In Progress.........\n\n");   
       
   347 	for ( i=0; i<tp.numOfBitStreams; i++ ) {
       
   348 		num_0s = 0;
       
   349 		num_1s = 0;
       
   350 		bitsRead = 0;
       
   351 		done = 0;
       
   352 		do {
       
   353 			if ( fread(buffer, sizeof(unsigned char), 4, fp) != 4 ) {
       
   354 				printf("READ ERROR:  Insufficient data in file.\n");
       
   355 				free(epsilon);
       
   356 				return;
       
   357 			}
       
   358 			done = convertToBits(buffer, 32, tp.n, &num_0s, &num_1s, &bitsRead);
       
   359 		} while ( !done );
       
   360 		fprintf(freqfp, "\t\tBITSREAD = %d 0s = %d 1s = %d\n", bitsRead, num_0s, num_1s);
       
   361 		
       
   362 		nist_test_suite();
       
   363 		
       
   364 	}
       
   365 	free(epsilon);
       
   366 }
       
   367 
       
   368 
       
   369 int
       
   370 convertToBits(const BYTE *x, int xBitLength, int bitsNeeded, int *num_0s, int *num_1s, int *bitsRead)
       
   371 {
       
   372 	int		i, j, count, bit;
       
   373 	BYTE	mask;
       
   374 	int		zeros, ones;
       
   375 
       
   376 	count = 0;
       
   377 	zeros = ones = 0;
       
   378 	for ( i=0; i<(xBitLength+7)/8; i++ ) {
       
   379 		mask = 0x80;
       
   380 		for ( j=0; j<8; j++ ) {
       
   381 			if ( *(x+i) & mask ) {
       
   382 				bit = 1;
       
   383 				(*num_1s)++;
       
   384 				ones++;
       
   385 			}
       
   386 			else {
       
   387 				bit = 0;
       
   388 				(*num_0s)++;
       
   389 				zeros++;
       
   390 			}
       
   391 			mask >>= 1;
       
   392 			epsilon[*bitsRead] = (BitSequence)bit;
       
   393 			(*bitsRead)++;
       
   394 			if ( *bitsRead == bitsNeeded )
       
   395 				return 1;
       
   396 			if ( ++count == xBitLength )
       
   397 				return 0;
       
   398 		}
       
   399 	}
       
   400 	
       
   401 	return 0;
       
   402 }
       
   403 
       
   404 
       
   405 void
       
   406 openOutputStreams(int option)
       
   407 {
       
   408 	int		i, numOfBitStreams, numOfOpenFiles = 0;
       
   409 	char	freqfn[200], statsDir[200], resultsDir[200];
       
   410     TBuf16<200>      logFilePath;
       
   411     logFilePath.Copy(_L("c:\\nist"));
       
   412 
       
   413     printf("      Directory for logs : ");
       
   414     gConsole->Printf(logFilePath);
       
   415     ReadStringFromConsole(logFilePath);
       
   416     gConsole->Printf(_L("\r\n"));
       
   417     gLogFilePath.Copy(logFilePath);
       
   418 
       
   419     TBuf8<100> tempName;
       
   420     TBuf<100> directoryName;
       
   421 
       
   422     for(i = 1; i <= NUMOFTESTS; ++i)
       
   423         {
       
   424         tempName.Format(_L8("%s\\experiments\\%s\\%s\\"), gLogFilePath.PtrZ(),  generatorDir[option], testNames[i]);
       
   425         directoryName.Copy(tempName);
       
   426         gFileSession.MkDirAll(directoryName);
       
   427         }
       
   428 	
       
   429 	sprintf(freqfn, "%s\\experiments\\%s\\freq", gLogFilePath.PtrZ(), generatorDir[option]);
       
   430 	if ( (freqfp = fopen(freqfn, "w")) == NULL ) {
       
   431 		printf("\t\tMAIN:  Could not open freq file: experiments/%s/freq", generatorDir[option]);
       
   432 		exit(-1);
       
   433 	}
       
   434 
       
   435 	TBuf8<512> finalAnalysisReport;
       
   436     finalAnalysisReport.Format(_L8("%s\\finalAnalysisReport"), gLogFilePath.PtrZ());
       
   437 
       
   438     if ( (summary = fopen((const char *)finalAnalysisReport.PtrZ(), "w")) == NULL ) {
       
   439 		printf("\t\tMAIN:  Could not open stats file: %s\\experiments\\%s\\finalAnalysisReport",gLogFilePath.PtrZ(), generatorDir[option]);
       
   440 		exit(-1);
       
   441 	}
       
   442 	
       
   443 	for( i=1; i<=NUMOFTESTS; i++ ) {
       
   444 		if ( testVector[i] == 1 ) {
       
   445 			sprintf(statsDir, "%s\\experiments\\%s\\%s\\stats", gLogFilePath.PtrZ(), generatorDir[option], testNames[i]);
       
   446 			sprintf(resultsDir, "%s\\experiments\\%s\\%s\\results", gLogFilePath.PtrZ(), generatorDir[option], testNames[i]);
       
   447 			if ( (stats[i] = fopen(statsDir, "w")) == NULL ) {	/* STATISTICS LOG */
       
   448 				printf("ERROR: LOG FILES COULD NOT BE OPENED.\n");
       
   449 				printf("       MAX # OF OPENED FILES HAS BEEN REACHED = %d\n", numOfOpenFiles);
       
   450 				printf("-OR-   THE OUTPUT DIRECTORY DOES NOT EXIST.\n");
       
   451 				exit(-1);
       
   452 			}
       
   453 			else
       
   454 				numOfOpenFiles++;
       
   455 			if ( (results[i] = fopen(resultsDir, "w")) == NULL ) {	/* P_VALUES LOG   */
       
   456 				 printf("ERROR: LOG FILES COULD NOT BE OPENED.\n");
       
   457 				 printf("       MAX # OF OPENED FILES HAS BEEN REACHED = %d\n", numOfOpenFiles);
       
   458 				 printf("-OR-   THE OUTPUT DIRECTORY DOES NOT EXIST.\n");
       
   459 				 exit(-1);
       
   460 			}
       
   461 			else
       
   462 				numOfOpenFiles++;
       
   463 		}
       
   464 	}
       
   465 	printf("   How many bitstreams? ");
       
   466 	scanf("%d", &numOfBitStreams);
       
   467 	tp.numOfBitStreams = numOfBitStreams;
       
   468 	printf("\n");
       
   469 }
       
   470 
       
   471 
       
   472 void
       
   473 invokeTestSuite(int option, char *streamFile)
       
   474 {
       
   475 	fprintf(freqfp, "________________________________________________________________________________\n\n");
       
   476 	fprintf(freqfp, "\t\tALPHA = %6.4f\n", ALPHA);
       
   477 	fprintf(freqfp, "________________________________________________________________________________\n\n");
       
   478 	if ( option != 0 )
       
   479 		printf("     Statistical Testing In Progress.........\n\n");
       
   480 	switch( option ) {
       
   481 		case 0:
       
   482 			fileBasedBitStreams(streamFile);
       
   483 			break;
       
   484 		case 1:
       
   485 			lcg();
       
   486 			break;
       
   487 		case 2:
       
   488 			quadRes1();
       
   489 			break;
       
   490 		case 3:
       
   491 			quadRes2();
       
   492 			break;
       
   493 		case 4:
       
   494 			cubicRes();
       
   495 			break;
       
   496 		case 5:
       
   497 			exclusiveOR();
       
   498 			break;
       
   499 		case 6:
       
   500 			modExp();
       
   501 			break;
       
   502 		case 7:
       
   503 			bbs();
       
   504 			break;
       
   505 		case 8:
       
   506 			micali_schnorr();
       
   507 			break;
       
   508 		case 9:
       
   509 			SHA1();
       
   510 			break;
       
   511 		case 10:
       
   512 		    HASH_DRBG();
       
   513 		    break;
       
   514 			
       
   515 		/* INTRODUCE NEW PSEUDO RANDOM NUMBER GENERATORS HERE */
       
   516 			
       
   517 		default:
       
   518 			printf("Error in invokeTestSuite!\n");
       
   519 			break;
       
   520 	}
       
   521 	printf("     Statistical Testing Complete!!!!!!!!!!!!\n\n");
       
   522 }
       
   523 
       
   524 
       
   525 void
       
   526 nist_test_suite()
       
   527 {
       
   528 	if ( (testVector[0] == 1) || (testVector[TEST_FREQUENCY] == 1) ) 
       
   529 		Frequency(tp.n);
       
   530 	
       
   531 	if ( (testVector[0] == 1) || (testVector[TEST_BLOCK_FREQUENCY] == 1) ) 
       
   532 		BlockFrequency(tp.blockFrequencyBlockLength, tp.n);
       
   533 	
       
   534 	if ( (testVector[0] == 1) || (testVector[TEST_CUSUM] == 1) )
       
   535 		CumulativeSums(tp.n);
       
   536 	
       
   537 	if ( (testVector[0] == 1) || (testVector[TEST_RUNS] == 1) )
       
   538 		Runs(tp.n); 
       
   539 	
       
   540 	if ( (testVector[0] == 1) || (testVector[TEST_LONGEST_RUN] == 1) )
       
   541 		LongestRunOfOnes(tp.n);
       
   542 	
       
   543 	if ( (testVector[0] == 1) || (testVector[TEST_RANK] == 1) )
       
   544 		Rank(tp.n);
       
   545 	
       
   546 	if ( (testVector[0] == 1) || (testVector[TEST_FFT] == 1) )
       
   547 	    {
       
   548         // Disable Fast Fourier Transform Test.
       
   549 		// NIST has discovered a problem with the Fast Fourier Transform test. 
       
   550 		// At this time NIST advises disregarding the results of this test until 
       
   551 		// a further update is posted.
       
   552 		// Link: http://csrc.nist.gov/groups/ST/toolkit/rng/documentation_software.html
       
   553 		//
       
   554 		// When the FFT test is fixed remove the following 3 printf lines and uncomment the 4th line.
       
   555         printf("  Please Note: NIST has discovered a problem with the DFT test and hence\n");
       
   556         printf("  the DFT results are invalid currently.\n");
       
   557         printf("  So all tests except DFT will run until futher notification from NIST \n \n");   
       
   558         //DiscreteFourierTransform(tp.n);
       
   559 	    }
       
   560 	    	
       
   561 	if ( (testVector[0] == 1) || (testVector[TEST_NONPERIODIC] == 1) )
       
   562 		NonOverlappingTemplateMatchings(tp.nonOverlappingTemplateBlockLength, tp.n);
       
   563 	
       
   564 	if ( (testVector[0] == 1) || (testVector[TEST_OVERLAPPING] == 1) )
       
   565 		OverlappingTemplateMatchings(tp.overlappingTemplateBlockLength, tp.n);
       
   566 	
       
   567 	if ( (testVector[0] == 1) || (testVector[TEST_UNIVERSAL] == 1) )
       
   568 		Universal(tp.n);
       
   569 	
       
   570 	if ( (testVector[0] == 1) || (testVector[TEST_APEN] == 1) )
       
   571 		ApproximateEntropy(tp.approximateEntropyBlockLength, tp.n);
       
   572 	
       
   573 	if ( (testVector[0] == 1) || (testVector[TEST_RND_EXCURSION] == 1) )
       
   574 		RandomExcursions(tp.n);
       
   575 	
       
   576 	if ( (testVector[0] == 1) || (testVector[TEST_RND_EXCURSION_VAR] == 1) )
       
   577 		RandomExcursionsVariant(tp.n);
       
   578 	
       
   579 	if ( (testVector[0] == 1) || (testVector[TEST_SERIAL] == 1) )
       
   580 		Serial(tp.serialBlockLength,tp.n);
       
   581 	
       
   582 	if ( (testVector[0] == 1) || (testVector[TEST_LINEARCOMPLEXITY] == 1) )
       
   583 		LinearComplexity(tp.linearComplexitySequenceLength, tp.n);
       
   584 }
       
   585 
       
   586 void GetNextTemplateItem(BitSequence aBitSequence[])
       
   587     {
       
   588     int count = (TInt)pow(2, tp.overlappingTemplateBlockLength);
       
   589     
       
   590     for(bool isSuccess = false; (!isSuccess) && (gTemplateIndex < count); ++gTemplateIndex)
       
   591         {
       
   592         isSuccess = ConvertToAperiodicBits(aBitSequence, gTemplateIndex);
       
   593         }
       
   594     }
       
   595 
       
   596 
       
   597 bool ConvertToAperiodicBits(BitSequence aSequence[32], long value)
       
   598     {
       
   599     int bitMask = 1 << (KMaxBit-1);
       
   600     long count = tp.overlappingTemplateBlockLength;
       
   601     
       
   602     for(int c = 0; c < KMaxBit; c++) 
       
   603         {
       
   604         if (value & bitMask)
       
   605             aSequence[c] = 1;
       
   606         else
       
   607             aSequence[c] = 0;
       
   608         value <<= 1;
       
   609         }
       
   610 
       
   611     bool match = false;
       
   612     
       
   613     for(int i = 1; i < count; i++) 
       
   614         {
       
   615         match = false;
       
   616         if ((aSequence[KMaxBit-count]!= aSequence[KMaxBit-1]) && ((aSequence[KMaxBit-count]!= aSequence[KMaxBit-2])||(aSequence[KMaxBit-count+1] != aSequence[KMaxBit-1]))) 
       
   617             {
       
   618             for(int c = KMaxBit-count; c <= (KMaxBit-1)-i; c++) 
       
   619                 {
       
   620                 if (aSequence[c] != aSequence[c+i]) 
       
   621                     {
       
   622                     match = true;
       
   623                     break;
       
   624                     }
       
   625                 }
       
   626             }
       
   627         
       
   628         if (!match) 
       
   629             {
       
   630             break;
       
   631             }
       
   632         }
       
   633 
       
   634     return match;
       
   635     }
       
   636