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

C语言实现Rijndael S-box计算函数结果异常,请问问题出在哪里

代码错误原因

你实现的逻辑只有Rijndael S-box的仿射变换步骤,缺少了前置的GF(2⁸)有限域乘法逆元计算步骤,这是结果偏差的核心原因。

Rijndael S-box的完整计算流程为:

  • 处理输入字节b:如果b == 0x00,则中间值x = 0x00;否则计算b在GF(2⁸)(不可约多项式为x⁸+x⁴+x³+x+1,对应值0x11B)下的乘法逆元,赋值给x
  • 对x执行你代码中写的仿射变换:s = x ^ ROTL8(x,1) ^ ROTL8(x,2) ^ ROTL8(x,3) ^ ROTL8(x,4) ^ 0x63,得到最终S盒输出

你测的前两个值刚好正确属于巧合:

  • 0x00的逆元就是0x00,代入仿射变换得到结果0x63和正确值一致
  • 0x01的逆元就是0x01,代入仿射变换得到结果0x7c和正确值一致
  • 从0x02开始,输入的逆元不等于原始输入值,你直接用原始输入做仿射变换,结果自然和预期不符。

正确实现示例

首先补充GF(2⁸)逆元计算函数,再整合到S盒逻辑中:

#include <stdint.h>

#define ROTL8(x,shift) ((uint8_t) ((x) << shift | ((x) >> (8 - (shift)))))

// GF(2^8)下乘法实现,不可约多项式0x11B
uint8_t gf_mul(uint8_t a, uint8_t b) {
    uint8_t p = 0;
    uint8_t hi_bit_set;
    for (int i = 0; i < 8; i++) {
        if (b & 1) p ^= a;
        hi_bit_set = (a & 0x80);
        a <<= 1;
        if (hi_bit_set) a ^= 0x1B;
        b >>= 1;
    }
    return p;
}

// 求GF(2^8)下的逆元,用费马小定理:a^(2^8-2) = a^254
uint8_t gf_inv(uint8_t a) {
    if (a == 0) return 0;
    uint8_t p = 1;
    uint8_t exp = 254;
    uint8_t base = a;
    while (exp > 0) {
        if (exp & 1) p = gf_mul(p, base);
        base = gf_mul(base, base);
        exp >>= 1;
    }
    return p;
}

uint8_t sbox(uint8_t b) {
    uint8_t x = gf_inv(b);
    uint8_t s = x ^ ROTL8(x,1) ^ ROTL8(x,2) ^ ROTL8(x,3) ^ ROTL8(x,4) ^ 0x63;
    return s;
}

该实现计算sbox(0x02)会得到正确结果0x77。

内容的提问来源于stack exchange,提问作者Paul Kim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 14:15:03