1. 程式人生 > >基於FPGA的加密演算法設計

基於FPGA的加密演算法設計

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;

    [email protected](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