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}&