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

📄 des_impl.c

📁 C++ 编写的EROS RTOS
💻 C
📖 第 1 页 / 共 2 页
字号:
#define l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff), \			 *((c)++)=(unsigned char)(((l)>> 8)&0xff), \			 *((c)++)=(unsigned char)(((l)>>16)&0xff), \			 *((c)++)=(unsigned char)(((l)>>24)&0xff))/* * IP and FP * The problem is more of a geometric problem that random bit fiddling. *  0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6 *  8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4 * 16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2 * 24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0 * * 32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7 * 40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5 * 48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3 * 56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1 * * The output has been subject to swaps of the form * 0 1 -> 3 1 but the odd and even bits have been put into * 2 3    2 0 * different words.  The main trick is to remember that * t=((l>>size)^r)&(mask); * r^=t; * l^=(t<<size); * can be used to swap and move bits between words. * * So l =  0  1  2  3  r = 16 17 18 19 *         4  5  6  7      20 21 22 23 *         8  9 10 11      24 25 26 27 *        12 13 14 15      28 29 30 31 * becomes (for size == 2 and mask == 0x3333) * t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19 *  	 6^20  7^21 -- --        4  5 20 21       6  7 22 23 *	10^24 11^25 -- --        8  9 24 25      10 11 24 25 * 	14^28 15^29 -- --       12 13 28 29      14 15 28 29 * * Thanks for hints from Richard Outerbridge - he told me IP&FP * could be done in 15 xor, 10 shifts and 5 ands. * When I finally started to think of the problem in 2D * I first got ~42 operations without xors.  When I remembered * how to use xors :-) I got it to its final state. */#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\	(b)^=(t),\	(a)^=((t)<<(n)))#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\	(a)=(a)^(t)^(t>>(16-(n))))/* The changes to this macro may help or hinder, depending on the * compiler and the achitecture.  gcc2 always seems to do well :-). * Inspired by Dana How <how@isl.stanford.edu> * DO NOT use the alternative version on machines with 8 byte longs. */#ifdef ALT_ECB#define D_ENCRYPT(L,R,S) \	u=((R^s[S  ])<<2);	\	t= R^s[S+1]; \	t=((t>>2)+(t<<30)); \	L^= \	*(unsigned long *)(des_SP+0x0100+((t    )&0xfc))+ \	*(unsigned long *)(des_SP+0x0300+((t>> 8)&0xfc))+ \	*(unsigned long *)(des_SP+0x0500+((t>>16)&0xfc))+ \	*(unsigned long *)(des_SP+0x0700+((t>>24)&0xfc))+ \	*(unsigned long *)(des_SP+       ((u    )&0xfc))+ \  	*(unsigned long *)(des_SP+0x0200+((u>> 8)&0xfc))+ \  	*(unsigned long *)(des_SP+0x0400+((u>>16)&0xfc))+ \ 	*(unsigned long *)(des_SP+0x0600+((u>>24)&0xfc));#else /* original version */#define D_ENCRYPT(L,R,S)	\	u=(R^s[S  ]); \	t=R^s[S+1]; \	t=((t>>4)+(t<<28)); \	L^=	des_SPtrans[1][(t    )&0x3f]| \		des_SPtrans[3][(t>> 8)&0x3f]| \		des_SPtrans[5][(t>>16)&0x3f]| \		des_SPtrans[7][(t>>24)&0x3f]| \		des_SPtrans[0][(u    )&0x3f]| \		des_SPtrans[2][(u>> 8)&0x3f]| \		des_SPtrans[4][(u>>16)&0x3f]| \		des_SPtrans[6][(u>>24)&0x3f];#endif#define ITERATIONS 16static char shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};static void des_set_key(key,schedule)     char *key;     unsigned long *schedule;{    register unsigned long c,d,t,s;    register unsigned char *in;    register unsigned long *k;    register int i;    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;    }}static void des_encrypt(buf,schedule,encrypt)     unsigned long *buf;     char *schedule;     int encrypt;{    register unsigned long l,r,t,u;#ifdef ALT_ECB    register unsigned char *des_SP=(unsigned char *)des_SPtrans;#endif    register int i;    register unsigned long *s;    l=buf[0];    r=buf[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 *)schedule;    /* 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);    buf[0]=l;    buf[1]=r;    l = r = t = u = 0;}int _des_crypt(buf,len,desp)char *buf;unsigned len;struct desparams *desp;{    unsigned long schedule[32];    register unsigned long tin0 = 0 ,tin1 = 0;    register unsigned long tout0,tout1,xor0,xor1;    register unsigned char *in, *out;    unsigned long tbuf[2];    unsigned char *iv, *oiv;    int cbc_mode;    cbc_mode = (desp->des_mode == CBC) ? 1 : 0;    in=(unsigned char *)buf;    out=(unsigned char *)buf;    oiv=iv=(unsigned char *)desp->des_ivec;        des_set_key(desp->des_key,schedule);    if (desp->des_dir == ENCRYPT) {	c2l(iv,tout0);	c2l(iv,tout1);	for (; len>0; len-=8) {	    c2l(in,tin0);	    c2l(in,tin1);	    if (cbc_mode) {		tin0^=tout0;		tin1^=tout1;	    }	    tbuf[0]=tin0;	    tbuf[1]=tin1;	    des_encrypt(tbuf,schedule,1);	    tout0=tbuf[0];	    tout1=tbuf[1];	    l2c(tout0,out);	    l2c(tout1,out);	}	l2c(tout0,oiv);	l2c(tout1,oiv);    } else {	c2l(iv,xor0);	c2l(iv,xor1);	for (; len>0; len-=8) {	    c2l(in,tin0);	    c2l(in,tin1);	    tbuf[0]=tin0;	    tbuf[1]=tin1;	    des_encrypt(tbuf,schedule,0); 	    if (cbc_mode) {		tout0=tbuf[0]^xor0;		tout1=tbuf[1]^xor1;		xor0=tin0;		xor1=tin1;	    } else {		tout0=tbuf[0];		tout1=tbuf[1];	    }	    l2c(tout0,out);	    l2c(tout1,out);	}	l2c(tin0,oiv);	l2c(tin1,oiv);    }    tin0=tin1=tout0=tout1=xor0=xor1=0;    tbuf[0]=tbuf[1]=0;    bzero(schedule, sizeof(schedule));    return(1);}

⌨️ 快捷键说明

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