原理部分可以参考:AES加密算法原理的详细介绍与实现_TimeShatter的博客-CSDN博客废话不多说直接上代码:
2024.5.8:在评论区更新了最新的代码,和官方文档加解密结果一致
主要模块:aes_main模块
module aes_main (
input wire [127:0] plaintext, // 输入明文
input wire [128*11-1:0] round_keys , // 输入密钥
input [5:0]state,
input clk,
input rst,
output wire [127:0] ciphertext,// 输出密文
output wire [127:0] plaintext_1// 输出恢复明文
);
integer k;
reg [127:0] round_key [0:10];
always @(*)begin
for(k=0;k<=10;k=k+1)begin
round_key[k]=round_keys[128*k +:128];
end
end
reg[127:0]mid_value;
reg[127:0]mid_value_1;
wire [127:0]data[0:9];
wire [127:0]data_1[0:9];
assign data[0] = mid_value;
assign data_1[0]=mid_value_1;
// 初始轮
always @(posedge clk or negedge rst) begin
if (!rst) begin
mid_value<=128'b0;
end
else begin
case (state)
12: mid_value<=plaintext^round_key[0];// 初始轮
endcase
end
end
// 轮函数
genvar i;
generate
for (i = 1; i < 10; i = i + 1) begin : round
aes_round round (
.state(data[i-1]),
.round_key(round_key[i]),
.next_state(data[i]),
.clk(clk),
.rst(rst)
);
end
endgenerate
// 最后一轮
final_round final (
.state(data[9]),
.round_key(round_key[10]),
.ciphertext(ciphertext)
);
// 初始轮
always @(posedge clk or negedge rst) begin
if (!rst) begin
mid_value_1<=128'b0;
end
else begin
case (state)
22: mid_value_1<=ciphertext^round_key[10];// 初始轮
endcase
end
end
//逆轮变换
genvar j;
generate
for (j = 1; j < 10; j = j + 1) begin : round_1
inv_aes_round inv_round (
.state(data_1[j-1]),
.round_key(round_key[10-j]),
.next_state(data_1[j]),
.clk(clk),
.rst(rst)
);
end
endgenerate
// 最后一轮
inv_final_round inv_final (
.state(data_1[9]),
.round_key(round_key[0]),
.ciphertext(plaintext_1)
);
endmodule
-
模块定义:
- 模块名为
aes_main
。 - 输入信号包括明文
plaintext
,密钥round_keys
,状态state
,时钟信号clk
,复位信号rst
。 - 输出信号包括密文
ciphertext
和恢复的明文plaintext_1
。
- 模块名为
-
整数
k
和reg
数组round_key
用于存储轮密钥。 -
always
块用于将round_keys
分解成各轮的密钥存储在round_key
数组中。 -
mid_value
和mid_value_1
是用于存储中间数据的寄存器。 -
data
和data_1
数组用于存储每轮的数据。 -
初始轮(Initialization Round):
- 使用
always
块,根据state
的值来执行初始轮操作。在状态为12
时,执行plaintext
和第一轮密钥的异或操作,并将结果存储在mid_value
中。
- 使用
-
轮函数(Round Function):
- 使用
generate
区块创建轮函数。它包括一个循环,从第二轮到第九轮。每轮都使用名为aes_round
的子模块进行处理,传递前一轮的状态数据、当前轮的密钥、时钟信号和复位信号。
- 使用
-
最后一轮(Final Round):
- 使用名为
final_round
的子模块,将第十轮的状态数据和密钥传递给它,生成最终的密文ciphertext
。
- 使用名为
-
逆初始轮和逆轮变换:
- 类似于初始轮,使用
always
块执行逆初始轮操作。在状态为22
时,执行密文和第十轮密钥的异或操作,并将结果存储在mid_value_1
中。 - 使用
generate
区块创建逆轮变换。它包括一个循环,从第二轮到第九轮,与加密轮函数相反。每轮都使用名为inv_aes_round
的子模块进行处理。
- 类似于初始轮,使用
-
逆最后一轮:
- 使用名为
inv_final_round
的子模块,将第一轮密钥和逆变换后的状态数据传递给它,生成恢复的明文plaintext_1
。
- 使用名为
这个模块实际上是一个高级的AES加密和解密模块,通过组合不同的轮函数来实现加密和解密过程。它依赖于子模块(aes_round
、final_round
、inv_aes_round
、inv_final_round
)来执行每个轮的操作,而这些子模块的实现需要在代码中提供。此外,模块还需要外部提供的密钥和状态信息来控制加密和解密过程。
2.aes_round是轮运行模块
module aes_round (
input clk,
input rst,
input wire [127:0] state, // 输入状态
input wire [127:0] round_key, // 输入轮密钥
output reg [127:0] next_state // 输出下一轮状态
);
// 定义中间信号
wire [127:0] sub_bytes_out;
wire [127:0] shift_rows_out;
wire [127:0] mix_columns_out;
wire [127:0] add_round_key_out;
// 16个S盒子实例化
genvar j;
generate
for (j = 0; j < 16; j = j + 1) begin
s_box s_box_inst (
.in_byte(state[8*j +: 8]),
.out_byte(sub_bytes_out[8*j +: 8])
);
end
endgenerate
// 行移位子模块实例化
shift_rows shift_rows_inst (
.in_state(sub_bytes_out),
.out_state(shift_rows_out)
);
// 列混淆子模块实例化
genvar i;
generate
for (i = 0; i < 4; i = i + 1) begin
mix_col mix_col_inst (
.s0(shift_rows_out[32*i +:8]),
.s1(shift_rows_out[32*i+8 +:8]),
.s2(shift_rows_out[32*i+16 +:8]),
.s3(shift_rows_out[32*i+24 +:8]),
.mix_col_0(mix_columns_out[32*i +:8]),
.mix_col_1(mix_columns_out[32*i+8 +:8]),
.mix_col_2(mix_columns_out[32*i+16 +:8]),
.mix_col_3(mix_columns_out[32*i+24 +:8])
);
end
endgenerate
// 轮密钥加
assign add_round_key_out = mix_columns_out ^ round_key;
// 输出下一轮状态
always @(posedge clk or negedge rst) begin
if (!rst) begin
next_state<=128'b0;
end
else begin
next_state <= add_round_key_out;
end
end
endmodule
3.下面是顶层模块
module aes_top (
input wire clk, // 时钟输入
input wire rst // 复位输入
);
localparam key=128'h0123456789ABCDEF0123456789ABCDEF;
localparam plaintext=128'h5E6C6C152BBC01B8961A2DED00822B0E;
wire [5:0] state;
wire [128*11-1:0]round_keys;
wire [127:0]ciphertext;
fsm fsm_inst(
.clk(clk),
.rst(rst),
.state(state)
);
key_exp key_exp_inst(
.clk(clk),
.state(state),
.rst(rst),
.key(key),
.round_key(round_keys)
);
aes_main aes_main_inst(
.clk(clk),
.rst(rst),
.state(state),
.round_keys(round_keys),
.plaintext(plaintext),
.ciphertext(ciphertext)
);
endmodule
4.最后一轮
module final_round (
input wire [127:0] state, // 输入状态
input wire [127:0] round_key, // 输入轮密钥
output wire [127:0] ciphertext // 输出下一轮状态
);
// 定义中间信号
wire [127:0] sub_bytes_out;
wire [127:0] shift_rows_out;
// 16个S盒子实例化
genvar i;
generate
for (i = 0; i < 16; i = i + 1) begin
s_box s_box_inst (
.in_byte(state[8*i +: 8]),
.out_byte(sub_bytes_out[8*i +: 8])
);
end
endgenerate
// 行移位子模块实例化
shift_rows shift_rows_inst (
.in_state(sub_bytes_out),
.out_state(shift_rows_out)
);
// 轮密钥加
assign ciphertext = shift_rows_out ^ round_key;
endmodule
5.写了个状态机表示state状态
module fsm(
input clk,
input rst,
output reg [5:0]state
);
always @(posedge clk or negedge rst) begin
if (!rst) begin
state<=6'b0;
end
else begin
state<=state+1'b1;
end
end
endmodule
6.解密的轮模块
module inv_aes_round (
input clk,
input rst,
input wire [127:0] state, // 输入状态
input wire [127:0] round_key, // 输入轮密钥
output reg [127:0] next_state // 输出下一轮状态
);
// 定义中间信号
wire [127:0] sub_bytes_out;
wire [127:0] shift_rows_out;
wire [127:0] mix_columns_out;
wire [127:0] add_round_key_out;
// 16个S盒子实例化
genvar j;
generate
for (j = 0; j < 16; j = j + 1) begin
inv_s_box inv_s_box_inst (
.in_byte(shift_rows_out[8*j +: 8]),
.out_byte(sub_bytes_out[8*j +: 8])
);
end
endgenerate
// 行移位子模块实例化
inv_shift_rows inv_shift_rows_inst (
.in_state(state),
.out_state(shift_rows_out)
);
// 列混淆子模块实例化
genvar i;
generate
for (i = 0; i < 4; i = i + 1) begin
inv_mix_col inv_mix_col_inst (
.s0(add_round_key_out[32*i +:8]),
.s1(add_round_key_out[32*i+8 +:8]),
.s2(add_round_key_out[32*i+16 +:8]),
.s3(add_round_key_out[32*i+24 +:8]),
.inv_mix_col_0(mix_columns_out[32*i +:8]),
.inv_mix_col_1(mix_columns_out[32*i+8 +:8]),
.inv_mix_col_2(mix_columns_out[32*i+16 +:8]),
.inv_mix_col_3(mix_columns_out[32*i+24 +:8])
);
end
endgenerate
// 轮密钥加
assign add_round_key_out = sub_bytes_out ^ round_key;
// 输出下一轮状态
always @(posedge clk or negedge rst) begin
if (!rst) begin
next_state<=128'b0;
end
else begin
next_state <= mix_columns_out;
end
end
endmodule
7.解密的最终轮模块
module inv_final_round (
input wire [127:0] state, // 输入状态
input wire [127:0] round_key, // 输入轮密钥
output wire [127:0] ciphertext // 输出下一轮状态
);
// 定义中间信号
wire [127:0] sub_bytes_out;
wire [127:0] shift_rows_out;
// 16个S盒子实例化
genvar i;
generate
for (i = 0; i < 16; i = i + 1) begin
inv_s_box inv_s_box_inst (
.in_byte(shift_rows_out[8*i +: 8]),
.out_byte(sub_bytes_out[8*i +: 8])
);
end
endgenerate
// 行移位子模块实例化
inv_shift_rows inv_shift_rows_inst (
.in_state(state),
.out_state(shift_rows_out)
);
// 轮密钥加
assign ciphertext = sub_bytes_out ^ round_key;
endmodule
8.逆列混合模块
module inv_mix_col(
input [7:0] s0, s1, s2, s3,
output reg [7:0] inv_mix_col_0,
output reg [7:0] inv_mix_col_1,
output reg [7:0] inv_mix_col_2,
output reg [7:0] inv_mix_col_3
);
//logic: decryption mixcolumns
always @(s0,s1,s2,s3)begin
inv_mix_col_0=pmul_e(s0)^pmul_b(s1)^pmul_d(s2)^pmul_9(s3);
inv_mix_col_1=pmul_9(s0)^pmul_e(s1)^pmul_b(s2)^pmul_d(s3);
inv_mix_col_2=pmul_d(s0)^pmul_9(s1)^pmul_e(s2)^pmul_b(s3);
inv_mix_col_3=pmul_b(s0)^pmul_d(s1)^pmul_9(s2)^pmul_e(s3);
end
//function
function [7:0] pmul_e;
input [7:0] b;
reg [7:0] two,four,eight;
begin
two=gf8_2(b);
four=gf8_2(two);
eight=gf8_2(four);
pmul_e=eight^four^two;
end
endfunction
function [7:0] pmul_9;
input [7:0] b;
reg [7:0] two,four,eight;
begin
two=gf8_2(b);
four=gf8_2(two);
eight=gf8_2(four);
pmul_9=eight^b;
end
endfunction
function [7:0] pmul_d;
input [7:0] b;
reg [7:0] two,four,eight;
begin
two=gf8_2(b);
four=gf8_2(two);
eight=gf8_2(four);
pmul_d=eight^four^b;
end
endfunction
function [7:0] pmul_b;
input [7:0] b;
reg [7:0] two,four,eight;
begin
two=gf8_2(b);
four=gf8_2(two);
eight=gf8_2(four);
pmul_b=eight^two^b;
end
endfunction
function [7:0] gf8_2;
input [7:0] b;
gf8_2={b[6:0],1'b0}^(8'h1b&{8{b[7]}});
endfunction
endmodule
9.逆s盒模块
module inv_s_box(
input [7:0] in_byte,
output reg [7:0] out_byte
);
/*
// 16x16 Inverse S-box lookup table
reg [7:0] inv_s_box [0:255] = {
8'h52, 8'h09, 8'h6a, 8'hd5, 8'h30, 8'h36, 8'ha5, 8'h38, 8'hbf, 8'h40, 8'ha3, 8'h9e, 8'h81, 8'hf3, 8'hd7, 8'hfb,
8'h7c, 8'hE3, 8'h39, 8'h82, 8'h9b, 8'h2f, 8'hff, 8'h87, 8'h34, 8'h8e, 8'h43, 8'h44, 8'hc4, 8'hde, 8'hE9, 8'hcb,
8'h54, 8'h7b, 8'h94, 8'h32, 8'hA6, 8'hC2, 8'h23, 8'h3d, 8'hEE, 8'h4C, 8'h95, 8'h0B, 8'h42, 8'hFA, 8'hC3, 8'h4E,
8'h08, 8'h2E, 8'hA1, 8'h66, 8'h28, 8'hD9, 8'h24, 8'hB2, 8'h76, 8'h5B, 8'hA2, 8'h49, 8'h6D, 8'h8B, 8'hD1, 8'h25,
8'h72, 8'hF8, 8'hF6, 8'h64, 8'h86, 8'h68, 8'h98, 8'h16, 8'hD4, 8'hA4, 8'h5C, 8'hCC, 8'h5D, 8'h65, 8'hB6, 8'h92,
8'h6C, 8'h70, 8'h48, 8'h50, 8'hFD, 8'hED, 8'hB9, 8'hDA, 8'h5E, 8'h15, 8'h46, 8'h57, 8'hA7, 8'h8D, 8'h9D, 8'h84,
8'h90, 8'hD8, 8'hAB, 8'h00, 8'h8C, 8'hBC, 8'hD3, 8'h0A, 8'hF7, 8'hE4, 8'h58, 8'h05, 8'hB8, 8'hB3, 8'h45, 8'h06,
8'hD0, 8'h2C, 8'h1E, 8'h8F, 8'hCA, 8'h3F, 8'h0F, 8'h02, 8'hC1, 8'hAF, 8'hBD, 8'h03, 8'h01, 8'h13, 8'h8A, 8'h6B,
8'h3A, 8'h91, 8'h11, 8'h41, 8'h4F, 8'h67, 8'hDC, 8'hEA, 8'h97, 8'hF2, 8'hCF, 8'hCE, 8'hF0, 8'hB4, 8'hE6, 8'h73,
8'h96, 8'hAC, 8'h74, 8'h22, 8'hE7, 8'hAD, 8'h35, 8'h85, 8'hE2, 8'hF9, 8'h37, 8'hE8, 8'h1C, 8'h75, 8'hDF, 8'h6E,
8'h47, 8'hF1, 8'h1A, 8'h71, 8'h1D, 8'h29, 8'hC5, 8'h89, 8'h6F, 8'hB7, 8'h62, 8'h0E, 8'hAA, 8'h18, 8'hBE, 8'h1B,
8'hFC, 8'h56, 8'h3E, 8'h4B, 8'hC6, 8'hD2, 8'h79, 8'h20, 8'h9A, 8'hDB, 8'hC0, 8'hFE, 8'h78, 8'hCD, 8'h5A, 8'hF4,
8'h1F, 8'hDD, 8'hA8, 8'h33, 8'h88, 8'h07, 8'hC7, 8'h31, 8'hB1, 8'h12, 8'h10, 8'h59, 8'h27, 8'h80, 8'hEC, 8'h5F,
8'h60, 8'h51, 8'h7F, 8'hA9, 8'h19, 8'hB5, 8'h4A, 8'h0D, 8'h2D, 8'hE5, 8'h7A, 8'h9F, 8'h93, 8'hC9, 8'h9C, 8'hEF,
8'hA0, 8'hE0, 8'h3B, 8'h4D, 8'hAE, 8'h2A, 8'hF5, 8'hB0, 8'hC8, 8'hEB, 8'hBB, 8'h3C, 8'h83, 8'h53, 8'h99, 8'h61,
8'h17, 8'h2B, 8'h04, 8'h7E, 8'hBA, 8'h77, 8'hD6, 8'h26, 8'hE1, 8'h69, 8'h14, 8'h63, 8'h55, 8'h21, 8'h0C, 8'h7D
};*/
always @(in_byte) begin
case (in_byte)
8'h00: out_byte = 8'h52;
8'h01: out_byte = 8'h09;
8'h02: out_byte = 8'h6A;
8'h03: out_byte = 8'hD5;
8'h04: out_byte = 8'h30;
8'h05: out_byte = 8'h36;
8'h06: out_byte = 8'hA5;
8'h07: out_byte = 8'h38;
8'h08: out_byte = 8'hBF;
8'h09: out_byte = 8'h40;
8'h0A: out_byte = 8'hA3;
8'h0B: out_byte = 8'h9E;
8'h0C: out_byte = 8'h81;
8'h0D: out_byte = 8'hF3;
8'h0E: out_byte = 8'hD7;
8'h0F: out_byte = 8'hFB;
8'h10: out_byte = 8'h7C;
8'h11: out_byte = 8'hE3;
8'h12: out_byte = 8'h39;
8'h13: out_byte = 8'h82;
8'h14: out_byte = 8'h9B;
8'h15: out_byte = 8'h2F;
8'h16: out_byte = 8'hFF;
8'h17: out_byte = 8'h87;
8'h18: out_byte = 8'h34;
8'h19: out_byte = 8'h8E;
8'h1A: out_byte = 8'h43;
8'h1B: out_byte = 8'h44;
8'h1C: out_byte = 8'hC4;
8'h1D: out_byte = 8'hDE;
8'h1E: out_byte = 8'hE9;
8'h1F: out_byte = 8'hCB;
8'h20: out_byte = 8'h54;
8'h21: out_byte = 8'h7B;
8'h22: out_byte = 8'h94;
8'h23: out_byte = 8'h32;
8'h24: out_byte = 8'hA6;
8'h25: out_byte = 8'hC2;
8'h26: out_byte = 8'h23;
8'h27: out_byte = 8'h3D;
8'h28: out_byte = 8'hEE;
8'h29: out_byte = 8'h4C;
8'h2A: out_byte = 8'h95;
8'h2B: out_byte = 8'h0B;
8'h2C: out_byte = 8'h42;
8'h2D: out_byte = 8'hFA;
8'h2E: out_byte = 8'hC3;
8'h2F: out_byte = 8'h4E;
8'h30: out_byte = 8'h08;
8'h31: out_byte = 8'h2E;
8'h32: out_byte = 8'hA1;
8'h33: out_byte = 8'h66;
8'h34: out_byte = 8'h28;
8'h35: out_byte = 8'hD9;
8'h36: out_byte = 8'h24;
8'h37: out_byte = 8'hB2;
8'h38: out_byte = 8'h76;
8'h39: out_byte = 8'h5B;
8'h3A: out_byte = 8'hA2;
8'h3B: out_byte = 8'h49;
8'h3C: out_byte = 8'h6D;
8'h3D: out_byte = 8'h8B;
8'h3E: out_byte = 8'hD1;
8'h3F: out_byte = 8'h25;
8'h40: out_byte = 8'h72;
8'h41: out_byte = 8'hF8;
8'h42: out_byte = 8'hF6;
8'h43: out_byte = 8'h64;
8'h44: out_byte = 8'h86;
8'h45: out_byte = 8'h68;
8'h46: out_byte = 8'h98;
8'h47: out_byte = 8'h16;
8'h48: out_byte = 8'hD4;
8'h49: out_byte = 8'hA4;
8'h4A: out_byte = 8'h5C;
8'h4B: out_byte = 8'hCC;
8'h4C: out_byte = 8'h5D;
8'h4D: out_byte = 8'h65;
8'h4E: out_byte = 8'hB6;
8'h4F: out_byte = 8'h92;
8'h50: out_byte = 8'h6C;
8'h51: out_byte = 8'h70;
8'h52: out_byte = 8'h48;
8'h53: out_byte = 8'h50;
8'h54: out_byte = 8'hFD;
8'h55: out_byte = 8'hED;
8'h56: out_byte = 8'hB9;
8'h57: out_byte = 8'hDA;
8'h58: out_byte = 8'h5E;
8'h59: out_byte = 8'h15;
8'h5A: out_byte = 8'h46;
8'h5B: out_byte = 8'h57;
8'h5C: out_byte = 8'hA7;
8'h5D: out_byte = 8'h8D;
8'h5E: out_byte = 8'h9D;
8'h5F: out_byte = 8'h84;
8'h60: out_byte = 8'h90;
8'h61: out_byte = 8'hD8;
8'h62: out_byte = 8'hAB;
8'h63: out_byte = 8'h00;
8'h64: out_byte = 8'h8C;
8'h65: out_byte = 8'hBC;
8'h66: out_byte = 8'hD3;
8'h67: out_byte = 8'h0A;
8'h68: out_byte = 8'hF7;
8'h69: out_byte = 8'hE4;
8'h6A: out_byte = 8'h58;
8'h6B: out_byte = 8'h05;
8'h6C: out_byte = 8'hB8;
8'h6D: out_byte = 8'hB3;
8'h6E: out_byte = 8'h45;
8'h6F: out_byte = 8'h06;
8'h70: out_byte = 8'hD0;
8'h71: out_byte = 8'h2C;
8'h72: out_byte = 8'h1E;
8'h73: out_byte = 8'h8F;
8'h74: out_byte = 8'hCA;
8'h75: out_byte = 8'h3F;
8'h76: out_byte = 8'h0F;
8'h77: out_byte = 8'h02;
8'h78: out_byte = 8'hC1;
8'h79: out_byte = 8'hAF;
8'h7A: out_byte = 8'hBD;
8'h7B: out_byte = 8'h03;
8'h7C: out_byte = 8'h01;
8'h7D: out_byte = 8'h13;
8'h7E: out_byte = 8'h8A;
8'h7F: out_byte = 8'h6B;
8'h80: out_byte = 8'h3A;
8'h81: out_byte = 8'h91;
8'h82: out_byte = 8'h11;
8'h83: out_byte = 8'h41;
8'h84: out_byte = 8'h4F;
8'h85: out_byte = 8'h67;
8'h86: out_byte = 8'hDC;
8'h87: out_byte = 8'hEA;
8'h88: out_byte = 8'h97;
8'h89: out_byte = 8'hF2;
8'h8A: out_byte = 8'hCF;
8'h8B: out_byte = 8'hCE;
8'h8C: out_byte = 8'hF0;
8'h8D: out_byte = 8'hB4;
8'h8E: out_byte = 8'hE6;
8'h8F: out_byte = 8'h73;
8'h90: out_byte = 8'h96;
8'h91: out_byte = 8'hAC;
8'h92: out_byte = 8'h74;
8'h93: out_byte = 8'h22;
8'h94: out_byte = 8'hE7;
8'h95: out_byte = 8'hAD;
8'h96: out_byte = 8'h35;
8'h97: out_byte = 8'h85;
8'h98: out_byte = 8'hE2;
8'h99: out_byte = 8'hF9;
8'h9A: out_byte = 8'h37;
8'h9B: out_byte = 8'hE8;
8'h9C: out_byte = 8'h1C;
8'h9D: out_byte = 8'h75;
8'h9E: out_byte = 8'hDF;
8'h9F: out_byte = 8'h6E;
8'hA0: out_byte = 8'h47;
8'hA1: out_byte = 8'hF1;
8'hA2: out_byte = 8'h1A;
8'hA3: out_byte = 8'h71;
8'hA4: out_byte = 8'h1D;
8'hA5: out_byte = 8'h29;
8'hA6: out_byte = 8'hC5;
8'hA7: out_byte = 8'h89;
8'hA8: out_byte = 8'h6F;
8'hA9: out_byte = 8'hB7;
8'hAA: out_byte = 8'h62;
8'hAB: out_byte = 8'h0E;
8'hAC: out_byte = 8'hAA;
8'hAD: out_byte = 8'h18;
8'hAE: out_byte = 8'hBE;
8'hAF: out_byte = 8'h1B;
8'hB0: out_byte = 8'hFC;
8'hB1: out_byte = 8'h56;
8'hB2: out_byte = 8'h3E;
8'hB3: out_byte = 8'h4B;
8'hB4: out_byte = 8'hC6;
8'hB5: out_byte = 8'hD2;
8'hB6: out_byte = 8'h79;
8'hB7: out_byte = 8'h20;
8'hB8: out_byte = 8'h9A;
8'hB9: out_byte = 8'hDB;
8'hBA: out_byte = 8'hC0;
8'hBB: out_byte = 8'hFE;
8'hBC: out_byte = 8'h78;
8'hBD: out_byte = 8'hCD;
8'hBE: out_byte = 8'h5A;
8'hBF: out_byte = 8'hF4;
8'hC0: out_byte = 8'h1F;
8'hC1: out_byte = 8'hDD;
8'hC2: out_byte = 8'hA8;
8'hC3: out_byte = 8'h33;
8'hC4: out_byte = 8'h88;
8'hC5: out_byte = 8'h07;
8'hC6: out_byte = 8'hC7;
8'hC7: out_byte = 8'h31;
8'hC8: out_byte = 8'hB1;
8'hC9: out_byte = 8'h12;
8'hCA: out_byte = 8'h10;
8'hCB: out_byte = 8'h59;
8'hCC: out_byte = 8'h27;
8'hCD: out_byte = 8'h80;
8'hCE: out_byte = 8'hEC;
8'hCF: out_byte = 8'h5F;
8'hD0: out_byte = 8'h60;
8'hD1: out_byte = 8'h51;
8'hD2: out_byte = 8'h7F;
8'hD3: out_byte = 8'hA9;
8'hD4: out_byte = 8'h19;
8'hD5: out_byte = 8'hB5;
8'hD6: out_byte = 8'h4A;
8'hD7: out_byte = 8'h0D;
8'hD8: out_byte = 8'h2D;
8'hD9: out_byte = 8'hE5;
8'hDA: out_byte = 8'h7A;
8'hDB: out_byte = 8'h9F;
8'hDC: out_byte = 8'h93;
8'hDD: out_byte = 8'hC9;
8'hDE: out_byte = 8'h9C;
8'hDF: out_byte = 8'hEF;
8'hE0: out_byte = 8'hA0;
8'hE1: out_byte = 8'hE0;
8'hE2: out_byte = 8'h3B;
8'hE3: out_byte = 8'h4D;
8'hE4: out_byte = 8'hAE;
8'hE5: out_byte = 8'h2A;
8'hE6: out_byte = 8'hF5;
8'hE7: out_byte = 8'hB0;
8'hE8: out_byte = 8'hC8;
8'hE9: out_byte = 8'hEB;
8'hEA: out_byte = 8'hBB;
8'hEB: out_byte = 8'h3C;
8'hEC: out_byte = 8'h83;
8'hED: out_byte = 8'h53;
8'hEE: out_byte = 8'h99;
8'hEF: out_byte = 8'h61;
8'hF0: out_byte = 8'h17;
8'hF1: out_byte = 8'h2B;
8'hF2: out_byte = 8'h04;
8'hF3: out_byte = 8'h7E;
8'hF4: out_byte = 8'hBA;
8'hF5: out_byte = 8'h77;
8'hF6: out_byte = 8'hD6;
8'hF7: out_byte = 8'h26;
8'hF8: out_byte = 8'hE1;
8'hF9: out_byte = 8'h69;
8'hFA: out_byte = 8'h14;
8'hFB: out_byte = 8'h63;
8'hFC: out_byte = 8'h55;
8'hFD: out_byte = 8'h21;
8'hFE: out_byte = 8'h0C;
8'hFF: out_byte = 8'h7D;
default: out_byte = 8'h00;
endcase
end
endmodule
10.逆行移位模块
module inv_shift_rows(
input [127:0] in_state, // 输入状态矩阵,每行32位,总共4行
output reg [127:0] out_state // 输出状态矩阵
);
// 定义每一列的信号,从上而下,从左到右
reg [31:0] col0, col1, col2, col3;
// 从输入状态中提取每一列的每个字节
always @(*) begin
col0 = in_state[31:0];
col1 = in_state[63:32];
col2 = in_state[95:64];
col3 = in_state[127:96];
end
// 行移位操作
always @(*) begin
out_state[7:0] = col0[7:0];
out_state[15:8] = col3[15:8];
out_state[23:16] = col2[23:16];
out_state[31:24] = col1[31:24];
out_state[39:32] = col1[7:0];
out_state[47:40] = col0[15:8];
out_state[55:48] = col3[23:16];
out_state[63:56] = col2[31:24];
out_state[71:64] = col2[7:0];
out_state[79:72] = col1[15:8];
out_state[87:80] = col0[23:16];
out_state[95:88] = col3[31:24];
out_state[103:96] = col3[7:0];
out_state[111:104] = col2[15:8];
out_state[119:112] = col1[23:16];
out_state[127:120] = col0[31:24];
end
endmodule
11.密钥拓展模块
module key_exp(
input clk,
input rst,
input [5:0]state,
input [127:0] key, // 输入的128位主密钥
output [128*11-1:0] round_key // 输出的轮密钥数组,共11个轮密钥
);
// 定义局部参数
localparam rcon0 = 32'h01000000;
localparam rcon1 = 32'h02000000;
localparam rcon2 = 32'h04000000;
localparam rcon3 = 32'h08000000;
localparam rcon4 = 32'h10000000;
localparam rcon5 = 32'h20000000;
localparam rcon6 = 32'h40000000;
localparam rcon7 = 32'h80000000;
localparam rcon8 = 32'h1b000000;
localparam rcon9 = 32'h36000000;
wire [31:0]subword;
wire [31:0]tmp_w;
reg [127:0] round_keys [0:10];// 输出的轮密钥数组,共11个轮密钥
reg [31:0] w[0:3]; // 用于临时存储中间结果的寄存器数组
// 初始化轮密钥数组的前4个轮密钥为主密钥的前4个字
always @(posedge clk or negedge rst)begin
if (!rst) begin
w[0]=32'b0;
end
else begin
case (state)
0: w[0] <= key[127:96]; // 根据 state 选择不同的 rcon 值
1: w[0] <= w[0] ^ subword ^ rcon0;
2: w[0] <= w[0] ^ subword ^ rcon1;
3: w[0] <= w[0] ^ subword ^ rcon2;
4: w[0] <= w[0] ^ subword ^ rcon3;
5: w[0] <= w[0] ^ subword ^ rcon4;
6: w[0] <= w[0] ^ subword ^ rcon5;
7: w[0] <= w[0] ^ subword ^ rcon6;
8: w[0] <= w[0] ^ subword ^ rcon7;
9: w[0] <= w[0] ^ subword ^ rcon8;
10: w[0] <= w[0] ^ subword ^ rcon9;
default: w[0] <= 32'b0; // 默认情况下设置为 0
endcase
end
end
always @(posedge clk or negedge rst)begin
if (!rst) begin
w[1]=32'b0;
end
else begin
case (state)
0: w[1] <= key[95:64]; // 根据 state 选择不同的 rcon 值
1: w[1] <= w[0]^w[1]^subword^rcon0;
2: w[1] <= w[0]^w[1]^subword^rcon1;
3: w[1] <= w[0]^w[1]^subword^rcon2;
4: w[1] <= w[0]^w[1]^subword^rcon3;
5: w[1] <= w[0]^w[1]^subword^rcon4;
6: w[1] <= w[0]^w[1]^subword^rcon5;
7: w[1] <= w[0]^w[1]^subword^rcon6;
8: w[1] <= w[0]^w[1]^subword^rcon7;
9: w[1] <= w[0]^w[1]^subword^rcon8;
10: w[1] <= w[0]^w[1]^subword^rcon9;
default: w[1] <= 32'b0; // 默认情况下设置为 0
endcase
end
end
always @(posedge clk or negedge rst)begin
if (!rst) begin
w[2]=32'b0;
end
else begin
case (state)
0: w[2] <= key[63:32]; // 根据 state 选择不同的 rcon 值
1: w[2] <= w[2]^w[0]^w[1]^subword^rcon0;
2: w[2] <= w[2]^w[0]^w[1]^subword^rcon1;
3: w[2] <= w[2]^w[0]^w[1]^subword^rcon2;
4: w[2] <= w[2]^w[0]^w[1]^subword^rcon3;
5: w[2] <= w[2]^w[0]^w[1]^subword^rcon4;
6: w[2] <= w[2]^w[0]^w[1]^subword^rcon5;
7: w[2] <= w[2]^w[0]^w[1]^subword^rcon6;
8: w[2] <= w[2]^w[0]^w[1]^subword^rcon7;
9: w[2] <= w[2]^w[0]^w[1]^subword^rcon8;
10: w[2] <= w[2]^w[0]^w[1]^subword^rcon9;
default: w[2] <= 32'b0; // 默认情况下设置为 0
endcase
end
end
always @(posedge clk or negedge rst)begin
if (!rst) begin
w[3]=32'b0;
end
else begin
case (state)
0: w[3] <= key[31:0]; // 根据 state 选择不同的 rcon 值
1: w[3] <= w[3]^w[2]^w[0]^w[1]^subword^rcon0;
2: w[3] <= w[3]^w[2]^w[0]^w[1]^subword^rcon1;
3: w[3] <= w[3]^w[2]^w[0]^w[1]^subword^rcon2;
4: w[3] <= w[3]^w[2]^w[0]^w[1]^subword^rcon3;
5: w[3] <= w[3]^w[2]^w[0]^w[1]^subword^rcon4;
6: w[3] <= w[3]^w[2]^w[0]^w[1]^subword^rcon5;
7: w[3] <= w[3]^w[2]^w[0]^w[1]^subword^rcon6;
8: w[3] <= w[3]^w[2]^w[0]^w[1]^subword^rcon7;
9: w[3] <= w[3]^w[2]^w[0]^w[1]^subword^rcon8;
10: w[3] <= w[3]^w[2]^w[0]^w[1]^subword^rcon9;
default: w[3] <= 32'b0; // 默认情况下设置为 0
endcase
end
end
assign tmp_w = w[3];
s_box u0(.in_byte(tmp_w[23:16]), .out_byte(subword[31:24]));
s_box u1(.in_byte(tmp_w[15:08]), .out_byte(subword[23:16]));
s_box u2(.in_byte(tmp_w[07:00]), .out_byte(subword[15:08]));
s_box u3(.in_byte(tmp_w[31:24]), .out_byte(subword[07:00]));
always @(posedge clk or negedge rst) begin
if (!rst) begin
round_keys[0]=128'b0;
round_keys[1]=128'b0;
round_keys[2]=128'b0;
round_keys[3]=128'b0;
round_keys[4]=128'b0;
round_keys[5]=128'b0;
round_keys[6]=128'b0;
round_keys[7]=128'b0;
round_keys[8]=128'b0;
round_keys[9]=128'b0;
round_keys[10]=128'b0;
end
else begin
case (state)
1: round_keys[0] <= {w[0],w[1],w[2],w[3]};
2: round_keys[1] <= {w[0],w[1],w[2],w[3]};
3: round_keys[2] <= {w[0],w[1],w[2],w[3]};
4: round_keys[3] <= {w[0],w[1],w[2],w[3]};
5: round_keys[4] <= {w[0],w[1],w[2],w[3]};
6: round_keys[5] <= {w[0],w[1],w[2],w[3]};
7: round_keys[6] <= {w[0],w[1],w[2],w[3]};
8: round_keys[7] <= {w[0],w[1],w[2],w[3]};
9: round_keys[8] <= {w[0],w[1],w[2],w[3]};
10: round_keys[9] <= {w[0],w[1],w[2],w[3]};
11: round_keys[10] <= {w[0],w[1],w[2],w[3]};
endcase
end
end
assign round_key={round_keys[10],round_keys[9],round_keys[8],round_keys[7],round_keys[6],round_keys[5],round_keys[4],round_keys[3],round_keys[2],round_keys[1],round_keys[0]};
endmodule
12.列混合模块
module mix_col(
input [7:0] s0, s1, s2, s3,
output reg [7:0] mix_col_0,
output reg [7:0] mix_col_1,
output reg [7:0] mix_col_2,
output reg [7:0] mix_col_3
);
//logic: decryption mixcolumns
always @(s0,s1,s2,s3)begin
mix_col_0=pmul_2(s0)^pmul_3(s1)^pmul_1(s2)^pmul_1(s3);
mix_col_1=pmul_1(s0)^pmul_2(s1)^pmul_3(s2)^pmul_1(s3);
mix_col_2=pmul_1(s0)^pmul_1(s1)^pmul_2(s2)^pmul_3(s3);
mix_col_3=pmul_3(s0)^pmul_1(s1)^pmul_1(s2)^pmul_2(s3);
end
//function
function [7:0] pmul_1;
input [7:0] b;
begin
pmul_1=b;
end
endfunction
function [7:0] pmul_3;
input [7:0] b;
reg [7:0] two;
begin
two=pmul_2(b);
pmul_3=two^b;
end
endfunction
function [7:0] pmul_2;
input [7:0] b;
pmul_2={b[6:0],1'b0}^(8'h1b&{8{b[7]}});
endfunction
endmodule
13.s盒子模块
module s_box(
input [7:0] in_byte,
output reg [7:0] out_byte
);
// 256x8 S-box lookup table
/*reg [7:0] s_box [0:255] = {
8'h63, 8'h7c, 8'h77, 8'h7b, 8'hf2, 8'h6b, 8'h6f, 8'hc5,
8'h30, 8'h01, 8'h67, 8'h2b, 8'hfe, 8'hd7, 8'hab, 8'h76,
8'hca, 8'h82, 8'hc9, 8'h7d, 8'hfa, 8'h59, 8'h47, 8'hf0,
8'had, 8'hd4, 8'ha2, 8'haf, 8'h9c, 8'ha4, 8'h72, 8'hc0,
8'hb7, 8'hfd, 8'h93, 8'h26, 8'h36, 8'h3f, 8'hf7, 8'hcc,
8'h34, 8'ha5, 8'he5, 8'hf1, 8'h71, 8'hd8, 8'h31, 8'h15,
8'h04, 8'hc7, 8'h23, 8'hc3, 8'h18, 8'h96, 8'h05, 8'h9a,
8'h07, 8'h12, 8'h80, 8'he2, 8'heb, 8'h27, 8'hb2, 8'h75,
8'h09, 8'h83, 8'h2c, 8'h1a, 8'h1b, 8'h6e, 8'h5a, 8'ha0,
8'h52, 8'h3b, 8'hd6, 8'hb3, 8'h29, 8'he3, 8'h2f, 8'h84,
8'h53, 8'hd1, 8'h00, 8'hed, 8'h20, 8'hfc, 8'hb1, 8'h5b,
8'h6a, 8'hcb, 8'hbe, 8'h39, 8'h4a, 8'h4c, 8'h58, 8'hcf,
8'hd0, 8'hef, 8'haa, 8'hfb, 8'h43, 8'h4d, 8'h33, 8'h85,
8'h45, 8'hf9, 8'h02, 8'h7f, 8'h50, 8'h3c, 8'h9f, 8'ha8,
8'h51, 8'ha3, 8'h40, 8'h8f, 8'h92, 8'h9d, 8'h38, 8'hf5,
8'hbc, 8'hb6, 8'hda, 8'h21, 8'h10, 8'hff, 8'hf3, 8'hd2,
8'hcd, 8'h0c, 8'h13, 8'hec, 8'h5f, 8'h97, 8'h44, 8'h17,
8'hc4, 8'ha7, 8'h7e, 8'h3d, 8'h64, 8'h5d, 8'h19, 8'h73,
8'h60, 8'h81, 8'h4f, 8'hdc, 8'h22, 8'h2a, 8'h90, 8'h88,
8'h46, 8'hee, 8'hb8, 8'h14, 8'hde, 8'h5e, 8'h0b, 8'hdb,
8'he0, 8'h32, 8'h3a, 8'h0a, 8'h49, 8'h06, 8'h24, 8'h5c,
8'hc2, 8'hd3, 8'hac, 8'h62, 8'h91, 8'h95, 8'he4, 8'h79,
8'he7, 8'hc8, 8'h37, 8'h6d, 8'h8d, 8'hd5, 8'h4e, 8'ha9,
8'h6c, 8'h56, 8'hf4, 8'hea, 8'h65, 8'h7a, 8'hae, 8'h08,
8'hba, 8'h78, 8'h25, 8'h2e, 8'h1c, 8'ha6, 8'hb4, 8'hc6,
8'he8, 8'hdd, 8'h74, 8'h1f, 8'h4b, 8'hbd, 8'h8b, 8'h8a,
8'h70, 8'h3e, 8'hb5, 8'h66, 8'h48, 8'h03, 8'hf6, 8'h0e,
8'h61, 8'h35, 8'h57, 8'hb9, 8'h86, 8'hc1, 8'h1d, 8'h9e,
8'he1, 8'hf8, 8'h98, 8'h11, 8'h69, 8'hd9, 8'h8e, 8'h94,
8'h9b, 8'h1e, 8'h87, 8'he9, 8'hce, 8'h55, 8'h28, 8'hdf,
8'h8c, 8'ha1, 8'h89, 8'h0d, 8'hbf, 8'he6, 8'h42, 8'h68,
8'h41, 8'h99, 8'h2d, 8'h0f, 8'hb0, 8'h54, 8'hbb, 8'h16
};*/
always @(in_byte) begin
case (in_byte)
8'h00: out_byte = 8'h63;
8'h01: out_byte = 8'h7C;
8'h02: out_byte = 8'h77;
8'h03: out_byte = 8'h7B;
8'h04: out_byte = 8'hF2;
8'h05: out_byte = 8'h6B;
8'h06: out_byte = 8'h6F;
8'h07: out_byte = 8'hC5;
8'h08: out_byte = 8'h30;
8'h09: out_byte = 8'h01;
8'h0A: out_byte = 8'h67;
8'h0B: out_byte = 8'h2B;
8'h0C: out_byte = 8'hFE;
8'h0D: out_byte = 8'hD7;
8'h0E: out_byte = 8'hAB;
8'h0F: out_byte = 8'h76;
8'h10: out_byte = 8'hCA;
8'h11: out_byte = 8'h82;
8'h12: out_byte = 8'hC9;
8'h13: out_byte = 8'h7D;
8'h14: out_byte = 8'hFA;
8'h15: out_byte = 8'h59;
8'h16: out_byte = 8'h47;
8'h17: out_byte = 8'hF0;
8'h18: out_byte = 8'hAD;
8'h19: out_byte = 8'hD4;
8'h1A: out_byte = 8'hA2;
8'h1B: out_byte = 8'hAF;
8'h1C: out_byte = 8'h9C;
8'h1D: out_byte = 8'hA4;
8'h1E: out_byte = 8'h72;
8'h1F: out_byte = 8'hC0;
8'h20: out_byte = 8'hB7;
8'h21: out_byte = 8'hFD;
8'h22: out_byte = 8'h93;
8'h23: out_byte = 8'h26;
8'h24: out_byte = 8'h36;
8'h25: out_byte = 8'h3F;
8'h26: out_byte = 8'hF7;
8'h27: out_byte = 8'hCC;
8'h28: out_byte = 8'h34;
8'h29: out_byte = 8'hA5;
8'h2A: out_byte = 8'hE5;
8'h2B: out_byte = 8'hF1;
8'h2C: out_byte = 8'h71;
8'h2D: out_byte = 8'hD8;
8'h2E: out_byte = 8'h31;
8'h2F: out_byte = 8'h15;
8'h30: out_byte = 8'h04;
8'h31: out_byte = 8'hC7;
8'h32: out_byte = 8'h23;
8'h33: out_byte = 8'hC3;
8'h34: out_byte = 8'h18;
8'h35: out_byte = 8'h96;
8'h36: out_byte = 8'h05;
8'h37: out_byte = 8'h9A;
8'h38: out_byte = 8'h07;
8'h39: out_byte = 8'h12;
8'h3A: out_byte = 8'h80;
8'h3B: out_byte = 8'hE2;
8'h3C: out_byte = 8'hEB;
8'h3D: out_byte = 8'h27;
8'h3E: out_byte = 8'hB2;
8'h3F: out_byte = 8'h75;
8'h40: out_byte = 8'h09;
8'h41: out_byte = 8'h83;
8'h42: out_byte = 8'h2C;
8'h43: out_byte = 8'h1A;
8'h44: out_byte = 8'h1B;
8'h45: out_byte = 8'h6E;
8'h46: out_byte = 8'h5A;
8'h47: out_byte = 8'hA0;
8'h48: out_byte = 8'h52;
8'h49: out_byte = 8'h3B;
8'h4A: out_byte = 8'hD6;
8'h4B: out_byte = 8'hB3;
8'h4C: out_byte = 8'h29;
8'h4D: out_byte = 8'hE3;
8'h4E: out_byte = 8'h2F;
8'h4F: out_byte = 8'h84;
8'h50: out_byte = 8'h53;
8'h51: out_byte = 8'hD1;
8'h52: out_byte = 8'h00;
8'h53: out_byte = 8'hED;
8'h54: out_byte = 8'h20;
8'h55: out_byte = 8'hFC;
8'h56: out_byte = 8'hB1;
8'h57: out_byte = 8'h5B;
8'h58: out_byte = 8'h6A;
8'h59: out_byte = 8'hCB;
8'h5A: out_byte = 8'hBE;
8'h5B: out_byte = 8'h39;
8'h5C: out_byte = 8'h4A;
8'h5D: out_byte = 8'h4C;
8'h5E: out_byte = 8'h58;
8'h5F: out_byte = 8'hCF;
8'h60: out_byte = 8'hD0;
8'h61: out_byte = 8'hEF;
8'h62: out_byte = 8'hAA;
8'h63: out_byte = 8'hFB;
8'h64: out_byte = 8'h43;
8'h65: out_byte = 8'h4D;
8'h66: out_byte = 8'h33;
8'h67: out_byte = 8'h85;
8'h68: out_byte = 8'h45;
8'h69: out_byte = 8'hF9;
8'h6A: out_byte = 8'h02;
8'h6B: out_byte = 8'h7F;
8'h6C: out_byte = 8'h50;
8'h6D: out_byte = 8'h3C;
8'h6E: out_byte = 8'h9F;
8'h6F: out_byte = 8'hA8;
8'h70: out_byte = 8'h51;
8'h71: out_byte = 8'hA3;
8'h72: out_byte = 8'h40;
8'h73: out_byte = 8'h8F;
8'h74: out_byte = 8'h92;
8'h75: out_byte = 8'h9D;
8'h76: out_byte = 8'h38;
8'h77: out_byte = 8'hF5;
8'h78: out_byte = 8'hBC;
8'h79: out_byte = 8'hB6;
8'h7A: out_byte = 8'hDA;
8'h7B: out_byte = 8'h21;
8'h7C: out_byte = 8'h10;
8'h7D: out_byte = 8'hFF;
8'h7E: out_byte = 8'hF3;
8'h7F: out_byte = 8'hD2;
8'h80: out_byte = 8'hCD;
8'h81: out_byte = 8'h0C;
8'h82: out_byte = 8'h13;
8'h83: out_byte = 8'hEC;
8'h84: out_byte = 8'h5F;
8'h85: out_byte = 8'h97;
8'h86: out_byte = 8'h44;
8'h87: out_byte = 8'h17;
8'h88: out_byte = 8'hC4;
8'h89: out_byte = 8'hA7;
8'h8A: out_byte = 8'h7E;
8'h8B: out_byte = 8'h3D;
8'h8C: out_byte = 8'h64;
8'h8D: out_byte = 8'h5D;
8'h8E: out_byte = 8'h19;
8'h8F: out_byte = 8'h73;
8'h90: out_byte = 8'h60;
8'h91: out_byte = 8'h81;
8'h92: out_byte = 8'h4F;
8'h93: out_byte = 8'hDC;
8'h94: out_byte = 8'h22;
8'h95: out_byte = 8'h2A;
8'h96: out_byte = 8'h90;
8'h97: out_byte = 8'h88;
8'h98: out_byte = 8'h46;
8'h99: out_byte = 8'hEE;
8'h9A: out_byte = 8'hB8;
8'h9B: out_byte = 8'h14;
8'h9C: out_byte = 8'hDE;
8'h9D: out_byte = 8'h5E;
8'h9E: out_byte = 8'h0B;
8'h9F: out_byte = 8'hDB;
8'hA0: out_byte = 8'hE0;
8'hA1: out_byte = 8'h32;
8'hA2: out_byte = 8'h3A;
8'hA3: out_byte = 8'h0A;
8'hA4: out_byte = 8'h49;
8'hA5: out_byte = 8'h06;
8'hA6: out_byte = 8'h24;
8'hA7: out_byte = 8'h5C;
8'hA8: out_byte = 8'hC2;
8'hA9: out_byte = 8'hD3;
8'hAA: out_byte = 8'hAC;
8'hAB: out_byte = 8'h62;
8'hAC: out_byte = 8'h91;
8'hAD: out_byte = 8'h95;
8'hAE: out_byte = 8'hE4;
8'hAF: out_byte = 8'h79;
8'hB0: out_byte = 8'hE7;
8'hB1: out_byte = 8'hC8;
8'hB2: out_byte = 8'h37;
8'hB3: out_byte = 8'h6D;
8'hB4: out_byte = 8'h8D;
8'hB5: out_byte = 8'hD5;
8'hB6: out_byte = 8'h4E;
8'hB7: out_byte = 8'hA9;
8'hB8: out_byte = 8'h6C;
8'hB9: out_byte = 8'h56;
8'hBA: out_byte = 8'hF4;
8'hBB: out_byte = 8'hEA;
8'hBC: out_byte = 8'h65;
8'hBD: out_byte = 8'h7A;
8'hBE: out_byte = 8'hAE;
8'hBF: out_byte = 8'h08;
8'hC0: out_byte = 8'hBA;
8'hC1: out_byte = 8'h78;
8'hC2: out_byte = 8'h25;
8'hC3: out_byte = 8'h2E;
8'hC4: out_byte = 8'h1C;
8'hC5: out_byte = 8'hA6;
8'hC6: out_byte = 8'hB4;
8'hC7: out_byte = 8'hC6;
8'hC8: out_byte = 8'hE8;
8'hC9: out_byte = 8'hDD;
8'hCA: out_byte = 8'h74;
8'hCB: out_byte = 8'h1F;
8'hCC: out_byte = 8'h4B;
8'hCD: out_byte = 8'hBD;
8'hCE: out_byte = 8'h8B;
8'hCF: out_byte = 8'h8A;
8'hD0: out_byte = 8'h70;
8'hD1: out_byte = 8'h3E;
8'hD2: out_byte = 8'hB5;
8'hD3: out_byte = 8'h66;
8'hD4: out_byte = 8'h48;
8'hD5: out_byte = 8'h03;
8'hD6: out_byte = 8'hF6;
8'hD7: out_byte = 8'h0E;
8'hD8: out_byte = 8'h61;
8'hD9: out_byte = 8'h35;
8'hDA: out_byte = 8'h57;
8'hDB: out_byte = 8'hB9;
8'hDC: out_byte = 8'h86;
8'hDD: out_byte = 8'hC1;
8'hDE: out_byte = 8'h1D;
8'hDF: out_byte = 8'h9E;
8'hE0: out_byte = 8'hE1;
8'hE1: out_byte = 8'hF8;
8'hE2: out_byte = 8'h98;
8'hE3: out_byte = 8'h11;
8'hE4: out_byte = 8'h69;
8'hE5: out_byte = 8'hD9;
8'hE6: out_byte = 8'h8E;
8'hE7: out_byte = 8'h94;
8'hE8: out_byte = 8'h9B;
8'hE9: out_byte = 8'h1E;
8'hEA: out_byte = 8'h87;
8'hEB: out_byte = 8'hE9;
8'hEC: out_byte = 8'hCE;
8'hED: out_byte = 8'h55;
8'hEE: out_byte = 8'h28;
8'hEF: out_byte = 8'hDF;
8'hF0: out_byte = 8'h8C;
8'hF1: out_byte = 8'hA1;
8'hF2: out_byte = 8'h89;
8'hF3: out_byte = 8'h0D;
8'hF4: out_byte = 8'hBF;
8'hF5: out_byte = 8'hE6;
8'hF6: out_byte = 8'h42;
8'hF7: out_byte = 8'h68;
8'hF8: out_byte = 8'h41;
8'hF9: out_byte = 8'h99;
8'hFA: out_byte = 8'h2D;
8'hFB: out_byte = 8'h0F;
8'hFC: out_byte = 8'hB0;
8'hFD: out_byte = 8'h54;
8'hFE: out_byte = 8'hBB;
8'hFF: out_byte = 8'h16;
default: out_byte = 8'h00;
endcase
end
endmodule
14.行移位模块
module shift_rows(
input [127:0] in_state, // 输入状态矩阵,每行32位,总共4行
output reg [127:0] out_state // 输出状态矩阵
);
// 定义每一列的信号,从上而下,从左到右
reg [31:0] col0, col1, col2, col3;
// 从输入状态中提取每一列的每个字节
always @(*) begin
col0 = in_state[31:0];
col1 = in_state[63:32];
col2 = in_state[95:64];
col3 = in_state[127:96];
end
// 行移位操作
always @(*) begin
out_state[7:0] = col0[7:0];
out_state[15:8] = col1[15:8];
out_state[23:16] = col2[23:16];
out_state[31:24] = col3[31:24];
out_state[39:32] = col1[7:0];
out_state[47:40] = col2[15:8];
out_state[55:48] = col3[23:16];
out_state[63:56] = col0[31:24];
out_state[71:64] = col2[7:0];
out_state[79:72] = col3[15:8];
out_state[87:80] = col0[23:16];
out_state[95:88] = col1[31:24];
out_state[103:96] = col3[7:0];
out_state[111:104] = col0[15:8];
out_state[119:112] = col1[23:16];
out_state[127:120] = col2[31:24];
end
endmodule
15.testbench
module testbench;
reg clk; // 时钟信号
reg rst; // 复位信号
// 被测试的模块实例化
aes_top aes_top_inst (
.clk(clk),
.rst(rst)
);
// 时钟生成
always begin
#5 clk = ~clk; // 周期为 10 个时间单位
end
// 模块输入数据生成
initial begin
clk = 0;
rst = 1;
// 等待一些时间来确保模块初始化完成
#20;
// 使能复位
rst = 0;
// 在时钟上升沿之前等待一些时间
#20;
// 停止复位
rst = 1;
end
endmodule