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

📄 des.c

📁 DES及3DES算法
💻 C
📖 第 1 页 / 共 2 页
字号:
#define DES_ENCRYPT	1
#define DES_DECRYPT	0


#define C_Block des_cblock
#define Key_schedule des_key_schedule
#define ENCRYPT DES_ENCRYPT
#define DECRYPT DES_DECRYPT
#define KEY_SZ DES_KEY_SZ


//static int check_parity();
static unsigned char exchange[256]={
   0,  128,    2,  130,    4,  132,    6,  134,    8,  136,   10,  138,   12,  140,   14,
  142,   16,  144,   18,  146,   20,  148,   22,  150,   24,  152,   26,  154,   28,  156,
   30,  158,   32,  160,   34,  162,   36,  164,   38,  166,   40,  168,   42,  170,   44,
  172,   46,  174,   48,  176,   50,  178,   52,  180,   54,  182,   56,  184,   58,  186,
   60,  188,   62,  190,   64,  192,   66,  194,   68,  196,   70,  198,   72,  200,   74,
  202,   76,  204,   78,  206,   80,  208,   82,  210,   84,  212,   86,  214,   88,  216,
   90,  218,   92,  220,   94,  222,   96,  224,   98,  226,  100,  228,  102,  230,  104,
  232,  106,  234,  108,  236,  110,  238,  112,  240,  114,  242,  116,  244,  118,  246,
  120,  248,  122,  250,  124,  252,  126,  254,    1,  129,    3,  131,    5,  133,    7,
  135,    9,  137,   11,  139,   13,  141,   15,  143,   17,  145,   19,  147,   21,  149,
   23,  151,   25,  153,   27,  155,   29,  157,   31,  159,   33,  161,   35,  163,   37,
  165,   39,  167,   41,  169,   43,  171,   45,  173,   47,  175,   49,  177,   51,  179,
   53,  181,   55,  183,   57,  185,   59,  187,   61,  189,   63,  191,   65,  193,   67,
  195,   69,  197,   71,  199,   73,  201,   75,  203,   77,  205,   79,  207,   81,  209,
   83,  211,   85,  213,   87,  215,   89,  217,   91,  219,   93,  221,   95,  223,   97,
  225,   99,  227,  101,  229,  103,  231,  105,  233,  107,  235,  109,  237,  111,  239,
  113,  241,  115,  243,  117,  245,  119,  247,  121,  249,  123,  251,  125,  253,  127,
  255};

int des_check_key=0;

//void des_set_odd_parity(des_cblock *key)
//{
//	int i;
//
//	for (i=0; i<DES_KEY_SZ; i++)
//		(*key)[i]=odd_parity[(*key)[i]];
//}

//static int check_parity(des_cblock *key)
//{
//	int i;
//
//	for (i=0; i<DES_KEY_SZ; i++)
//		{
//		if ((*key)[i] != odd_parity[(*key)[i]])
//			return(0);
//		}
//	return(1);
//}

//#define NUM_WEAK_KEY	16
//des_cblock xdata weak_keys[NUM_WEAK_KEY]={
//	/* weak keys */
//	0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
//	0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,
//	0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
//	0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,
//	/* semi-weak keys */
//	0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,
//	0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,
//	0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1,
//	0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E,
//	0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,
//	0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01,
//	0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE,
//	0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,
//	0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,
//	0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01,
//	0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE,
//	0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1};

//int des_is_weak_key(des_cblock *key)
//{
//	int i;
//
//	for (i=0; i<NUM_WEAK_KEY; i++)
//		/* Added == 0 to comparision, I obviously don't run
//		 * this section very often :-(, thanks to
//		 * engineering for the fix
//		 * eay 93/06/29 */
//		if (memcmp(weak_keys[i],key,sizeof(key)) == 0) return(1);
//	return(0);
//}

/* NOW DEFINED IN des_local.h
 * See ecb_encrypt.c for a pseudo description of these macros. 
 * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
 * 	(b)^=(t),\
 * 	(a)=((a)^((t)<<(n))))
 */

#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
	(a)=(a)^(t)^(t>>(16-(n))))

char xdata shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};

/* return 0 if key parity is odd (correct),
 * return -1 if key parity error,
 * return -2 if illegal weak key.
 */
