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

📄 twofish.c

📁 BestCrypt开源加密原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
 * File: bc_tfish.c
 *  
 * Purpose: The TWOFISH algorithm implementation.
 *
 *  Twofish algorithm's authors:
 *		Bruce Schneier, Counterpane Systems
 *		Doug Whiting,	Hi/fn
 *		John Kelsey,	Counterpane Systems
 *		Chris Hall,		Counterpane Systems
 *		David Wagner,	UC Berkeley
 *
 * The code is based on Doug Whiting Twofish implementation.
 *
 * The code is modified for using as an Encryption Module for BestCrypt system.
 *
 * The following changings were made:
 *
 *   1) BestCrypt uses a maximum encryption key length, i.e. 256 bit.
 *	    So the Twofish implementation here is for key length equal to 256 bites only.
 *
 *   2) Reenterability of the BestCrypt module requires to avoid modifications 
 *	    of the extended KeyInstance structure after its initialization, so 
 *      the ReverseRoundSubkeys procedure was completely removed from 
 *		Mr. Doug Whiting's original sources. To compensate that, EncryptRound(K,R) 
 *		macros was modified.
 *
 *  The changings were made by Sergey Frolov, Jetico, Inc.
 * 
 ***************************************************************************/

/* the string MUST be commented if */
/*#include <windows.h>   #ifndef __WIN95__
#include <windef.h>
#else
#include <basedef.h>
#endif

*/#include "bc_tfish.h"

#include "table.h"

#if LittleEndian
#define		Bswap(x)			(x)		/* NOP for little-endian machines */
#define		ADDR_XOR			0		/* NOP for little-endian machines */
#else
#define		Bswap(x)			((ROR(x,8) & 0xFF00FF00) | (ROL(x,8) & 0x00FF00FF))
#define		ADDR_XOR			3		/* convert byte address in dword */
#endif

/*	Macros for extracting bytes from dwords (correct for endianness) */
#define	_b(x,N)	(((BYTE *)&x)[((N) & 3) ^ ADDR_XOR]) /* pick bytes out of a dword */

#define		b0(x)			_b(x,0)		/* extract LSB of DWORD */
#define		b1(x)			_b(x,1)
#define		b2(x)			_b(x,2)
#define		b3(x)			_b(x,3)		/* extract MSB of DWORD */

/* Rotation left (ROL) and rotation right (ROR) operations */
#define	ROL(x,n) (((x) << ((n) & 0x1F)) | ((x) >> (32-((n) & 0x1F))))
#define	ROR(x,n) (((x) >> ((n) & 0x1F)) | ((x) << (32-((n) & 0x1F))))


/*	Macros for extracting bytes from dwords (correct for endianness):
    pick bytes out of a dword 
 */
#define	_b(x,N)	(((BYTE *)&x)[((N) & 3) ^ ADDR_XOR])


/* Global data */
int		NeedToBuildMDS=1;	/* is MDStab initialized yet? */

DWORD	MDStab[4][256];		/* Initialized ONE time only */


#define		_sBox_	 key->sBox8x32

/* set a single S-box value, given the input byte */
#define sbSet(N,i,J,v) { _sBox_[N&2][2*i+(N&1)+2*J]=MDStab[N][v]; }

 /* Fe32_ does a full S-box + MDS lookup.  Need to #define _sBox_ before use.
   Note that we "interleave" 0,1, and 2,3 to avoid cache bank collisions
   in optimized assembly language.
*/
#define	Fe32(x,R) (_sBox_[0][2*_b(x,R  )] ^ _sBox_[0][2*_b(x,R+1)+1] ^	\                   _sBox_[2][2*_b(x,R+2)] ^ _sBox_[2][2*_b(x,R+3)+1])
	
/* Encryption macroses */

#define	EncryptRound(K,R)		                                \			t0	   = Fe32(x[K  ],0);		        \			t1	   = Fe32(x[K^1],3);		        \			x[K^3] = ROL (x[K^3],1);			\			x[K^2]^= t0 +   t1 + sk[ TOTAL_SUBKEYS - 2 - 2*(R) ]; \			x[K^3]^= t0 + 2*t1 + sk[ TOTAL_SUBKEYS - 1 - 2*(R) ]; \			x[K^2] = ROR(x[K^2],1);

