阶段一对称密码基础 — S-Box(替换盒)是分组密码的非线性核心,它决定了算法抵抗线性和差分密码分析的能力。
Shannon 在 1949 年提出密码设计的两个基本原则:
S-Box 是实现混淆的核心组件。它将输入通过非线性映射转换为输出,使得输入-输出关系无法用简单线性函数描述。
AES S-Box 的构造基于两个步骤:
在 GF(2⁸) 上,以不可约多项式 m(x) = x⁸ + x⁴ + x³ + x + 1(0x11B)定义域运算。对输入字节 a,先求其在 GF(2⁸) 上的乘法逆元 a⁻¹(0 映射到 0)。
其中 A 是 GF(2) 上的 8×8 可逆矩阵,c = 0x63。
对逆元结果施加仿射变换:
这个仿射变换的矩阵表示为:
仿射矩阵 A:
[1 0 0 0 1 1 1 1] 常数 c = [1]
[1 1 0 0 0 1 1 1] [1]
[1 1 1 0 0 0 1 1] [0]
[1 1 1 1 0 0 0 1] [0]
[1 1 1 1 1 0 0 0] [0]
[0 1 1 1 1 1 0 0] [1]
[0 0 1 1 1 1 1 0] [1]
[0 0 0 1 1 1 1 1] [0]
最直接的方法:预计算全部 256 个映射值,存储为 ROM。这是 FPGA 实现的标准做法,利用 BRAM 或分布式 RAM。
// aes_sbox_lut.v - AES S-Box 查找表实现
module aes_sbox_lut (
input wire [7:0] addr, // 输入字节
output wire [7:0] data // S-Box 输出
);
// 256 x 8-bit ROM,存储 AES S-Box 完整映射表
reg [7:0] sbox [0:255];
initial begin
// S-Box 完整查找表(NIST FIPS-197 标准定义)
sbox[8'h00] = 8'h63; sbox[8'h01] = 8'h7c; sbox[8'h02] = 8'h77; sbox[8'h03] = 8'h7b;
sbox[8'h04] = 8'hf2; sbox[8'h05] = 8'h6b; sbox[8'h06] = 8'h6f; sbox[8'h07] = 8'hc5;
sbox[8'h08] = 8'h30; sbox[8'h09] = 8'h01; sbox[8'h0a] = 8'h67; sbox[8'h0b] = 8'h2b;
sbox[8'h0c] = 8'hfe; sbox[8'h0d] = 8'hd7; sbox[8'h0e] = 8'hab; sbox[8'h0f] = 8'h76;
sbox[8'h10] = 8'hca; sbox[8'h11] = 8'h82; sbox[8'h12] = 8'hc9; sbox[8'h13] = 8'h7d;
sbox[8'h14] = 8'hfa; sbox[8'h15] = 8'h59; sbox[8'h16] = 8'h47; sbox[8'h17] = 8'hf0;
sbox[8'h18] = 8'had; sbox[8'h19] = 8'hd4; sbox[8'h1a] = 8'ha2; sbox[8'h1b] = 8'haf;
sbox[8'h1c] = 8'h9c; sbox[8'h1d] = 8'ha4; sbox[8'h1e] = 8'h72; sbox[8'h1f] = 8'hc0;
sbox[8'h20] = 8'hb7; sbox[8'h21] = 8'hfd; sbox[8'h22] = 8'h93; sbox[8'h23] = 8'h26;
sbox[8'h24] = 8'h36; sbox[8'h25] = 8'h3f; sbox[8'h26] = 8'hf7; sbox[8'h27] = 8'hcc;
sbox[8'h28] = 8'h34; sbox[8'h29] = 8'ha5; sbox[8'h2a] = 8'he5; sbox[8'h2b] = 8'hf1;
sbox[8'h2c] = 8'h71; sbox[8'h2d] = 8'hd8; sbox[8'h2e] = 8'h31; sbox[8'h2f] = 8'h15;
sbox[8'h30] = 8'h04; sbox[8'h31] = 8'hc7; sbox[8'h32] = 8'h23; sbox[8'h33] = 8'hc3;
sbox[8'h34] = 8'h18; sbox[8'h35] = 8'h96; sbox[8'h36] = 8'h05; sbox[8'h37] = 8'h9a;
sbox[8'h38] = 8'h07; sbox[8'h39] = 8'h12; sbox[8'h3a] = 8'h80; sbox[8'h3b] = 8'he2;
sbox[8'h3c] = 8'heb; sbox[8'h3d] = 8'h27; sbox[8'h3e] = 8'hb2; sbox[8'h3f] = 8'h75;
sbox[8'h40] = 8'h09; sbox[8'h41] = 8'h83; sbox[8'h42] = 8'h2c; sbox[8'h43] = 8'h1a;
sbox[8'h44] = 8'h1b; sbox[8'h45] = 8'h6e; sbox[8'h46] = 8'h5a; sbox[8'h47] = 8'ha0;
sbox[8'h48] = 8'h52; sbox[8'h49] = 8'h3b; sbox[8'h4a] = 8'hd6; sbox[8'h4b] = 8'hb3;
sbox[8'h4c] = 8'h29; sbox[8'h4d] = 8'he3; sbox[8'h4e] = 8'h2f; sbox[8'h4f] = 8'h84;
sbox[8'h50] = 8'h53; sbox[8'h51] = 8'hd1; sbox[8'h52] = 8'h00; sbox[8'h53] = 8'hed;
sbox[8'h54] = 8'h20; sbox[8'h55] = 8'hfc; sbox[8'h56] = 8'hb1; sbox[8'h57] = 8'h5b;
sbox[8'h58] = 8'h6a; sbox[8'h59] = 8'hcb; sbox[8'h5a] = 8'hbe; sbox[8'h5b] = 8'h39;
sbox[8'h5c] = 8'h4a; sbox[8'h5d] = 8'h4c; sbox[8'h5e] = 8'h58; sbox[8'h5f] = 8'hcf;
sbox[8'h60] = 8'hd0; sbox[8'h61] = 8'hef; sbox[8'h62] = 8'haa; sbox[8'h63] = 8'hfb;
sbox[8'h64] = 8'h43; sbox[8'h65] = 8'h4d; sbox[8'h66] = 8'h33; sbox[8'h67] = 8'h85;
sbox[8'h68] = 8'h45; sbox[8'h69] = 8'hf9; sbox[8'h6a] = 8'h02; sbox[8'h6b] = 8'h7f;
sbox[8'h6c] = 8'h50; sbox[8'h6d] = 8'h3c; sbox[8'h6e] = 8'h9f; sbox[8'h6f] = 8'ha8;
sbox[8'h70] = 8'h51; sbox[8'h71] = 8'ha3; sbox[8'h72] = 8'h40; sbox[8'h73] = 8'h8f;
sbox[8'h74] = 8'h92; sbox[8'h75] = 8'h9d; sbox[8'h76] = 8'h38; sbox[8'h77] = 8'hf5;
sbox[8'h78] = 8'hbc; sbox[8'h79] = 8'hb6; sbox[8'h7a] = 8'hda; sbox[8'h7b] = 8'h21;
sbox[8'h7c] = 8'h10; sbox[8'h7d] = 8'hff; sbox[8'h7e] = 8'hf3; sbox[8'h7f] = 8'hd2;
sbox[8'h80] = 8'hcd; sbox[8'h81] = 8'h0c; sbox[8'h82] = 8'h13; sbox[8'h83] = 8'hec;
sbox[8'h84] = 8'h5f; sbox[8'h85] = 8'h97; sbox[8'h86] = 8'h44; sbox[8'h87] = 8'h17;
sbox[8'h88] = 8'hc4; sbox[8'h89] = 8'ha7; sbox[8'h8a] = 8'h7e; sbox[8'h8b] = 8'h3d;
sbox[8'h8c] = 8'h64; sbox[8'h8d] = 8'h5d; sbox[8'h8e] = 8'h19; sbox[8'h8f] = 8'h73;
sbox[8'h90] = 8'h60; sbox[8'h91] = 8'h81; sbox[8'h92] = 8'h4f; sbox[8'h93] = 8'hdc;
sbox[8'h94] = 8'h22; sbox[8'h95] = 8'h2a; sbox[8'h96] = 8'h90; sbox[8'h97] = 8'h88;
sbox[8'h98] = 8'h46; sbox[8'h99] = 8'hee; sbox[8'h9a] = 8'hb8; sbox[8'h9b] = 8'h14;
sbox[8'h9c] = 8'hde; sbox[8'h9d] = 8'h5e; sbox[8'h9e] = 8'h0b; sbox[8'h9f] = 8'hdb;
sbox[8'ha0] = 8'he0; sbox[8'ha1] = 8'h32; sbox[8'ha2] = 8'h3a; sbox[8'ha3] = 8'h0a;
sbox[8'ha4] = 8'h49; sbox[8'ha5] = 8'h06; sbox[8'ha6] = 8'h24; sbox[8'ha7] = 8'h5c;
sbox[8'ha8] = 8'hc2; sbox[8'ha9] = 8'hd3; sbox[8'haa] = 8'hac; sbox[8'hab] = 8'h62;
sbox[8'hac] = 8'h91; sbox[8'had] = 8'h95; sbox[8'hae] = 8'he4; sbox[8'haf] = 8'h79;
sbox[8'hb0] = 8'he7; sbox[8'hb1] = 8'hc8; sbox[8'hb2] = 8'h37; sbox[8'hb3] = 8'h6d;
sbox[8'hb4] = 8'h8d; sbox[8'hb5] = 8'hd5; sbox[8'hb6] = 8'h4e; sbox[8'hb7] = 8'ha9;
sbox[8'hb8] = 8'h6c; sbox[8'hb9] = 8'h56; sbox[8'hba] = 8'hf4; sbox[8'hbb] = 8'hea;
sbox[8'hbc] = 8'h65; sbox[8'hbd] = 8'h7a; sbox[8'hbe] = 8'hae; sbox[8'hbf] = 8'h08;
sbox[8'hc0] = 8'hba; sbox[8'hc1] = 8'h78; sbox[8'hc2] = 8'h25; sbox[8'hc3] = 8'h2e;
sbox[8'hc4] = 8'h1c; sbox[8'hc5] = 8'ha6; sbox[8'hc6] = 8'hb4; sbox[8'hc7] = 8'hc6;
sbox[8'hc8] = 8'he8; sbox[8'hc9] = 8'hdd; sbox[8'hca] = 8'h74; sbox[8'hcb] = 8'h1f;
sbox[8'hcc] = 8'h4b; sbox[8'hcd] = 8'hbd; sbox[8'hce] = 8'h8b; sbox[8'hcf] = 8'h8a;
sbox[8'hd0] = 8'h70; sbox[8'hd1] = 8'h3e; sbox[8'hd2] = 8'hb5; sbox[8'hd3] = 8'h66;
sbox[8'hd4] = 8'h48; sbox[8'hd5] = 8'h03; sbox[8'hd6] = 8'hf6; sbox[8'hd7] = 8'h0e;
sbox[8'hd8] = 8'h61; sbox[8'hd9] = 8'h35; sbox[8'hda] = 8'h57; sbox[8'hdb] = 8'hb9;
sbox[8'hdc] = 8'h86; sbox[8'hdd] = 8'hc1; sbox[8'hde] = 8'h1d; sbox[8'hdf] = 8'h9e;
sbox[8'he0] = 8'he1; sbox[8'he1] = 8'hf8; sbox[8'he2] = 8'h98; sbox[8'he3] = 8'h11;
sbox[8'he4] = 8'h69; sbox[8'he5] = 8'hd9; sbox[8'he6] = 8'h8e; sbox[8'he7] = 8'h94;
sbox[8'he8] = 8'h9b; sbox[8'he9] = 8'h1e; sbox[8'hea] = 8'h87; sbox[8'heb] = 8'he9;
sbox[8'hec] = 8'hce; sbox[8'hed] = 8'h55; sbox[8'hee] = 8'h28; sbox[8'hef] = 8'hdf;
sbox[8'hf0] = 8'h8c; sbox[8'hf1] = 8'ha1; sbox[8'hf2] = 8'h89; sbox[8'hf3] = 8'h0d;
sbox[8'hf4] = 8'hbf; sbox[8'hf5] = 8'he6; sbox[8'hf6] = 8'h42; sbox[8'hf7] = 8'h68;
sbox[8'hf8] = 8'h41; sbox[8'hf9] = 8'h99; sbox[8'hfa] = 8'h2d; sbox[8'hfb] = 8'h0f;
sbox[8'hfc] = 8'hb0; sbox[8'hfd] = 8'h54; sbox[8'hfe] = 8'hbb; sbox[8'hff] = 8'h16;
end
assign data = sbox[addr];
endmodule
不用查找表,而是用组合逻辑直接计算 GF(2⁸) 逆元和仿射变换。面积更小但时序可能更差。
// aes_sbox_comb.v - AES S-Box 组合逻辑实现
// 使用仿射变换实现,GF(2^8) 逆元通过查找表简化
module aes_sbox_comb (
input wire [7:0] addr,
output wire [7:0] data
);
// 内部查找逆元,然后施加仿射变换
reg [7:0] inv;
// GF(2^8) 逆元查找表(不可约多项式 0x11B)
always @(*) begin
case(addr)
8'h00: inv = 8'h00; 8'h01: inv = 8'h01; 8'h02: inv = 8'h8d;
8'h03: inv = 8'hf5; 8'h04: inv = 8'hcb; 8'h05: inv = 8'h4f;
8'h06: inv = 8'hbd; 8'h07: inv = 8'h8e; 8'h08: inv = 8'h5f;
8'h09: inv = 8'h3d; 8'h0a: inv = 8'hb7; 8'h0b: inv = 8'h24;
8'h0c: inv = 8'h77; 8'h0d: inv = 8'hd2; 8'h0e: inv = 8'he2;
8'h0f: inv = 8'h5a; 8'h10: inv = 8'h09; 8'h11: inv = 8'h83;
8'h12: inv = 8'hc8; 8'h13: inv = 8'hb2; 8'h14: inv = 8'hb5;
8'h15: inv = 8'hfd; 8'h16: inv = 8'h5c; 8'h17: inv = 8'hb1;
8'h18: inv = 8'hd4; 8'h19: inv = 8'h30; 8'h1a: inv = 8'had;
8'h1b: inv = 8'h57; 8'h1c: inv = 8'h3c; 8'h1d: inv = 8'hb0;
8'h1e: inv = 8'hf6; 8'h1f: inv = 8'hf7; 8'h20: inv = 8'hb6;
8'h21: inv = 8'h22; 8'h22: inv = 8'hdf; 8'h23: inv = 8'hd1;
default: inv = 8'h00;
endcase
end
// 仿射变换: b' = A * inv + c (c = 0x63)
// 矩阵每行的位操作展开
wire [7:0] affine;
assign affine[0] = inv[0]^inv[1]^inv[2]^inv[3]^inv[4]^1'b1;
assign affine[1] = inv[1]^inv[2]^inv[3]^inv[4]^inv[5]^1'b1;
assign affine[2] = inv[2]^inv[3]^inv[4]^inv[5]^inv[6]^1'b0;
assign affine[3] = inv[3]^inv[4]^inv[5]^inv[6]^inv[7]^1'b0;
assign affine[4] = inv[4]^inv[5]^inv[6]^inv[7]^inv[0]^1'b0;
assign affine[5] = inv[5]^inv[6]^inv[7]^inv[0]^inv[1]^1'b1;
assign affine[6] = inv[6]^inv[7]^inv[0]^inv[1]^inv[2]^1'b1;
assign affine[7] = inv[7]^inv[0]^inv[1]^inv[2]^inv[3]^1'b0;
assign data = affine;
endmodule
解密时需要逆 S-Box(InvSubBytes)。它先施加逆仿射变换,再求 GF(2⁸) 逆元。由于逆元运算自逆,逆 S-Box 的构造为:
// aes_inv_sbox.v - AES 逆 S-Box 查找表
module aes_inv_sbox (
input wire [7:0] addr,
output wire [7:0] data
);
reg [7:0] inv_sbox [0:255];
initial begin
inv_sbox[8'h00] = 8'h52; inv_sbox[8'h01] = 8'h09; inv_sbox[8'h02] = 8'h6a; inv_sbox[8'h03] = 8'hd5;
inv_sbox[8'h04] = 8'h30; inv_sbox[8'h05] = 8'h36; inv_sbox[8'h06] = 8'ha5; inv_sbox[8'h07] = 8'h38;
inv_sbox[8'h08] = 8'hbf; inv_sbox[8'h09] = 8'h40; inv_sbox[8'h0a] = 8'ha3; inv_sbox[8'h0b] = 8'h9e;
inv_sbox[8'h0c] = 8'h81; inv_sbox[8'h0d] = 8'hf3; inv_sbox[8'h0e] = 8'hd7; inv_sbox[8'h0f] = 8'hfb;
inv_sbox[8'h10] = 8'h7c; inv_sbox[8'h11] = 8'he3; inv_sbox[8'h12] = 8'h39; inv_sbox[8'h13] = 8'h82;
inv_sbox[8'h14] = 8'h9b; inv_sbox[8'h15] = 8'h2f; inv_sbox[8'h16] = 8'hff; inv_sbox[8'h17] = 8'h87;
inv_sbox[8'h18] = 8'h34; inv_sbox[8'h19] = 8'h8e; inv_sbox[8'h1a] = 8'h43; inv_sbox[8'h1b] = 8'h44;
inv_sbox[8'h1c] = 8'hc4; inv_sbox[8'h1d] = 8'hde; inv_sbox[8'h1e] = 8'he9; inv_sbox[8'h1f] = 8'hcb;
inv_sbox[8'h20] = 8'h54; inv_sbox[8'h21] = 8'h7b; inv_sbox[8'h22] = 8'h94; inv_sbox[8'h23] = 8'h32;
inv_sbox[8'h24] = 8'ha6; inv_sbox[8'h25] = 8'hc2; inv_sbox[8'h26] = 8'h23; inv_sbox[8'h27] = 8'h3d;
inv_sbox[8'h28] = 8'hee; inv_sbox[8'h29] = 8'h4c; inv_sbox[8'h2a] = 8'h95; inv_sbox[8'h2b] = 8'h0b;
inv_sbox[8'h2c] = 8'h42; inv_sbox[8'h2d] = 8'hfa; inv_sbox[8'h2e] = 8'hc3; inv_sbox[8'h2f] = 8'h4e;
inv_sbox[8'h30] = 8'h08; inv_sbox[8'h31] = 8'h2e; inv_sbox[8'h32] = 8'ha1; inv_sbox[8'h33] = 8'h66;
inv_sbox[8'h34] = 8'h28; inv_sbox[8'h35] = 8'hd9; inv_sbox[8'h36] = 8'h24; inv_sbox[8'h37] = 8'hb2;
inv_sbox[8'h38] = 8'h76; inv_sbox[8'h39] = 8'h5b; inv_sbox[8'h3a] = 8'ha2; inv_sbox[8'h3b] = 8'h49;
inv_sbox[8'h3c] = 8'h6d; inv_sbox[8'h3d] = 8'h8b; inv_sbox[8'h3e] = 8'hd1; inv_sbox[8'h3f] = 8'h25;
inv_sbox[8'h40] = 8'h72; inv_sbox[8'h41] = 8'hf8; inv_sbox[8'h42] = 8'hf6; inv_sbox[8'h43] = 8'h64;
inv_sbox[8'h44] = 8'h86; inv_sbox[8'h45] = 8'h68; inv_sbox[8'h46] = 8'h98; inv_sbox[8'h47] = 8'h16;
inv_sbox[8'h48] = 8'hd4; inv_sbox[8'h49] = 8'ha4; inv_sbox[8'h4a] = 8'h5c; inv_sbox[8'h4b] = 8'hcc;
inv_sbox[8'h4c] = 8'h5d; inv_sbox[8'h4d] = 8'h65; inv_sbox[8'h4e] = 8'hb6; inv_sbox[8'h4f] = 8'h92;
inv_sbox[8'h50] = 8'h6c; inv_sbox[8'h51] = 8'h70; inv_sbox[8'h52] = 8'h48; inv_sbox[8'h53] = 8'h50;
inv_sbox[8'h54] = 8'hfd; inv_sbox[8'h55] = 8'hed; inv_sbox[8'h56] = 8'hb9; inv_sbox[8'h57] = 8'hda;
inv_sbox[8'h58] = 8'h5e; inv_sbox[8'h59] = 8'h15; inv_sbox[8'h5a] = 8'h46; inv_sbox[8'h5b] = 8'h57;
inv_sbox[8'h5c] = 8'ha7; inv_sbox[8'h5d] = 8'h8d; inv_sbox[8'h5e] = 8'h9d; inv_sbox[8'h5f] = 8'h84;
inv_sbox[8'h60] = 8'h90; inv_sbox[8'h61] = 8'hd8; inv_sbox[8'h62] = 8'hab; inv_sbox[8'h63] = 8'h00;
inv_sbox[8'h64] = 8'h8c; inv_sbox[8'h65] = 8'hbc; inv_sbox[8'h66] = 8'hd3; inv_sbox[8'h67] = 8'h0a;
inv_sbox[8'h68] = 8'hf7; inv_sbox[8'h69] = 8'he4; inv_sbox[8'h6a] = 8'h58; inv_sbox[8'h6b] = 8'h05;
inv_sbox[8'h6c] = 8'hb8; inv_sbox[8'h6d] = 8'hb3; inv_sbox[8'h6e] = 8'h45; inv_sbox[8'h6f] = 8'h06;
inv_sbox[8'h70] = 8'hd0; inv_sbox[8'h71] = 8'h2c; inv_sbox[8'h72] = 8'h1e; inv_sbox[8'h73] = 8'h8f;
inv_sbox[8'h74] = 8'hca; inv_sbox[8'h75] = 8'h3f; inv_sbox[8'h76] = 8'h0f; inv_sbox[8'h77] = 8'h02;
inv_sbox[8'h78] = 8'hc1; inv_sbox[8'h79] = 8'haf; inv_sbox[8'h7a] = 8'hbd; inv_sbox[8'h7b] = 8'h03;
inv_sbox[8'h7c] = 8'h01; inv_sbox[8'h7d] = 8'h13; inv_sbox[8'h7e] = 8'h8a; inv_sbox[8'h7f] = 8'h6b;
inv_sbox[8'h80] = 8'h3a; inv_sbox[8'h81] = 8'h91; inv_sbox[8'h82] = 8'h11; inv_sbox[8'h83] = 8'h41;
inv_sbox[8'h84] = 8'h4f; inv_sbox[8'h85] = 8'h67; inv_sbox[8'h86] = 8'hdc; inv_sbox[8'h87] = 8'hea;
inv_sbox[8'h88] = 8'h97; inv_sbox[8'h89] = 8'hf2; inv_sbox[8'h8a] = 8'hcf; inv_sbox[8'h8b] = 8'hce;
inv_sbox[8'h8c] = 8'hf0; inv_sbox[8'h8d] = 8'hb4; inv_sbox[8'h8e] = 8'he6; inv_sbox[8'h8f] = 8'h73;
inv_sbox[8'h90] = 8'h96; inv_sbox[8'h91] = 8'hac; inv_sbox[8'h92] = 8'h74; inv_sbox[8'h93] = 8'h22;
inv_sbox[8'h94] = 8'he7; inv_sbox[8'h95] = 8'had; inv_sbox[8'h96] = 8'h35; inv_sbox[8'h97] = 8'h85;
inv_sbox[8'h98] = 8'he2; inv_sbox[8'h99] = 8'hf9; inv_sbox[8'h9a] = 8'h37; inv_sbox[8'h9b] = 8'he8;
inv_sbox[8'h9c] = 8'h1c; inv_sbox[8'h9d] = 8'h75; inv_sbox[8'h9e] = 8'hdf; inv_sbox[8'h9f] = 8'h6e;
inv_sbox[8'ha0] = 8'h47; inv_sbox[8'ha1] = 8'hf1; inv_sbox[8'ha2] = 8'h1a; inv_sbox[8'ha3] = 8'h71;
inv_sbox[8'ha4] = 8'h1d; inv_sbox[8'ha5] = 8'h29; inv_sbox[8'ha6] = 8'hc5; inv_sbox[8'ha7] = 8'h89;
inv_sbox[8'ha8] = 8'h6f; inv_sbox[8'ha9] = 8'hb7; inv_sbox[8'haa] = 8'h62; inv_sbox[8'hab] = 8'h0e;
inv_sbox[8'hac] = 8'haa; inv_sbox[8'had] = 8'h18; inv_sbox[8'hae] = 8'hbe; inv_sbox[8'haf] = 8'h1b;
inv_sbox[8'hb0] = 8'hfc; inv_sbox[8'hb1] = 8'h56; inv_sbox[8'hb2] = 8'h3e; inv_sbox[8'hb3] = 8'h4b;
inv_sbox[8'hb4] = 8'hc6; inv_sbox[8'hb5] = 8'hd2; inv_sbox[8'hb6] = 8'h79; inv_sbox[8'hb7] = 8'h20;
inv_sbox[8'hb8] = 8'h9a; inv_sbox[8'hb9] = 8'hdb; inv_sbox[8'hba] = 8'hc0; inv_sbox[8'hbb] = 8'hfe;
inv_sbox[8'hbc] = 8'h78; inv_sbox[8'hbd] = 8'hcd; inv_sbox[8'hbe] = 8'h5a; inv_sbox[8'hbf] = 8'hf4;
inv_sbox[8'hc0] = 8'h1f; inv_sbox[8'hc1] = 8'hdd; inv_sbox[8'hc2] = 8'ha8; inv_sbox[8'hc3] = 8'h33;
inv_sbox[8'hc4] = 8'h88; inv_sbox[8'hc5] = 8'h07; inv_sbox[8'hc6] = 8'hc7; inv_sbox[8'hc7] = 8'h31;
inv_sbox[8'hc8] = 8'hb1; inv_sbox[8'hc9] = 8'h12; inv_sbox[8'hca] = 8'h10; inv_sbox[8'hcb] = 8'h59;
inv_sbox[8'hcc] = 8'h27; inv_sbox[8'hcd] = 8'h80; inv_sbox[8'hce] = 8'hec; inv_sbox[8'hcf] = 8'h5f;
inv_sbox[8'hd0] = 8'h60; inv_sbox[8'hd1] = 8'h51; inv_sbox[8'hd2] = 8'h7f; inv_sbox[8'hd3] = 8'ha9;
inv_sbox[8'hd4] = 8'h19; inv_sbox[8'hd5] = 8'hb5; inv_sbox[8'hd6] = 8'h4a; inv_sbox[8'hd7] = 8'h0d;
inv_sbox[8'hd8] = 8'h2d; inv_sbox[8'hd9] = 8'he5; inv_sbox[8'hda] = 8'h7a; inv_sbox[8'hdb] = 8'h9f;
inv_sbox[8'hdc] = 8'h93; inv_sbox[8'hdd] = 8'hc9; inv_sbox[8'hde] = 8'h9c; inv_sbox[8'hdf] = 8'hef;
inv_sbox[8'he0] = 8'ha0; inv_sbox[8'he1] = 8'he0; inv_sbox[8'he2] = 8'h3b; inv_sbox[8'he3] = 8'h4d;
inv_sbox[8'he4] = 8'hae; inv_sbox[8'he5] = 8'h2a; inv_sbox[8'he6] = 8'hf5; inv_sbox[8'he7] = 8'hb0;
inv_sbox[8'he8] = 8'hc8; inv_sbox[8'he9] = 8'heb; inv_sbox[8'hea] = 8'hbb; inv_sbox[8'heb] = 8'h3c;
inv_sbox[8'hec] = 8'h83; inv_sbox[8'hed] = 8'h53; inv_sbox[8'hee] = 8'h99; inv_sbox[8'hef] = 8'h61;
inv_sbox[8'hf0] = 8'h17; inv_sbox[8'hf1] = 8'h2b; inv_sbox[8'hf2] = 8'h04; inv_sbox[8'hf3] = 8'h7e;
inv_sbox[8'hf4] = 8'hba; inv_sbox[8'hf5] = 8'h77; inv_sbox[8'hf6] = 8'hd6; inv_sbox[8'hf7] = 8'h26;
inv_sbox[8'hf8] = 8'he1; inv_sbox[8'hf9] = 8'h69; inv_sbox[8'hfa] = 8'h14; inv_sbox[8'hfb] = 8'h63;
inv_sbox[8'hfc] = 8'h55; inv_sbox[8'hfd] = 8'h21; inv_sbox[8'hfe] = 8'h0c; inv_sbox[8'hff] = 8'h7d;
end
assign data = inv_sbox[addr];
endmodule
AES S-Box 具有优秀的密码学性质:
| 性质 | 值 | 含义 |
|---|---|---|
| 非线性度 | 112 | 距最近仿射函数的 Hamming 距离,越大越好 |
| 差分均匀度 | 4 | 最大差分传播概率的倒数,越小越好 |
| 代数次数 | 7 | 代数正规形的最高次数,越高越难代数攻击 |
| 固定点 | 0 | 满足 S(a)=a 的 a 个数,为 0 最安全 |
// aes_sbox_tb.v - S-Box 测试台
module aes_sbox_tb;
reg [7:0] addr;
wire [7:0] fwd_data;
wire [7:0] inv_data;
aes_sbox_lut u_fwd (.addr(addr), .data(fwd_data));
aes_inv_sbox u_inv (.addr(addr), .data(inv_data));
integer i;
integer err_count;
initial begin
err_count = 0;
$display("=== AES S-Box Verification ===");
// 测试关键值
addr = 8'h00; #10;
$display("S(0x00) = 0x%02h (expect 0x63)", fwd_data);
if (fwd_data !== 8'h63) err_count = err_count + 1;
addr = 8'h01; #10;
$display("S(0x01) = 0x%02h (expect 0x7c)", fwd_data);
if (fwd_data !== 8'h7c) err_count = err_count + 1;
addr = 8'h53; #10;
$display("S(0x53) = 0x%02h (expect 0xed)", fwd_data);
if (fwd_data !== 8'hed) err_count = err_count + 1;
addr = 8'hff; #10;
$display("S(0xff) = 0x%02h (expect 0x16)", fwd_data);
if (fwd_data !== 8'h16) err_count = err_count + 1;
// 验证 S(S^-1(x)) = x
$display("\n=== Inv-SBox round-trip test ===");
for (i = 0; i < 256; i = i + 1) begin
addr = i[7:0]; #10;
// fwd_data = S(i), 验证 S^-1(S(i)) = i
addr = fwd_data; #10;
if (inv_data !== i[7:0]) begin
$display("ERROR: S^-1(S(0x%02h)) = 0x%02h", i[7:0], inv_data);
err_count = err_count + 1;
end
end
if (err_count == 0)
$display("All 256 round-trip tests PASSED!");
else
$display("FAILED: %0d errors found", err_count);
$finish;
end
endmodule
1. 验证 S(0x00) = 0x63,手动推导:0 的逆元仍为 0,施加仿射变换得 0x63。
2. 计算 S(0x01):1 的逆元为 1,仿射变换 A·1 + 0x63 = ?
3. 实现一个 S-Box 流水线模块:输入地址在时钟上升沿锁存,输出延迟一个周期。比较 LUT 方案和组合逻辑方案的时序差异。
4. 分析:如果 S-Box 的某个条目被错误地改为 S(0x00)=0x64(仅最低位翻转),对 AES 加密的影响是什么?
你已掌握 AES S-Box 的数学构造(GF(2⁸) 逆元 + 仿射变换)和硬件实现方法(LUT 法和组合逻辑法),并理解了 S-Box 的密码学性质。S-Box 是所有分组密码的核心混淆组件!
获得徽章:🧩 NONLINEAR_CORE