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
相关产品推荐
相关产品推荐

