AES_128加密解密算法,verilog实现。完整代码

具体的理论知识,本人不在详述。网上已经有很多了

AES128加密算法完整实现_u013605322的博客-CSDN博客_aes128加密算法

AES加密 - block2016 - 博客园

AES算法简介_Jimmy.li的博客-CSDN博客_aes算法

密码算法详解——AES - ReadingLover - 博客园

以上内容都对aes_128加密有很详细的说明。

下面直接进入正题,代码实现!

一、top层模  

       详细说明已在模块内部标注

/*
    说明:
1.aes_top模块作用是完成整个加密或者解密轮循环的计数,及对应的数据流向。
2.由于加解密10轮循环不是完全一样的,所有需设计状态机4种状态,初始状态,开始状态,中间9轮
 轮循环计数状态及最后一轮状态。
3.密钥扩展可以在循环之前把十轮密钥全部计算存入寄存器组,也可以在每轮循环中做一次密钥扩展,
 由于节省资源,本人是在每次轮循环时,再计算密钥扩展。


*/
module  aes_top(
	input       		 clk, 
    input                rst_n,
    input                start_i, //加解密开始信号
    input                decrypt, //加密 / 解密
	input       [127:0]	 data_in, // 密文输入
    input       [127:0]  key_in, // 密钥输入
	output reg  [127:0]  data_o, // 明文
    output reg           ready_o  //完成标志信号
);
//状态参数
    localparam  IDLE   =4'b0001,
                FIRST  =4'b0010,
                MIDDLE =4'b0100, 
                FINALLY=4'b1000;
    reg  [3:0]  state;
    reg  [3:0]  state_next;
    wire        idle_first     ;
    wire        first_middle   ;
    wire        middle_finally ;
    wire        finally_idle   ;

//计数器
    reg  [3:0]      cnt;
    wire            add_cnt;
    wire            end_cnt;
    reg             decrypt_i;  //加解密寄存器
    wire            midround_done; 
    reg             first_round;  
    reg             finally_end; 



//密钥寄存器组 
    reg [127:0]     key_orginal ;
    reg    [3:0]    rcon        ;
    reg             key_en      ;
    wire            key_done    ;
    wire   [127:0]  key_rdata   ;

 //列混合 变量
    reg             mixcolum_en       ;
    wire  [127:0]   mixcolum_data     ;
    wire   [127:0]  mixcolum_dout     ;
    wire            mixcolum_ready    ;
//行移位 变量  
    reg             invshiftrow_en    ;
    reg   [127:0]   invshiftrow_data  ;
    wire   [127:0]  invshiftrow_dout  ;
    wire            invshiftrow_ready ;	
//字节代换 变量 
    wire            sbox_ready        ;
    wire  [127:0]   sbox_dout         ;
    reg             sbox_en           ;
    wire  [127:0]   sbox_data         ;
//轮密钥加 变量
    reg     addround_flag2;
    reg     addround_flag1;
    reg     addround_en1 ;
    wire            addround_en       ;
    reg   [127:0]   addround_data     ;
    wire  [127:0]   addround_key      ;
    wire  [127:0]   addround_dout     ;
    wire            addround_ready    ;

