DSP

基于FPGA的加密算法设计

2019-07-13 18:24发布

1.设计描述
此设计为DES加密解密算法的FPGA实现,DES算法为密码体制中的对称密码体制,也被称为美国数据加密标准。明文按64位进行分组,密钥长度为64位,随后按照一系列置换和代替技术进行具体的加密算法。 输入为100MHz的时钟,复位信号。 输出为16位数据D[15:0]。 IP核:v4_dcm进行系统分频       输入时钟首先进行dcm分频为10MHz,再通过分频模块进一步分频为100K时钟,并以此为算法中数据处理的基准时钟。复位信号中对各寄存器值初始化,其中对data_in(加密模式下的明文或解密模式下的密文,64位)和密钥key(64位)赋初值,经过DES算法后产生data_out(加密模式下的密文或解密模式下的明文,64位)。将64位data_out分为8组赋给D的数据输出,同时按时钟循环赋给D控制输出,最终在实验箱8个数码管上显示,每个数码管表示8位输出,目的是验证在可综合以及仿真成功的条件下能够在真实环境中运行。 2.代码设计

2.1时钟模块

//main函数例化模块  系统时间分频 //dcm IP核 输入100MHz,输出10MHz     v4_dcm CLK_DIV_10M(     .CLKIN_IN(CLK),     .RST_IN(!rst_n),         .CLKDV_OUT(CLK_10M),         .CLKIN_IBUFG_OUT(),         .CLK0_OUT(),     .LOCKED_OUT(CLK_LOCKED)         ); //100k模块运行时间分频        wire CLK_100K;     parameter DIV_FACTOR = 100;         CLK_DIV CLK_DIV_100K (         .CLK_IN(CLK_10M),         .nRST(CLK_LOCKED),    .CLK_OUT(CLK_100K)     );     defparam CLK_DIV_100K.DIV_FACTOR =DIV_FACTOR;     wire   nRST_USER;     assign nRST_USER= CLK_LOCKED;      //时钟分频模块 moduleCLK_DIV(CLK_IN, nRST, CLK_OUT);     input CLK_IN;     input nRST;     output CLK_OUT;         reg CLK_OUT = 1'b1;     reg [9:0] DIV_counter = 10'h000;       parameter DIV_FACTOR = 1;         always@(posedge CLK_IN)      begin        if(!nRST)         begin            CLK_OUT <= 1'b1;            DIV_counter<= 10'h000;         end        else         begin            if(DIV_counter != DIV_FACTOR >>1)             begin               DIV_counter <= DIV_counter + 1;             end            else             begin               DIV_counter <= 10'h000;               CLK_OUT <= !CLK_OUT;             end         end      end endmodule 2.2 置换函数
2'b01:     //明文初始置换(IP)               begin                   data_temp <={data_in[6],data_in[14],data_in[22],data_in[30],data_in[38],data_in[46],data_in[54],data_in[62],                   data_in[4],data_in[12],data_in[20],data_in[28],data_in[36],data_in[44],data_in[52],data_in[60],                   data_in[2],data_in[10],data_in[18],data_in[26],data_in[34],data_in[42],data_in[50],data_in[58],                   data_in[0],data_in[8],data_in[16],data_in[24],data_in[32],data_in[40],data_in[48],data_in[56],                   data_in[7],data_in[15],data_in[23],data_in[31],data_in[39],data_in[47],data_in[55],data_in[63],                   data_in[5],data_in[13],data_in[21],data_in[29],data_in[37],data_in[45],data_in[53],data_in[61],                   data_in[3],data_in[11],data_in[19],data_in[27],data_in[35],data_in[43],data_in[51],data_in[59],                   data_in[1],data_in[9],data_in[17],data_in[25],data_in[33],data_in[41],data_in[49],data_in[57]};                   step_counter <=step_counter+1;                  end   //每一轮加密算法实现 case(round_counter) 4'h0:      //第一轮加密     begin        case(inter_counter)        4'h0: //将数据分为左右两部分 各32位        begin            data_L <= data_temp[63:32];            data_R <= data_temp[31:0];            inter_counter <= inter_counter+1;        end        4'h1: //将本轮右半部数据赋值给下一轮左半部        begin            data_temp[63:32] <= data_R;            inter_counter <= inter_counter+1;        end        4'h2:  //扩展置换        begin     // 32>48            extend <={data_R[0],data_R[31],data_R[30],data_R[29],data_R[28],data_R[27],                              data_R[28],data_R[27],data_R[26],data_R[25],data_R[24],data_R[23],                              data_R[24],data_R[23],data_R[22],data_R[21],data_R[20],data_R[19],                              data_R[20],data_R[19],data_R[18],data_R[17],data_R[16],data_R[15],                              data_R[16],data_R[15],data_R[14],data_R[13],data_R[12],data_R[11],                              data_R[12],data_R[11],data_R[10],data_R[9],data_R[8],data_R[7],                             data_R[8],data_R[7],data_R[6],data_R[5],data_R[4],data_R[3],                              data_R[4],data_R[3],data_R[2],data_R[1],data_R[0],data_R[31]};                          inter_counter <=inter_counter+1;        end        4'h3: //和子密钥异或        begin            case(model)            1'b0:                extend<= extend ^ sub_key[0];            1'b1:                extend <= extend ^ sub_key[15];            endcase            inter_counter<= inter_counter+1;        end        4'h4: //S盒代替选择        begin     //S盒 48>32               end 4'hC: //置换函数P          begin            data_R <={data_S[16],data_S[25],data_S[12],data_S[11],data_S[3],data_S[20],data_S[4],data_S[15],                              data_S[31],data_S[17],data_S[9],data_S[6],data_S[27],data_S[14],data_S[1],data_S[22],                              data_S[30],data_S[24],data_S[8],data_S[18],data_S[0],data_S[5],data_S[29],data_S[23],                            data_S[13],data_S[19],data_S[2],data_S[26],data_S[10],data_S[21],data_S[28],data_S[7]};            inter_counter <= inter_counter+1;        end        4'hD: //和左半部异或        begin            data_temp[31:0] <= data_L ^data_R;            inter_counter <= 4'h0;            round_counter <= round_counter+1;        end        endcase     end 2.3 数码管显示 case(round_counter)            4'h0:        begin           select <= 8'hFE;     //数码管控制引脚            data<= data_out[7:0]; //数码管数据引脚            round_counter<= round_counter+1;        end        4'h1:        begin           select <= 8'hFD;           data <= data_out[63:56];           round_counter <= round_counter+1;        end            4'h2:        begin           select <= 8'hFB;           data <= data_out[55:48];           round_counter <= round_counter+1;        end        4'h3:        begin           select <= 8'hF7;           data <= data_out[47:40];           round_counter <= round_counter+1;        end        4'h4:        begin            select<= 8'hEF;            data<= data_out[39:32];            round_counter<= round_counter+1;        end        4'h5:        begin            select<= 8'hDF;           data <= data_out[31:24];            round_counter<= round_counter+1;        end        4'h6:        begin            select<= 8'hBF;            data<= data_out[23:16];            round_counter<= round_counter+1;        end        4'h7:        begin            select<= 8'h7F;            data<= data_out[15:8];            round_counter<= 0;        en        default:            round_counter<= round_counter;    endcase