SMS4(中国商用加密算法)

来源:互联网 发布:越狱软件安装 编辑:程序博客网 时间:2024/04/27 13:36
/*******************************************************************************密码学实验-----SMS4算法演示 Wuhan University    Computer School  HonYi YanChao    *******************************************************************************//*头文件声明*/ #include<stdlib.h>#include<stdio.h>#include<string.h>/*数据结构定义*/ //S盒子 unsigned char S_box[256]= { 0xd6 ,0x90 ,0xe9 ,0xfe ,0xcc ,0xe1 ,0x3d ,0xb7 ,0x16 ,0xb6 ,0x14 ,0xc2 ,0x28 ,0xfb ,0x2c ,0x05 ,0x2b ,0x67 ,0x9a ,0x76 ,0x2a ,0xbe ,0x04 ,0xc3 ,0xaa ,0x44 ,0x13 ,0x26 ,0x49 ,0x86 ,0x06 ,0x99 ,0x9c ,0x42 ,0x50 ,0xf4 ,0x91 ,0xef ,0x98 ,0x7a ,0x33 ,0x54 ,0x0b ,0x43 ,0xed ,0xcf ,0xac ,0x62 ,0xe4 ,0xb3 ,0x1c ,0xa9 ,0xc9 ,0x08 ,0xe8 ,0x95 ,0x80 ,0xdf ,0x94 ,0xfa ,0x75 ,0x8f ,0x3f ,0xa6 ,0x47 ,0x07 ,0xa7 ,0xfc ,0xf3 ,0x73 ,0x17 ,0xba ,0x83 ,0x59 ,0x3c ,0x19 ,0xe6 ,0x85 ,0x4f ,0xa8 ,0x68 ,0x6b ,0x81 ,0xb2 ,0x71 ,0x64 ,0xda ,0x8b ,0xf8 ,0xeb ,0x0f ,0x4b ,0x70 ,0x56 ,0x9d ,0x35 ,0x1e ,0x24 ,0x0e ,0x5e ,0x63 ,0x58 ,0xd1 ,0xa2 ,0x25 ,0x22 ,0x7c ,0x3b ,0x01 ,0x21 ,0x78 ,0x87 ,0xd4 ,0x00 ,0x46 ,0x57 ,0x9f ,0xd3 ,0x27 ,0x52 ,0x4c ,0x36 ,0x02 ,0xe7 ,0xa0 ,0xc4 ,0xc8 ,0x9e ,0xea ,0xbf ,0x8a ,0xd2 ,0x40 ,0xc7 ,0x38 ,0xb5 ,0xa3 ,0xf7 ,0xf2 ,0xce ,0xf9 ,0x61 ,0x15 ,0xa1 ,0xe0 ,0xae ,0x5d ,0xa4 ,0x9b ,0x34 ,0x1a ,0x55 ,0xad ,0x93 ,0x32 ,0x30 ,0xf5 ,0x8c ,0xb1 ,0xe3 ,0x1d ,0xf6 ,0xe2 ,0x2e ,0x82 ,0x66 ,0xca ,0x60 ,0xc0 ,0x29 ,0x23 ,0xab ,0x0d ,0x53 ,0x4e ,0x6f ,0xd5 ,0xdb ,0x37 ,0x45 ,0xde ,0xfd ,0x8e ,0x2f ,0x03 ,0xff ,0x6a ,0x72 ,0x6d ,0x6c ,0x5b ,0x51 ,0x8d ,0x1b ,0xaf ,0x92 ,0xbb ,0xdd ,0xbc ,0x7f ,0x11 ,0xd9 ,0x5c ,0x41 ,0x1f ,0x10 ,0x5a ,0xd8 ,0x0a ,0xc1 ,0x31 ,0x88 ,0xa5 ,0xcd ,0x7b ,0xbd ,0x2d ,0x74 ,0xd0 ,0x12 ,0xb8 ,0xe5 ,0xb4 ,0xb0 ,0x89 ,0x69 ,0x97 ,0x4a ,0x0c ,0x96 ,0x77 ,0x7e ,0x65 ,0xb9 ,0xf1 ,0x09 ,0xc5 ,0x6e ,0xc6 ,0x84 ,0x18 ,0xf0 ,0x7d ,0xec ,0x3a ,0xdc ,0x4d ,0x20 ,0x79 ,0xee ,0x5f ,0x3e ,0xd7 ,0xcb ,0x39 ,0x48 };//常数FKunsigned int FK0=0xa3b1bac6 ,FK1=0x56aa3350 ,FK2=0x677d9197 ,FK3=0xb27022dc;//固定参数CKunsigned int CK[32]={    0x00070e15 ,0x1c232a31 ,0x383f464d ,0x545b6269 ,    0x70777e85 ,0x8c939aa1 ,0xa8afb6bd ,0xc4cbd2d9 ,    0xe0e7eef5 ,0xfc030a11 ,0x181f262d ,0x343b4249 ,    0x50575e65 ,0x6c737a81 ,0x888f969d ,0xa4abb2b9 ,    0xc0c7ced5 ,0xdce3eaf1 ,0xf8ff060d ,0x141b2229 ,    0x30373e45 ,0x4c535a61 ,0x686f767d ,0x848b9299 ,    0xa0a7aeb5 ,0xbcc3cad1 ,0xd8dfe6ed ,0xf4fb0209 ,    0x10171e25 ,0x2c333a41 ,0x484f565d ,0x646b7279 };//循环移位  SHL(x,y)为32位的x循环左移y位#define SHL(x,y)  ((x<<y)|(x>>32-y)) //加解密 非线性τ函数B=τ(A)#define unline_change(A) (S_box[(A)>>24&0xFF]<<24^S_box[(A)>>16&0xFF]<<16^S_box[(A)>>8&0xFF]<<8^S_box[(A)&0xFF])//加解密中的L函数#define L1(B)  ((B)^SHL(B,2)^SHL(B,10)^SHL(B,18)^SHL(B,24))//秘钥扩展中的L‘函数#define L2(B) ((B)^SHL(B,13)^SHL(B,23))/*子函数声明*/ void KeyExpasion(unsigned char *Key ,unsigned int *rk);//密钥扩展算法void Encrypt (unsigned char * Input,unsigned char * Output,unsigned int * rk);//加密函数 void Dncrypt (unsigned char * Input,unsigned char * Output,unsigned int * rk);// 解密函数 /*主函数*/ //实验明文 :1 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10  //正确密文:88 f9 a3 b1 7b 1d 9f 65 2c 17 d7 7  b2 ae e4 60int main(void){    printf ("\n********************SMS4算法演示********************\n\n");        //待加密的明文 unsigned char m[16]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};//初始加密密钥 unsigned char key[16]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};    unsigned char c[16];//用以存储密文的数组   unsigned int rk[32];//定义轮密钥rk int i;//计数变量 KeyExpasion(key,rk); //密钥扩展算法//加密过程     printf("**********加密过程**********\n");   printf("明文:\n");//显示加密前的明文   for (i=0;i<16;i++)printf("%x  ",m[i]);       printf ("\n\n");       printf("密钥\n");//显示密钥   for (i=0;i<16;i++)        printf("%x  ",key[i]);       printf ("\n\n");Encrypt(m,c,rk);//调用加密算法 printf ("加密后的密文:\n");//显示加密后的密文 for (i=0 ;i<16 ;i++ )printf("%x  ",c[i]);       printf("\n\n\n");    //解密过程    //先将轮密钥逆序 unsigned int temp;int j; for(j=0;j<16;j++)//将密钥逆序 temp=rk[j],rk[j]=rk[31-j],rk[31-j]=temp;printf("**********解密过程**********\n");   printf("密文:\n");//显示解密前的密文   for (i=0;i<16;i++)printf("%x  ",c[i]);       printf ("\n\n");       printf("密钥:\n");//显示密钥   for (i=0;i<16;i++)        printf("%x  ",key[i]);       printf ("\n\n");Dncrypt(c,m,rk);//调用解密算法 printf ("解密后的明文:\n");//显示解密后的明文 for (i=0 ;i<16 ;i++ )printf("%x  ",m[i]);       printf("\n\n"); system("pause");return 0;      }/*加密函数*/void Encrypt (unsigned char * Input,unsigned char * Output,unsigned int * rk)// Input:输入已分组的明文,Output:输出的对应分组的密文,rk为轮密钥{    unsigned int  r,mid,x0,x1,x2,x3,*p;//需要用到的中间变量         p=(unsigned int *)Input;//此时p指针指向输入     x0=p[0];    x1=p[1];    x2=p[2];    x3=p[3];        for(r=0;r<32;r+=4)//开始32轮加密 ,一次进行4轮,共计八次 {//F被分解为三步         mid=x1^x2^x3^rk[r+0]; //先计算 x1^x2^x3^rk        mid=unline_change(mid);//非线性τ函数        x0=x0^L1(mid);//与x0亦或                 mid=x2^x3^x0^rk[r+1];        mid=unline_change(mid);                    x1^=L1(mid);                mid=x3^x0^x1^rk[r+2];        mid=unline_change(mid);        x2^=L1(mid);                mid=x0^x1^x2^rk[r+3];        mid=unline_change(mid);        x3^=L1(mid);}p=(unsigned int *)Output;//此时p指针指向输出   p[0]=x3;  p[1]=x2;  p[2]=x1;  p[3]=x0;}/*解密函数,基本等同于于加密过程,只是密钥不同(被事先逆序)*/ void Dncrypt (unsigned char * Input,unsigned char * Output,unsigned int * rk)// Input:输入分组的密文,Output:输出的对应的分组明文,rk为轮密钥{    unsigned int r,mid,x0,x1,x2,x3,*p;//需要用到的中间变量         p=(unsigned int *)Input;//此时p指针指向输入     x0=p[0];    x1=p[1];    x2=p[2];    x3=p[3];        for(r=0;r<32;r+=4)//开始32轮解密 ,一次进行4轮,共计八次 {//F被分解为三步         mid=x1^x2^x3^rk[r+0];//先计算 x1^x2^x3^rk        mid=unline_change(mid);//非线性τ函数        x0=x0^L1(mid);//与x0亦或                mid=x2^x3^x0^rk [r+1];        mid=unline_change(mid);                    x1^=L1(mid);                mid=x3^x0^x1^rk[r+2];        mid=unline_change(mid);        x2^=L1(mid);                mid=x0^x1^x2^rk[r+3];        mid=unline_change(mid);        x3^=L1(mid);}   p=(unsigned int *)Output;//此时p指针指向输出  p[0]=x3;    p[1]=x2;  p[2]=x1;  p[3]=x0;}/*密钥扩展算法*/void KeyExpasion(unsigned char *Key ,unsigned int *rk)//Key :为加密密钥,rk:为轮密钥{    unsigned int r,mid,MK0,MK1,MK2,MK3,*p,k0,k1,k2,k3;//中间变量     p=(unsigned int *)Key ;//此时p指向密钥,以便将密钥Key分解为MK0~3    MK0=p[0];    MK1=p[1];    MK2=p[2];    MK3=p[3];        //初始计算K0~3     k0=MK0^FK0;k1=MK1^FK1;k2=MK2^FK2;k3=MK3^FK3;for(r=0;r<32;r+=4)//开始32轮密钥扩展 ,一次进行4轮,共计八次 {mid=k1^k2^k3^CK[r+0];//先计算 x1^x2^x3^rmid=unline_change(mid);//非线性τ函数rk[r+0]=k0^L2(mid);//与k0亦或mid=k2^k3^k0^CK[r+1];mid=unline_change(mid);rk[r+1]=k1^L2(mid);mid=k3^k0^k1^CK[r+2];mid=unline_change(mid);rk[r+2]=k2^L2(mid);mid=k0^k1^k2^CK[r+3];mid=unline_change(mid);rk[r+3]=k3^L2 (mid);}   }


0 0
原创粉丝点击