基於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