byte des_set_key(des_cblock *key,des_key_schedule xdata schedule)
{
	unsigned long xdata c,d,t,s;
	unsigned char xdata *in;
	unsigned long xdata *k;
	int xdata i;

	if (des_check_key==1)
		{
//		if (!check_parity(key))
//		{
//			return -1;
//		}
//		if (des_is_weak_key(key))
//		    return -2;
		}

	k=(unsigned long *)schedule;
	in=(unsigned char *)key;

	c2l(in,c);
	c2l(in,d);



	/* I now do it in 47 simple operations :-)
	 * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
	 * for the inspiration. :-) */
	PERM_OP (d,c,t,4,0x0f0f0f0f);
	HPERM_OP(c,t,-2,0xcccc0000);
	HPERM_OP(d,t,-2,0xcccc0000);
	PERM_OP (d,c,t,1,0x55555555);
	PERM_OP (c,d,t,8,0x00ff00ff);
	PERM_OP (d,c,t,1,0x55555555);
	d=	(((d&0x000000ff)<<16)| (d&0x0000ff00)     |
		 ((d&0x00ff0000)>>16)|((c&0xf0000000)>>4));
	c&=0x0fffffff;

	for (i=0; i<ITERATIONS; i++)
		{
		if (shifts2[i])
			{ c=((c>>2)|(c<<26)); d=((d>>2)|(d<<26)); }
		else
			{ c=((c>>1)|(c<<27)); d=((d>>1)|(d<<27)); }
		c&=0x0fffffff;
		d&=0x0fffffff;
		/* could be a few less shifts but I am to lazy at this
		 * point in time to investigate */
		s=	des_skb[0][ (c    )&0x3f                ]|
			des_skb[1][((c>> 6)&0x03)|((c>> 7)&0x3c)]|
			des_skb[2][((c>>13)&0x0f)|((c>>14)&0x30)]|
			des_skb[3][((c>>20)&0x01)|((c>>21)&0x06) |
						  ((c>>22)&0x38)];
		t=	des_skb[4][ (d    )&0x3f                ]|
			des_skb[5][((d>> 7)&0x03)|((d>> 8)&0x3c)]|
			des_skb[6][ (d>>15)&0x3f                ]|
			des_skb[7][((d>>21)&0x0f)|((d>>22)&0x30)];

		/* table contained 0213 4657 */
		*(k++)=((t<<16)|(s&0x0000ffff))&0xffffffff;
		s=     ((s>>16)|(t&0xffff0000));
		
		s=(s<<4)|(s>>28);
		*(k++)=s&0xffffffff;
		}
	return(0);
}

//int des_key_sched(des_cblock *key,des_key_schedule schedule)
//{
//	return(des_set_key(key,schedule));
//}



byte des_encrypt(unsigned long *input,
				unsigned long *output,
				des_key_schedule xdata ks,
				byte encrypt)
{
	unsigned long xdata l,r,t,u;

	int xdata i;
	unsigned long xdata *s;

	l=input[0];
	r=input[1];

	/* do IP */
	PERM_OP(r,l,t, 4,0x0f0f0f0f);
	PERM_OP(l,r,t,16,0x0000ffff);
	PERM_OP(r,l,t, 2,0x33333333);
	PERM_OP(l,r,t, 8,0x00ff00ff);
	PERM_OP(r,l,t, 1,0x55555555);
	/* r and l are reversed - remember that :-) - fix
	 * it in the next step */

	/* Things have been modified so that the initial rotate is
	 * done outside the loop.  This required the
	 * des_SPtrans values in sp.h to be rotated 1 bit to the right.
	 * One perl script later and things have a 5% speed up on a sparc2.
	 * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
	 * for pointing this out. */
	t=(r<<1)|(r>>31);
	r=(l<<1)|(l>>31);
	l=t;

	/* clear the top bits on machines with 8byte longs */
	l&=0xffffffff;
	r&=0xffffffff;

	s=(unsigned long *)ks;
	/* I don't know if it is worth the effort of loop unrolling the
	 * inner loop */
	if (encrypt)
		{
		for (i=0; i<32; i+=4)
			{
			D_ENCRYPT(l,r,i+0); /*  1 */
			D_ENCRYPT(r,l,i+2); /*  2 */
			}
		}
	else
		{
		for (i=30; i>0; i-=4)
			{
			D_ENCRYPT(l,r,i-0); /* 16 */
			D_ENCRYPT(r,l,i-2); /* 15 */
			}
		}
	l=(l>>1)|(l<<31);
	r=(r>>1)|(r<<31);
	/* clear the top bits on machines with 8byte longs */
	l&=0xffffffff;
	r&=0xffffffff;

	/* swap l and r
	 * we will not do the swap so just remember they are
	 * reversed for the rest of the subroutine
	 * luckily FP fixes this problem :-) */

	PERM_OP(r,l,t, 1,0x55555555);
	PERM_OP(l,r,t, 8,0x00ff00ff);
	PERM_OP(r,l,t, 2,0x33333333);
	PERM_OP(l,r,t,16,0x0000ffff);
	PERM_OP(r,l,t, 4,0x0f0f0f0f);

	output[0]=l;
	output[1]=r;
	l=r=t=u=0;
	return(0);
}

