⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tst2fish.c

📁 嵌入环境下Blowfish加密算法的实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************
	TST2FISH.C	-- Test code for Twofish encryption

	Submitters:
		Bruce Schneier, Counterpane Systems
		Doug Whiting,	Hi/fn
		John Kelsey,	Counterpane Systems
		Chris Hall,		Counterpane Systems
		David Wagner,	UC Berkeley
			
	Code Author:		Doug Whiting,	Hi/fn
		
	Version  1.00		April 1998
		
	Copyright 1998, Hi/fn and Counterpane Systems.  All rights reserved.
		
	Notes:
		*	Tab size is set to 4 characters in this file
		*	A random number generator is generated and used here, so that 
			the same results can be generated on different platforms/compilers.
		*	Command line arguments:
				-h or ?	==>	give help message
				-lNN	==> set sanity count test loop count to NN
				-m		==> do full MCT generation
				-pPath	==> set file base path
				-r      ==> set initial random seed based on time
				-tNN	==> perform timings with iteration count NN
				-rNN	==> set initial random seed to NN
				-v		==> read & verify files instead of creating them

***************************************************************************/

#include	"aes.h"
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<time.h>
#include	<ctype.h>

extern	CONST char *moduleDescription;	/* which module is running */
extern	CONST char *modeString;			/* which key schedule mode */
extern	CONST int  debugCompile;		/* is external module compiled with debug? */

char CompilerName[8]=
	#if   defined(__BORLANDC__)
		"BCC";
	#elif defined(_MSC_VER)
		"MSC";
	#elif defined(__WATCOMC__)
		"WAT";
	#else
		"???";
	#endif

#if defined(__WATCOMC__) && defined(_M_IX86) && !defined(NO_TIMER)
    DWORD ReadTimeStampCounter(void);
	#pragma aux ReadTimeStampCounter = " db 0Fh,031h" value [eax] modify exact [eax edx] // RDTSC opcode
#endif


/*
+*****************************************************************************
*			Constants/Macros/Tables
-****************************************************************************/

typedef struct
	{
	FILE *f;				/* the file being written/read */
	int  I;					/* test number */
	int	 keySize;			/* key size in bits */
	int	 gotDebugIO;		/* got any debug IO? */
	BYTE pt[BLOCK_SIZE/8];	/* plaintext */
	BYTE ct[BLOCK_SIZE/8];	/* ciphertext */

	keyInstance    ki;		/* use ki.keyDwords as key bits */
	cipherInstance ci;		/* use ci.iv as iv bits */
	} testData;


static char hexTab[]	=	"0123456789ABCDEF";
char		filePath[80]=	"";

int			useAsm		=	0;	/* use assembly language */
int			mctInner	=	MCT_INNER/100;
int			mctOuter	=	MCT_OUTER/10;
int			verify		=	0;	/* set to nonzero to read&verify files */
int			debug		=	0;	/* debugging mode */
int			verbose		=	0;	/* verbose output */
int			quietVerify	=	0;	/* quiet during verify */
int			timeIterCnt	=	0;	/* how many times to iterate for timing */
DWORD		randBits[64]= {1};	/* use Knuth's additive generator */
int			randPtr;
testData *	debugTD		= NULL;	/* for use with debugIO */
int			CLKS_BYTE	=	0;	/* use clks/byte? (vs. clks/block) */
int			FMT_LOG		=	0;	/* format for log file */
int			CLK_MHZ		=	200;/* default clock speed */

#define		KEY_BITS_0			128			/* first key bit setting to test */
#define		STEP_KEY_BITS		((MAX_KEY_BITS-KEY_BITS_0)/2)

static char  hexString[]=
		"0123456789ABCDEFFEDCBA987654321000112233445566778899AABBCCDDEEFF";

/*
+*****************************************************************************
*			Functions
-****************************************************************************/
DWORD Here(DWORD x)
	{
	unsigned int mask=~0U;

	return (* (((DWORD *)&x)-1)) & mask;
	}
extern DWORD TwofishCodeSize(void);

#ifdef USE_ASM
int cdecl get_cpu_type(void);			/* return CPU type */
#endif

/*
+*****************************************************************************
*
* Function Name:	Rand
*
* Function:			Generate random number
*
* Arguments:		None.
*
* Return:			New random number.
*
* Notes:			Uses Knuth's additive generator, other magic
*
-****************************************************************************/
DWORD Rand(void)
	{
	if (randPtr >= 57)
		randPtr = 0;			/* handle the ptr wrap */

	randBits[randPtr] += randBits[(randPtr < 7) ? randPtr-7+57 : randPtr-7];

	randBits[62]+= randBits[61];
	randBits[63] = ROL(randBits[63],9) + 0x6F4ED7D0;	/* very long period! */
	
	return (randBits[randPtr++] ^ randBits[63]) + randBits[62];
	}


