算法過程
更多的原理介紹參考:SM4原理介紹


代碼實現
S盒實現
#include <stdio.h>
/*
SM4-S盒實現:
由三個復合函數組成,S(x)=L(I(L(x))),其中L(x)是仿射變換,而I(x)是逆變換
*/
int sbox[256]; // S盒
//仿射變換實現
int change(int x)
{
int A1 = 0xA7;
int flag;
int result = 0;
int tem;
int flage2;
for (int i = 0; i < 8; i++)
{
flag = (A1 & 0x80) >> 7;
tem = x & A1;
flage2 = 0;
for (int j = 0; j < 8; j++)
{
flage2 ^= (tem & 1);
tem >>= 1;
}
result = result | (flage2 << i);
A1 = (A1 << 1) | flag;
}
result ^= 0xd3;
return result;
}
//模2 多項式乘法
int multiplication(int a, int b)
{
int tem = 0;
int i = 0;
while (b)
{
if (b & 1)
{
tem ^= a << i;
}
i++;
b >>= 1;
}
return tem;
}
//模2 多項式除法
int length(int x)
{
int i = 0;
int comp = 1;
while (1)
{
if (comp >= x)
{
return i;
}
comp = (comp << 1) + 1;
i++;
}
}
void division(int a, int b, int* round, int* left)
{
*round = 0;
*left = 0;
int distence;
while (1)
{
distence = length(a) - length(b);
if (distence >= 0 && a)
{
a = a ^ (b << distence);
*round = (*round) | (1 << distence);
}
else {
*left = a;
break;
}
}
}
//模2 多項式求逆(擴展歐幾里得算法)
int inverse(int a, int b)
{
int x2 = 1;
int x1 = 0;
int y2 = 0;
int y1 = 1;
int temX1, temY1;
int q, r, x, y;
int i;
while (b)
{
division(a, b, &q, &r);
y = y2 ^ multiplication(q, y1);
a = b;
b = r;
y2 = y1;
y1 = y;
}
return y2;
}
void genXbox()
{
printf("-------------------------------------------------------------SM4-Sbox生成---------------------------------------------------------\n");
for (int i = 0; i <= 0xf; i++)
{
printf("\t%x", i);
}
printf("\n");
for (int i = 0; i <= 0xf; i++)
{
printf("%x", i);
for (int j = 0; j <= 0xf; j++)
{
printf("\t%x", change(inverse(0x1f5, change((i << 4) | j))));
}
printf("\n");
}
printf("----------------------------------------------------------------------------------------------------------------------------------\n");
system("pause");
}
int main()
{
genXbox();
return 0;
}

以上是S盒實現,詳細代碼見github
后續可實現:txt文本加密、Doc文件加密、圖片加密、PDF文本加密
參考
1、國標—SM4
2、密碼學-基礎理論與應用(李子臣著)
3、商用密碼檢測中心-源碼下載
