You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何借助另一矩阵实现矩阵字节旋转,适配修改版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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:15:08