本文基于FPGA实现高速SM4加密与解密,提供开源Verilog RTL设计和可综合工程:https://github.com/cassuto/SM4-FPGA

本文仅讨论实现细节,不涉及算法原理。相关原理可参考其它资料。


一、国密标准概述

  国家密码局制定了一系列密码学算法,包括SM1/2/3/4等,其中SM2是椭圆曲线公钥密码算法,SM3是密码杂凑算法,SM4是分组加密算法。

上述算法的现行标准如下。标准原文可在“国家标准全文公开系统”查询。

  • SM2:

    GB/T 32918系列标准:

    《GB/T 32918.1-2016 SM2椭圆曲线公钥密码算法 第1部分:总则》

    《GB/T 32918.2-2016 SM2椭圆曲线公钥密码算法 第2部分:数字签名算法》

    《GB/T 32918.3-2016 SM2椭圆曲线公钥密码算法 第3部分:密钥交换协议》

    《GB/T 32918.4-2016 SM2椭圆曲线公钥密码算法 第4部分:公钥加密算法》

    《GB/T 32918.5-2017 SM2椭圆曲线公钥密码算法 第5部分:参数定义》

  • SM3:

    《GB/T 32905-2016 SM3密码杂凑算法》

  • SM4:

    《GB/T 32907-2016 SM4分组密码算法》

SM1算法并未公开。

二、SM4简介

  SM4算法是分组加密算法,分组长度和密钥长度均为128bit。SM4算法由密钥扩展算法与加密(解密)算法两部分构成,均采用非线性迭代结构;加密与解密算法具有相同的结构,只是对输入轮密钥进行反序变换。

2.1 密钥

  密钥长度为128bit,用\(MK=({MK}_0,{MK}_1, {MK}_2,{MK}_3)\)表示,其中向量\({MK}_i \space (i=0,1,2,3)\)表示一个字(32bit)。

  例如密钥\(\text{0x} \space 01 \space 23 \space 45 \space 67 \space 89 \space AB \space CD \space EF \space FE \space DC \space BA \space 98 \space 76 \space 54 \space 32 \space 10\)对应的\(MK\)为:

\[MK = \begin{bmatrix} 01 & 89 & FE & 76 \\ 23 & AB & DC & 54 \\ 45 & CD & BA & 32 \\ 67 & EF & 98 & 10 \end{bmatrix}
\]

  其中\({MK}_0=\begin{bmatrix} 01 & 23 & 45 & 67 \end{bmatrix}^T\)。

2.2 密钥扩展算法

  密钥扩展算法用于生成轮密钥,轮密钥用于加密算法每轮非线性迭代的输入。轮密钥用\(({rk}_1,{rk}_2, \dots , {rk}_{31})\)表示,其中向量\({rk}_i \space (i=0, \dots ,31)\)为一个字,表示第\(i\)轮迭代所使用的轮密钥。

  在介绍密钥扩展算法之前,需要引入轮函数和合成置换函数。

2.2.1 轮函数

  设轮函数输入为\((X_0,X_1,X_2,X_3)\),轮密钥为\(rk \in Z\),轮函数定义为:

\[F(X_0,X_1,X_2,X_3,rk) = X_0 \oplus T (X_1 \oplus X_2 \oplus X_3 \oplus rk)
\]

2.2.2 合成置换函数

  T函数由一个非线性变换和线性变换构成。其中非线性变换函数通过查找表(S盒)确定。设32bit输入为\(A=(a_0,a_1,a_2,a_3)\),输出为\(B=(b_0,b_1,b_2,b_3)\),其中分量\(a_i,b_i \space (i=0, \dots 3)\)是一个字节,非线性变换表示为:

\[(b_0,b_1,b_2,b_3)=(Sbox(a_0),Sbox(a_1),Sbox(a_2),Sbox(a_3))
\]

  每个S盒都是\(16 \times 16\)的查找表,具体取值见附录C。

  经过S盒置换后,再进行如下线性变换。设输入为B,输出为C,定义线性变换\(L\):

\[C=L(B)=B \oplus (B<<2) \oplus (B<<10) \oplus (B<<18) \oplus (B<<24)
\]

2.2.3 密钥扩展算法

  其中\({CK}_i\)、\({FK}_i\)都是常量,具体取值见附录A、B。将合成置换函数\(T\)中的线性变换\(L\)替换为\(L'(B)=B \oplus (B<<13) \oplus (B<<23)\),就得到了\(T'\)函数。

  上述每一步迭代的数据流如下图所示:

  第\(i\)、\(i+1\)、\(i+2\)、\(i+3\)步迭代的输出将作为第\(i+4\)步迭代的输入,具体可参考下图:

  从总体看,轮密钥是以密钥为唯一变量的函数,若密钥已经确定,则轮密钥也是确定的。因此当密钥固定不变时,轮密钥可以预先计算。

