반응형
  • 숨쉬는 공부방
    • Security
      • SHA
    • Hardware Security
    • Verilog HDL
    • ─── ✿ ───
      • IT
      • 이것저것

블로그 메뉴

  • 홈
  • 모든 글
  • 방명록

인기 글

최근 글

태그

  • SHA256
  • Modelsim
  • 순차회로
  • KISA
  • SHA-256
  • C코드
  • FSM
  • 설계
  • Verilog
  • 조합회로

hELLO · Designed By 정상우.
숨.
Hardware Security

[SHA256] FF 모듈

[SHA256] FF 모듈
Hardware Security

[SHA256] FF 모듈

2022. 2. 23. 11:23

SHA-256 해시함수를 구성하는 모듈 중 FF 모듈을 Verilog HDL 언어로 만들어보려 한다.

KISA에서 제공하는 SHA-256의 C코드의 FF 모듈과 기존 알고리즘을 활용한 FF 모듈을 만들 것이다.

 

KISA에서 만든 C코드에 대한 알고리즘에 대하여 알고싶다면 아래의 글↓을 참고하면 된다.

 

[SHA-256] 코드 및 알고리즘 분석 - (4)

이제 소스 코드를 분석하는 마지막 글이다. SHA-256 함수의 가장 핵심적인 부분이라고 말할 수 있는 SHA-Transform() 함수를 분석하겠다. (전체 코드는 KSIA에서 다운로드할 수 있습니다.) 1. 매크로(define

s00m.tistory.com

 

기존 알고리즘을 활용한 FF 모듈에 대해 알고싶다면 아래의 글↓을 참고하면 된다.

 

[SHA-256] 코드 및 알고리즘 분석 - (5)

SHA256_Transform() 함수의 알고리즘에 대해서 이전 포스팅에서 분석하였다. 이번에는 FIPS-180 문서를 통해 더욱 자세히 분석해보려 한다. 먼저 알아둘 것이 있다면 for문을 제외하고는 알고리즘 모양

s00m.tistory.com

 


* 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

 

 


출력 결과

verilog HDL 코드 실행
c 코드 실행 결과

 

 


- 참고 -

 

'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
    'Hardware Security' 카테고리의 다른 글
    • FF 구성 모듈
    • [SHA256] FF() 구성 모듈 - (1): RR, Sigma0, Sigma1
    • RR(Rotate Right)
    • [SHA256][Verilog HDL] 코드 만들기
    숨.
    숨.

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.