SHA-256 해시함수를 구성하는 모듈 중 FF 모듈을 Verilog HDL 언어로 만들어보려 한다.
KISA에서 제공하는 SHA-256의 C코드의 FF 모듈과 기존 알고리즘을 활용한 FF 모듈을 만들 것이다.
KISA에서 만든 C코드에 대한 알고리즘에 대하여 알고싶다면 아래의 글↓을 참고하면 된다.
기존 알고리즘을 활용한 FF 모듈에 대해 알고싶다면 아래의 글↓을 참고하면 된다.
* r_sha245_k
해당 코드는 FF 모듈 안에서 i_count의 값에 따라 r_sha256_k의 값이 바뀌는 것을 나타낸 것이다.
(c코드에서는 배열로 구성됨)
always @(i_count) begin
case (i_count)
6'd0 : r_sha256_k = 32'h428a2f98;
6'd1 : r_sha256_k = 32'h71374491;
6'd2 : r_sha256_k = 32'hb5c0fbcf;
6'd3 : r_sha256_k = 32'he9b5dba5;
6'd4 : r_sha256_k = 32'h3956c25b;
6'd5 : r_sha256_k = 32'h59f111f1;
6'd6 : r_sha256_k = 32'h923f82a4;
6'd7 : r_sha256_k = 32'hab1c5ed5;
6'd8 : r_sha256_k = 32'hd807aa98;
6'd9 : r_sha256_k = 32'h12835b01;
6'd10 : r_sha256_k = 32'h243185be;
6'd11 : r_sha256_k = 32'h550c7dc3;
6'd12 : r_sha256_k = 32'h72be5d74;
6'd13 : r_sha256_k = 32'h80deb1fe;
6'd14 : r_sha256_k = 32'h9bdc06a7;
6'd15 : r_sha256_k = 32'hc19bf174;
6'd16 : r_sha256_k = 32'he49b69c1;
6'd17 : r_sha256_k = 32'hefbe4786;
6'd18 : r_sha256_k = 32'h0fc19dc6;
6'd19 : r_sha256_k = 32'h240ca1cc;
6'd20 : r_sha256_k = 32'h2de92c6f;
6'd21 : r_sha256_k = 32'h4a7484aa;
6'd22 : r_sha256_k = 32'h5cb0a9dc;
6'd23 : r_sha256_k = 32'h76f988da;
6'd24 : r_sha256_k = 32'h983e5152;
6'd25 : r_sha256_k = 32'ha831c66d;
6'd26 : r_sha256_k = 32'hb00327c8;
6'd27 : r_sha256_k = 32'hbf597fc7;
6'd28 : r_sha256_k = 32'hc6e00bf3;
6'd29 : r_sha256_k = 32'hd5a79147;
6'd30 : r_sha256_k = 32'h06ca6351;
6'd31 : r_sha256_k = 32'h14292967;
6'd32 : r_sha256_k = 32'h27b70a85;
6'd33 : r_sha256_k = 32'h2e1b2138;
6'd34 : r_sha256_k = 32'h4d2c6dfc;
6'd35 : r_sha256_k = 32'h53380d13;
6'd36 : r_sha256_k = 32'h650a7354;
6'd37 : r_sha256_k = 32'h766a0abb;
6'd38 : r_sha256_k = 32'h81c2c92e;
6'd39 : r_sha256_k = 32'h92722c85;
6'd40 : r_sha256_k = 32'ha2bfe8a1;
6'd41 : r_sha256_k = 32'ha81a664b;
6'd42 : r_sha256_k = 32'hc24b8b70;
6'd43 : r_sha256_k = 32'hc76c51a3;
6'd44 : r_sha256_k = 32'hd192e819;
6'd45 : r_sha256_k = 32'hd6990624;
6'd46 : r_sha256_k = 32'hf40e3585;
6'd47 : r_sha256_k = 32'h106aa070;
6'd48 : r_sha256_k = 32'h19a4c116;
6'd49 : r_sha256_k = 32'h1e376c08;
6'd50 : r_sha256_k = 32'h2748774c;
6'd51 : r_sha256_k = 32'h34b0bcb5;
6'd52 : r_sha256_k = 32'h391c0cb3;
6'd53 : r_sha256_k = 32'h4ed8aa4a;
6'd54 : r_sha256_k = 32'h5b9cca4f;
6'd55 : r_sha256_k = 32'h682e6ff3;
6'd56 : r_sha256_k = 32'h748f82ee;
6'd57 : r_sha256_k = 32'h78a5636f;
6'd58 : r_sha256_k = 32'h84c87814;
6'd59 : r_sha256_k = 32'h8cc70208;
6'd60 : r_sha256_k = 32'h90befffa;
6'd61 : r_sha256_k = 32'ha4506ceb;
6'd62 : r_sha256_k = 32'hbef9a3f7;
6'd63 : r_sha256_k = 32'hc67178f2;
endcase
end
* KISA 제공 코드 기반 FF 모듈 RTL
module ff (
input wire [32*8-1:0] i_hgfedcba, // 256-bit (each data = 32-bit)
input wire [31:0] i_x,
input wire [5:0] i_count, // = j
output wire [32*8-1:0] o_hgfedcba
);
// ***** local register definition *****
reg [31:0] r_sha256_k;
// ***** local wire definition *****
wire [31:0] w_cal_sig1;
wire [31:0] w_cal_ch;
wire [31:0] w_cal_sig0;
wire [31:0] w_cal_maj;
wire [31:0] w_a;
wire [31:0] w_b;
wire [31:0] w_c;
wire [31:0] w_d0, w_d1; // d0:input, d1:output
wire [31:0] w_e;
wire [31:0] w_f;
wire [31:0] w_g;
wire [31:0] w_h0, w_h1; // h0:input, h1:output
wire [31:0] w_t1;
assign o_hgfedcba = { w_h1, w_g, w_f, w_e, w_d1, w_c, w_b, w_a };
assign w_a = i_hgfedcba[32*1-1:32*0];
assign w_b = i_hgfedcba[32*2-1:32*1];
assign w_c = i_hgfedcba[32*3-1:32*2];
assign w_d0 = i_hgfedcba[32*4-1:32*3];
assign w_e = i_hgfedcba[32*5-1:32*4];
assign w_f = i_hgfedcba[32*6-1:32*5];
assign w_g = i_hgfedcba[32*7-1:32*6];
assign w_h0 = i_hgfedcba[32*8-1:32*7];
assign w_t1 = w_h0 + w_cal_sig1 + w_cal_ch + r_sha256_k + i_x;
assign w_d1 = w_d0 + w_t1;
assign w_h1 = w_t1 + w_cal_sig0 + w_cal_maj;
////////////////////////////////////////////////////////////////////////////////
// ***** Instantiate the design module *****
sigma1 U0_SIGMA1 (
.i_x ( w_e ),
.o_x ( w_cal_sig1 )
);
ch U1_CH (
.i_x ( w_e ),
.i_y ( w_f ),
.i_z ( w_g ),
.o_data ( w_cal_ch )
);
sigma0 U2_SIGMA0 (
.i_x ( w_a ),
.o_x ( w_cal_sig0 )
);
maj U3_MAJ (
.i_x ( w_a ),
.i_y ( w_b ),
.i_z ( w_c ),
.o_data ( w_cal_maj )
);
////////////////////////////////////////////////////////////////////////////////
// sha256_k[j]
// 코드 생략
endmodule
* 기존 알고리즘 기반 FF 모듈
(위의 c코드는 직접 구현한 후 검증해보았습니다.)
module ff (
input wire [32*8-1:0] i_hgfedcba, // 256-bit (each data = 32-bit)
input wire [31:0] i_x,
input wire [5:0] i_count, // = j
output wire [32*8-1:0] o_hgfedcba
);
// ***** local register definition *****
reg [31:0] r_sha256_k;
// ***** local wire definition *****
wire [31:0] w_cal_sig1;
wire [31:0] w_cal_ch;
wire [31:0] w_cal_sig0;
wire [31:0] w_cal_maj;
wire [31:0] w_a0, w_a1;
wire [31:0] w_b0, w_b1;
wire [31:0] w_c0, w_c1;
wire [31:0] w_d0, w_d1; // d0:input, d1:output
wire [31:0] w_e0, w_e1;
wire [31:0] w_f0, w_f1;
wire [31:0] w_g0, w_g1;
wire [31:0] w_h0, w_h1; // h0:input, h1:output
wire [31:0] w_t1;
wire [31:0] w_t2;
assign o_hgfedcba = { w_h1, w_g1, w_f1, w_e1, w_d1, w_c1, w_b1, w_a1 };
assign w_a0 = i_hgfedcba[32*1-1:32*0];
assign w_b0 = i_hgfedcba[32*2-1:32*1];
assign w_c0 = i_hgfedcba[32*3-1:32*2];
assign w_d0 = i_hgfedcba[32*4-1:32*3];
assign w_e0 = i_hgfedcba[32*5-1:32*4];
assign w_f0 = i_hgfedcba[32*6-1:32*5];
assign w_g0 = i_hgfedcba[32*7-1:32*6];
assign w_h0 = i_hgfedcba[32*8-1:32*7];
assign w_t1 = w_h0 + w_cal_sig1 + w_cal_ch + r_sha256_k + i_x;
assign w_t2 = w_cal_sig0 + w_cal_maj;
assign w_h1 = w_g0;
assign w_g1 = w_f0;
assign w_f1 = w_e0;
assign w_e1 = w_d0 + w_t1;
assign w_d1 = w_c0;
assign w_c1 = w_b0;
assign w_b1 = w_a0;
assign w_a1 = w_t1 + w_t2;
////////////////////////////////////////////////////////////////////////////////
// ***** Instantiate the design module *****
sigma1 U0_SIGMA1 (
.i_x ( w_e0 ),
.o_x ( w_cal_sig1 )
);
ch U1_CH (
.i_x ( w_e0 ),
.i_y ( w_f0 ),
.i_z ( w_g0 ),
.o_data ( w_cal_ch )
);
sigma0 U2_SIGMA0 (
.i_x ( w_a0 ),
.o_x ( w_cal_sig0 )
);
maj U3_MAJ (
.i_x ( w_a0 ),
.i_y ( w_b0 ),
.i_z ( w_c0 ),
.o_data ( w_cal_maj )
);
////////////////////////////////////////////////////////////////////////////////
// sha256_k[j]
// 코드 생략
endmodule
* TestBench
`timescale 1ns/1ps
module tb_ff;
reg [32*8-1:0] i_hgfedcba; // 256-bit (each data = 32-bit)
reg [31:0] i_x;
reg [5:0] i_count; // = j
wire [32*8-1:0] o_hgfedcba;
ff U0_FF (
.i_hgfedcba ( i_hgfedcba ),
.i_x ( i_x ),
.i_count ( i_count ),
.o_hgfedcba ( o_hgfedcba )
);
// verify vaule
wire [32*8-1:0] verify_plain = 'h5be0cd19_1f83d9ab_9b05688c_510e527f_a54ff53a_3c6ef372_bb67ae85_6a09e667;
wire [32*8-1:0] verify_res = 'h1f83d9ab_9b05688c_510e527f_c8f812d2_3c6ef372_bb67ae85_6a09e667_2c38b87d;
// Generate inputs
initial begin
i_hgfedcba = 'h5be0cd19_1f83d9ab_9b05688c_510e527f_a54ff53a_3c6ef372_bb67ae85_6a09e667;
i_x = "00000000";
i_count = 'd0;
#(50);
$finish;
end
initial begin
#(1);
$display("--PLAIN--");
if(i_hgfedcba == verify_plain)
$display("Correct~!!");
else
$display("Incorrect...");
$display("--RESULT--");
if(o_hgfedcba == verify_res)
$display("Correct~!!");
else
$display("Incorrect...");
$display("i_hgfedcba = %h", i_hgfedcba);
$display("o_hgfedcba = %h", o_hgfedcba);
end
endmodule
출력 결과
- 참고 -
'Hardware Security' 카테고리의 다른 글
FF 구성 모듈 (0) | 2022.02.17 |
---|---|
[SHA256] FF() 구성 모듈 - (1): RR, Sigma0, Sigma1 (0) | 2022.02.04 |
RR(Rotate Right) (0) | 2022.02.04 |
[SHA256][Verilog HDL] 코드 만들기 (0) | 2021.11.18 |