/*
+*****************************************************************************
*
* Function Name:	SetRand
*
* Function:			Initialize random number seed
*
* Arguments:		seed	=	new seed value
*
* Return:			None.
*
* Notes:			
*
-****************************************************************************/
void SetRand(DWORD seed)
	{
	int i;
	DWORD x;

	randPtr=0;
	for (i=x=0;i<64;i++)
		{
		randBits[i]=seed;
		x |= seed;		/* keep track of lsb of all entries */
		seed = ROL(seed,11) + 0x12345678;
		}

	if ((x & 1) == 0)	/* insure maximal period by having at least one odd value */
		randBits[0]++;

	for (i=0;i<1000;i++)
		Rand();			/* run it for a while */

	randBits[63] = Rand();
	randBits[62] = Rand();
	randBits[61] = Rand() | 1;	/* make it odd */
	}


/*
+*****************************************************************************
*
* Function Name:	ClearTestData
*
* Function:			Initialize test data to all zeroes
*
* Arguments:		t		=	pointer to testData structure
*
* Return:			None.
*
* Notes:			
*
-****************************************************************************/
void ClearTestData(testData *t)
	{
	t->gotDebugIO=0;
	memset(t->pt,0,BLOCK_SIZE/8);
	memset(t->ct,0,BLOCK_SIZE/8);
	memset(t->ci.iv32,0,BLOCK_SIZE/8);
	memset(t->ki.key32,0,MAX_KEY_BITS/8);
	memset(t->ki.keyMaterial,'0',sizeof(t->ki.keyMaterial));
#if defined(COMPILE_KEY) && defined(USE_ASM)
	t->ki.cSig1=t->ki.cSig2=0;
#endif
	}

/*
+*****************************************************************************
*
* Function Name:	FatalError
*
* Function:			Output a fatal error message and exit
*
* Arguments:		msg		=	fatal error description (printf string)
*					msg2	=	2nd parameter to printf msg
*
* Return:			None.
*
* Notes:
*
-****************************************************************************/
void FatalError(CONST char *msg,CONST char *msg2)
	{
	printf("\nFATAL ERROR: ");
	printf(msg,msg2);
	exit(2);
	}


/*
+*****************************************************************************
*
* Function Name:	GetTimer
*
* Function:			Return a hi-frequency timer value
*
* Arguments:		None
*
* Return:			None.
*
* Notes:
*
-****************************************************************************/
DWORD GetTimer(void)
	{
	DWORD x;

#if defined(__BORLANDC__) && defined(__WIN32__) && !defined(NO_TIMER)
#define	HI_RES_CLK	1
	x=0;
#pragma option -Od					/* disable optimizations (it's a REAL hack!) */
	__emit__(0x0F);	__emit__(0x31);	/* RDTSC opcode */
#pragma option -O.					/* restore optimization setting */
#elif defined(_MSC_VER) && defined(_M_IX86) && !defined(NO_TIMER)
#define	HI_RES_CLK	1
	_asm
		{
		_emit 0x0F
		_emit 0x31
		mov	x,eax
		};
#elif defined(__WATCOMC__) && defined(_M_IX86) && !defined(NO_TIMER)
	#define	HI_RES_CLK	1
	x = ReadTimeStampCounter();
#elif defined(CLOCKS_PER_SEC)
	x=clock();
#else
#define CLOCKS_PER_SEC	1			/* very low resolution timer */
	x=time(NULL);
#endif

	return x;
	}


