正在阅读:实现基于IDEA算法的加密工具(6)实现基于IDEA算法的加密工具(6)

2004-02-14 09:34 出处:PConline 作者:吴真 责任编辑:zwg
任何媒体不得转载  3.5 算法实现代码 /*此处略去信息说明和头文件*/ #include "idea.h" #define NULL ((void *)0) typedef int INT32; typedef char INT8; typedef unsigned char ULONG8; typedef unsigned short ULONG16; typedef unsigned long ULONG32; #define SUCCESS 0 #define FAIL -1 #define LOW16(x) ((x)&0xffff) #define _USEDFINDTABLE_ 1 /*是否采用查表实现*/ /*解密时密钥的换位表*/ //ULONG16 outkey[52] = { 0 }; static ULONG8 wz_spkey[52] = { 48,49,50,51,46,47, 42,44,43,45,40,41,/*解密密钥配置,2,3位要交换:44<->43*/ 36,38,37,39,34,35,/*解密密钥配置,2,3位要交换:38<->37*/ 30,32,31,33,28,29,/*解密密钥配置,2,3位要交换:32<->31*/ 24,26,25,27,22,23,/*解密密钥配置,2,3位要交换:26<->25*/ 18,20,19,21,16,17,/*解密密钥配置,2,3位要交换:20<->19*/ 12,14,13,15,10,11,/*解密密钥配置,2,3位要交换:14<->13*/ 6, 8, 7, 9, 4, 5,/*解密密钥配置,2,3位要交换:8<->7*/ 0, 1, 2, 3 }; static ULONG8 wz_spmulrevr[18] = {/*变乘法逆的位*/ 0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51 }; static ULONG8 wz_spaddrever[18] ={/*变加法逆的位*/ 1,2,7,8,13,14,19,20,25,26,31,32,37,38,43,44,49,50 }; INT32 mulInv( ULONG16 x);/*取x的(%0x10001L)乘法逆*/ INT32 handle_data( ULONG16 *data, /*待加密的64位数据首地址*/ ULONG16 *key /* 6组本轮使用的16位长的密钥首地址*/ ); INT32 idea_makekey( ULONG32 *inkey,/*用户输入的128位密钥首地址*/ ULONG16 *outkey/*生成的52组16位密钥的首地址*/ ); INT32 key_leftmove(ULONG32 *inkey); INT32 key_decryExp(ULONG16 *outkey);/*解密密钥的变逆处理*/ INT32 MUL( ULONG16 a, ULONG16 b);/*(a*b)*/   INT32 idea_dec( ULONG16 *data, /*待解密的64位数据首地址*/ ULONG16 *outkey ) { ULONG32 i ; ULONG16 tmp; if ( NULL == data || NULL == outkey) { return FAIL; } for ( i = 0 ; i < 48 ; i += 6)/*8轮*/ { handle_data( data , &outkey[i]); /*交换中间两个*/ tmp = data[1]; data[1] = data[2]; data[2] = tmp; } tmp = data[1];/*最后一轮不交换*/ data[1] = data[2]; data[2] = tmp; data[0] = MUL(data[0],outkey[48]); data[1] += outkey[49]; data[2] += outkey[50]; data[3] = MUL(data[3],outkey[51]); return SUCCESS; } INT32 idea_enc( ULONG16 *data, /*待加密的64位数据首地址*/ ULONG16 *outkey ) { ULONG32 i ; ULONG16 tmp; if ( NULL == data || NULL == outkey) { return FAIL; } for ( i = 0 ; i < 48 ; i += 6)/*8轮*/ { handle_data( data , &outkey[i]); /*交换中间两个*/ tmp = data[1]; data[1] = data[2]; data[2] = tmp; } tmp = data[1];/*最后一轮不交换*/ data[1] = data[2]; data[2] = tmp; data[0] = MUL(data[0],outkey[48]); data[1] += outkey[49]; data[2] += outkey[50]; data[3] = MUL(data[3],outkey[51]); return SUCCESS; } INT32 handle_data( ULONG16 *data, /*待加密的64位数据首地址*/ ULONG16 *key /* 6组本轮使用的16位长的密钥首地址*/ ) { ULONG16 *D1,*D2,*D3,*D4; ULONG16 D57;/*提供给第5,7步用的暂存数据的*/ ULONG16 D68;/*提供给第6,8,9,10步用的暂存数据的*/ D1 = &data[0]; D2 = &data[1]; D3 = &data[2]; D4 = &data[3]; /*start*/ *D1 = MUL(*D1,key[0]);/*第1步*/ *D2 += key[1];/*第2步*/ *D3 += key[2];/*第3步*/ *D4 = MUL(*D4,key[3]);/*第4步*/ D57 = *D1 ^ *D3;/*第5步*/ D68 = *D2 ^ *D4;/*第6步*/ D57 = MUL(D57,key[4]);/*第7步*/ D68 += D57;/*第8步*/ D68 = MUL(D68,key[5]);/*第9步*/ *D1 ^= D68;/*第11步*/ *D3 ^= D68;/*第12步*/ D68 += D57;/*第10步*/ *D2 ^= D68;/*第13步*/ *D4 ^= D68;/*第14步*/ return SUCCESS; } INT32 idea_makekey( ULONG32 *inkey,/*用户输入的128位密钥首地址*/ ULONG16 *outkey/*生成的52组16位密钥的首地址*/ ) { ULONG32 i,j,k; ULONG16 *Pkey = ( ULONG16*)inkey; for (i = 0 ; i < 6; i++) { k = i << 3; for( j = 0 ; j < 8 ; j++)/*生成8组密钥*/ { outkey[k+j] = Pkey[j] ; } key_leftmove(inkey);/*128位密钥左环移25位*/ } for( i = 0 ; i < 4; i++) { outkey[48+i] = Pkey[i] ; } return SUCCESS; } INT32 key_leftmove(ULONG32 *inkey)/*密钥左环移25位*/ { ULONG32 itmpfirst = 0,itmp = 0 ; ULONG32 i; inkey[0] = (inkey[0]<<25) | (inkey[0]>>7); /*取低25位,因为前面已经做了环移,原始的低7位已经移到了高位,保存*/ itmpfirst = inkey[0]&0x1ffffff; inkey[0] &= 0xfe000000;/*低25位清0*/ for ( i = 1 ; i < 4 ; i++) { inkey[i] = (inkey[i]<<25) | (inkey[i]>>7); itmp = inkey[i] & 0x1ffffff; inkey[i-1] |= itmp; inkey[i] &= 0xfe000000;/*低25位清0*/ } inkey[i-1] |= itmpfirst;/*把最高25位移到最低25位*/ return SUCCESS; }   INT32 key_decryExp(ULONG16 *outkey)/*解密密钥的变逆处理*/ { /*我习惯用查表的方法实现换位,当然也可以采用一些编程技巧直接实现*/ #if _USEDFINDTABLE_ /*用查表法*/ ULONG16 tmpkey[52] = { 0 }; ULONG32 i; for ( i = 0 ; i < 52 ; i++) { tmpkey[i] = outkey[ wz_spkey[i] ] ;/*换位*/ } for ( i = 0 ; i < 52 ; i++) { outkey[i] = tmpkey[i]; } for ( i = 0 ; i < 18 ; i++) { outkey[wz_spaddrever[i]] = 65536 -outkey[wz_spaddrever[i]] ;/*替换成加法逆*/ } for ( i = 0 ; i < 18 ; i++) { outkey[wz_spmulrevr[i]] = mulInv(outkey[wz_spmulrevr[i]] );/*替换成乘法逆*/ } #else ULONG16 K1, K2, K3, K4, i; ULONG16 tmpkey[52] = { 0 }; ULONG16 *pin = outkey ; ULONG16 *p = tmpkey + 52; /* 从后往前 */ K1 = mulInv(*pin); K2 = 65536 - *++pin; K3 = 65536 - *++pin; K4 = mulInv(*++pin); pin++; *--p = K4; *--p = K3; *--p = K2; *--p = K1; for (i = 0 ; i < 7; i++) { K1 = *pin++;/*不变的两个*/ K2 = *pin++; *--p = K2; *--p = K1; K1 = mulInv(*pin); K2 = 65536 - *++pin; K3 = 65536 - *++pin; K4 = mulInv(*++pin); pin++; *--p = K4; *--p = K2; /* 交换 */ *--p = K3; *--p = K1; } K1 = *pin++;/*最后一组不交换*/ K2 = *pin++; *--p = K2; *--p = K1; K1 = mulInv(*pin); K2 = 65536 - *++pin; K3 = 65536 - *++pin; K4 = mulInv(*++pin); *--p = K4; *--p = K3; *--p = K2; *--p = K1; for (i = 0 ; i < 52 ; i++) { outkey[i] = tmpkey[i]; }   #endif return SUCCESS; } DllExport INT32 idea_MakeEncKey(ULONG16 *key, ULONG16 *outkey) { if ( NULL == outkey || NULL == key) { return FAIL; } idea_makekey( (ULONG32*)key , outkey); return SUCCESS; } INT32 idea_MakeDecKey(ULONG16 *key, ULONG16 *outkey) { if ( NULL == outkey || NULL == key) { return FAIL; } idea_makekey( (ULONG32*)key , outkey); key_decryExp(outkey); return SUCCESS; } /*算法实现结束*/ 上述代码在vc6.0环境下测试通过.

相关文章

关注我们

最新资讯离线随时看 聊天吐槽赢奖品