//******************************************************************/

    //decrypt  打拍 ,也可不用打拍
    always @(posedge clk or negedge rst_n)  begin
        if(!rst_n)  begin
        decrypt_i <= 0;
        end
        else   begin
        decrypt_i <= decrypt;
        end
    end
    

    //中间9轮计数
    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
        cnt <= 0;
      end
      else if(add_cnt) begin
        if(end_cnt) begin
           cnt <= 0; 
        end
        else begin
          cnt <= cnt + 1'b1 ;
        end
      end
    end

    assign add_cnt = (state==MIDDLE) && midround_done ;
    assign end_cnt = add_cnt && (cnt==9-1); 
    assign midround_done = (decrypt_i ? mixcolum_ready : addround_ready);

    always@(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
        state <= IDLE;
      end
      else begin
        state <= state_next;
      end
    end
    always @(*) begin
        case (state)
         IDLE  :begin
             if(idle_first) begin
                state_next = FIRST;
             end
             else begin
                state_next = IDLE;
             end
         end 
        FIRST   :begin
             if(first_middle) begin
                state_next = MIDDLE;
             end
             else begin
                state_next = FIRST;
             end
         end
        MIDDLE  :begin
             if(middle_finally) begin
                state_next = FINALLY;
             end
             else begin
                state_next = MIDDLE;
             end
         end
        FINALLY :begin
             if(finally_idle) begin
                state_next = IDLE;
             end
             else begin
                state_next = FINALLY;
             end
         end     
        default:state_next = IDLE;
        endcase
    end
    assign idle_first     = state==IDLE    && (start_i      ) ;   //IDLE初始状态  
    assign first_middle   = state==FIRST   && (first_round  ) ;  //第一次轮密钥加  
    assign middle_finally = state==MIDDLE  && (end_cnt      ) ;  //中间循环9次
    assign finally_idle   = state==FINALLY && (finally_end  ) ;   //最后一次循环


    always@(posedge clk  or negedge rst_n) begin
        if(!rst_n) begin
            first_round <= 0;
        end
        else if(state==FIRST) begin
            first_round <= addround_ready ;
        end
        else begin
           first_round <= 0; 
        end
    end
    always@(posedge clk  or negedge rst_n) begin
        if(!rst_n) begin
            finally_end <= 0;
        end
        else if(state==FINALLY) begin
            finally_end <=  addround_ready ;
        end
        else begin
            finally_end <= 0;
        end
    end


//密钥扩展
    key_memory u_key_memory(
        //exterior
        .clk            (clk         ),
        .rst_n          (rst_n       ),
        .start_i        (key_en      ),
        .key_in         (key_orginal ),
        .rcon           (rcon        ), //轮常量
        .key_rcon       (key_rdata   ),  
        .allkey_done    (key_done    )
    );
    
    //key_orginal  
    always@(posedge clk  or negedge rst_n) begin
        if(!rst_n) begin
            key_orginal <= 0;
        end
        else if(start_i) begin
            key_orginal <= key_in ;
        end
    end
    //rcon 轮常量计数
    always@(posedge clk  or negedge rst_n) begin
        if(!rst_n) begin
            rcon <= 0;
        end
        else if( ~decrypt_i ) begin
            if(state==FIRST || state==IDLE) begin
                rcon <= 0;
            end
            else if(state==MIDDLE) begin   //正向加密不需要等所有密钥扩展完,即可加密;
                case(cnt)             //逆向解密 必须要等所有密钥扩展完,才能加密  
                    0: rcon <= 1;
                    1: rcon <= 2;    
                    2: rcon <= 3;
                    3: rcon <= 4;
                    4: rcon <= 5;
                    5: rcon <= 6;
                    6: rcon <= 7;
                    7: rcon <= 8;
                    8: rcon <= 9; 
                default:;
                endcase
            end
            else if(state==FINALLY) begin
                rcon <= 10;
            end
        end
        else if(decrypt_i) begin
            if(state==FIRST || state==IDLE) begin
                rcon <= 10;
            end
            else if(state==MIDDLE) begin
                case(cnt)
                    0: rcon <= 9;
                    1: rcon <= 8;
                    2: rcon <= 7;
                    3: rcon <= 6;
                    4: rcon <= 5;
                    5: rcon <= 4;
                    6: rcon <= 3;
                    7: rcon <= 2;
                    8: rcon <= 1; 
                default:rcon <= 0;
                endcase
            end
            else if(state==FINALLY) begin
                rcon <= 0;
            end
        end
    end
    //key_en 需在字节代换后,开始计算密钥
    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
        key_en <= 0;
      end
      else  begin
        key_en <= sbox_ready | start_i;    
      end
    end



    addroundkey u_add(              //轮密钥加
    	.clk     (clk           ) , 
        .rst_n   (rst_n         ) ,
        .start_i (addround_en   ) ,
    	.data    (addround_data ) ,
        .key     (addround_key  ) ,

    	.data_o  (addround_dout ) ,
        .ready_o (addround_ready)  
    );

    //轮密钥加 循环条件转换
    assign addround_key = key_rdata ;
    always @(posedge clk or negedge rst_n)  begin
       if(!rst_n)  begin
         addround_en1 <= 0;
         addround_data <= 0;
        // addround_key <= 0;
       end
       else if(state==MIDDLE )begin
          if(~decrypt_i) begin
              addround_en1 <=   mixcolum_ready ;
              addround_data <= mixcolum_dout;
  
              //addround_key <= key_rdata;
          end
          else begin
              addround_data <= sbox_dout  ;
              addround_en1   <= sbox_ready ;
              
              //addround_key <= key_rdata;
          end
       end
       else if(state==FINALLY )begin
          if(~decrypt_i) begin
              addround_en1 <=   invshiftrow_ready  ;
              addround_data <= invshiftrow_dout  ;
  
             // addround_key <= key_rdata;
          end
          else begin
              addround_data <= sbox_dout  ;
              addround_en1   <= sbox_ready ;
              
              //addround_key <= key_rdata;
          end
       end
       else  begin
          if(~decrypt_i) begin
              addround_en1 <= start_i;
              addround_data <= data_in;
              //addround_key <= key_rdata;
          end
          else begin
              addround_en1 <= start_i;
              addround_data <= data_in;
              //addround_key <= key_rdata;
          end
       end
    end
    //轮密钥加 ,需在一轮循环完 和 密钥扩展完 同时完成条件下
    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
        addround_flag1 <= 0;
      end
      else if(addround_en) begin
         addround_flag1 <= 0;
      end
      else if(addround_en1) begin
         addround_flag1 <= 1'b1;
      end
    end
    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
        addround_flag2 <= 0;
      end
      else if(addround_en) begin
         addround_flag2 <= 0;
      end
      else if(key_done) begin
         addround_flag2 <= 1'b1;
      end
    end
    assign addround_en=addround_flag2 & addround_flag1;



    aes_sbox  u_aes_sbox(     //字节代换
    	.clk       (clk                 ), 
        .rst_n     (rst_n               ),
        .start_i   (sbox_en             ),
        .decrypt_i (decrypt_i           ),
    	.data_i    (sbox_data           ),
    	.data_o    (sbox_dout           ),
        .ready_o   (sbox_ready          )    
    );
    assign sbox_data= decrypt_i ? invshiftrow_dout : addround_dout;
    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
            sbox_en   <= 0;
           // sbox_data <= 0;
      end
      else if( ~decrypt_i )begin
            sbox_en   <= addround_ready && (rcon!=10); //除去最后一轮
           // sbox_data <= addround_dout;
      end
      else if(decrypt_i) begin
            sbox_en   <= invshiftrow_ready;
            //sbox_data <= invshiftrow_dout;
      end
    end


    invshiftrow  u_invshiftrow(          //行移位
    	.clk        (clk                ), 
        .rst_n      (rst_n              ),
        .start_i    (invshiftrow_en     ),
        .decrypt_i  (decrypt_i          ),
    	.data_i     (invshiftrow_data   ),
    	.data_o     (invshiftrow_dout   ),
        .ready_o    (invshiftrow_ready  ) 
    );

    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
            invshiftrow_en   <= 0;
            invshiftrow_data <= 0;
      end
      else if( ~decrypt_i )begin
            invshiftrow_en   <= sbox_ready ;
            invshiftrow_data <= sbox_dout ;
      end
      else if(decrypt_i) begin
          if(state==FIRST ) begin
            invshiftrow_en   <= addround_ready  ;
            invshiftrow_data <= addround_dout  ;
          end
          else if(state==MIDDLE ||state==FINALLY) begin
            invshiftrow_en   <= mixcolum_ready  ;
            invshiftrow_data <= mixcolum_dout  ;
          end
      end
    end


    mixcolum u_mixcolum(        //列混合
    	.clk       (clk                 ), 
        .rst_n     (rst_n               ),
        .start_i   (mixcolum_en         ),
        .decrypt_i (decrypt_i           ),
    	.data_i    (mixcolum_data       ),

    	.data_o    (mixcolum_dout       ),
        .ready_o   (mixcolum_ready      )     
    ); 
    assign mixcolum_data = decrypt_i ? addround_dout : invshiftrow_dout;
    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
            mixcolum_en   <= 0;
           // mixcolum_data <= 0;
      end
      else if( ~decrypt_i && state==MIDDLE )begin
            mixcolum_en   <= invshiftrow_ready;
            //mixcolum_data <= invshiftrow_dout ;
      end
      else if(decrypt_i && state==MIDDLE ) begin
            mixcolum_en   <= addround_ready;
           // mixcolum_data <= addround_dout ;
      end
    end



    //data_o,
    //ready_o 
    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
            data_o  <= 0;
            ready_o <= 0;
      end
      else if(finally_end) begin
            data_o  <= addround_dout ;
            ready_o <= finally_end;
      end
      else begin
          ready_o <= 0;
      end
    end


endmodule 

二、密钥扩展

        此部分含义2个模块,一. key_memory.v 对密钥扩展的次数进行计数。二.key_extend.v 完成密钥扩展与轮常量因子的计数

/*
    密钥扩展轮数计数层

*/


module key_memory(
    //exterior
    input                 clk                ,
    input                 rst_n              ,
    input                 start_i            ,
    input       [127:0]   key_in             ,
    input       [3:0]     rcon               , //轮数
    output      [127:0]   key_rcon           ,  
    output reg            allkey_done        
);


    reg [3:0]   cnt;
    wire        add_cnt;
    wire        end_cnt;

    //interior
    reg  [127:0]   key_extend_data    ;
    reg            key_extend_en        ;
    wire [3:0]     rd_num             ;
    wire [127:0]   key_extend_in      ;
    wire           key_extend_ready   ;
    key_extend u_key_extend(
        .clk      (clk                  ) ,
        .rst_n    (rst_n                ) ,
        .start_i  (key_extend_en        ) ,
        .rd_num   (rd_num               ) ,
        .key_in   (key_extend_data      ) ,
        .ready_o  (key_extend_ready     ) ,
        .key_out  (key_extend_in        ) 
    );

    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
        cnt <= 0;
      end
      else if(add_cnt)begin
        if(end_cnt) begin
          cnt <= 0;
        end
        else begin
          cnt <= cnt+1'b1;
        end
      end
    end
    assign add_cnt= key_extend_ready;
    assign end_cnt= add_cnt && cnt== ( rcon-1 );  //0-10

    assign rd_num = cnt;
    //key_extend_i
    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
        key_extend_data <= 0;
      end
      else if(add_cnt) begin
        key_extend_data <= key_extend_in ;
      end
      else if(cnt==0) begin
        key_extend_data <= key_in;
      end
    end
    //key_strat_i 
    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
        key_extend_en <= 1'b0;
      end
      else if( start_i && rcon ) begin
        key_extend_en <= 1'b1 ;
      end
      else if( end_cnt==0 )begin
        key_extend_en <= add_cnt ;
      end
      else begin
        key_extend_en <= 1'b0;
      end
    end

/************************ exterior  **********************/
    //allkey_done
    always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
        allkey_done <= 0; 
      end
      else  if(rcon==0)  begin
        allkey_done <= start_i ;
      end
      else  if(end_cnt)  begin
        allkey_done <= 1'b1 ;
      end
      else begin
        allkey_done <= 0; 
      end
    end

    //    时序逻辑与组合逻辑的选择
    assign key_rcon = (rcon==0) ? key_in : key_extend_in ;
   /* always @(posedge clk or negedge rst_n)  begin
      if(!rst_n)  begin
        key_rcon <= 0; 
      end
      else if(rcon==0)begin
          key_rcon <= key_in ;
      end
      else if(end_cnt)begin
        key_rcon <= key_extend_in ;
      end
    end */

endmodule

 /*
    密钥扩展逻辑代码实现

 1.若i不是4的倍数,那么第i列如下计算:
  w[i] = w[i-4] ^ w[i-1] ;
2.若i是4的倍数,那么第i列如下计算:
 	w[i] = w[i-4] ^ g w[i-1] ;
    g函数由字循环、字节代换和轮常量异或三部分组成,这三部分的作用分别如下:
    (1) 字循环:将1个字中的4个字节循环左移1个字节;
    (2) 字节代换:对字循环的结果使用S盒 进行字节代换;
    (3) 轮常量异或:对前两步的结果同轮常量Rcon[j] 进行异或,其中j代表轮数。
    casex (x)
        第 0次: rcon = 8'h01;
        第 1次: rcon = 8'h02;
        第 2次: rcon = 8'h04;
        第 3次: rcon = 8'h08;
        第 4次: rcon = 8'h10;
        第 5次: rcon = 8'h20;
        第 6次: rcon = 8'h40;
        第 7次: rcon = 8'h80;
        第 8次: rcon = 8'h1b;
        第 9次: rcon = 8'h36;
*/
module key_extend(
    input               clk ,
    input               rst_n,
    input               start_i,
    input  [3:0]        rd_num,
    input  [127:0]      key_in,

    output reg          ready_o,
    output reg[127:0]   key_out

);


reg [3:0]   state;
reg [3:0]   state_next;
reg [7:0]   rcon;
reg [31:0]  w0;
reg [31:0]  w1;
reg [31:0]  w2;
reg [31:0]  w3;
wire [31:0]  wreg0;
wire [31:0]  wreg1;
wire [31:0]  wreg2;
wire [31:0]  wreg3;
reg [31:0]  shift_wreg;
wire[31:0]  norshift_wreg;
reg [7:0]  addr;
wire [7:0] mem_out;
reg [7:0] a;
reg [7:0] b;
reg [7:0] c;
reg [7:0] d;
reg [23:0] zero=24'b0;
always @(   rd_num  ) begin
    case(rd_num)  
        0:  rcon = 8'h01;
        1:  rcon = 8'h02;
        2:  rcon = 8'h04;
        3:  rcon = 8'h08;
        4:  rcon = 8'h10;
        5:  rcon = 8'h20;
        6:  rcon = 8'h40;
        7:  rcon = 8'h80;
        8:  rcon = 8'h1b;
        9:  rcon = 8'h36; 
        default :rcon =0;
    endcase
end
always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    w0 <= 0;
    w1 <= 0;
    w2 <= 0;
    w3 <= 0;
  end
  else begin
    w3 <= key_in[31:0];  
    w2 <= key_in[63:32]; 
    w1 <= key_in[95:64]; 
    w0 <= key_in[127:96]; 
  end
end

memory_S   u_S(.clk(clk), .rst_n(rst_n),.addr(addr) , .mem_out(mem_out));
//这里我们直接采样S盒转换

always@(posedge clk  or negedge rst_n) begin
    if(!rst_n) begin
        state <= 0;
    end
    else  begin
        state  <= state_next; 
    end
end
always @(*) begin
    case (state)
    0: 
    if(start_i) begin
        state_next = 1;
    end
    else begin
        state_next = 0;
    end
    1: begin
        state_next = 2;
    end
    2: begin
        state_next = 3;
    end
    3: begin
        state_next = 4;
    end
    4: begin
        state_next = 5;
    end
    5:begin
        state_next =6;
    end
    6:  begin
        state_next = 7;
    end
    7:  begin
        state_next = 0;
    end
    default:state_next = 0;
    endcase
end
always @(*) begin
    case (state)
    1: begin
        addr=w3[7:0] ;
    end
    2: begin
        addr=w3[15:8] ;
    end
    3: begin
        addr=w3[23:16] ;
    end
    4: begin
        addr=w3[31:24] ;
    end
    default:begin
        addr= 0;
    end     
    endcase
end
always @(*) begin
    case (state)
    2: begin
        a=mem_out  ;
        d= shift_wreg[7:0];
        b= shift_wreg[23:16];  
        c= shift_wreg[31:24]; 
    end
    3: begin
        d= shift_wreg[7:0];
        a= shift_wreg[15:8]; 
        c= shift_wreg[31:24];             
        b=mem_out  ;
    end
    4: begin
        d= shift_wreg[7:0];
        a= shift_wreg[15:8];
        b= shift_wreg[23:16];  
        c=mem_out  ;
    end
    5: begin
        a= shift_wreg[15:8];
        b= shift_wreg[23:16];  
        c= shift_wreg[31:24]; 
        d=mem_out  ;
    end
    default:begin
        d= shift_wreg[7:0];
        a= shift_wreg[15:8];
        b= shift_wreg[23:16];  
        c= shift_wreg[31:24]; 
    end     
    endcase
end
//字节移位
always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    shift_wreg <= 0;
  end
  else begin    
    shift_wreg <={c,b,a,d};
  end
end
//异或常轮量
assign   norshift_wreg = shift_wreg ^ {rcon,zero} ;
assign   wreg0 = w0 ^ norshift_wreg;
assign   wreg1 = w1 ^ wreg0;
assign   wreg2 = w2 ^ wreg1;
assign   wreg3 = w3 ^ wreg2;  
always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    key_out <= 0;
  end
  else if(state==7) begin
    key_out <= {wreg0,wreg1,wreg2,wreg3};
  end
end
always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    ready_o <= 0;
  end
  else begin
    ready_o <= state==7;
  end
end

endmodule

三、轮密钥加

        此部分比较简单,直接密钥与密文异或即可。代码如下

module  addroundkey(
	input			     clk, 
    input                rst_n,
    input                start_i,
	input       [127:0]	 data,
    input       [127:0]  key,
	output      [127:0]  data_o,
    output reg           ready_o 
);

    
    assign data_o = data ^ key ;
    
    always@(posedge clk  or negedge rst_n) begin
        if(!rst_n) begin
            ready_o <= 0;
        end
        else   begin
            ready_o <= start_i ;
        end
    end


endmodule

四、字节代换

        此部分分为2个模块,1.对128bit数据进行32bit一组划分,2.对每组32bit数据通过S盒、逆S盒进行查找,完成字节代换。有兴趣的朋友可以自己写一下直接代码实现的S盒与逆S盒。代码如下:

/* 
    对128bit数据进行32bit一组分化,通过状态机实现计数

*/


module  aes_sbox(
	input			 clk, 
    input            rst_n,
    input            start_i,
    input            decrypt_i,
	input     [127:0]data_i,
	output reg[127:0]data_o,
    output reg       ready_o 
);


localparam    STATE0=5'b0000_1 ,
              STATE1=5'b0001_0 ,
              STATE2=5'b0010_0 ,
              STATE3=5'b0100_0 ,
              STATE4=5'b1000_0 ;
reg [4:0]     state;
reg [4:0]     next_state;
wire          s0_s1;
wire          s1_s2;
wire          s2_s3;
wire          s3_s4;
wire          s4_s0;

reg [31:0]    sbox_word;
reg  [127:0]  data_i_var;
reg           work_en;
reg           ready_o_r0;
wire          done;
reg           start;
wire [31:0]   sboxout;
sbox_word u_sbox_word(
  .clk        (clk          ) , 
  .rst_n      (rst_n        ) ,
  .start_i    (work_en      ) ,
  .decrypt_i  (decrypt_i    ) ,
  .data_i     (sbox_word    ) ,
  .data_o     (sboxout      ) ,
  .ready_o    (done         )  
);
//***********************fsm********************************//
always@(posedge clk or negedge rst_n ) begin
    if(!rst_n) begin
      state <= STATE0;
    end
    else  begin
      state <= next_state;
    end
end
always @(*)   begin
  case(state)
  STATE0:begin
    if(s0_s1) begin
      next_state = STATE1;
    end
    else begin
      next_state = STATE0;
    end
  end
  STATE1:begin
    if(s1_s2) begin
      next_state = STATE2;
    end
    else begin
      next_state = STATE1;
    end
  end
  STATE2:begin
    if(s2_s3) begin
      next_state = STATE3;
    end
    else begin
      next_state = STATE2;
    end
  end
  STATE3:begin
    if(s3_s4) begin
      next_state = STATE4;
    end
    else begin
      next_state = STATE3;
    end
  end
  STATE4:begin
    if(s4_s0) begin
      next_state = STATE0;
    end
    else begin
      next_state = STATE4;
    end
  end
  default:next_state =STATE0;
  endcase
end
assign s0_s1= state==STATE0 && (start    ) ;
assign s1_s2= state==STATE1 && (done     ) ;
assign s2_s3= state==STATE2 && (done     ) ;
assign s3_s4= state==STATE3 && (done     ) ;
assign s4_s0= state==STATE4 && (done     ) ;

always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    start <= 0;
  end
  else   begin   
    start <= start_i;
  end
end
//
always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    data_i_var <= 0;
  end
  else  if(start_i) begin   
    data_i_var <= data_i;
  end
end

//sbox_word
always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
      sbox_word <= 0;
  end
  else if(s0_s1) begin
    sbox_word <= data_i_var[127:96]; 
  end
  else if(s1_s2) begin
    sbox_word <= data_i_var[95:64];
  end
  else if(s2_s3) begin
    sbox_word <= data_i_var[63:32];
  end
  else if(s3_s4) begin
    sbox_word <= data_i_var[31:0];
  end
end

//   work_en
always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    work_en <= 0;
  end
  else if(s0_s1 | s1_s2 | s2_s3 | s3_s4) begin
    work_en <= 1'b1;
  end
  else begin
    work_en <= 0;
  end
end


always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    data_o <= 0;
  end
  else if(s1_s2) begin
    data_o[127:96] <= sboxout; 
  end
  else if(s2_s3) begin
    data_o[95:64] <= sboxout; 
  end
  else if(s3_s4) begin
    data_o[63:32] <= sboxout; 
  end
  else if(s4_s0) begin
    data_o[31:0] <= sboxout; 
  end
end
//ready_o
always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    ready_o <= 0;
    ready_o_r0 <=0;
  end
  else  	begin
    ready_o_r0 <= s4_s0 ;
    ready_o <= ready_o_r0;
  end
end

endmodule
/*
    字节代换,
*/

module sbox_word(
	input			    clk, 
    input               rst_n,
    input               start_i,
    input               decrypt_i,
	input       [31:0]	data_i,
	output reg  [31:0]  data_o,
    output reg          ready_o 
       
);
  
    reg [2:0]   state;
    reg [2:0]   state_next;

	reg [7:0]	byte_0;
    reg [7:0]	byte_1;
    reg [7:0]   byte_2;
    reg [7:0]   byte_3;

    reg [7:0]	dout_0;
    reg [7:0]	dout_1;
    reg [7:0]   dout_2;
    reg [7:0]   dout_3;
	 
	reg [7:0]	 addr_s;
    reg [7:0]    addr_sinv;
	wire [7:0]	 mem_out_s;
    wire [7:0]	 mem_out_sinv;
	 //逆S盒
    memory_S_inv   u_Sinv(.clk(clk),.rst_n(rst_n), .addr(addr_sinv) , .mem_out(mem_out_sinv));
    //S盒
    memory_S   u_S(.clk(clk),.rst_n(rst_n), .addr(addr_s) , .mem_out(mem_out_s));
     
    always@(posedge clk  or negedge rst_n) begin
        if(!rst_n) begin
            byte_0 <= 0;
            byte_1 <= 0;
            byte_2 <= 0;
            byte_3 <= 0; 
        end
        else begin
            byte_0 <= data_i[7:0];
            byte_1 <= data_i[15:8];
            byte_2 <= data_i[23:16];
            byte_3 <= data_i[31:24];
        end
    end
    always@(posedge clk  or negedge rst_n) begin
        if(!rst_n) begin
            state <= 0;
        end
        else  begin
            state  <= state_next; 
        end
    end

    always @(*) begin
        case (state)
        0: 
        if(start_i) begin
            state_next =1;
        end
        else begin
            state_next=0;
        end
        1: begin
            state_next =2;
        end
        2: begin
            state_next =3;
        end
        3: begin
            state_next =4;
        end
        4: begin
            state_next =5;
        end
        5:begin
            state_next =6;
        end
        6:begin
            state_next =0;
        end
        default:state_next =0;
        endcase
    end

    always @(*) begin
        case (state)
        1: begin
        if(decrypt_i) begin
            addr_sinv=byte_0 ;
            addr_s = 0;
        end
        else begin
            addr_s=byte_0 ;
            addr_sinv =0;
        end
        end
        2: begin
        if(decrypt_i) begin
            addr_sinv=byte_1 ;
            addr_s = 0;
        end
        else begin
            addr_s=byte_1 ;
            addr_sinv =0;    
        end
        end
        3: begin
        if(decrypt_i) begin
            addr_sinv=byte_2;
            addr_s = 0;
        end
        else begin
            addr_s=byte_2 ;
            addr_sinv =0;
        end
        end
        4: begin
        if(decrypt_i) begin
            addr_sinv=byte_3 ;
            addr_s = 0;
        end
        else begin
            addr_s=byte_3 ;
            addr_sinv =0;
        end
        end
        default: begin
            addr_s=0 ;
            addr_sinv =0;
        end
        endcase
    end

    always @(*) begin
        case (state)
        2: begin
        if(decrypt_i) begin
            dout_0=mem_out_sinv ;
            dout_3 =data_o[31:24]; 
            dout_2 =data_o[23:16]; 
            dout_1 =data_o[15:8] ;
        end
        else begin
            dout_0=mem_out_s ; 
            dout_3 =data_o[31:24]; 
            dout_2 =data_o[23:16]; 
            dout_1 =data_o[15:8] ;
        end
        end
        3: begin
        if(decrypt_i) begin
            dout_1=mem_out_sinv ;
            dout_3 =data_o[31:24]; 
            dout_2 =data_o[23:16];
            dout_0 =data_o[7:0]  ;
        end
        else begin
            dout_1=mem_out_s ; 
            dout_3 =data_o[31:24]; 
            dout_2 =data_o[23:16];
            dout_0 =data_o[7:0]  ;    
        end
        end
        4: begin
        if(decrypt_i) begin
            dout_2=mem_out_sinv ;
            dout_3 =data_o[31:24];
            dout_1 =data_o[15:8] ;
            dout_0 =data_o[7:0]  ;
        end
        else begin
            dout_2=mem_out_s ;
            dout_3 =data_o[31:24]; 
            dout_1 =data_o[15:8] ;
            dout_0 =data_o[7:0]  ;
        end
        end
        5: begin
        if(decrypt_i) begin
            dout_3=mem_out_sinv ; 
            dout_2 =data_o[23:16]; 
            dout_1 =data_o[15:8] ;
            dout_0 =data_o[7:0]  ;
        end
        else begin
            dout_3=mem_out_s ; 
            dout_2 =data_o[23:16]; 
            dout_1 =data_o[15:8] ;
            dout_0 =data_o[7:0]  ;
        end
        end
        default: begin
            dout_3 =data_o[31:24]; 
            dout_2 =data_o[23:16]; 
            dout_1 =data_o[15:8] ;
            dout_0 =data_o[7:0]  ;
        end
        endcase
    end

    always@(posedge clk  or negedge rst_n) begin
        if(!rst_n) begin
            data_o <= 0;
        end
        else  begin
            data_o  <= {dout_3,dout_2,dout_1,dout_0}; 
        end
    end

    always@(posedge clk  or negedge rst_n) begin
        if(!rst_n) begin
            ready_o <= 0;
        end
        else   begin
            ready_o <= state==6;
        end
    end

endmodule

五、行移位

        如果你的明文加密后的密文,与标准的密文不一样,但是你的密文又能正常的通过密钥解密,那么你多半是在行移位这里出问题了。

行移位转换图如下:

AES_128加密解密算法,verilog实现。完整代码_第1张图片

行移位代码如下:

/*
     行移位
*/

module invshiftrow(
	input			 clk, 
    input            rst_n,
    input            start_i,
    input            decrypt_i,
	input [127:0]	 data_i,
	output reg[127:0]data_o,
    output reg       ready_o 
);


reg [31:0] a;
reg [31:0] b;
reg [31:0] c;
reg [31:0] d;
wire [31:0] a_r;
wire [31:0] b_r;
wire [31:0] c_r;
wire [31:0] d_r;
//reg [127:0] data_o_r;
reg       ready_r0;
reg       ready_r1;

always@(posedge clk  or negedge rst_n) begin
    if(!rst_n) begin
        a <= 0;
        b <= 0;
        c <= 0;
        d <= 0;
    end
    else if(start_i) begin
        a <= data_i[31:0];
        b <= data_i[63:32];
        c <= data_i[95:64];
        d <= data_i[127:96];
    end
end
assign a_r=decrypt_i ? {a[31:24],b[23:16],c[15:8],d[7:0]} : {a[31:24],d[23:16],c[15:8],b[7:0]};
assign b_r=decrypt_i ? {b[31:24],c[23:16],d[15:8],a[7:0]} : {b[31:24],a[23:16],d[15:8],c[7:0]};
assign c_r=decrypt_i ? {c[31:24],d[23:16],a[15:8],b[7:0]} : {c[31:24],b[23:16],a[15:8],d[7:0]};
assign d_r=decrypt_i ? {d[31:24],a[23:16],b[15:8],c[7:0]} : {d[31:24],c[23:16],b[15:8],a[7:0]};
always@(posedge clk  or negedge rst_n) begin
    if(!rst_n) begin
       // data_o_r <= 0;
        data_o <= 0;
    end
    else  begin
        data_o <= {d_r,c_r,b_r,a_r};
        //data_o <= data_o_r;
    end
end
always@(posedge clk  or negedge rst_n) begin
    if(!rst_n) begin
        ready_o <= 0;
        ready_r0 <= 0;                
        ready_r1 <= 0;    
    end
    else  begin
        ready_r0 <= start_i;
        ready_r1 <= ready_r0;                
        ready_o <= ready_r1;
    end
end

endmodule

六、列混合

        列混合运算需要在G F ( 2 ^8 )域上作运算。具体运算关系,本人不在详述, 代码中调用的2个函数即完成了列混合的运算。代码如下:

/*
  列混合
*/

module  mixcolum(
  input			      clk, 
  input               rst_n,
  input               start_i,
  input               decrypt_i,
  input [127:0]	      data_i,

  output reg[127:0]   data_o,
  output reg          ready_o 
); 

 
reg  [2:0] cnt;
wire       add_cnt;
wire       end_cnt;
reg        flag;
integer i=0 ;

// 
reg  [7:0] a;
reg  [7:0] b;
reg  [7:0] c;
reg  [7:0] d;
wire [7:0] b0;
wire [7:0] b1;
wire [7:0] b2;
wire [7:0] b3;

function [7:0] mul_02;
  input [7:0] in;
  reg   [7:0] reg_in;
  reg [8:0]  shift_in;
  begin
    reg_in = in;
    shift_in= ( reg_in<<1 );
    mul_02= shift_in[8] ? shift_in[7:0]^8'h1b : shift_in[7:0] ;
  end
endfunction

function [7:0] mbyte;
  input [7:0] in0,in1,in2,in3;
  reg [7:0] w1,w2,w3,w4,w5,w6,w7,w8,outx_var;
  begin
    w1 = in0 ^in1;
    w2 = in0 ^in2;
    w3 = in2 ^in3;
    w4 = mul_02(w1);
    w5 = mul_02(w3);
    w6 = w2 ^w4 ^w5;
    w7 = mul_02(w6);
    w8 = mul_02(w7);
    outx_var = in1^w3^w4;
    if(decrypt_i) begin
      mbyte=outx_var^w8;
    end
    else begin
      mbyte=outx_var;
    end
  end
endfunction


always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    flag <= 0;
  end
  else if(cnt ==4 ) begin
    flag <= 0;
  end
  else  if(start_i) begin
    flag <= 1'b1;
  end
end

always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    cnt <= 0;
  end
  else if(add_cnt) begin
    if(end_cnt) begin
      cnt <= 0;
    end
    else begin
      cnt <= cnt+1'b1;
    end
  end
end
assign add_cnt=flag;
assign end_cnt=add_cnt && cnt==4;


assign b0 = mbyte (a,b,c,d);  
assign b1 = mbyte (b,c,d,a);   
assign b2 = mbyte (c,d,a,b);   
assign b3 = mbyte (d,a,b,c);

always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    /*for(i=0;i<16;i=i+1) begin
        memory_r[i] <= 0;
    end*/
    data_o <= 0;   
  end
  else if(cnt==0)begin
  //第0行
    data_o[127:120] <= b0 ; 
    data_o[119:112] <= b1 ;      
    data_o[111:104] <= b2 ;    
    data_o[103:96]  <= b3 ;
  end
  else if(cnt==1)begin      
    //第1行
    data_o[95:88]  <= b0 ;    
    data_o[87:80]  <= b1 ;      
    data_o[79:72]  <= b2 ;   
    data_o[71:64]  <= b3 ; 
  end
  else if(cnt==2)begin  
    //第2行
    data_o[63:56]  <= b0 ;       
    data_o[55:48]  <= b1 ;         
    data_o[47:40]  <= b2 ;       
    data_o[39:32]  <= b3 ;  
  end
  else if(cnt==3)begin       
    //第3行
    data_o[31:24] <= b0 ;   
    data_o[23:16] <= b1 ;   
    data_o[15:8]  <= b2 ;   
    data_o[7:0]   <= b3 ;   
  end
end
always @(* )  begin
  if(cnt==0)begin
  //第0行
     a = data_i[127:120];  
     b = data_i[119:112];       
     c = data_i[111:104];     
     d = data_i[103:96] ;
  end
  else if(cnt==1)begin      
    //第1行
    a = data_i[95:88] ;   
    b = data_i[87:80] ;     
    c = data_i[79:72] ;  
    d = data_i[71:64] ;
  end
  else if(cnt==2)begin  
    //第2行
    a = data_i[63:56] ;      
    b = data_i[55:48] ;        
    c = data_i[47:40] ;      
    d = data_i[39:32] ; 
  end
  else if(cnt==3)begin       
    //第3行
    a = data_i[31:24] ;    
    b = data_i[23:16] ;    
    c = data_i[15:8]  ;    
    d = data_i[7:0]   ;    
  end
  else begin       
    //第3行
    a = 0 ;    
    b = 0 ;    
    c = 0 ;    
    d = 0 ;    
  end
end


always @(posedge clk or negedge rst_n)  begin
  if(!rst_n)  begin
    ready_o <= 0;
  end
  else  begin
    ready_o <= end_cnt ;
  end
end

endmodule


七、S盒

         S查找表与逆S盒查找表,如下:

//S盒
module memory_S(
    input              clk,
	input 			   rst_n,
    input     [7:0]    addr ,
    output reg[7:0]    mem_out
);

(* ramstyle = "M9K" *)    reg [7:0]	int_mem_i [255:0];  //S盒


    always@(posedge clk or negedge rst_n )  begin
		if(!rst_n) begin
                    int_mem_i [8'h00] <=  8'h63 ;
                    int_mem_i [8'h01] <=  8'h7c ;
                    int_mem_i [8'h02] <=  8'h77 ;
                    int_mem_i [8'h03] <=  8'h7b ;
                    int_mem_i [8'h04] <=  8'hf2 ;
                    int_mem_i [8'h05] <=  8'h6b ;
                    int_mem_i [8'h06] <=  8'h6f ;
                    int_mem_i [8'h07] <=  8'hc5 ;
                    int_mem_i [8'h08] <=  8'h30 ;
                    int_mem_i [8'h09] <=  8'h01 ;
                    int_mem_i [8'h0a] <=  8'h67 ;
                    int_mem_i [8'h0b] <=  8'h2b ;
                    int_mem_i [8'h0c] <=  8'hfe ;
                    int_mem_i [8'h0d] <=  8'hd7 ;
                    int_mem_i [8'h0e] <=  8'hab ;
                    int_mem_i [8'h0f] <=  8'h76 ;
                    int_mem_i [8'h10] <=  8'hca ;
                    int_mem_i [8'h11] <=  8'h82 ;
                    int_mem_i [8'h12] <=  8'hc9 ;
                    int_mem_i [8'h13] <=  8'h7d ;
                    int_mem_i [8'h14] <=  8'hfa ;
                    int_mem_i [8'h15] <=  8'h59 ;
                    int_mem_i [8'h16] <=  8'h47 ;
                    int_mem_i [8'h17] <=  8'hf0 ;
                    int_mem_i [8'h18] <=  8'had ;
                    int_mem_i [8'h19] <=  8'hd4 ;
                    int_mem_i [8'h1a] <=  8'ha2 ;
                    int_mem_i [8'h1b] <=  8'haf ;
                    int_mem_i [8'h1c] <=  8'h9c ;
                    int_mem_i [8'h1d] <=  8'ha4 ;
                    int_mem_i [8'h1e] <=  8'h72 ;
                    int_mem_i [8'h1f] <=  8'hc0 ;
                    int_mem_i [8'h20] <=  8'hb7 ;
                    int_mem_i [8'h21] <=  8'hfd ;
                    int_mem_i [8'h22] <=  8'h93 ;
                    int_mem_i [8'h23] <=  8'h26 ;
                    int_mem_i [8'h24] <=  8'h36 ;
                    int_mem_i [8'h25] <=  8'h3f ;
                    int_mem_i [8'h26] <=  8'hf7 ;
                    int_mem_i [8'h27] <=  8'hcc ;
                    int_mem_i [8'h28] <=  8'h34 ;
                    int_mem_i [8'h29] <=  8'ha5 ;
                    int_mem_i [8'h2a] <=  8'he5 ;
                    int_mem_i [8'h2b] <=  8'hf1 ;
                    int_mem_i [8'h2c] <=  8'h71 ;
                    int_mem_i [8'h2d] <=  8'hd8 ;
                    int_mem_i [8'h2e] <=  8'h31 ;
                    int_mem_i [8'h2f] <=  8'h15 ;
                    int_mem_i [8'h30] <=  8'h04 ;
                    int_mem_i [8'h31] <=  8'hc7 ;
                    int_mem_i [8'h32] <=  8'h23 ;
                    int_mem_i [8'h33] <=  8'hc3 ;
                    int_mem_i [8'h34] <=  8'h18 ;
                    int_mem_i [8'h35] <=  8'h96 ;
                    int_mem_i [8'h36] <=  8'h05 ;
                    int_mem_i [8'h37] <=  8'h9a ;
                    int_mem_i [8'h38] <=  8'h07 ;
                    int_mem_i [8'h39] <=  8'h12 ;
                    int_mem_i [8'h3a] <=  8'h80 ;
                    int_mem_i [8'h3b] <=  8'he2 ;
                    int_mem_i [8'h3c] <=  8'heb ;
                    int_mem_i [8'h3d] <=  8'h27 ;
                    int_mem_i [8'h3e] <=  8'hb2 ;
                    int_mem_i [8'h3f] <=  8'h75 ;
                    int_mem_i [8'h40] <=  8'h09 ;
                    int_mem_i [8'h41] <=  8'h83 ;
                    int_mem_i [8'h42] <=  8'h2c ;
                    int_mem_i [8'h43] <=  8'h1a ;
                    int_mem_i [8'h44] <=  8'h1b ;
                    int_mem_i [8'h45] <=  8'h6e ;
                    int_mem_i [8'h46] <=  8'h5a ;
                    int_mem_i [8'h47] <=  8'ha0 ;
                    int_mem_i [8'h48] <=  8'h52 ;
                    int_mem_i [8'h49] <=  8'h3b ;
                    int_mem_i [8'h4a] <=  8'hd6 ;
                    int_mem_i [8'h4b] <=  8'hb3 ;
                    int_mem_i [8'h4c] <=  8'h29 ;
                    int_mem_i [8'h4d] <=  8'he3 ;
                    int_mem_i [8'h4e] <=  8'h2f ;
                    int_mem_i [8'h4f] <=  8'h84 ;
                    int_mem_i [8'h50] <=  8'h53 ;
                    int_mem_i [8'h51] <=  8'hd1 ;
                    int_mem_i [8'h52] <=  8'h00 ;
                    int_mem_i [8'h53] <=  8'hed ;
                    int_mem_i [8'h54] <=  8'h20 ;
                    int_mem_i [8'h55] <=  8'hfc ;
                    int_mem_i [8'h56] <=  8'hb1 ;
                    int_mem_i [8'h57] <=  8'h5b ;
                    int_mem_i [8'h58] <=  8'h6a ;
                    int_mem_i [8'h59] <=  8'hcb ;
                    int_mem_i [8'h5a] <=  8'hbe ;
                    int_mem_i [8'h5b] <=  8'h39 ;
                    int_mem_i [8'h5c] <=  8'h4a ;
                    int_mem_i [8'h5d] <=  8'h4c ;
                    int_mem_i [8'h5e] <=  8'h58 ;
                    int_mem_i [8'h5f] <=  8'hcf ;
                    int_mem_i [8'h60] <=  8'hd0 ;
                    int_mem_i [8'h61] <=  8'hef ;
                    int_mem_i [8'h62] <=  8'haa ;
                    int_mem_i [8'h63] <=  8'hfb ;
                    int_mem_i [8'h64] <=  8'h43 ;
                    int_mem_i [8'h65] <=  8'h4d ;
                    int_mem_i [8'h66] <=  8'h33 ;
                    int_mem_i [8'h67] <=  8'h85 ;
                    int_mem_i [8'h68] <=  8'h45 ;
                    int_mem_i [8'h69] <=  8'hf9 ;
                    int_mem_i [8'h6a] <=  8'h02 ;
                    int_mem_i [8'h6b] <=  8'h7f ;
                    int_mem_i [8'h6c] <=  8'h50 ;
                    int_mem_i [8'h6d] <=  8'h3c ;
                    int_mem_i [8'h6e] <=  8'h9f ;
                    int_mem_i [8'h6f] <=  8'ha8 ;
                    int_mem_i [8'h70] <=  8'h51 ;
                    int_mem_i [8'h71] <=  8'ha3 ;
                    int_mem_i [8'h72] <=  8'h40 ;
                    int_mem_i [8'h73] <=  8'h8f ;
                    int_mem_i [8'h74] <=  8'h92 ;
                    int_mem_i [8'h75] <=  8'h9d ;
                    int_mem_i [8'h76] <=  8'h38 ;
                    int_mem_i [8'h77] <=  8'hf5 ;
                    int_mem_i [8'h78] <=  8'hbc ;
                    int_mem_i [8'h79] <=  8'hb6 ;
                    int_mem_i [8'h7a] <=  8'hda ;
                    int_mem_i [8'h7b] <=  8'h21 ;
                    int_mem_i [8'h7c] <=  8'h10 ;
                    int_mem_i [8'h7d] <=  8'hff ;
                    int_mem_i [8'h7e] <=  8'hf3 ;
                    int_mem_i [8'h7f] <=  8'hd2 ;
                    int_mem_i [8'h80] <=  8'hcd ;
                    int_mem_i [8'h81] <=  8'h0c ;
                    int_mem_i [8'h82] <=  8'h13 ;
                    int_mem_i [8'h83] <=  8'hec ;
                    int_mem_i [8'h84] <=  8'h5f ;
                    int_mem_i [8'h85] <=  8'h97 ;
                    int_mem_i [8'h86] <=  8'h44 ;
                    int_mem_i [8'h87] <=  8'h17 ;
                    int_mem_i [8'h88] <=  8'hc4 ;
                    int_mem_i [8'h89] <=  8'ha7 ;
                    int_mem_i [8'h8a] <=  8'h7e ;
                    int_mem_i [8'h8b] <=  8'h3d ;
                    int_mem_i [8'h8c] <=  8'h64 ;
                    int_mem_i [8'h8d] <=  8'h5d ;
                    int_mem_i [8'h8e] <=  8'h19 ;
                    int_mem_i [8'h8f] <=  8'h73 ;
                    int_mem_i [8'h90] <=  8'h60 ;
                    int_mem_i [8'h91] <=  8'h81 ;
                    int_mem_i [8'h92] <=  8'h4f ;
                    int_mem_i [8'h93] <=  8'hdc ;
                    int_mem_i [8'h94] <=  8'h22 ;
                    int_mem_i [8'h95] <=  8'h2a ;
                    int_mem_i [8'h96] <=  8'h90 ;
                    int_mem_i [8'h97] <=  8'h88 ;
                    int_mem_i [8'h98] <=  8'h46 ;
                    int_mem_i [8'h99] <=  8'hee ;
                    int_mem_i [8'h9a] <=  8'hb8 ;
                    int_mem_i [8'h9b] <=  8'h14 ;
                    int_mem_i [8'h9c] <=  8'hde ;
                    int_mem_i [8'h9d] <=  8'h5e ;
                    int_mem_i [8'h9e] <=  8'h0b ;
                    int_mem_i [8'h9f] <=  8'hdb ;
                    int_mem_i [8'ha0] <=  8'he0 ;
                    int_mem_i [8'ha1] <=  8'h32 ;
                    int_mem_i [8'ha2] <=  8'h3a ;
                    int_mem_i [8'ha3] <=  8'h0a ;
                    int_mem_i [8'ha4] <=  8'h49 ;
                    int_mem_i [8'ha5] <=  8'h06 ;
                    int_mem_i [8'ha6] <=  8'h24 ;
                    int_mem_i [8'ha7] <=  8'h5c ;
                    int_mem_i [8'ha8] <=  8'hc2 ;
                    int_mem_i [8'ha9] <=  8'hd3 ;
                    int_mem_i [8'haa] <=  8'hac ;
                    int_mem_i [8'hab] <=  8'h62 ;
                    int_mem_i [8'hac] <=  8'h91 ;
                    int_mem_i [8'had] <=  8'h95 ;
                    int_mem_i [8'hae] <=  8'he4 ;
                    int_mem_i [8'haf] <=  8'h79 ;
                    int_mem_i [8'hb0] <=  8'he7 ;
                    int_mem_i [8'hb1] <=  8'hc8 ;
                    int_mem_i [8'hb2] <=  8'h37 ;
                    int_mem_i [8'hb3] <=  8'h6d ;
                    int_mem_i [8'hb4] <=  8'h8d ;
                    int_mem_i [8'hb5] <=  8'hd5 ;
                    int_mem_i [8'hb6] <=  8'h4e ;
                    int_mem_i [8'hb7] <=  8'ha9 ;
                    int_mem_i [8'hb8] <=  8'h6c ;
                    int_mem_i [8'hb9] <=  8'h56 ;
                    int_mem_i [8'hba] <=  8'hf4 ;
                    int_mem_i [8'hbb] <=  8'hea ;
                    int_mem_i [8'hbc] <=  8'h65 ;
                    int_mem_i [8'hbd] <=  8'h7a ;
                    int_mem_i [8'hbe] <=  8'hae ;
                    int_mem_i [8'hbf] <=  8'h08 ;
                    int_mem_i [8'hc0] <=  8'hba ;
                    int_mem_i [8'hc1] <=  8'h78 ;
                    int_mem_i [8'hc2] <=  8'h25 ;
                    int_mem_i [8'hc3] <=  8'h2e ;
                    int_mem_i [8'hc4] <=  8'h1c ;
                    int_mem_i [8'hc5] <=  8'ha6 ;
                    int_mem_i [8'hc6] <=  8'hb4 ;
                    int_mem_i [8'hc7] <=  8'hc6 ;
                    int_mem_i [8'hc8] <=  8'he8 ;
                    int_mem_i [8'hc9] <=  8'hdd ;
                    int_mem_i [8'hca] <=  8'h74 ;
                    int_mem_i [8'hcb] <=  8'h1f ;
                    int_mem_i [8'hcc] <=  8'h4b ;
                    int_mem_i [8'hcd] <=  8'hbd ;
                    int_mem_i [8'hce] <=  8'h8b ;
                    int_mem_i [8'hcf] <=  8'h8a ;
                    int_mem_i [8'hd0] <=  8'h70 ;
                    int_mem_i [8'hd1] <=  8'h3e ;
                    int_mem_i [8'hd2] <=  8'hb5 ;
                    int_mem_i [8'hd3] <=  8'h66 ;
                    int_mem_i [8'hd4] <=  8'h48 ;
                    int_mem_i [8'hd5] <=  8'h03 ;
                    int_mem_i [8'hd6] <=  8'hf6 ;
                    int_mem_i [8'hd7] <=  8'h0e ;
                    int_mem_i [8'hd8] <=  8'h61 ;
                    int_mem_i [8'hd9] <=  8'h35 ;
                    int_mem_i [8'hda] <=  8'h57 ;
                    int_mem_i [8'hdb] <=  8'hb9 ;
                    int_mem_i [8'hdc] <=  8'h86 ;
                    int_mem_i [8'hdd] <=  8'hc1 ;
                    int_mem_i [8'hde] <=  8'h1d ;
                    int_mem_i [8'hdf] <=  8'h9e ;
                    int_mem_i [8'he0] <=  8'he1 ;
                    int_mem_i [8'he1] <=  8'hf8 ;
                    int_mem_i [8'he2] <=  8'h98 ;
                    int_mem_i [8'he3] <=  8'h11 ;
                    int_mem_i [8'he4] <=  8'h69 ;
                    int_mem_i [8'he5] <=  8'hd9 ;
                    int_mem_i [8'he6] <=  8'h8e ;
                    int_mem_i [8'he7] <=  8'h94 ;
                    int_mem_i [8'he8] <=  8'h9b ;
                    int_mem_i [8'he9] <=  8'h1e ;
                    int_mem_i [8'hea] <=  8'h87 ;
                    int_mem_i [8'heb] <=  8'he9 ;
                    int_mem_i [8'hec] <=  8'hce ;
                    int_mem_i [8'hed] <=  8'h55 ;
                    int_mem_i [8'hee] <=  8'h28 ;
                    int_mem_i [8'hef] <=  8'hdf ;
                    int_mem_i [8'hf0] <=  8'h8c ;
                    int_mem_i [8'hf1] <=  8'ha1 ;
                    int_mem_i [8'hf2] <=  8'h89 ;
                    int_mem_i [8'hf3] <=  8'h0d ;
                    int_mem_i [8'hf4] <=  8'hbf ;
                    int_mem_i [8'hf5] <=  8'he6 ;
                    int_mem_i [8'hf6] <=  8'h42 ;
                    int_mem_i [8'hf7] <=  8'h68 ;
                    int_mem_i [8'hf8] <=  8'h41 ;
                    int_mem_i [8'hf9] <=  8'h99 ;
                    int_mem_i [8'hfa] <=  8'h2d ;
                    int_mem_i [8'hfb] <=  8'h0f ;
                    int_mem_i [8'hfc] <=  8'hb0 ;
                    int_mem_i [8'hfd] <=  8'h54 ;
                    int_mem_i [8'hfe] <=  8'hbb ;
                    int_mem_i [8'hff] <=  8'h16 ;
        end
		else begin
			mem_out= int_mem_i[addr];
		end
	end
endmodule 



//逆S盒
module memory_S_inv(
    input              clk,
	input 			   rst_n,
    input     [7:0]    addr ,
    output reg[7:0]    mem_out
);

(* ramstyle = "M9K" *)   reg [7:0]	int_mem_o [255:0];  //S盒

    always@(posedge clk or negedge rst_n )  begin
		if(!rst_n) begin
                    int_mem_o [8'h00] <= 8'h52 ;
                    int_mem_o [8'h01] <= 8'h09 ;
                    int_mem_o [8'h02] <= 8'h6a ;
                    int_mem_o [8'h03] <= 8'hd5 ;
                    int_mem_o [8'h04] <= 8'h30 ;
                    int_mem_o [8'h05] <= 8'h36 ;
                    int_mem_o [8'h06] <= 8'ha5 ;
                    int_mem_o [8'h07] <= 8'h38 ;
                    int_mem_o [8'h08] <= 8'hbf ;
                    int_mem_o [8'h09] <= 8'h40 ;
                    int_mem_o [8'h0a] <= 8'ha3 ;
                    int_mem_o [8'h0b] <= 8'h9e ;
                    int_mem_o [8'h0c] <= 8'h81 ;
                    int_mem_o [8'h0d] <= 8'hf3 ;
                    int_mem_o [8'h0e] <= 8'hd7 ;
                    int_mem_o [8'h0f] <= 8'hfb ;
                    int_mem_o [8'h10] <= 8'h7c ;
                    int_mem_o [8'h11] <= 8'he3 ;
                    int_mem_o [8'h12] <= 8'h39 ;
                    int_mem_o [8'h13] <= 8'h82 ;
                    int_mem_o [8'h14] <= 8'h9b ;
                    int_mem_o [8'h15] <= 8'h2f ;
                    int_mem_o [8'h16] <= 8'hff ;
                    int_mem_o [8'h17] <= 8'h87 ;
                    int_mem_o [8'h18] <= 8'h34 ;
                    int_mem_o [8'h19] <= 8'h8e ;
                    int_mem_o [8'h1a] <= 8'h43 ;
                    int_mem_o [8'h1b] <= 8'h44 ;
                    int_mem_o [8'h1c] <= 8'hc4 ;
                    int_mem_o [8'h1d] <= 8'hde ;
                    int_mem_o [8'h1e] <= 8'he9 ;
                    int_mem_o [8'h1f] <= 8'hcb ;
                    int_mem_o [8'h20] <= 8'h54 ;
                    int_mem_o [8'h21] <= 8'h7b ;
                    int_mem_o [8'h22] <= 8'h94 ;
                    int_mem_o [8'h23] <= 8'h32 ;
                    int_mem_o [8'h24] <= 8'ha6 ;
                    int_mem_o [8'h25] <= 8'hc2 ;
                    int_mem_o [8'h26] <= 8'h23 ;
                    int_mem_o [8'h27] <= 8'h3d ;
                    int_mem_o [8'h28] <= 8'hee ;
                    int_mem_o [8'h29] <= 8'h4c ;
                    int_mem_o [8'h2a] <= 8'h95 ;
                    int_mem_o [8'h2b] <= 8'h0b ;
                    int_mem_o [8'h2c] <= 8'h42 ;
                    int_mem_o [8'h2d] <= 8'hfa ;
                    int_mem_o [8'h2e] <= 8'hc3 ;
                    int_mem_o [8'h2f] <= 8'h4e ;
                    int_mem_o [8'h30] <= 8'h08 ;
                    int_mem_o [8'h31] <= 8'h2e ;
                    int_mem_o [8'h32] <= 8'ha1 ;
                    int_mem_o [8'h33] <= 8'h66 ;
                    int_mem_o [8'h34] <= 8'h28 ;
                    int_mem_o [8'h35] <= 8'hd9 ;
                    int_mem_o [8'h36] <= 8'h24 ;
                    int_mem_o [8'h37] <= 8'hb2 ;
                    int_mem_o [8'h38] <= 8'h76 ;
                    int_mem_o [8'h39] <= 8'h5b ;
                    int_mem_o [8'h3a] <= 8'ha2 ;
                    int_mem_o [8'h3b] <= 8'h49 ;
                    int_mem_o [8'h3c] <= 8'h6d ;
                    int_mem_o [8'h3d] <= 8'h8b ;
                    int_mem_o [8'h3e] <= 8'hd1 ;
                    int_mem_o [8'h3f] <= 8'h25 ;
                    int_mem_o [8'h40] <= 8'h72 ;
                    int_mem_o [8'h41] <= 8'hf8 ;
                    int_mem_o [8'h42] <= 8'hf6 ;
                    int_mem_o [8'h43] <= 8'h64 ;
                    int_mem_o [8'h44] <= 8'h86 ;
                    int_mem_o [8'h45] <= 8'h68 ;
                    int_mem_o [8'h46] <= 8'h98 ;
                    int_mem_o [8'h47] <= 8'h16 ;
                    int_mem_o [8'h48] <= 8'hd4 ;
                    int_mem_o [8'h49] <= 8'ha4 ;
                    int_mem_o [8'h4a] <= 8'h5c ;
                    int_mem_o [8'h4b] <= 8'hcc ;
                    int_mem_o [8'h4c] <= 8'h5d ;
                    int_mem_o [8'h4d] <= 8'h65 ;
                    int_mem_o [8'h4e] <= 8'hb6 ;
                    int_mem_o [8'h4f] <= 8'h92 ;
                    int_mem_o [8'h50] <= 8'h6c ;
                    int_mem_o [8'h51] <= 8'h70 ;
                    int_mem_o [8'h52] <= 8'h48 ;
                    int_mem_o [8'h53] <= 8'h50 ;
                    int_mem_o [8'h54] <= 8'hfd ;
                    int_mem_o [8'h55] <= 8'hed ;
                    int_mem_o [8'h56] <= 8'hb9 ;
                    int_mem_o [8'h57] <= 8'hda ;
                    int_mem_o [8'h58] <= 8'h5e ;
                    int_mem_o [8'h59] <= 8'h15 ;
                    int_mem_o [8'h5a] <= 8'h46 ;
                    int_mem_o [8'h5b] <= 8'h57 ;
                    int_mem_o [8'h5c] <= 8'ha7 ;
                    int_mem_o [8'h5d] <= 8'h8d ;
                    int_mem_o [8'h5e] <= 8'h9d ;
                    int_mem_o [8'h5f] <= 8'h84 ;
                    int_mem_o [8'h60] <= 8'h90 ;
                    int_mem_o [8'h61] <= 8'hd8 ;
                    int_mem_o [8'h62] <= 8'hab ;
                    int_mem_o [8'h63] <= 8'h00 ;
                    int_mem_o [8'h64] <= 8'h8c ;
                    int_mem_o [8'h65] <= 8'hbc ;
                    int_mem_o [8'h66] <= 8'hd3 ;
                    int_mem_o [8'h67] <= 8'h0a ;
                    int_mem_o [8'h68] <= 8'hf7 ;
                    int_mem_o [8'h69] <= 8'he4 ;
                    int_mem_o [8'h6a] <= 8'h58 ;
                    int_mem_o [8'h6b] <= 8'h05 ;
                    int_mem_o [8'h6c] <= 8'hb8 ;
                    int_mem_o [8'h6d] <= 8'hb3 ;
                    int_mem_o [8'h6e] <= 8'h45 ;
                    int_mem_o [8'h6f] <= 8'h06 ;
                    int_mem_o [8'h70] <= 8'hd0 ;
                    int_mem_o [8'h71] <= 8'h2c ;
                    int_mem_o [8'h72] <= 8'h1e ;
                    int_mem_o [8'h73] <= 8'h8f ;
                    int_mem_o [8'h74] <= 8'hca ;
                    int_mem_o [8'h75] <= 8'h3f ;
                    int_mem_o [8'h76] <= 8'h0f ;
                    int_mem_o [8'h77] <= 8'h02 ;
                    int_mem_o [8'h78] <= 8'hc1 ;
                    int_mem_o [8'h79] <= 8'haf ;
                    int_mem_o [8'h7a] <= 8'hbd ;
                    int_mem_o [8'h7b] <= 8'h03 ;
                    int_mem_o [8'h7c] <= 8'h01 ;
                    int_mem_o [8'h7d] <= 8'h13 ;
                    int_mem_o [8'h7e] <= 8'h8a ;
                    int_mem_o [8'h7f] <= 8'h6b ;
                    int_mem_o [8'h80] <= 8'h3a ;
                    int_mem_o [8'h81] <= 8'h91 ;
                    int_mem_o [8'h82] <= 8'h11 ;
                    int_mem_o [8'h83] <= 8'h41 ;
                    int_mem_o [8'h84] <= 8'h4f ;
                    int_mem_o [8'h85] <= 8'h67 ;
                    int_mem_o [8'h86] <= 8'hdc ;
                    int_mem_o [8'h87] <= 8'hea ;
                    int_mem_o [8'h88] <= 8'h97 ;
                    int_mem_o [8'h89] <= 8'hf2 ;
                    int_mem_o [8'h8a] <= 8'hcf ;
                    int_mem_o [8'h8b] <= 8'hce ;
                    int_mem_o [8'h8c] <= 8'hf0 ;
                    int_mem_o [8'h8d] <= 8'hb4 ;
                    int_mem_o [8'h8e] <= 8'he6 ;
                    int_mem_o [8'h8f] <= 8'h73 ;
                    int_mem_o [8'h90] <= 8'h96 ;
                    int_mem_o [8'h91] <= 8'hac ;
                    int_mem_o [8'h92] <= 8'h74 ;
                    int_mem_o [8'h93] <= 8'h22 ;
                    int_mem_o [8'h94] <= 8'he7 ;
                    int_mem_o [8'h95] <= 8'had ;
                    int_mem_o [8'h96] <= 8'h35 ;
                    int_mem_o [8'h97] <= 8'h85 ;
                    int_mem_o [8'h98] <= 8'he2 ;
                    int_mem_o [8'h99] <= 8'hf9 ;
                    int_mem_o [8'h9a] <= 8'h37 ;
                    int_mem_o [8'h9b] <= 8'he8 ;
                    int_mem_o [8'h9c] <= 8'h1c ;
                    int_mem_o [8'h9d] <= 8'h75 ;
                    int_mem_o [8'h9e] <= 8'hdf ;
                    int_mem_o [8'h9f] <= 8'h6e ;
                    int_mem_o [8'ha0] <= 8'h47 ;
                    int_mem_o [8'ha1] <= 8'hf1 ;
                    int_mem_o [8'ha2] <= 8'h1a ;
                    int_mem_o [8'ha3] <= 8'h71 ;
                    int_mem_o [8'ha4] <= 8'h1d ;
                    int_mem_o [8'ha5] <= 8'h29 ;
                    int_mem_o [8'ha6] <= 8'hc5 ;
                    int_mem_o [8'ha7] <= 8'h89 ;
                    int_mem_o [8'ha8] <= 8'h6f ;
                    int_mem_o [8'ha9] <= 8'hb7 ;
                    int_mem_o [8'haa] <= 8'h62 ;
                    int_mem_o [8'hab] <= 8'h0e ;
                    int_mem_o [8'hac] <= 8'haa ;
                    int_mem_o [8'had] <= 8'h18 ;
                    int_mem_o [8'hae] <= 8'hbe ;
                    int_mem_o [8'haf] <= 8'h1b ;
                    int_mem_o [8'hb0] <= 8'hfc ;
                    int_mem_o [8'hb1] <= 8'h56 ;
                    int_mem_o [8'hb2] <= 8'h3e ;
                    int_mem_o [8'hb3] <= 8'h4b ;
                    int_mem_o [8'hb4] <= 8'hc6 ;
                    int_mem_o [8'hb5] <= 8'hd2 ;
                    int_mem_o [8'hb6] <= 8'h79 ;
                    int_mem_o [8'hb7] <= 8'h20 ;
                    int_mem_o [8'hb8] <= 8'h9a ;
                    int_mem_o [8'hb9] <= 8'hdb ;
                    int_mem_o [8'hba] <= 8'hc0 ;
                    int_mem_o [8'hbb] <= 8'hfe ;
                    int_mem_o [8'hbc] <= 8'h78 ;
                    int_mem_o [8'hbd] <= 8'hcd ;
                    int_mem_o [8'hbe] <= 8'h5a ;
                    int_mem_o [8'hbf] <= 8'hf4 ;
                    int_mem_o [8'hc0] <= 8'h1f ;
                    int_mem_o [8'hc1] <= 8'hdd ;
                    int_mem_o [8'hc2] <= 8'ha8 ;
                    int_mem_o [8'hc3] <= 8'h33 ;
                    int_mem_o [8'hc4] <= 8'h88 ;
                    int_mem_o [8'hc5] <= 8'h07 ;
                    int_mem_o [8'hc6] <= 8'hc7 ;
                    int_mem_o [8'hc7] <= 8'h31 ;
                    int_mem_o [8'hc8] <= 8'hb1 ;
                    int_mem_o [8'hc9] <= 8'h12 ;
                    int_mem_o [8'hca] <= 8'h10 ;
                    int_mem_o [8'hcb] <= 8'h59 ;
                    int_mem_o [8'hcc] <= 8'h27 ;
                    int_mem_o [8'hcd] <= 8'h80 ;
                    int_mem_o [8'hce] <= 8'hec ;
                    int_mem_o [8'hcf] <= 8'h5f ;
                    int_mem_o [8'hd0] <= 8'h60 ;
                    int_mem_o [8'hd1] <= 8'h51 ;
                    int_mem_o [8'hd2] <= 8'h7f ;
                    int_mem_o [8'hd3] <= 8'ha9 ;
                    int_mem_o [8'hd4] <= 8'h19 ;
                    int_mem_o [8'hd5] <= 8'hb5 ;
                    int_mem_o [8'hd6] <= 8'h4a ;
                    int_mem_o [8'hd7] <= 8'h0d ;
                    int_mem_o [8'hd8] <= 8'h2d ;
                    int_mem_o [8'hd9] <= 8'he5 ;
                    int_mem_o [8'hda] <= 8'h7a ;
                    int_mem_o [8'hdb] <= 8'h9f ;
                    int_mem_o [8'hdc] <= 8'h93 ;
                    int_mem_o [8'hdd] <= 8'hc9 ;
                    int_mem_o [8'hde] <= 8'h9c ;
                    int_mem_o [8'hdf] <= 8'hef ;
                    int_mem_o [8'he0] <= 8'ha0 ;
                    int_mem_o [8'he1] <= 8'he0 ;
                    int_mem_o [8'he2] <= 8'h3b ;
                    int_mem_o [8'he3] <= 8'h4d ;
                    int_mem_o [8'he4] <= 8'hae ;
                    int_mem_o [8'he5] <= 8'h2a ;
                    int_mem_o [8'he6] <= 8'hf5 ;
                    int_mem_o [8'he7] <= 8'hb0 ;
                    int_mem_o [8'he8] <= 8'hc8 ;
                    int_mem_o [8'he9] <= 8'heb ;
                    int_mem_o [8'hea] <= 8'hbb ;
                    int_mem_o [8'heb] <= 8'h3c ;
                    int_mem_o [8'hec] <= 8'h83 ;
                    int_mem_o [8'hed] <= 8'h53 ;
                    int_mem_o [8'hee] <= 8'h99 ;
                    int_mem_o [8'hef] <= 8'h61 ;
                    int_mem_o [8'hf0] <= 8'h17 ;
                    int_mem_o [8'hf1] <= 8'h2b ;
                    int_mem_o [8'hf2] <= 8'h04 ;
                    int_mem_o [8'hf3] <= 8'h7e ;
                    int_mem_o [8'hf4] <= 8'hba ;
                    int_mem_o [8'hf5] <= 8'h77 ;
                    int_mem_o [8'hf6] <= 8'hd6 ;
                    int_mem_o [8'hf7] <= 8'h26 ;
                    int_mem_o [8'hf8] <= 8'he1 ;
                    int_mem_o [8'hf9] <= 8'h69 ;
                    int_mem_o [8'hfa] <= 8'h14 ;
                    int_mem_o [8'hfb] <= 8'h63 ;
                    int_mem_o [8'hfc] <= 8'h55 ;
                    int_mem_o [8'hfd] <= 8'h21 ;
                    int_mem_o [8'hfe] <= 8'h0c ;
                    int_mem_o [8'hff] <= 8'h7d ;
        end
		else begin
		mem_out= int_mem_o[addr];
		end
	end


endmodule	

最后,代码已全部上传完,全部拷贝下去,可以直接跑的。由于此代码多数都是时序逻辑,从开始加密到结束加密可能会有上千个时钟周期的延迟。如有不理解的欢迎留言咨询。

你可能感兴趣的:(算法,fpga开发)