关于国密算法SM4的流程

关于国密算法SM4的流程

 

    原来用于无线局域网的国密算法SMS4被定义为SM4作为密码行业标准发布。SM4是一个分组对称密钥算法,明文、密钥、密文都是16字节,加密和解密密钥相同。通过32次循环的非线性迭代轮函数来实现加密和解密。其中包括非线性变换S盒,以及由移位异或构成的线性变换。除了256字节的S盒之外,还定义了另外两组参数FK以及CK(具体数据参考密码局网站)。基本过程是首先把16字节密钥按照4字节一组分成4组,然后根据密钥扩展算法,生成32组4字节轮密钥;再把输入的16字节数据也按照4字节一组分成4组然后进行循环运算(这点和AES算法类似)。以下是一个简单的加密demo流程。(特别说明:本程序未经编译验证,仅供理解SM4流程参考

 

 

 

 

U32 CK[32] = {}; // CK参数

U32 FK[4] = {}; // FK参数

U8 Sbox[256] = {}; // S盒数据

 

U32 K[35];

U32 X[35];

U8 Key[16]={}; // 密钥

U8 Input[16]={}; // 输入明文

U8 Output[16]; //  输出密文

U32 rk[32];

 

typedef union

       {

              U32 UL_Long;

              U8 UC_Byte[4];

       } UN_LongByte;

 

 

void SM4_Encrypt()

{

       UN_LongByte TempX,TempY;

       U8 i,j;

      

       KeyExpansion();

      

       for(i=0;i<4;i++)

       {

              for(j=0;j<4;j++)

              {

                     TempX.UC_Byte[j] = Input[j + i*4];

              }

              X[i] = TempX.UL_Long;

       }

      

       for(i=0;i<32;i++)

       {

              X[i+4] = RoundFunction(X[i],X[i+1],X[i+2],X[i+3],rk[i]);

       }

      

       for(i=0;i<4;i++)

       {

              TempY.UL_Long = X[35-i];

              for(j=0;j<4;j++)

              {

                     Output[j + i*4] = TempY.UC_Byte[j];

              }

       }

 

}

 

void KeyExpansion(void)

{

       UN_LongByte TempMK;

       U8 i, j;

      

       for(j=0;j<4;j++)

       {

              for(i=0;i<4;i++)

              {

                     TempMK.UC_Byte[i] = Key[i + 4*j];

              }

             

              K[j] = TempMK.UL_Long ^ FK[j];

       }

 

       for(i=0;i<32;i++)

       {

              K[i+4] = K[i] ^ FunctionT1(K[i+1] ^ K[i+2] ^ K[i+3] ^ CK[i]);

              rk[i] = K[i+4];

       }

}

      

 

U32 RoundFunction(U32 X1, U32 X2, U32 X3, U32 X4, U32 rk)

{

       return X1 ^ FunctionT( X2 ^ X3 ^ X4 ^ rk);

}

 

U32 FunctionT(U32 A)

{

       U8 i;

      

       UN_LongByte TempA, B;

       TempA.UL_Long = A;

      

       for (i=0;i<4;i++)

       {

              B.UC_Byte[i] = Sbox[TempA.UC_Byte[i]];

       }

      

       return (B.UL_Long ^ Left_Shift(B.UL_Long,2) ^ Left_Shift(B.UL_Long,10) ^ Left_Shift(B.UL_Long,18) ^ Left_Shift(B.UL_Long,24));

}

             

U32 FunctionT1(U32 A)

{

       U8 i;

      

       UN_LongByte TempA, B;

       TempA.UL_Long = A;

      

       for (i=0;i<4;i++)

       {

              B.UC_Byte[i] = Sbox[TempA.UC_Byte[i]];

       }

      

       return (B.UL_Long ^ Left_Shift(B.UL_Long,13) ^ Left_Shift(B.UL_Long,23));

}

      

 

U32 Left_Shift(U32 TargetData, U8 times)

{

       return ( (TargetData >> (32 - times)) | (TargetData << times) );

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值