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

Rust实现NIST FIPS PUB202规范SHA3-512遇字符串输入失效求助

SHA3-512实现错误修复

核心错误点及修复

1. 填充函数(pad101)计算错误

FIPS PUB 202中Pad10*1的规范要求:找到最小的j≥0,使得(m + 1 + j) ≡ 0 mod r,即j = (-m -1) mod r。你的代码中错误使用-m -2计算j,导致填充长度不符合标准。

修复代码:

fn pad101(&mut self, msg: &mut String, r: isize, m: isize) {
    let j = (-m - 1).rem_euclid(r);
    msg.push_str("1");
    msg.push_str(&"0".repeat(j as usize));
    msg.push('1');
}

2. 海绵函数(sponge)输出提取逻辑错误

Keccak海绵结构要求:先完成所有消息块的吸收阶段,再进入挤压阶段提取输出。你的代码在每个消息块处理循环内就执行输出提取,违反了流程逻辑。

修复代码:

fn sponge(&mut self, msg: &mut String) {
    // 填充消息
    let len = msg.len() as isize;
    self.pad101(msg, self.r as isize, len);

    // 分割为r位的消息块
    let n = msg.len() / self.r;
    let c = self.b - self.r;

    // 初始化状态为全0
    let mut s: Vec<String> = vec!["0".repeat(8); self.b / 8];

    // 吸收阶段:处理所有消息块
    for i in 0..n {
        let p_block = &msg[i * self.r..(i + 1) * self.r];
        // 构造长度为b的块:消息块 + c位0
        let p = format!("{}{}", p_block, "0".repeat(c));
        // 状态与块异或
        let xor_str: String = (0..p.len())
            .step_by(8)
            .map(|x| {
                let p_byte = u8::from_str_radix(&p[x..x+8], 2).unwrap();
                let s_byte = u8::from_str_radix(&s[x/8], 2).unwrap();
                format!("{:08b}", p_byte ^ s_byte)
            })
            .collect();
        // 执行Keccak-f变换
        s = self.keccakf(&xor_str);
    }

    // 挤压阶段:提取输出直到达到指定长度
    let mut z = String::new();
    while z.len() < self.d {
        let state_str = s.join("");
        z += &state_str[0..self.r];
        s = self.keccakf(&state_str);
    }
    z.truncate(self.d);
    self.from_bin_string(&z);
}

3. 状态转换(to_state)索引错误

Keccak状态的lane索引规则为z + w*(x + 5*y),你的代码错误使用w*(5*y +x)+z,导致状态加载顺序完全混乱。

修复代码:

fn to_state(&self, msg: &str) -> Vec<Vec<Vec<u8>>> {
    let mut s = vec![vec![vec![0; self.w]; 5]; 5];
    for x in 0..5 {
        for y in 0..5 {
            for z in 0..self.w {
                let idx = z + self.w * (x + 5 * y);
                s[x][y][z] = msg[idx..idx+1].parse().unwrap();
            }
        }
    }
    s
}

4. 二进制转十六进制(from_bin_string)比特反转错误

SHA3输出不需要反转每个字节的比特位,你的代码中反转了每个8位块的比特顺序,导致输出结果完全错误。

修复代码:

fn from_bin_string(&self, str: &str) {
    let hex_str: String = (0..str.len())
        .step_by(8)
        .map(|i| {
            let byte = u8::from_str_radix(&str[i..i+8], 2).unwrap();
            format!("{:02x}", byte)
        })
        .collect();
    println!("{}", hex_str);
}

5. 拼写错误修正

代码中多次将keccakf拼写成keccackf(多了一个c),建议统一修正为keccakf,避免潜在问题。

验证测试

修复后,输入"abc"应得到SHA3-512标准结果:
b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0

内容的提问来源于stack exchange,提问作者Non Reply

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 21:45:37