#define		Encrypt2(R)	{ EncryptRound(0,R+1); EncryptRound(2,R); }


/* Decryption macroses */

#define	DecryptRound(K,R)					\			t0	   = Fe32(x[K  ],0);		\			t1	   = Fe32(x[K^1],3);		\			x[K^2] = ROL (x[K^2],1);	        \			x[K^2]^= t0 +   t1 + sk[ROUND_SUBKEYS+2*(R)  ];	        \			x[K^3]^= t0 + 2*t1 + sk[ROUND_SUBKEYS+2*(R)+1];	        \			x[K^3] = ROR (x[K^3],1);				\
#define		Decrypt2(R)	{ DecryptRound(2,R+1); DecryptRound(0,R); }

/*
+*****************************************************************************
*
* Function Name:	BuildMDS
*
* Function:			Initialize the MDStab array
*
* Arguments:		None.
*
* Return:			None.
*
* Notes:
*	Here we precompute all the fixed MDS table.  This only needs to be done
*	one time at initialization.
*
-****************************************************************************/

void BuildMDS(void)
{
	int i;
	DWORD d;
	BYTE m1[2],mX[2],mY[2];

	if (!NeedToBuildMDS) return;
	NeedToBuildMDS = 0;			/* we won't modify the table again */
	
	for (i=0;i<256;i++)
	{
		m1[0]=P8x8[0][i];		/* compute all the matrix elements */
		mX[0]=(BYTE) Mul_X(m1[0]);
		mY[0]=(BYTE) Mul_Y(m1[0]);

		m1[1]=P8x8[1][i];
		mX[1]=(BYTE) Mul_X(m1[1]);
		mY[1]=(BYTE) Mul_Y(m1[1]);

#undef	Mul_1					/* change what the pre-processor does with Mij */
#undef	Mul_X
#undef	Mul_Y
#define	Mul_1	m1				/* It will now access m01[], m5B[], and mEF[] */
#define	Mul_X	mX				
#define	Mul_Y	mY

#define	SetMDS(N)				\		b0(d) = M0##N[P_##N##0];	\		b1(d) = M1##N[P_##N##0];	\		b2(d) = M2##N[P_##N##0];	\		b3(d) = M3##N[P_##N##0];	\		MDStab[N][i] = d;

		SetMDS(0);				/* fill in the matrix with elements computed above */
		SetMDS(1);
		SetMDS(2);
		SetMDS(3);
	}

#undef	Mul_1
#undef	Mul_X
#undef	Mul_Y
#define	Mul_1	Mx_1			/* re-enable true multiply */
#define	Mul_X	Mx_X
#define	Mul_Y	Mx_Y
	
}


/*
+*****************************************************************************
*
* Function Name:	RS_MDS_encode
*
* Function:			Use (12,8) Reed-Solomon code over GF(256) to produce
*					a key S-box dword from two key material dwords.
*
* Arguments:		k0	=	1st dword
*					k1	=	2nd dword
*
* Return:			Remainder polynomial generated using RS code
*
* Notes:
*	Since this computation is done only once per reKey per 64 bits of key,
*	the performance impact of this routine is imperceptible. The RS code
*	chosen has "simple" coefficients to allow smartcard/hardware implementation
*	without lookup tables.
*
-****************************************************************************/

DWORD RS_MDS_Encode(DWORD k0,DWORD k1)
{
	int i,j;
	DWORD r;

	for (i=r=0;i<2;i++)
	{
		r ^= (i) ? k0 : k1;			/* merge in 32 more key bits */
		for (j=0;j<4;j++)			/* shift one byte at a time */
			RS_rem(r);				
	}
	return r;
}




/*
+*****************************************************************************
*
* Function Name:	Xor256
*
* Function:			Copy an 8-bit permutation (256 bytes), xoring with a byte
*
* Arguments:		dst		=	where to put result
*					src		=	where to get data (can be same asa dst)
*					b		=	byte to xor
*
* Return:			None
*
-****************************************************************************/

