idea.c

来自「在PGP中用到的IDEA专利算法源码」· C语言 代码 · 共 632 行 · 第 1/2 页

C
632
字号
		else			for(i=0; i<6; i++)				printf(" %6u", Z[j*6+i]);	}	/* Compute decryption subkeys from encryption subkeys... */	de_key_idea(Z,DK);	printf("\nDecryption key subblocks: ");	for(j=0; j<ROUNDS+1; j++)	{		printf("\nround %d:   ", j+1);		if (j==ROUNDS)			for(i=0; i<4; i++)				printf(" %6u", DK[j*6+i]);		else			for(i=0; i<6; i++)				printf(" %6u", DK[j*6+i]);	}	/* Make a sample plaintext pattern for testing... */	for (k=0; k<4; k++)		XX[k] = k;	printf("\n Encrypting %d KBytes (%ld blocks)...", KBYTES, KBYTES*64l);	fflush(stdout);	start = clock();	cipher_idea(XX,YY,Z);       /* encrypt plaintext XX, making YY */ 	for (l = 1; l < 64*KBYTES; l++)		cipher_idea(YY,YY,Z);	/* repeated encryption */	cipher_idea(YY,TT,DK);      /* decrypt ciphertext YY, making TT */ 	for (l = 1; l < 64*KBYTES; l++)		cipher_idea(TT,TT,DK);	/* repeated decryption */	end = clock() - start;	l = end * 1000. / CLOCKS_PER_SEC + 1;	i = l/1000;	j = l%1000;	l = KBYTES * 1024. * CLOCKS_PER_SEC / end;	printf("%d.%03d seconds = %ld bytes per second\n", i, j, l);	printf("\nX %6u   %6u  %6u  %6u \n",    	  XX[0], XX[1],  XX[2], XX[3]);	printf("Y %6u   %6u  %6u  %6u \n",	  YY[0], YY[1],  YY[2], YY[3]);	printf("T %6u   %6u  %6u  %6u \n",	  TT[0], TT[1],  TT[2], TT[3]);	/* Now decrypted TT should be same as original XX */	for (k=0; k<4; k++)		if (TT[k] != XX[k])		{			printf("\n\07Error!  Noninvertable encryption.\n");			exit(-1);	/* error exit */ 		}	printf("\nNormal exit.\n");	exit(0);	/* normal exit */ }        /* main */#endif		/* TEST *//*************************************************************************//* *	xorbuf - change buffer via xor with random mask block *	Used for Cipher Feedback (CFB) or Cipher Block Chaining *	(CBC) modes of encryption. *	Can be applied for any block encryption algorithm, *	with any block size, such as the DES or the IDEA cipher. */static void xorbuf(register byteptr buf, register byteptr mask, 	register int count)/*	count must be > 0 */{	if (count) 		do			*buf++ ^= *mask++;		while (--count);}	/* xorbuf *//* *	cfbshift - shift bytes into IV for CFB input *	Used only for Cipher Feedback (CFB) mode of encryption. *	Can be applied for any block encryption algorithm with any  *	block size, such as the DES or the IDEA cipher. */static void cfbshift(register byteptr iv, register byteptr buf, 		register int count, int blocksize)/* 	iv is the initialization vector. *	buf is the buffer pointer. *	count is the number of bytes to shift in...must be > 0. *	blocksize is 8 bytes for DES or IDEA ciphers. */{	int retained;	if (count)	{		retained = blocksize-count;	/* number bytes in iv to retain */		/* left-shift retained bytes of IV over by count bytes to make room */		while (retained--)		{			*iv = *(iv+count);			iv++;		}		/* now copy count bytes from buf to shifted tail of IV */		do	*iv++ = *buf++;		while (--count);	}}	/* cfbshift *//* Key schedules for IDEA encryption and decryption */static IDEAkey Z;static word16 *iv_idea;		/* pointer to IV for CFB or CBC */static boolean cfb_dc_idea; /* TRUE iff CFB decrypting *//* initkey_idea initializes IDEA for ECB mode operations */static void initkey_idea(byte key[16], boolean decryp){	word16 userkey[8];	/* IDEA key is 16 bytes long */	int i;	/* Assume each pair of bytes comprising a word is ordered MSB-first. */	for (i=0; i<8; i++)	{		userkey[i] = (key[0]<<8) + key[1];		key++; key++;	}	en_key_idea(userkey,Z);	if (decryp)	{		de_key_idea(Z,Z);	/* compute inverse key schedule DK */	}	for (i=0; i<8; i++)	/* Erase dangerous traces */		userkey[i] = 0;} /* initkey_idea *//*	Run a 64-bit block thru IDEA in ECB (Electronic Code Book) mode,	using the currently selected key schedule.*/static void idea_ecb(word16 *inbuf, word16 *outbuf){	/* Assume each pair of bytes comprising a word is ordered MSB-first. */#ifndef HIGHFIRST	/* If this is a least-significant-byte-first CPU */	word16 x;	/* Invert the byte order for each 16-bit word for internal use. */	x = inbuf[0]; outbuf[0] = x >> 8 | x << 8;	x = inbuf[1]; outbuf[1] = x >> 8 | x << 8;	x = inbuf[2]; outbuf[2] = x >> 8 | x << 8;	x = inbuf[3]; outbuf[3] = x >> 8 | x << 8;	cipher_idea(outbuf, outbuf, Z);	x = outbuf[0]; outbuf[0] = x >> 8 | x << 8;	x = outbuf[1]; outbuf[1] = x >> 8 | x << 8;	x = outbuf[2]; outbuf[2] = x >> 8 | x << 8;	x = outbuf[3]; outbuf[3] = x >> 8 | x << 8;#else	/* HIGHFIRST */	/* Byte order for internal and external representations is the same. */	cipher_idea(inbuf, outbuf, Z);#endif	/* HIGHFIRST */} /* idea_ecb *//* *	initcfb - Initializes the IDEA key schedule tables via key, *	and initializes the Cipher Feedback mode IV. *	References context variables cfb_dc_idea and iv_idea. */void initcfb_idea(word16 iv0[4], byte key[16], boolean decryp)/* 	iv0 is copied to global iv_idea, buffer will be destroyed by ideacfb.	key is pointer to key buffer.	decryp is TRUE if decrypting, FALSE if encrypting.*/{	iv_idea = iv0;	cfb_dc_idea = decryp;	initkey_idea(key,FALSE);} /* initcfb_idea *//* *	ideacfb - encipher a buffer with IDEA enciphering algorithm, *		using Cipher Feedback (CFB) mode. * *	Assumes initcfb_idea has already been called. *	References context variables cfb_dc_idea and iv_idea. */void ideacfb(byteptr buf, int count)/*	buf is input, output buffer, may be more than 1 block. *	count is byte count of buffer.  May be > IDEABLOCKSIZE. */{	int chunksize;	/* smaller of count, IDEABLOCKSIZE */	word16 temp[IDEABLOCKSIZE/2];	while ((chunksize = min(count,IDEABLOCKSIZE)) > 0)	{		idea_ecb(iv_idea,temp);  /* encrypt iv_idea, making temp. */ 		if (cfb_dc_idea)	/* buf is ciphertext */			/* shift in ciphertext to IV... */			cfbshift((byte *)iv_idea,buf,chunksize,IDEABLOCKSIZE);		/* convert buf via xor */		xorbuf(buf,(byte *)temp,chunksize); /* buf now has enciphered output */		if (!cfb_dc_idea)	/* buf was plaintext, is now ciphertext */			/* shift in ciphertext to IV... */			cfbshift((byte *)iv_idea,buf,chunksize,IDEABLOCKSIZE);		count -= chunksize;		buf += chunksize;	}} /* ideacfb *//*	close_idea function erases all the key schedule information when 	we are all done with a set of operations for a particular IDEA key 	context.  This is to prevent any sensitive data from being left 	around in memory.*/void close_idea(void)	/* erase current key schedule tables */{	short i;	for (i = 0; i < KEYLEN; i++)		Z[i] = 0;}	/* close_idea() *//********************************************************************//* *	These buffers are used by init_idearand, idearand, and close_idearand. */static word16 dtbuf_idea[4] = {0}; /* buffer for enciphered timestamp */static word16 randseed_idea[4] = {0}; /* seed for IDEA random # generator */static word16 randbuf_idea[4] = {0}; /* buffer for IDEA random # generator */static byte randbuf_idea_counter = 0;	/* # of random bytes left in randbuf_idea */static IDEAkey randkey_idea;	/* Expanded key for IDEA random # generator *//* *	init_idearand - initialize idearand, IDEA random number generator. *		Used for generating cryptographically strong random numbers. *		Much of the design comes from Appendix C of ANSI X9.17. *		key is pointer to IDEA key buffer. *		seed is pointer to random number seed buffer. *		tstamp is a 32-bit timestamp */void init_idearand(byte key[16], byte seed[8], word32 tstamp){	int i;	en_key_idea((word16 *)key, randkey_idea);	for (i=0; i<4; i++)		/* capture timestamp material */	{	dtbuf_idea[i] = tstamp;	/* get bottom word */		tstamp = tstamp >> 16;	/* drop bottom word */		/* tstamp has only 4 bytes-- last 4 bytes will always be 0 */	}	/* Start with enciphered timestamp: */	cipher_idea(dtbuf_idea, dtbuf_idea, randkey_idea);	/* initialize seed material */	for (i=0; i<8; i++)		((byte *)randseed_idea)[i] = seed[i];	randbuf_idea_counter = 0;	/* # of random bytes left in randbuf_idea */} /* init_idearand *//* *	idearand - IDEA pseudo-random number generator *		Used for generating cryptographically strong random numbers. *		Much of the design comes from Appendix C of ANSI X9.17. */byte idearand(void){	int i;	if (randbuf_idea_counter==0)	/* if random buffer is spent...*/	{	/* Combine enciphered timestamp with seed material: */		for (i=0; i<4; i++)			randseed_idea[i] ^= dtbuf_idea[i];		cipher_idea(randseed_idea,randbuf_idea,randkey_idea); /* fill new block */		/* Compute new seed vector: */		for (i=0; i<4; i++)			randseed_idea[i] = randbuf_idea[i] ^ dtbuf_idea[i];		cipher_idea(randseed_idea,randseed_idea,randkey_idea); /* fill new seed */		randbuf_idea_counter = 8;	/* reset counter for full buffer */	}	/* Take a byte from randbuf_idea: */	return(((byte *)randbuf_idea)[--randbuf_idea_counter]);} /* idearand */void close_idearand(void){	/* Erase random IDEA buffers and wipe out IDEA key info */	int i;	for (i=0; i<4; i++)	{	randbuf_idea[i] = 0;		randseed_idea[i] = 0;		dtbuf_idea[i] = 0;	}	for (i = 0; i<KEYLEN; i++)		randkey_idea[i] = 0;}	/* close_idearand *//* end of idea.c */

⌨️ 快捷键说明

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