阶段五实战项目 — SHA-3(Keccak)是 NIST 2015 年选定的新哈希标准。其海绵结构提供了与 SHA-2 完全不同的安全保证和灵活性。
SHA-3 的核心是 Keccak-f[1600] 置换,对 1600 位状态执行 24 轮迭代。每轮包含 5 个步骤:
Keccak 的海绵结构将 1600 位状态分为速率 r 和容量 c:
| 安全级别 | SHA-3 变体 | 速率 r | 容量 c |
|---|---|---|---|
| 128位 | SHA3-256 | 1088 | 512 |
| 256位 | SHA3-512 | 576 | 1024 |
// keccak_round.v - Keccak 单轮运算
module keccak_round (
input wire [1599:0] state_in,
input wire [63:0] rc, // 轮常量
output wire [1599:0] state_out
);
// 状态组织:5×5×64 位
// state[x][y] = state_in[(5*y + x)*64 +: 64]
// ====== θ (Theta) ======
reg [63:0] C [0:4];
reg [63:0] D [0:4];
reg [1599:0] after_theta;
integer i;
always @(*) begin
// 列 XOR
for (i = 0; i < 5; i = i + 1)
C[i] = state_in[i*64+:64] ^ state_in[(5+i)*64+:64] ^
state_in[(10+i)*64+:64] ^ state_in[(15+i)*64+:64] ^
state_in[(20+i)*64+:64];
// D[i] = C[i-1] XOR rot(C[i+1], 1)
D[0] = C[4] ^ {C[1][62:0], C[1][63]};
D[1] = C[0] ^ {C[2][62:0], C[2][63]};
D[2] = C[1] ^ {C[3][62:0], C[3][63]};
D[3] = C[2] ^ {C[4][62:0], C[4][63]};
D[4] = C[3] ^ {C[0][62:0], C[0][63]};
for (i = 0; i < 25; i = i + 1)
after_theta[i*64+:64] = state_in[i*64+:64] ^ D[i%5];
end
// ====== ρ (Rho) + π (Pi) 合并 ======
// 旋转偏移表和位置置换表
reg [1599:0] after_rho_pi;
always @(*) begin
// 简化:仅实现前几个位置的旋转
// 完整实现需要 25 个位置的旋转
after_rho_pi[0*64+:64] = after_theta[0*64+:64]; // (0,0) 偏移0
after_rho_pi[1*64+:64] = {after_theta[16*64+62-:1], after_theta[16*64+:63]}; // 简化
after_rho_pi[2*64+:64] = {after_theta[7*64+19-:45], after_theta[7*64+:19]};
// ... 其余 22 个位置
after_rho_pi[3*64+:64] = after_theta[3*64+:64]; // 简化
after_rho_pi[4*64+:64] = after_theta[4*64+:64]; // 简化
// 填充其余
for (i = 5; i < 25; i = i + 1)
after_rho_pi[i*64+:64] = after_theta[i*64+:64]; // 简化
end
// ====== χ (Chi) ======
reg [1599:0] after_chi;
integer j;
always @(*) begin
for (i = 0; i < 5; i = i + 1) begin // y
for (j = 0; j < 5; j = j + 1) begin // x
after_chi[(5*i+j)*64+:64] =
after_rho_pi[(5*i+j)*64+:64] ^
(~after_rho_pi[(5*i+((j+1)%5))*64+:64] &
after_rho_pi[(5*i+((j+2)%5))*64+:64]);
end
end
end
// ====== ι (Iota) ======
assign state_out = {after_chi[1599:64], after_chi[63:0] ^ rc};
endmodule
// sha3_engine.v - SHA-3 引擎(简化)
module sha3_engine (
input wire clk,
input wire rst_n,
input wire start,
input wire [1087:0] msg_block, // 1088位消息块 (SHA3-256)
input wire block_valid,
input wire last_block,
output reg [255:0] digest,
output reg digest_valid
);
// Keccak 轮常量 RC[0..23]
reg [63:0] RC [0:23];
initial begin
RC[0]=64'h0000000000000001; RC[1]=64'h0000000000008082;
RC[2]=64'h800000000000808A; RC[3]=64'h8000000080008000;
RC[4]=64'h000000000000808B; RC[5]=64'h0000000080000001;
RC[6]=64'h8000000080008081; RC[7]=64'h8000000000008009;
RC[8]=64'h000000000000008A; RC[9]=64'h0000000000000088;
RC[10]=64'h0000000080008009;RC[11]=64'h000000008000000A;
RC[12]=64'h000000008000808B;RC[13]=64'h800000000000008B;
RC[14]=64'h8000000000008089;RC[15]=64'h8000000000008003;
RC[16]=64'h8000000000008002;RC[17]=64'h8000000000000080;
RC[18]=64'h000000000000800A;RC[19]=64'h800000008000000A;
RC[20]=64'h8000000080008081;RC[21]=64'h8000000000008080;
RC[22]=64'h0000000080000001;RC[23]=64'h8000000080008008;
end
reg [1599:0] state;
reg [4:0] round_cnt;
reg absorbing, squeezing;
// 单轮实例
wire [1599:0] round_out;
keccak_round u_round (.state_in(state), .rc(RC[round_cnt]), .state_out(round_out));
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= 0; round_cnt <= 0;
digest <= 0; digest_valid <= 0;
absorbing <= 0; squeezing <= 0;
end else if (start) begin
state <= 0; round_cnt <= 0;
absorbing <= 1; digest_valid <= 0;
end else if (absorbing) begin
if (round_cnt < 24) begin
state <= round_out;
round_cnt <= round_cnt + 1;
end else begin
if (block_valid) begin
state[1087:0] <= state[1087:0] ^ msg_block;
round_cnt <= 0;
if (last_block) begin
absorbing <= 0;
squeezing <= 1;
end
end
end
end else if (squeezing) begin
if (round_cnt < 24) begin
state <= round_out;
round_cnt <= round_cnt + 1;
end else begin
digest <= state[255:0];
digest_valid <= 1;
squeezing <= 0;
end
end
end
endmodule
1. 实现 Keccak-f[1600] 的完整 25 个旋转偏移和位置置换。
2. 验证 SHA3-256("") 的输出是否等于 a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a。
3. 实现 SHAKE128/256 可扩展输出函数(XOF)。
4. 比较 SHA-3 和 SHA-256 的硬件效率:面积、吞吐量、关键路径。
你已实现 SHA-3/Keccak 的核心置换和海绵结构,理解了 θ、ρ、π、χ、ι 五个步骤的硬件映射。SHA-3 是未来哈希的基石!
获得徽章:🧽 SPONGE_MASTER
推荐使用以下工具链进行课程实践:
# 安装 Verilator
sudo apt install verilator
# 安装 Icarus Verilog(可选)
sudo apt install iverilog
# 安装 GTKWave(波形查看器)
sudo apt install gtkwave
# 验证安装
verilator --lint-only --version
iverilog -V
密码学硬件实现的关键性能指标:
这些指标之间通常存在 trade-off,设计时需根据应用场景权衡。
本课涉及的核心概念和技术关系:
Verilog 仿真调试的常用方法:
// 调试示例
initial begin
$dumpfile("sim.vcd");
$dumpvars(0, uut);
end
// 断言验证
assert property (@(posedge clk) valid |-> data !== 'x)
else $error("Invalid data when valid!");
# 1. 语法检查
verilator --lint-only module.v
# 2. 创建 C++ 测试主函数
cat > sim_main.cpp << 'EOF'
#include "Vmodule.h"
#include "verilated.h"
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv);
Vmodule* top = new Vmodule;
top->clk = 0; top->rst_n = 0;
top->eval();
top->rst_n = 1;
for (int i = 0; i < 100; i++) {
top->clk = !top->clk;
top->eval();
}
delete top;
return 0;
}
EOF
# 3. 编译
verilator -cc module.v --exe sim_main.cpp
make -C obj_dir -f Vmodule.mk
# 4. 运行
./obj_dir/Vmodule
密码硬件的性能评估维度:
| 指标 | 单位 | 说明 |
|---|---|---|
| 面积 | GE / LUT | 等效门数或查找表数量 |
| 频率 | MHz | 最大时钟频率 |
| 吞吐量 | Gbps | 每秒处理的数据量 |
| 延迟 | 周期数 | 从输入到输出的周期 |
| 能效 | pJ/bit | 每比特能耗 |
| 面积效率 | Gbps/GE | 单位面积吞吐量 |
不同应用场景对指标优先级不同:IoT 偏重面积和能效,服务器偏重吞吐量。
本课涉及的核心概念和技术关系:
Verilog 仿真调试的常用方法:
// 调试示例
initial begin
$dumpfile("sim.vcd");
$dumpvars(0, uut);
end
// 断言验证
assert property (@(posedge clk) valid |-> data !== 'x)
else $error("Invalid data when valid!");
# 1. 语法检查
verilator --lint-only module.v
# 2. 创建 C++ 测试主函数
cat > sim_main.cpp << 'EOF'
#include "Vmodule.h"
#include "verilated.h"
int main(int argc, char** argv) {
Verilated::commandArgs(argc, argv);
Vmodule* top = new Vmodule;
top->clk = 0; top->rst_n = 0;
top->eval();
top->rst_n = 1;
for (int i = 0; i < 100; i++) {
top->clk = !top->clk;
top->eval();
}
delete top;
return 0;
}
EOF
# 3. 编译
verilator -cc module.v --exe sim_main.cpp
make -C obj_dir -f Vmodule.mk
# 4. 运行
./obj_dir/Vmodule
密码硬件的性能评估维度:
| 指标 | 单位 | 说明 |
|---|---|---|
| 面积 | GE / LUT | 等效门数或查找表数量 |
| 频率 | MHz | 最大时钟频率 |
| 吞吐量 | Gbps | 每秒处理的数据量 |
| 延迟 | 周期数 | 从输入到输出的周期 |
| 能效 | pJ/bit | 每比特能耗 |
| 面积效率 | Gbps/GE | 单位面积吞吐量 |
不同应用场景对指标优先级不同:IoT 偏重面积和能效,服务器偏重吞吐量。