• 图解Intel SM4-AES-NI实现方案


    摘要:本文档对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计算yy = 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实方案

    输入:

    1. 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))。
    2. 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。

    输出:

    1. Dout:4m比特的输出数据Dout;这4m比特数据按分组大小128比特划分为Z = 4m/128个分组,即Dout = (C(0), C(1) , …, C(Z-1))。

    步骤

    1步:加载输入数据

    1. 将各分组的128比特数据B(i)按32比特依次划分为4个32比特,即

    B(j) = (X0(j), X1(j), X2(j), X3(j)),j = 0, 1, …, Z-1。

    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执行如下轮迭代:

    1. 加载第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))。

    1. 计算异或值。4个m比特的数据X1、X2、X3和rki执行异或运算:

    T = X1X2X3⊕rki

    1. 执行非线性运算SBOX更新m比特数据T的值:intel方案核心】

    T = SBOX(T)见1.3节

    1. 执行如下线性混淆运更新m比特数据T的值:

    T= T(T<<<2)(T <<<10)(T <<<18)(T <<< 24)

    代码中优化为:

    T= (T(T <<< 24))  ⊕  (((T)(T <<<8)(T <<<16))<<<2)

    其中:

    • X<<<8/16/24可以通过shuffle指令实现;
    • X<<<2采取((X<<2)⊕(X>>30))实现;AVX512好像支持<<<指令。

     

    图 线性变换层的优化实现

    1. 更新4个m比特的数据(X0, X1, X2, X3) = (X1, X2, X3, X0⊕T)

    步骤3:保存并输出数据。

    参考文献

    1. kentle. SM4 AESNI指令集优化(intel).

    https://www.cnblogs.com/kentle/p/15826075.html

  • 相关阅读:
    Strings数据类型
    uboot启动流程-涉及board_init_f 函数
    React SSR - 写个 Demo 一学就会
    卷积层与池化层输出的尺寸的计算公式详解
    Mac环境下安装Ruby
    贴片天线的HFSS和CST仿真对比
    docker 本地保存镜像方法--docker export 和docker save 使用介绍
    Java 8 中需要知道的4个函数式接口-Function、Consumer、Supplier、Predicate
    Spring-ApplicationContext refresh的流程
    【SA8295P 源码分析 (一)】55 - ifs2_la.img 镜像加载解析过程分析
  • 原文地址:https://blog.csdn.net/samsho2/article/details/127841308