2.3 反序变换

  设反序变换的输入为\(A=(a_0,a_1,a_2,a_3)\),输出为\(B=(b_0,b_1,b_2,b_3)\),反序变换定义为:

\[(b_0,b_1,b_2,b_3) = (a_3,a_2,a_1,a_0)
\]

2.4 加密算法

  设明文输入为\((X_3,X_2,X_1,X_0)\),密文输出为\((Y_0,Y_1,Y_2,Y_3)\),密码扩展算法输出轮密钥为\(rk\),则加密算法由如下步骤完成:

(1)非线性迭代

  数据流图如下所示:

(2)输出

\[(Y_0,Y_1,Y_2,Y_3) = R(X_{32},X_{33},X_{34},X_{35})
\]

2.5 解密算法

  解密算法与加密算法结构相同,只是对轮密钥反序变换后再使用,即使用\(rk'=({rk}_{31},{rk}_{30}, \dots ,{rk}_0)\)作为轮密钥。

三、实现

  根据上文得出的数据流图,容易导出硬件实现。

3.1 流水线总体结构

  SM4加密算法核心是32轮非线性迭代,在硬件上,可通过组合逻辑块来实现每轮迭代,第\(i\)个组合逻辑块的输出作为第\(i+1\)个组合逻辑块的输入,得到如下所示的非流水线实现:

  这种设计在低速时钟下可以工作,但关键路径已经很长,进一步提升时钟频率变得困难。

  解决办法是采用流水线,通过寄存器划分关键路径。设每个组合逻辑块的延时为\(d_i \space (i=0,1, \dots ,31)\),非流水线实现中,关键路径的数据传输延时为\(D=\sum_{i=0}^{31}d_i\),而流水线实现中关键路径的数据传输延时为\(D'=\max_{0 \le i \le 31}d_i + T_{cko}\)。可知\(D'\lt D\),时序得到了改善。

  设流水线时钟频率为\(F\),则系统的峰值吞吐率\(T_{max}\)可计算为:

\[T_{max} = (128 \cdot F) \space bps
\]

  当时钟频率\(F=100MHz\)时,峰值吞吐率\(T_{max}\)可达\(12.8Gbps\)。

  考虑流水线停顿(stall)对流水线效率造成的影响。若流水线效率为\(0 \lt \eta \le 1\),则实际吞吐率为:

\[Tp = T_{max} \cdot \eta
\]

3.2 行为级模型的建立

  建立算法的行为级模型,这里只贴出关键代码。

合成置换函数\(T\):

/* Transformation function */
uint32_t T(uint32_t x) {
uint32_t B = sbox(x);
return B ^ rol(B, 2) ^ rol(B, 10) ^ rol(B, 18) ^ rol(B, 24);
}

合成置换函数\(T'\)

/* Transformation inverse function */
uint32_t T_1(uint32_t x) {
uint32_t B = sbox(x);
return B ^ rol(B, 13) ^ rol(B, 23);
}

密钥扩展算法:

void keyexpand(const uint8_t *mk, uint32_t K[36]) {
K[0] = btw(mk) ^ FK[0];
K[1] = btw(mk+4) ^ FK[1];
K[2] = btw(mk+8) ^ FK[2];
K[3] = btw(mk+12) ^ FK[3]; for(int i=0; i<32; i++) {
K[i+4] = K[i] ^ T_1(K[i+1] ^ K[i+2] ^ K[i+3] ^ CK[i]);
}
}

加密/解密算法:

void decenc(bool enc, const uint8_t *in, uint8_t *out, uint32_t K[36]) {
unsigned long X[36] = {0}; X[0] = btw(in);
X[1] = btw(in+4);
X[2] = btw(in+8);
X[3] = btw(in+12); for(int i = 0; i<32; i++) {
X[i+4] = X[i] ^ T(X[i+1] ^ X[i+2] ^ X[i+3] ^ K[enc ? i+4 : 35-i]);
} wtb(X[35], out);
wtb(X[34], out+4);
wtb(X[33], out+8);
wtb(X[32], out+12);
}

  建立的行为级模型可用于差分测试,通过对比FPGA计算结果与行为级模型的计算结果,可检验FPGA实现是否正确。TODO:这部分待实现。

3.3 RTL模型的建立

3.3.1 S盒替换的实现

  S盒置换用于合成置换函数\(T\)。S盒置换函数是32bit字到32bit字的映射,按照字节粒度逐字节替换。

  通过ROM实现S盒函数。将输入字节\(a_0,a_1,a_2,a_3\)作为ROM的地址,将ROM的数据输出作为S盒函数的值。输入4个字节的替换是并行的。

3.3.2 流水级的实现

  流水级实现轮函数。轮函数的基本框架是异或门;合成置换函数\(T\)的非线性变换函数由ROM实现;流水线的数据暂存和传输通过寄存器实现。

  \(L\)为合成置换函数\(T\)的线性变换函数,具体可参见Verilog源码,这里不再赘述。

3.3.3 顶层模块的实现

信号名称 描述
CLK_i 时钟输入
RST_N_i 异步复位输入(下降沿有效)
MK_i 128bit密钥输入
MK_VALID_i 密钥输入是否有效
DAT_i 128bit明文(密文)分组输入
DAT_VALID_i 分组输入是否有效
DAT_o 128bit密文(明文)分组输出
DAT_READY_o 分组输出是否有效

顶层模块内部RTL原理图

其中keyexp模块实现密钥扩展算法,decenc模块实现加密/解密非线性迭代算法。

3.3.4 顶层模块的参数化

  通过可变参数实现顶层模块的可配置性。顶层模块既可以实现分组加密,又可以实现分组解密。此外,还可配置成使用固定轮密钥,从而省去keyexp模块的资源。

参数名 描述 默认值
MODE 0:加密; 非0:解密
ENABLE_FIXED_RK 0:不使用固定轮密钥;非0:使用固定轮密钥 0
FIXED_RK 若使用固定轮密钥,指定1024bit轮密钥 128’h0

  注:当ENABLE_FIXED_RK!=0时,采用FIXED_RK指定的轮密钥,外部输入信号MK_i和MK_VALID_i将被忽略,此时模块占用逻辑资源最少;否则,采用MK_i指定的密钥,轮密钥将动态生成。

四、FPGA测试

  在Xilinx ZYNQ-7010平台构建如下基于ILA(集成逻辑分析仪)的测试环境,测试SM4模块。

通过ILA抓取加密模块与解密模块输入输出信号波形,验证其功能。

输入明文分组:128'h \(01 \space 23 \space 45 \space 67 \space 89 \space AB \space CD \space EF \space FE \space DC \space BA \space 98 \space 76 \space 54 \space 32 \space 10\)

输入密钥为:128'h \(01 \space 23 \space 45 \space 67 \space 89 \space AB \space CD \space EF \space FE \space DC \space BA \space 98 \space 76 \space 54 \space 32 \space 10\)

加密模块输出密文:ciphertext = 128'h \(68 \space 1e \space df \space 34 \space d2 \space 06 \space 96 \space 5e \space 86 \space b3 \space e9 \space 4f \space 53 \space 6e \space 42 \space 46\)

解密模块输出明文为:DAT_o = 128'h \(01 \space 23 \space 45 \space 67 \space 89 \space AB \space CD \space EF \space FE \space DC \space BA \space 98 \space 76 \space 54 \space 32 \space 10\)

结果正确。

验证:TODO

4.1 资源占用

4.2 时序(\(Fclk=100MHz\))

计算得出理论最大工作频率\(F_{max} = \frac{1}{T-WNS} = 130 MHz\)

4.3 功耗

注意事项

目前的实现较为原始,没有针对S盒优化,也没有考虑侧信道攻击,有待进一步完善。

附录A:CK参数常量表

\({CK}_0\) \({CK}_1\) \({CK}_2\) \({CK}_3\)
0x00070E15 0x1C232A31 0x383F464D 0x545B6269
\({CK}_4\) \({CK}_5\) \({CK}_6\) \({CK}_7\)
0x70777E85 0x8C939AA1 0xA8AFB6BD 0xC4CBD2D9
\({CK}_8\) \({CK}_9\) \({CK}_{10}\) \({CK}_{11}\)
0xE0E7EEF5 0xFC030A11 0x181F262D 0x343B4249
\({CK}_{12}\) \({CK}_{13}\) \({CK}_{14}\) \({CK}_{15}\)
0x50575E65 0x6C737A81 0x888F969D 0xA4ABB2B9
\({CK}_{16}\) \({CK}_{17}\) \({CK}_{18}\) \({CK}_{19}\)
0xC0C7CED5 0xDCE3EAF1 0xF8FF060D 0x141B2229
\({CK}_{20}\) \({CK}_{21}\) \({CK}_{22}\) \({CK}_{23}\)
0x30373E45 0x4C535A61 0x686F767D 0x848B9299
\({CK}_{24}\) \({CK}_{25}\) \({CK}_{26}\) \({CK}_{27}\)
0xA0A7AEB5 0xBCC3CAD1 0xD8DFE6ED 0xF4FB0209
\({CK}_{28}\) \({CK}_{29}\) \({CK}_{30}\) \({CK}_{31}\)
0x10171E25 0x2C333A41 0x484F565D 0x646B7279

附录B:FK参数常量表

\({FK}_0\) \({FK}_1\) \({FK}_2\) \({FK}_3\)
0xA3B1BAC6 0x56AA3350 0x677D9197 0xB27022DC

附录C:S盒常量表

0 1 2 3 4 5 6 7 8 9 A B C D E F
0 0xD6 0x90 0xE9 0xFE 0xCC 0xE1 0x3D 0xB7 0x16 0xB6 0x14 0xC2 0x28 0xFB 0x2C 0x05
1 0x2B 0x67 0x9A 0x76 0x2A 0xBE 0x04 0xC3 0xAA 0x44 0x13 0x26 0x49 0x86 0x06 0x99
2 0x9C 0x42 0x50 0xF4 0x91 0xEF 0x98 0x7A 0x33 0x54 0x0B 0x43 0xED 0xCF 0xAC 0x62
3 0xE4 0xB3 0x1C 0xA9 0xC9 0x08 0xE8 0x95 0x80 0xDF 0x94 0xFA 0x75 0x8F 0x3F 0xA6
4 0x47 0x07 0xA7 0xFC 0xF3 0x73 0x17 0xBA 0x83 0x59 0x3C 0x19 0xE6 0x85 0x4F 0xA8
5 0x68 0x6B 0x81 0xB2 0x71 0x64 0xDA 0x8B 0xF8 0xEB 0x0F 0x4B 0x70 0x56 0x9D 0x35
6 0x1E 0x24 0x0E 0x5E 0x63 0x58 0xD1 0xA2 0x25 0x22 0x7C 0x3B 0x01 0x21 0x78 0x87
7 0xD4 0x00 0x46 0x57 0x9F 0xD3 0x27 0x52 0x4C 0x36 0x02 0xE7 0xA0 0xC4 0xC8 0x9E
8 0xEA 0xBF 0x8A 0xD2 0x40 0xC7 0x38 0xB5 0xA3 0xF7 0xF2 0xCE 0xF9 0x61 0x15 0xA1
9 0xE0 0xAE 0x5D 0xA4 0x9B 0x34 0x1A 0x55 0xAD 0x93 0x32 0x30 0xF5 0x8C 0xB1 0xE3
A 0x1D 0xF6 0xE2 0x2E 0x82 0x66 0xCA 0x60 0xC0 0x29 0x23 0xAB 0x0D 0x53 0x4E 0x6F
B 0xD5 0xDB 0x37 0x45 0xDE 0xFD 0x8E 0x2F 0x03 0xFF 0x6A 0x72 0x6D 0x6C 0x5B 0x51
C 0x8D 0x1B 0xAF 0x92 0xBB 0xDD 0xBC 0x7F 0x11 0xD9 0x5C 0x41 0x1F 0x10 0x5A 0xD8
D 0x0A 0xC1 0x31 0x88 0xA5 0xCD 0x7B 0xBD 0x2D 0x74 0xD0 0x12 0xB8 0xE5 0xB4 0xB0
E 0x89 0x69 0x97 0x4A 0x0C 0x96 0x77 0x7E 0x65 0xB9 0xF1 0x09 0xC5 0x6E 0xC6 0x84
F 0x18 0xF0 0x7D 0xEC 0x3A 0xDC 0x4D 0x20 0x79 0xEE 0x5F 0x3E 0xD7 0xCB 0x39 0x48

FPGA实现国密算法SM4的更多相关文章

  1. 关于国密算法 SM1,SM2,SM3,SM4 的笔记

    国密即国家密码局认定的国产密码算法.主要有SM1,SM2,SM3,SM4.密钥长度和分组长度均为128位. SM1 为对称加密.其加密强度与AES相当.该算法不公开,调用该算法时,需要通过加密芯片的接 ...

  2. java sm4国密算法加密、解密

      java sm4国密算法加密.解密 CreationTime--2018年7月5日09点20分 Author:Marydon 1.准备工作 所需jar包: bcprov-jdk15on-1.59. ...

  3. SM系列国密算法(转)

    原文地址:科普一下SM系列国密算法(从零开始学区块链 189) 众所周知,为了保障商用密码的安全性,国家商用密码管理办公室制定了一系列密码标准,包括SM1(SCB2).SM2.SM3.SM4.SM7. ...

  4. OpenSSL 1.1.1 国密算法支持

    OpenSSL 1.1.1 国密算法支持 https://www.openssl.org/ https://github.com/openssl/openssl OpenSSL 1.1.1 新特性: ...

  5. Hyperledger Fabric密码模块系列之BCCSP(五) - 国密算法实现

    Talk is cheap, show me your code. 代码也看了,蛋也扯了,之后总该做点什么.响应国家政策,把我们的国密算法融合进去吧--  先附两张bccsp下国密算法的设计实现图. ...

  6. 20155206赵飞 基于《Arm试验箱的国密算法应用》课程设计个人报告

    20155206赵飞 基于<Arm试验箱的国密算法应用>课程设计个人报告 课程设计中承担的任务 完成试验箱测试功能1,2,3 . 1:LED闪烁实验 一.实验目的  学习GPIO原理  ...

  7. 《基于Arm实验箱的国密算法应用》课程设计 结题报告

    <基于Arm实验箱的国密算法应用>课程设计 结题报告 小组成员姓名:20155206赵飞 20155220吴思其 20155234昝昕明 指导教师:娄嘉鹏 设计方案 题目要求:基于Arm实 ...

  8. 2015520吴思其 基于《Arm试验箱的国密算法应用》课程设计个人报告

    20155200吴思其 基于<Arm试验箱的国密算法应用>课程设计个人报告 课程设计中承担的任务 完成试验箱测试功能4,5,6以及SM3加密实验的实现 测试四 GPIO0按键中断实验 实验 ...

  9. 20155234 昝昕明《基于ARM实验箱的国密算法应用》课程设计个人报告

    20155234 昝昕明<基于ARM实验箱的国密算法应用>课程设计个人报告 个人贡献 参与课设题目讨论及完成全过程: 资料收集: SM1算法及和ARM之间通信 负责串口代码调试: 协调完成 ...

  10. 国密算法--Openssl 实现国密算法(基础介绍和产生秘钥对)

    国密非对称加密算法 又称sm2,它是采取了ECC(曲线加密算法)中的一条固定的曲线,实际上就是ECC算法. 因为openssl里面不包含sm2算法,所以就要重新进行封装-. - 对于ECC算法我就不介 ...

随机推荐

  1. MySQL 常用命令(4)------mysqladmin命令详解

    mysqladmin是一个执行管理操作的客户端程序.它可以用来检查服务器的配置和当前状态.创建和删除数据库等. mysqladmin 工具的使用格式: mysqladmin [option] comm ...

  2. 关于promise经典面试题

    这里涉及到同步和异步的问题

  3. WDA学习(24):Context Menu使用

    1.17 UI Element:Context Menu使用 本实例测试创建Context Menu. 1.创建Component,View: V_CONTEXT_MENU; 2.创建Context节 ...

  4. jquery语言中获取input标签后如何给input标签添加disabled的属性

    jquery语言中获取input标签后如何给input标签添加disabled的属性 1.使用JQuery函数prop():$("input").prop("disabl ...

  5. 057_Apex 开发中的问题

    2019/12/27 补充内容: 1. %2F 由于页面的按钮点击或者Detail 页面编辑url中会生成 returnURL=%2F id,需要注意下 2. Trigger 中, __r 与触发条件 ...

  6. Java+selenium自动爬取网站内容并写入本地

    目的:本文主要描述如何使用Java+selenium爬取58同城招聘页,并记录指定职位的招聘公司名保存到本地 一.首先创建一个maven工程,配置依赖包 1 <dependencies> ...

  7. Spring的隔离级别,Spring事务传播属性,Spring事务与数据库事务之间的联系

    一.Spring五大事务隔离级别 Spring事务隔离级别比数据库事务隔离级别多一个default在进行配置的时候,如果数据库和spring代码中的隔离级别不同,那么以spring的配置为主.1) D ...

  8. git 代码已经commit ,发现提错了分支

    步骤: git reset HEAD^ //把上次提交恢复为未提交状态 git status //查看当前状态 git stash //将修改add到暂存区,暂存代码 git checkout 分支 ...

  9. SQL----EXISTS 关键字EXISTS基本意思

    1.EXISTS基本意思 英语解释就是存在,不过他的意思也差不多,相当于存在量词'З'.他不返回数据的,当后带带的查询为空值是,返回"FALSE",非空则返回"TRUE& ...

  10. STM32中遇到的一些关键字

    3.在STM32编程中遇到的一些关键字 STM32是基于RAM的架构,学习它可以是嵌入式的一个基础部分.因此对于一些关键字也必须了解,在STM32学习过程中,遇到过如下变量,对其有疑问 关键字 功能 ...