/*
+*****************************************************************************
*
* Function Name:	TimeOps
*
* Function:			Time encryption/decryption and print results
*
* Arguments:		iterCnt	= how many calls to make
*
* Return:			None.
*
* Notes:			None.
*
-****************************************************************************/
void TimeOps(int iterCnt)
	{
	enum { TEST_CNT	= 3, BLOCK_CNT=64 };
	int   i,j,k,n,q;
	DWORD t0,t1,dt[8],minT;
	DWORD testTime[3][TEST_CNT];
	testData t;
	BYTE text[BLOCK_CNT*(BLOCK_SIZE/8)];
	static char *testName[TEST_CNT]={"BlockEncrypt:","BlockDecrypt:","reKeyEncrypt:"};
	static char *atomName[TEST_CNT]={"block","block","call "};
	static char *format  [TEST_CNT]={"%10.1f/%s ","%10.1f/%s ","%10.1f/%s "};
	static int	 denom   [TEST_CNT]={BLOCK_CNT,BLOCK_CNT,1};
	static int	 needSet [TEST_CNT]={1,1,0};

	ClearTestData(&t);
	for (i=0;i<TEST_CNT;i++)
		{
		if (needSet[i] & 1)
			{
			denom[i]=sizeof(text)/((CLKS_BYTE) ? 1 : (BLOCK_SIZE/8) );
			atomName[i] = (CLKS_BYTE) ? "byte "      : "block";
			}
		format  [i] = (CLKS_BYTE) ? "%10.1f/%s " : "%10.0f/%s ";
		}

	for (i=0;i<MAX_KEY_SIZE;i++)		/* generate random key material */
		t.ki.keyMaterial[i]=hexTab[Rand() & 0xF];
	for (j=0;j<sizeof(text);j++)
		text[j]=(BYTE) Rand();
	memset(dt,0,sizeof(dt));
	dt[0]++;							/* make sure it's in the cache */

	/* calibrate our timing code */
	t0=GetTimer();	t1=GetTimer();	t0++; t1++;	/* force cache line fill */
	for (i=0;i<sizeof(dt)/sizeof(dt[0]);i++)
		{
		t0=GetTimer();
		t1=GetTimer();
		dt[i]=t1-t0;
		}

	for (n=0;n<TEST_CNT;n++)			/* gather all data into testTime[][] */
		{
		for (t.keySize=KEY_BITS_0,q=0;t.keySize<=MAX_KEY_BITS;t.keySize+=STEP_KEY_BITS,q++)
			{
			cipherInit(&t.ci,MODE_ECB,NULL);
			makeKey(&t.ki,DIR_ENCRYPT,t.keySize,t.ki.keyMaterial);

#if defined(HI_RES_CLK)
#define		CALL_N						/* just call once */
#define		ICNT	1.0
#define		TSCALE	1.0
			for (k=0,minT=~0lu;k<iterCnt;k++)
#else
#define		CALL_N	for (j=0;j<iterCnt;j++)
#define		ICNT	((double)iterCnt)
#define		TSCALE	((1.0E6*CLK_MHZ)/CLOCKS_PER_SEC)
			for (k=0,minT=~0lu;k<4;k++)
#endif
				{	/* run a few times to get "best" time */
				switch (n)
					{
					case 0:
						blockEncrypt(&t.ci,&t.ki,text,sizeof(text)*8,text);
						GetTimer();
						t0=GetTimer();
						CALL_N blockEncrypt(&t.ci,&t.ki,text,sizeof(text)*8,text);
						t1=GetTimer();
						break;
					case 1:
						blockDecrypt(&t.ci,&t.ki,text,sizeof(text)*8,text);
						GetTimer();
						t0=GetTimer();
						CALL_N blockDecrypt(&t.ci,&t.ki,text,sizeof(text)*8,text);
						t1=GetTimer();
						break;
					case 2:
						reKey(&t.ki);
						GetTimer();
						t0=GetTimer();
						CALL_N { t.ki.key32[0]+=0x87654321;	/* change key bytes to force cache misses */
								 t.ki.key32[1]+=0x9ABCDEF3;
								 reKey(&t.ki); }
						t1=GetTimer();
						break;
					default:
						FatalError("Unknown test","");
						break;
					}
				if (minT > t1-t0)
					minT = t1-t0;
				}
			testTime[q][n]=minT;
			}
		}
	/* now print all the results */
#ifdef HI_RES_CLK
	if (!FMT_LOG)
		{
		printf("\nCalibrate GetTimer(): ",t1-t0);
		for (i=0;i<sizeof(dt)/sizeof(dt[0]);i++)
			printf("%6ld",dt[i]);
		printf("\n\n");
		}
#else
	printf("All times in clks, assuming %d MHz CPU (use -fmNN switch to set)\n",CLK_MHZ);
	printf("CLOCKS_PER_SEC = %8.1f\n",(double)CLOCKS_PER_SEC);
#endif

	printf("%-13s","keySize=");
	for (t.keySize=KEY_BITS_0;t.keySize<=MAX_KEY_BITS;t.keySize+=STEP_KEY_BITS)
		printf("%10d bits  ",t.keySize);
	printf("\n");
		
	for (n=0;n<TEST_CNT;n++)
		{
		printf("%-13s",testName[n]);
		for (q=0;q<3;q++)
			{
			printf(format[n],TSCALE*testTime[q][n]/(ICNT*(double)denom[n]),atomName[n]);
			}
		printf("\n");
		}
	if (FMT_LOG)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -