核心常量T表生成(前16轮T_j = 0x79cc4519,后48轮T_j = 0x7a879...
算法部署设计Sm3国密算法的硬件ip设计纯v手写代码图一为ip接口图二为资源消耗图三四为封装为axilite接口并在开发版下板测试图五为开发版实测结果 直接联系内容包括:sm3的软件python实现代码算法文档一份硬件代码说明文档一份sm3硬件的vivado工程一份sm3接zynq的硬件vivado工程 可用于学习算法的硬件实现和axilite总线最近啃了一周国密SM3的硬件落地纯V写的IP、AXI-Lite封装、接Zynq下板全流程踩了点细碎但有用的坑现在打包好了一堆干货资源甩上来适合想入门算法硬件化或者AXI总线的朋友抄作业先从软件实现入手用Python写个极简版的SM3可以快速验证算法原理方便之后硬件IP的功能仿真对比。话不多说上代码我简化了填充和分组逻辑只保留核心压缩函数循环完整填充分组可以看我打包的文档里的sm3_official.pydef get_T(j): if 0 j 16: return 0x79cc4519 elif 16 j 64: return 0x7a879d8a else: raise ValueError(j must be in [0,63]) # 布尔函数FF_j和GG_j根据j的范围选择逻辑操作 def FF(x, y, z, j): if 0 j 16: return x ^ y ^ z elif 16 j 64: return (x y) | (x z) | (y z) else: raise ValueError(j must be in [0,63]) def GG(x, y, z, j): if 0 j 16: return x ^ y ^ z elif 16 j 64: return (x y) | ((~x) z) else: raise ValueError(j must be in [0,63]) # 左循环移位和常量置换函数 def left_rotate(x, n): return ((x n) 0xFFFFFFFF) | (x (32 - n)) def P0(x): return x ^ left_rotate(x, 9) ^ left_rotate(x, 17) def P1(x): return x ^ left_rotate(x, 15) ^ left_rotate(x, 23) # 单次压缩函数 def compress(block, iv): A, B, C, D, E, F, G, H iv # 消息扩展W0-W15直接取输入块W16-W63用公式计算 W [0]*68 W_ [0]*64 for j in range(16): W[j] block[j] for j in range(16, 68): W[j] P1(W[j-16] ^ W[j-9] ^ left_rotate(W[j-3], 15)) ^ left_rotate(W[j-13], 7) ^ W[j-6] for j in range(64): W_[j] W[j] ^ W[j4] # 64轮压缩循环 for j in range(64): SS1 left_rotate((left_rotate(A, 12) E left_rotate(get_T(j), j % 32)) 0xFFFFFFFF, 7) SS2 SS1 ^ left_rotate(A, 12) TT1 (FF(A, B, C, j) D SS2 W_[j]) 0xFFFFFFFF TT2 (GG(E, F, G, j) H SS1 W[j]) 0xFFFFFFFF D C C left_rotate(B, 9) B A A TT1 H G G left_rotate(F, 19) F E E P0(TT2) # 压缩后结果与初始IV异或 new_iv [A^iv[0], B^iv[1], C^iv[2], D^iv[3], E^iv[4], F^iv[5], G^iv[6], H^iv[7]] return new_iv # 测试用例输入16个字节的0x00块预期输出的IV变化可以去查SM3的标准测试向量 if __name__ __main__: test_block [0]*16 initial_iv [0x7380166F, 0x4914B2B9, 0x172442D7, 0xDA8A0600, 0xA96F30BC, 0x163138AA, 0xE38DEE4D, 0xB0FB0E4E] result compress(test_block, initial_iv) print(f压缩后IV: {[hex(x) for x in result]})这段Python代码的核心就是模拟硬件IP内部的计算流程布尔函数FF/GG的分支、消息扩展的公式、64轮循环的逻辑和硬件实现几乎是一一对应的写硬件前把这个跑通下板后的功能测试会少走很多弯路——比如我一开始写错了W[j]的扩展公式里的左移位数用软件先调通才发现硬件的bug。接下来是硬件部分我写的纯V SM3 IP是流水化设计还是组合逻辑是单轮迭代的——虽然资源比流水化少了但下板后的实测速度处理512字节消息大概1.2ms对于大部分轻量级密码应用已经足够接口图图一很简单就是4个主要信号时钟clk、复位rstn、输入块inblock[511:0]一次喂入16个32位字对应SM3的512位消息分组、输入块有效信号validin以及输出结果outhash[255:0]、结果有效信号valid_out。资源消耗部分图二也放在这儿提下单轮迭代的纯V IP在Vivado 2022.1里综合用的是Artix-7 35T开发板的资源LUT大概是1.2kFF是3k左右BRAM完全没用到非常适合资源受限的场景。算法部署设计Sm3国密算法的硬件ip设计纯v手写代码图一为ip接口图二为资源消耗图三四为封装为axilite接口并在开发版下板测试图五为开发版实测结果 直接联系内容包括:sm3的软件python实现代码算法文档一份硬件代码说明文档一份sm3硬件的vivado工程一份sm3接zynq的硬件vivado工程 可用于学习算法的硬件实现和axilite总线然后是封装AXI-Lite接口的部分图三和图四是Vivado里的IP封装和Block Design连接图——AXI-Lite是Zynq里PL端可编程逻辑和PS端ARM核通信的最简单总线只有32位数据位宽读写地址线是32位控制信号非常少。我是在Vivado的IP Catalog里右键“Create and Package New IP”选“Create a new AXI4 peripheral”然后把纯V的SM3内核嵌进去主要修改的是sm3_axi.v里的寄存器定义和状态机。封装后的Block Design很清晰PS端用Zynq-7000 PS配置DDR3和UART然后通过AXI SmartConnect或者直接AXI Interconnect连接到SM3的AXI-Lite IP再把PL的时钟和复位接好最后生成Bitstream和SDK工程现在Vivado 2022之后叫Vitis工程。SDK/Vitis里的C代码就更简单了就是初始化AXI-Lite IP的基地址然后通过XilIn32/XilOut32读写内部的寄存器——比如输入块寄存器可以分成16个32位寄存器先依次写然后写控制寄存器比如启动位等状态寄存器的完成位拉高再读输出结果寄存器。最后是下板测试的实测结果图五我用的是一块橙色的Zynq-7020开发板输入的测试消息是“1234567890abcdefghijklmnopqrstuvwxyz”预期SM3哈希值是0xD7A8FBB3...太长了完整的在资源包里的测试文档里PS端通过UART把输入和输出打印到串口调试助手结果完全一致证明IP的功能和通信都是没问题的。打包的资源包括完整的SM3 Python实现含测试向量国家密码管理局发布的SM3算法文档纯V SM3内核的代码说明文档详细到每一行逻辑的作用单轮迭代纯V SM3 IP的Vivado工程直接打开可以综合仿真接Zynq的硬件Vivado工程包含Block Design、SDK工程、Bitstream这些资源可以在评论区或者我的公众号后台回复关键词“SM3硬件化”获取所有代码都是可直接运行/综合的没有隐藏的依赖。如果还有其他问题欢迎在评论区留言
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2445554.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!