如何借助另一矩阵实现矩阵字节旋转,适配修改版AES开发场景?
前提说明
128位密钥在AES体系中默认转换为4×4的字节矩阵(每个元素为8位无符号字节),默认采用AES标准的列优先存储规则,即16字节的128位序列按顺序依次填充到矩阵的第0列第0行、第0列第1行、第0列第2行、第0列第3行、第1列第0行……以此类推。
你提到的两个矩阵参考下图:
可行实现方案
方案1:逐元素对应旋转(最灵活,适合自定义规则)
逻辑:辅助密钥矩阵中每个位置的元素值,决定轮密钥矩阵同位置元素的循环位移位数。
实现步骤:
- 先将128位的轮密钥、辅助密钥分别转换为4×4的字节矩阵
- 对每个位置的元素,先将辅助矩阵的值对8取模(8位字节位移超过8位等价于模8后的结果)
- 按约定的位移方向(左循环/右循环)对轮密钥元素执行位移操作
代码示例:
def bytes_to_matrix(key: bytes) -> list[list[int]]: # 128位字节转4x4列优先矩阵 return [[key[col*4 + row] for row in range(4)] for col in range(4)] def matrix_to_bytes(matrix: list[list[int]]) -> bytes: # 4x4矩阵转回128位字节 res = [] for col in range(4): for row in range(4): res.append(matrix[col][row]) return bytes(res) def rotate_element(val: int, shift: int, left=True) -> int: shift = shift % 8 if shift == 0: return val if left: return ((val << shift) & 0xff) | (val >> (8 - shift)) else: return (val >> shift) | ((val << (8 - shift)) & 0xff) def element_wise_rotate(round_key: bytes, aux_key: bytes, left_rotate=True) -> bytes: rk_mat = bytes_to_matrix(round_key) aux_mat = bytes_to_matrix(aux_key) res_mat = [[0]*4 for _ in range(4)] for col in range(4): for row in range(4): res_mat[col][row] = rotate_element(rk_mat[col][row], aux_mat[col][row], left_rotate) return matrix_to_bytes(res_mat)
方案2:行/列批量旋转(性能更高,适合规则固定的修改版AES)
逻辑:取辅助矩阵每行/每列的第一个元素值,决定轮密钥矩阵对应整行/整列的统一位移量,不需要逐元素计算,性能损耗更低。
代码示例(以行为单位旋转为例):
def row_wise_rotate(round_key: bytes, aux_key: bytes, left_rotate=True) -> bytes: rk_mat = bytes_to_matrix(round_key) aux_mat = bytes_to_matrix(aux_key) res_mat = [[0]*4 for _ in range(4)] for row in range(4): # 取辅助矩阵当前行第一个元素作为整行位移量 shift = aux_mat[0][row] % 8 for col in range(4): res_mat[col][row] = rotate_element(rk_mat[col][row], shift, left_rotate) return matrix_to_bytes(res_mat)
方案3:预计算查表实现(适合高频调用场景)
逻辑:提前预计算所有256个字节在1-7位位移下的结果,运行时直接查表,不需要实时计算位移,性能最高。
代码示例:
# 预计算左移、右移1-7位的查找表 LEFT_ROT_TABLE = [[0]*8 for _ in range(256)] RIGHT_ROT_TABLE = [[0]*8 for _ in range(256)] for val in range(256): for shift in range(8): LEFT_ROT_TABLE[val][shift] = ((val << shift) & 0xff) | (val >> (8 - shift)) RIGHT_ROT_TABLE[val][shift] = (val >> shift) | ((val << (8 - shift)) & 0xff) def table_based_rotate(round_key: bytes, aux_key: bytes, left_rotate=True) -> bytes: rk_mat = bytes_to_matrix(round_key) aux_mat = bytes_to_matrix(aux_key) table = LEFT_ROT_TABLE if left_rotate else RIGHT_ROT_TABLE res_mat = [[0]*4 for _ in range(4)] for col in range(4): for row in range(4): shift = aux_mat[col][row] % 8 res_mat[col][row] = table[rk_mat[col][row]][shift] return matrix_to_bytes(res_mat)
注意事项
- 位移方向需要提前统一规则,加密和解密阶段要使用相反的位移方向才能还原数据
- 如果你的矩阵采用行优先存储,只需要修改
bytes_to_matrix和matrix_to_bytes的填充逻辑即可,位移部分不需要改动 - 辅助密钥如果不是字节值而是比特位组成的位移值,需要先提取对应位置的比特段转为整数再作为位移量使用
内容的提问来源于stack exchange,提问作者Alexandre Leite Lopes
相关产品推荐
相关产品推荐