byte des_ecb_encrypt(des_cblock *input,
					des_cblock *output,
					des_key_schedule xdata ks,
					byte encrypt)
{
	unsigned long xdata l0,l1;
	unsigned char xdata *in,*out;
	unsigned long xdata ll[2];

	in=(byte *)input;
	out=(byte *)output;
	c2l(in,l0);
	c2l(in,l1);
	ll[0]=l0;
	ll[1]=l1;
	des_encrypt(ll,ll,ks,encrypt);
	l0=ll[0];
	l1=ll[1];
	l2c(l0,out);
	l2c(l1,out);
	l0=l1=ll[0]=ll[1]=0;
	return(0);
}

byte DesEncrypt_ECB(byte *k, 
					byte *in, 
					byte *out,
//				   	long int l,
					byte l,
					byte f)				/*1加密,0解密*/
{
	des_key_schedule xdata ks;
	byte xdata temp[8];
//	long int s,i,j,w;
	byte i,j,w;

	if(f==ENCRYPT)
	{
    	des_set_key((C_Block *)k,ks);
		w=l%8;
//		s=l;
		l=l-w;
		for(i=0;i<l;i+=8)
		{			
			des_ecb_encrypt((des_cblock *)(in+i),(des_cblock *)(out+i),ks,1);
		}
		/*短块处理的方法之一*/
		if(w!=0)
		{
			
			for(j=0;j<8;j++)temp[j]=(unsigned char)j;
			des_ecb_encrypt((des_cblock *)temp,(des_cblock *)temp,ks,1);

			for(j=0;j<w;j++)
				out[i+j]=in[i+j]^temp[j];
		}
 	}
    
    else if(f==DECRYPT)
	{
		des_set_key((C_Block *)k,ks);
		w=l%8;
//		s=l;
		l=l-w;
		for(i=0;i<l;i+=8)
		{			
			des_ecb_encrypt((des_cblock *)(in+i),(des_cblock *)(out+i),ks,0);
		}
		/*短块处理的方法之一*/
		if(w!=0)
		{
			
			for(j=0;j<8;j++)temp[j]=(unsigned char)j;
			des_ecb_encrypt((des_cblock *)temp,(des_cblock *)temp,ks,1);
			for(j=0;j<w;j++)
				out[i+j]=in[i+j]^temp[j];
		}
	}
	return 0;
}

//void TriDes (unsigned char *Key, unsigned char *Input, unsigned char *Output, int mode)
//{
//	unsigned char temp[8];
//	DesEncrypt_ECB(Key, Input, Output, 8, mode);/*1加密,0解密*/
//	DesEncrypt_ECB(Key+8, Output, temp, 8, 1-mode);/*1加密,0解密*/
//	DesEncrypt_ECB(Key, temp, Output, 8, mode);/*1加密,0解密*/
//}

///*only for test
#include <stdio.h>
#include <stdlib.h>
main()
{
	byte i;
	byte bLen;
	byte xdata datacode[20];
	byte xdata mess2[20];
//	char *key="12345678";
//	unsigned char *key="00000000";
//	unsigned char key[8]={0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30};
	byte xdata key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
//	char *mess="hello!world";
//	unsigned char *mess="00000000";
//	unsigned char mess[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
	byte xdata mess[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
//	unsigned char mess[8]={0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11};
	for(i=0;i<20;i++){
		datacode[i]=0;
		mess2[i]=0;
	}
//	bLen=strlen(mess);
	bLen=7;
	DesEncrypt_ECB(key,mess,datacode,bLen+1,ENCRYPT);
//	code[strlen(mess)+1]=0;
//	puts(key);
//	puts(code);
//	i=strlen(code);
	DesEncrypt_ECB(key,datacode,mess2,bLen+1,DECRYPT);
//	puts(mess2);
	return 0;
}

⌨️ 快捷键说明

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