#define X_8(N)	{ d[N]=s[N] ^ x; d[N+1]=s[N+1] ^ x; }

#define X_32(N)	{ X_8(N); X_8(N+2); X_8(N+4); X_8(N+6); }

void Xor256(void *dst,void *src,BYTE b)
{
	register DWORD	x=b*0x01010101u;	/* replicate byte to all four bytes */
	register DWORD *d=(DWORD *)dst;
	register DWORD *s=(DWORD *)src;
	X_32(0 ); X_32( 8); X_32(16); X_32(24);	/* all inline */
	d+=32;	/* keep offsets small! */
	s+=32;
	X_32(0 ); X_32( 8); X_32(16); X_32(24);	/* all inline */
}

/*
+*****************************************************************************
*
* Function Name:	reKey
*
* Function:			Initialize the Twofish key schedule from key32
*
* Arguments:		key			=	ptr to keyInstance to be initialized
*
* Return:			TRUE on success
*
* Notes:
*	Here we precompute all the round subkeys, although that is not actually
*	required.  For example, on a smartcard, the round subkeys can 
*	be generated on-the-fly	using f32()
*
-****************************************************************************/


/* F32 macros is working for 256 bits only */

#define	F32(res,x,k32)	\{						\	DWORD t=x;				\	b0(t)   = p8(04)[b0(t)] ^ b0(k32[3]);	\	b1(t)   = p8(14)[b1(t)] ^ b1(k32[3]);	\	b2(t)   = p8(24)[b2(t)] ^ b2(k32[3]);	\	b3(t)   = p8(34)[b3(t)] ^ b3(k32[3]);	\						\	b0(t)   = p8(03)[b0(t)] ^ b0(k32[2]);	\	b1(t)   = p8(13)[b1(t)] ^ b1(k32[2]);	\	b2(t)   = p8(23)[b2(t)] ^ b2(k32[2]);	\	b3(t)   = p8(33)[b3(t)] ^ b3(k32[2]);	\						\	res=	MDStab[0][p8(01)[p8(02)[b0(t)] ^ b0(k32[1])] ^ b0(k32[0])] ^	\			MDStab[1][p8(11)[p8(12)[b1(t)] ^ b1(k32[1])] ^ b1(k32[0])] ^	\			MDStab[2][p8(21)[p8(22)[b2(t)] ^ b2(k32[1])] ^ b2(k32[0])] ^	\			MDStab[3][p8(31)[p8(32)[b3(t)] ^ b3(k32[1])] ^ b3(k32[0])] ;	\}


#define one256(N,J) sbSet(N,i,J,p8(N##1)[p8(N##2)[L0[i+J]]^k1]^k0)

#define	sb256(N)				\{	Xor256(L1,p8(N##4),b##N(sKey[3]));	\	for (i=0;i<256;i+=2)			\	{ L0[i  ]=p8(N##3)[L1[i]];		\	  L0[i+1]=p8(N##3)[L1[i+1]];		\	}					\	Xor256(L0,L0,b##N(sKey[2]));		\	{	register DWORD k0=b##N(sKey[0]);\		register DWORD k1=b##N(sKey[1]);\		for (i=0;i<256;i+=2)		\		{ one256(N,0); one256(N,1);	\		}				\	}					\}


BOOL reKey( DWORD       *keyInput,  /* 256-bit key that has to be prepared for using */
		    KeyInstance *key        /* Key data that will be used to encrypt/decrypt later */
		   )
{
	int		i,j;
	DWORD	A,B,q;
	DWORD	sKey[MAX_KEY_BITS/64],
			k32e[MAX_KEY_BITS/64],
			k32o[MAX_KEY_BITS/64];
	BYTE	L0[256],
			L1[256];	/* small local 8-bit permutations */

	BuildMDS();

	/* number of 64-bit key words k == 256 / 64 == 4 */

⌨️ 快捷键说明

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