關(guān)于國密算法SM4的流程
原來用于無線局域網(wǎng)的國密算法SMS4被定義為SM4作為密碼行業(yè)標準發(fā)布。SM4是一個分組對稱密鑰算法,明文、密鑰、密文都是16字節(jié),加密和解密密鑰相同。通過32次循環(huán)的非線性迭代輪函數(shù)來實現(xiàn)加密和解密。其中包括非線性變換S盒,以及由移位異或構(gòu)成的線性變換。除了256字節(jié)的S盒之外,還定義了另外兩組參數(shù)FK以及CK(具體數(shù)據(jù)參考密碼局網(wǎng)站)?;具^程是首先把16字節(jié)密鑰按照4字節(jié)一組分成4組,然后根據(jù)密鑰擴展算法,生成32組4字節(jié)輪密鑰;再把輸入的16字節(jié)數(shù)據(jù)也按照4字節(jié)一組分成4組然后進行循環(huán)運算(這點和AES算法類似)。以下是一個簡單的加密demo流程。(特別說明:本程序未經(jīng)編譯驗證,僅供理解SM4流程參考)
U32 CK[32] = {}; // CK參數(shù)
U32 FK[4] = {}; // FK參數(shù)
U8 Sbox[256] = {}; // S盒數(shù)據(jù)
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) );
}
- 中巨偉業(yè) -