摘要:本文档对Intel提出的基于AES-NI实现SM4算法的专利进行分析研究,记录其原理,并列出实现代码的具体实现流程。
1. 原理介绍
1.1 方案的核心思想
Intel的方案的核心思想是:
1)使用SIMD指令进行多个分组数据的并行处理;
2)使用AESENCLAST来完成SM4的S变换。
AESENCLAST指令执行AES加密的最后一轮,其具体功能是对16字节的AES状态数据依次做S变换、行移位、异或子密钥这三个操作。但该指令是对16个字节进行AES的S变换,而SM4的S变换仅对4个字节执行,因此需由4个SM4分组来并行实施以凑齐16字节(每个SM4分组取32比特/4字节,4个分组取128比特/16字节),以匹配一条AESENCLAST指令。
1.2 两个算法的S变换以及同构映射
AES的S变换的数学结构为Sr(x) = Ar × Invr(x) + Cr。【用下标r表示AES的对应记号】
SM4的S变换的数学结构为Sm(x) = Am × Invm( (Am(x) + Cm) ) + Cm。【用下标m表示SM4的对应记号】
对SM4的S变换,记
- Invm的输入值为y,即从输入值x计算y为y = Amx + Cm,
- Invm的输出值为z。
上述表达式中计算Inv是最复杂最耗时的运算。AES中可利用AES的硬件指令快速计算Inv,但SM4没有这样的指令。一种办法是借助有限域的同构映射,先把SM4的元素映射到AES中,在AES中利用硬件指令计算Inv,最后再映射回来。如下图1。
图1 两个算法的S变换以及同构映射图
1.3 用AES计算SM4的S变换的详解
如前所述,用AES计算SM4的S变换,就是借助有限域的同构映射,
1)先把SM4的元素映射到AES中,
2)在AES中利用硬件指令计算Inv,
3)最后再映射回来。
围绕以上三个步骤,用AES计算SM4的S变换的详细情况包括如下图列出的四个台阶。
图2 用AES计算SM4的S变换的规划图
1.3.1 第一个台阶 利用AES的Inv计算SM4的Inv
如下图,从y计算出z,有两种方案(如下图):
方案1:如下图蓝色虚线,直接计算SM4的inv,即z = Invm(y)
方案2:如下图红色虚线指定的路线,利用同构映射T映射到AES这边,再做AES与上的inv,最后再映射回来,即z = T-1Invr(T(y))
所以,
Invm(y) = z = T-1Invr(T(y))
图3 利用AES的Inv运算计算SM4的INV运算
1.3.2 第二个台阶 利用AES的S变换计算SM4的Inv
AES算法的Invr没有单独的指令实现,如果利用AES完整的S变换(更靠近可用的AESENCLAST指令),那么需要将Sr(x)值抵消掉Invr之后的两个操作+Cm和Am×,如下图。所以,从y计算出z的两种方案调整如下:
方案1:无调整,如下图蓝色虚线,直接计算SM4的inv,即z = Invm(y)。
方案2:有调整,如下图红色虚线指定的路线——利用同构映射T映射到AES这边,再做AES与上的S变换,接着抵消掉+Cm(逆运算仍然是+Cm)和Am×(逆运算是A-1m×),最后再映射回来,即
z = T-1 A-1r× ( Sr(T(y)) + Cr ) = T-1 A-1r× Sr(T(y)) + T-1 A-1r Cr。
所以
Invm(y) = z = T-1 A-1r× Sr(T(y)) + T-1 A-1r Cr
图4 利用AES的S变换计算SM4的Inv
1.3.3 第三个台阶 利用AES的S变换计算SM4的S变换
将步骤二得到的Invm(y)的算式带入SM4的S变换的表达式,就可以得到完整的SM4的S变换(如下图红色虚线):
Sm(x)
= Am × Invm(y) + Cm 【SM4的S变换的表达式】
= Am (T-1 A-1r× Sr(T(y)) + T-1 A-1r Cr ) + Cm【代入第二步结果表达式】
= Am T-1 A-1r× Sr(T(Am(x)+ Cm)) + Am T-1 A-1r Cr ) + Cm【代入y的表达式】
= Am T-1 A-1r× Sr(T×Am(x)+ T×Cm)) + Am T-1 A-1r Cr ) + Cm【展开】
图5 利用AES的S变换计算SM4的Inv
1.3.4 第四个台阶 简化与修订
上面得到的结果结果需要简化才能用于实际中。
首先,能合并的变换尽可能合并,以AES的S变换为分界线,
- S变换前的步骤可合并,即T×Am(x)+ T×Cm
- S变换后的步骤可合并,即Am (T-1 A-1r× Sr(*) + T-1 A-1r Cr ) + Cm = Am T-1 A-1r× Sr(*) + ( Am T-1 A-1r Cr + Cm )
其次,因为使用的是AESENCLAST指令,但只需要其中的S变换部分,所以,行移位和子密钥异或需要消除。其中,行移位可利用Shuffle指令去除,子密钥异或可将子密钥设置为全0即可。
1.4 SM4的S变换全流程整合
第一步:执行前变换:x(1) = T×Am(x)+ T×Cm。
第二步:执行AES-NI指令:x(2) = AESENCLAST(x(1), 0)。
第三步:执行抵消行变换:采用Shuffle指令,x(3) = Shuffle(x(2), *),本步结果为对应的AES的S变换值。
第四步:执行后变换:x(4) = Am T-1 A-1r×x(3) + ( Am T-1 A-1r Cr + Cm ),输出x(4)作为SM4的S运算结果。
图6简化运算和修订AESENCLAST
2. 实现部分
SM4-AES-NI实方案
输入:
- Din:4m比特的待处理输入数据(例如,使用SSE指令进行128比特并行处理时,m=128;使用AVX2指令进行256比特并行处理时,m=256;使用AVX512指令进行512比特并行处理时,m=512);这4m比特数据按分组大小128比特划分为Z = 4m/128个分组,即Din = (B(0), B(1) , …, B(Z-1))。
- K:共32×32×z比特的SM4子密钥。按SM4子密钥大小32×32比特划分为Z个分组,即K = (K(0), K(1) , …, K(Z-1)),K(j)为分组数据B(j)对应执行SM4算法的子密钥,j = 0, 1, 2, …, Z-1。
输出:
- Dout:4m比特的输出数据Dout;这4m比特数据按分组大小128比特划分为Z = 4m/128个分组,即Dout = (C(0), C(1) , …, C(Z-1))。
步骤
第1步:加载输入数据
- 将各分组的128比特数据B(i)按32比特依次划分为4个32比特,即
B(j) = (X0(j), X1(j), X2(j), X3(j)),j = 0, 1, …, Z-1。
- 将以上32比特数据按以下方式重新排列为4个m比特的数据X0, X1, X2, X3:
X0 = (X0(0), X0(1), …,X0(Z-1))
X1 = (X1(0), X1(1), …,X1(Z-1))
X2 = (X2(0), X2(1), …,X2(Z-1))
X3 = (X3(0), X3(1), …,X3(Z-1))
图 4m比特数据的排列方式
(行为按分组大小排列,列为按m比特的X0、X1、X2、X3排列)
步骤2:执行32次迭代。对轮计数器i = 0, 1, 2, …, 31执行如下轮迭代:
- 加载第i轮的轮密钥。首先将各分组数据对应的32×32比特子密钥数据K(j)按32比特依次划分为32个32比特,即
K(j) = (K0(j), K1(j) , …, K31(j)),j = 0, 1, …, Z-1
取第i轮的m比特子密钥为rki = (Ki(0), Ki(1) , …, Ki(Z-1))。
- 计算异或值。4个m比特的数据X1、X2、X3和rki执行异或运算:
T = X1⊕X2⊕X3⊕rki
- 执行非线性运算SBOX更新m比特数据T的值:【intel方案核心】:
T = SBOX(T)见1.3节
- 执行如下线性混淆运更新m比特数据T的值:
T= T⊕(T<<<2)⊕(T <<<10)⊕(T <<<18)⊕(T <<< 24)
代码中优化为: T= (T⊕(T <<< 24)) ⊕ (((T)⊕(T <<<8)⊕(T <<<16))<<<2) 其中:
|
图 线性变换层的优化实现
- 更新4个m比特的数据(X0, X1, X2, X3) = (X1, X2, X3, X0⊕T)
步骤3:保存并输出数据。
参考文献
- kentle. SM4 AESNI指令集优化(intel).