Python gmssl.SM4使用案例
摘要:在异构计算系统验证中,通常会有数据加解密的要求,例如用户数据、权重参数等,本文将详细介绍在UVM验证环境中,调用Python的gmssl库,用SM4实现加解密的验证方案。
一、Python gmssl
库介绍
gmssl
是一个开源的、纯Python实现的国密算法库。它的最大特点是不依赖任何底层C库(如OpenSSL),这使得它在各种环境中部署和使用都非常方便,尤其适合作为算法行为级参考模型(Golden Model/Oracle)。
1.1 主要功能和支持的算法:
- SM2 (非对称加密和签名): 基于椭圆曲线的公钥密码算法,用于加密通信、数字签名和密钥交换。
- SM3 (哈希算法): 密码杂凑算法,输出256位的哈希值,功能类似于SHA-256。
- SM4 (对称加密): 分组密码算法,分组长度和密钥长度都是128位,用于数据加密,功能类似于AES-128。
- ZUC (祖冲之序列密码): 用于移动通信4G/5G网络的对称加密和完整性保护。
1.2 为什么在验证中选择 gmssl
?
- 纯Python实现:易于安装和部署,
pip install gmssl
即可,避免了复杂的编译和环境依赖问题。 - 代码可读性高:可以直接阅读其Python源码来理解算法标准,非常适合作为学习和开发的参考。
- 易于集成:可以非常方便地与UVM验证环境通过DPI-C进行桥接,构建强大的参考模型。
二、gmssl
库用法示例
首先,安装gmssl
库:
pip install gmssl
1. SM4 对称加密示例 (最常用于RTL验证)
SM4是分组密码,处理数据时需要指定模式(Mode)和填充(Padding)。这里以常用的CBC (Cipher Block Chaining)模式为例。
# sm4_example.py
from gmssl.sm4 import Sm4, SM4_ENCRYPT, SM4_DECRYPT# 密钥和初始化向量(IV)都必须是128位 (16字节)
key = b'\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10'
iv = b'\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10'# 待加密的明文,这里是128位 (16字节)
# 在RTL验证中,我们通常处理一个或多个完整的数据块,可以不使用padding
plaintext = b'\x01\x23\x45\x67\x89\xab\xcd\xef\xfe\xdc\xba\x98\x76\x54\x32\x10'# 1. 初始化SM4加密器
crypt_sm4 = Sm4()
crypt_sm4.set_key(key, SM4_ENCRYPT) # 设置为加密模式# 2. 加密
# 使用CBC模式进行加密,输入为bytes,输出也为bytes
ciphertext = crypt_sm4.crypt_cbc(iv, plaintext)print("--- SM4 CBC Mode ---")
print(f"Key : {key.hex()}")
print(f"IV : {iv.hex()}")
print(f"Plaintext : {plaintext.hex()}")
print(f"Ciphertext : {ciphertext.hex()}")# 3. 解密过程
crypt_sm4.set_key(key, SM4_DECRYPT) # 切换为解密模式
decrypted_text = crypt_sm4.crypt_cbc(iv, ciphertext)print(f"Decrypted : {decrypted_text.hex()}")# 4. 验证结果
assert decrypted_text == plaintext
print("\nEncryption and Decryption successful!")
2. SM3 哈希算法示例
# sm3_example.py
from gmssl.sm3 import sm3_hash# 待计算哈希的数据 (bytes)
data_to_hash = b'hello world'# 计算哈希值,输入为bytes,输出也为bytes (32字节, 256位)
hash_value = sm3_hash(list(data_to_hash)) # gmssl的sm3_hash接收一个byte列表print("--- SM3 Hash ---")
print(f"Data : {data_to_hash.decode()}")
print(f"Hash Value : {hash_value.hex()}") # 以十六进制字符串输出
3. SM2 非对称加密示例
# sm2_example.py
from gmssl.sm2 import sm2_crypt# 1. 生成SM2密钥对 (公钥和私钥)
sm2_key = sm2_crypt.gen_key()
private_key = sm2_key.private_key.hex()
public_key = sm2_key.public_key.hex()print("--- SM2 Asymmetric Encryption ---")
print(f"Private Key: {private_key}")
print(f"Public Key : {public_key}")# 2. 使用公钥加密
data_to_encrypt = b'this is a secret message'
encryptor = sm2_crypt.Sm2Crypt(public_key=public_key)
ciphertext = encryptor.encrypt(data_to_encrypt)print(f"\nPlaintext : {data_to_encrypt.decode()}")
print(f"Ciphertext : {ciphertext.hex()}")# 3. 使用私钥解密
decryptor = sm2_crypt.Sm2Crypt(private_key=private_key)
decrypted_text = decryptor.decrypt(ciphertext)print(f"Decrypted : {decrypted_text.decode()}")assert decrypted_text == data_to_encrypt
print("\nSM2 Encryption and Decryption successful!")
三、gmssl
数据与 SystemVerilog 验证环境交互
在UVM等SystemVerilog验证环境中,与Python脚本交互的最佳实践是通过DPI-C接口。这形成了一个稳定且高效的三层架构:UVM <-> C <-> Python
。下面以SM4加密为例,展示一个完整的交互流程。
步骤 1: 创建Python脚本作为Oracle (gmssl_oracle.py
)
这个脚本通过命令行接收指令和数据,并从标准输出返回结果。这是解耦的关键。
# gmssl_oracle.py
import sys
from gmssl.sm4 import Sm4, SM4_ENCRYPT, SM4_DECRYPTdef main():# 命令行参数: gmssl_oracle.py <encrypt|decrypt> <key_hex> <iv_hex> <data_hex>if len(sys.argv) != 5:print("Error: Invalid arguments.", file=sys.stderr)sys.exit(1)mode, key_hex, iv_hex, data_hex = sys.argv[1:]try:key = bytes.fromhex(key_hex)iv = bytes.fromhex(iv_hex)data = bytes.fromhex(data_hex)except ValueError as e:print(f"Error: Invalid hex string. {e}&