当前位置:   article > 正文

SM3哈希算法的FPGA实现 II_fpga 哈希算法

fpga 哈希算法

SM3哈希算法的FPGA实现 II

语言 :verilog
仿真工具: Modelsim
EDA工具:quartus II

一、引言

上篇博客写了SM3哈希算法的解释和具体算法的实现步骤,
分为 :1.填充 2.迭代与压缩 3.计算拼凑值
这节博客来具体说怎么使用FPGA实现SM3哈希算法。

二、SM3哈希算法的FPGA实现

2.1 填充模块的FPGA实现
module msg_padding
#(
	parameter	WIDTH = 32
)
	(
		clk_in,
		reset_n_in,
		SM3_en_in,
		padding_en_in,
		msg_in,
		msg_valid_in,
		is_last_word_in,
		last_word_byte_in,
		is_1st_msg_block_out,
		msg_padded_out,
		padding_1_block_finished_out,
		padding_all_finished_out
	);
	
`define		IDLE					5'd0
`define		DIRECT_PASS				5'd1
`define		CASE1					5'd2
`define		CASE2_2B00				5'd3
`define		CASE2_2B01				5'd4
`define		CASE2_2B10				5'd5
`define		CASE2_2B11				5'd6
`define		CASE2_2B11_S			5'd7
`define		CASE3_2B00				5'd8
`define		CASE3_2B01				5'd9
`define		CASE3_2B10				5'd10
`define		CASE3_2B11				5'd11
`define		CASE3_2B11_S			5'd12
`define		SPECIAL_ALL_ZERO		5'd13
`define		CASE4_2B11_S			5'd14
`define		SPECIAL_80_ZERO			5'd15
`define		FINISH_GENERAL			5'd16
`define		FINISH_SPECIAL_ALL_ZERO	5'd17	
`define		FINISH_80_ZERO			5'd18

input					clk_in,
						reset_n_in,
						SM3_en_in,
						padding_en_in;		
input	[WIDTH - 1 : 0]	msg_in;				
input					msg_valid_in;		
input					is_last_word_in;	
input	[1:0]			last_word_byte_in;	//2'b00, |X|0|0|0|; 
											//2'b01, |X|X|0|0|;
											//2'b10, |X|X|X|0|;
											//2'b11, |X|X|X|X|
output	[511:0]			msg_padded_out;		
output					padding_1_block_finished_out;
output					padding_all_finished_out;
output					is_1st_msg_block_out;

reg		[4:0]			current_state,
						next_state;				
reg		[511:0]			msg_padded_out;
reg		[31:0]			tmp_0,
						tmp_1,
						tmp_2,
						tmp_3,
						tmp_4,
						tmp_5,
						tmp_6,
						tmp_7,
						tmp_8,
						tmp_9,
						tmp_a,
						tmp_b,
						tmp_c,
						tmp_d,
						tmp_e,
						tmp_f;
reg		[3:0]			count;
reg						count_enable;
reg		[8:0]			bit_count;
reg		[54:0]			block_count;
reg		[31:0]			next_input_data;
reg						padding_1_block_finished_out;
reg						padding_all_finished_out;
wire	[511:0]			data_concatenation;
reg		[63:0]			msg_length;
reg						special_zero;		
reg						special_80;		

assign	is_1st_msg_block_out = block_count == 'd0; 
	
assign	data_concatenation	=	{
									tmp_0,
									tmp_1,
									tmp_2,
									tmp_3,
									tmp_4,
									tmp_5,
									tmp_6,
									tmp_7,
									tmp_8,
									tmp_9,
									tmp_a,
									tmp_b,
									tmp_c,
									tmp_d,
									tmp_e,
									tmp_f
								};
								
always@(*)
	if(current_state == `FINISH_GENERAL ||
		special_zero ||
		special_80)
		msg_length = {block_count,9'd0} +  {55'b0,bit_count};
	else
		msg_length = 'd0;

reg						reg_msg_valid;
wire					valid_data_start;
reg						reg_is_last_word;
reg		[1:0]			reg_last_word_byte;
						
always@(posedge clk_in)
	if(!reset_n_in)
		reg_msg_valid	<=	'd0;
	else 
		reg_msg_valid	<=	msg_valid_in;
		
		
always@(posedge clk_in)
	if(!reset_n_in)
		reg_is_last_word	<=	'd0;
	else 
		reg_is_last_word	<=	is_last_word_in;
		

always@(posedge clk_in)
	if(!reset_n_in)
		reg_last_word_byte	<=	'd0;
	else 
		reg_last_word_byte	<=	last_word_byte_in;
		
		
assign	valid_data_start = reg_msg_valid == 1'b0 && msg_valid_in == 1'b1;
	
always@(posedge clk_in)
if(!reset_n_in)
	begin
		tmp_0	<=	32'd0;
		tmp_1	<=	32'd0;
		tmp_2	<=	32'd0;
		tmp_3	<=	32'd0;
		tmp_4	<=	32'd0;
		tmp_5	<=	32'd0;
		tmp_6	<=	32'd0;
		tmp_7	<=	32'd0;
		tmp_8	<=	32'd0;
		tmp_9	<=	32'd0;
		tmp_a	<=	32'd0;
		tmp_b	<=	32'd0;
		tmp_c	<=	32'd0;
		tmp_d	<=	32'd0;
        tmp_e	<=	32'd0;
        tmp_f	<=	32'd0;
    end
else if(count_enable)
	begin  
		case(count)
			4'h0:	tmp_0	<=	next_input_data;
			4'h1:	tmp_1	<=	next_input_data;
			4'h2:	tmp_2	<=	next_input_data;
			4'h3:	tmp_3	<=	next_input_data;
			4'h4:	tmp_4	<=	next_input_data;
			4'h5:	tmp_5	<=	next_input_data;
			4'h6:	tmp_6	<=	next_input_data;
			4'h7:	tmp_7	<=	next_input_data;
			4'h8:	tmp_8	<=	next_input_data;
			4'h9:	tmp_9	<=	next_input_data;
			4'ha:	tmp_a	<=	next_input_data;
			4'hb:	tmp_b	<=	next_input_data;
			4'hc:	tmp_c	<=	next_input_data;
			4'hd:	tmp_d	<=	next_input_data;
			4'he:	tmp_e	<=	next_input_data;
			4'hf:	tmp_f	<=	next_input_data;
		endcase
	end
else
	begin
		tmp_0	<=	tmp_0;
	    tmp_1	<=  tmp_1;
	    tmp_2	<=  tmp_2;
	    tmp_3	<=  tmp_3;
	    tmp_4	<=  tmp_4;
	    tmp_5	<=  tmp_5;
	    tmp_6	<=  tmp_6;
	    tmp_7	<=  tmp_7;
	    tmp_8	<=  tmp_8;
	    tmp_9	<=  tmp_9;
	    tmp_a	<=  tmp_a;
	    tmp_b	<=  tmp_b;
	    tmp_c	<=  tmp_c;
	    tmp_d	<=  tmp_d;
	    tmp_e	<=  tmp_e;
	    tmp_f	<=  tmp_f;
	end

always@(*)
if(padding_1_block_finished_out)
	begin
		if(current_state == `FINISH_GENERAL)
			msg_padded_out	=	{data_concatenation[511:64], msg_length};
		else if(special_zero)
			msg_padded_out	=	{448'd0, msg_length};		
		else if(special_80)
			msg_padded_out	=	{32'h8000_0000, 416'd0, msg_length};
		else
			msg_padded_out	=	data_concatenation;
	end
else
		msg_padded_out	=	'd0;
		
always@(posedge clk_in)
	if(!reset_n_in)
		count	<=	'd0;
	else if(count_enable)
		count	<=	count + 1'b1;			
	else
		count	<=	'd0;
		
reg		is_last_block;		
always@(posedge clk_in)
	if(!reset_n_in)
		is_last_block 	<=	1'b0;
	else if(reg_is_last_word)	
		is_last_block	<=	1'b1;
	else if(count == 'd15)
		is_last_block	<=	1'b0;
	else
		is_last_block	<=	is_last_block;
		
always@(posedge clk_in)
	if(!reset_n_in)
		block_count	<=	'd0;
	else if(count == 'd15 && !is_last_block)
		block_count	<=	block_count + 1'b1;
	else
		block_count	<=	block_count;
	
always@(posedge clk_in)
	if(!reset_n_in)
		bit_count	<=	'd0;
	else if(reg_is_last_word)
		bit_count	<=	{count, 5'd0} +  {4'd0,reg_last_word_byte,3'd0}+9'b0_0000_1000;
	else
		bit_count	<=	bit_count;
							

always@(posedge clk_in)					
	if(!reset_n_in)
		current_state	<=	`IDLE;
	else
		current_state	<=	next_state;
		
always@(*)
	begin	
		next_state	=	`IDLE;
		case(current_state)
			`IDLE:
					if(padding_en_in)
						next_state	=	`DIRECT_PASS;
					else
						next_state	=	`IDLE;
			`DIRECT_PASS:
					if(!reg_is_last_word && count == 'd15)	
						next_state	=	`CASE1;
					else if(reg_is_last_word && (count <'d13 || (count == 'd13 && reg_last_word_byte != 2'b11)))
						begin
							case(last_word_byte_in)
								2'b00:	next_state = `CASE2_2B00;
								2'b01:	next_state = `CASE2_2B01;
								2'b10:	next_state = `CASE2_2B10;
								2'b11:	next_state = `CASE2_2B11;
							endcase
						end
					else if(reg_is_last_word && ((count == 'd13 && reg_last_word_byte == 2'b11) ||
												 count == 'd14 ||
												 (count == 'd15 && reg_last_word_byte == 2'b00) ||
												 (count == 'd15 && reg_last_word_byte == 2'b01) ||
												 (count == 'd15 && reg_last_word_byte == 2'b10))
							)
						begin
							case(reg_last_word_byte)
								2'b00:	next_state = `CASE3_2B00;
								2'b01:	next_state = `CASE3_2B01;
								2'b10:	next_state = `CASE3_2B10;
								2'b11:	next_state = `CASE3_2B11;
							endcase
						end								
					else if(reg_is_last_word && count == 'd15 && reg_last_word_byte == 2'b11)
						next_state	=	`CASE4_2B11_S;
					else
						next_state = `DIRECT_PASS;
			`CASE1:
				next_state = `IDLE;
			
			`CASE2_2B00:
				if(count == 4'd15)
					next_state = `FINISH_GENERAL;
				else
					next_state = `CASE2_2B00;
					
			`CASE2_2B01:
				if(count == 4'd15)
					next_state = `FINISH_GENERAL;
				else
					next_state = `CASE2_2B01;
			`CASE2_2B10:
				if(count == 4'd15)
					next_state = `FINISH_GENERAL;
				else
					next_state = `CASE2_2B10;					
			`CASE2_2B11:
				next_state	=	`CASE2_2B11_S;
			
			`CASE2_2B11_S:
				if(count == 'd15)
					next_state = `FINISH_GENERAL;
				else
					next_state = `CASE2_2B11_S;					
			
			`CASE3_2B00:
				if(count == 'd15)
					next_state = `SPECIAL_ALL_ZERO;
				else
					next_state = `CASE3_2B00;					
			`CASE3_2B01:
				if(count == 'd15)
					next_state = `SPECIAL_ALL_ZERO;
				else
					next_state = `CASE3_2B01;
			`CASE3_2B10:
				if(count == 'd15)
					next_state = `SPECIAL_ALL_ZERO;
				else
					next_state = `CASE3_2B10;
					
			`CASE3_2B11:
					next_state = `CASE3_2B11_S;
					
			`CASE3_2B11_S:
				if(count == 'd15)
					next_state = `SPECIAL_ALL_ZERO;
				else
					next_state = `CASE3_2B11_S;	
					
			`CASE4_2B11_S:
					next_state = `SPECIAL_80_ZERO;
			
			`FINISH_GENERAL:
					next_state = `IDLE;
			
					
			`SPECIAL_ALL_ZERO:
					if(padding_en_in)
						next_state	=	`IDLE;
					else
						next_state	=	`SPECIAL_ALL_ZERO;
						
			`SPECIAL_80_ZERO:
					if(padding_en_in)
						next_state	=	`IDLE;
					else
						next_state	=	`SPECIAL_80_ZERO;
			default:
					next_state	=	`IDLE;
		endcase
	end

always@(posedge clk_in)	
	if(count == 'd15)
		padding_1_block_finished_out	<=	1'b1;
	else if(
				(current_state == `SPECIAL_ALL_ZERO && padding_en_in) ||
				(current_state == `SPECIAL_80_ZERO && padding_en_in) 
			)
		padding_1_block_finished_out	<=	1'b1;
	else
		padding_1_block_finished_out	<=	1'b0;	

	
	
always@(posedge clk_in)
	if(!reset_n_in)
		begin
			count_enable					<=	1'b0;
			next_input_data					<=	'd0;
			padding_all_finished_out		<=	1'b0;
			special_zero					<=	1'b0;
			special_80						<=	1'b0;
		end
	else
		begin			
			if(current_state == `SPECIAL_ALL_ZERO)	
				special_zero	<=	1'b1;
			else
				special_zero	<=	1'b0;
				
			if(current_state == `SPECIAL_80_ZERO)	
				special_80	<=	1'b1;
			else
				special_80	<=	1'b0;			
				
			if(current_state == `DIRECT_PASS  && msg_valid_in == 1'b1)
				count_enable	<=	1'b1;
			else if(count == 'd15
					)
				count_enable	<=	1'b0;
			else
				count_enable	<=	count_enable;

				
			case(current_state)
				`DIRECT_PASS:
								if(msg_valid_in && is_last_word_in && last_word_byte_in ==  2'b00)
									next_input_data	<=	{msg_in[31:24],8'h80, 16'h0};
								else if(msg_valid_in && is_last_word_in && last_word_byte_in ==  2'b01)
									next_input_data	<=	{msg_in[31:16],8'h80, 8'h0};
								else if(msg_valid_in && is_last_word_in && last_word_byte_in ==  2'b10)
									next_input_data	<=	{msg_in[31:8],8'h80};
								else
									next_input_data	<=	msg_in;
				`CASE2_2B11_S:	next_input_data	<=	32'h8000_0000;
				`CASE3_2B11_S:  next_input_data	<=	32'h8000_0000;
				default:		next_input_data	<=	msg_valid_in == 1'b1 ? msg_in : 'd0;
			endcase	
						
			if(
				(current_state == `CASE2_2B00 && next_state == `FINISH_GENERAL) ||
				(current_state == `CASE2_2B01 && next_state == `FINISH_GENERAL) ||
				(current_state == `CASE2_2B10 && next_state == `FINISH_GENERAL) ||
				(current_state == `CASE2_2B11_S && next_state == `FINISH_GENERAL) ||
				(current_state == `SPECIAL_ALL_ZERO && next_state == `IDLE) ||
				(current_state == `SPECIAL_80_ZERO && next_state == `IDLE)
			)
				padding_all_finished_out	<=	1'b1;
			else if(SM3_en_in == 1'b0)
				padding_all_finished_out	<=	1'b0;
			else
				padding_all_finished_out	<=	padding_all_finished_out;			
						
		end
		

		
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
2.2 消息扩展的FPGA实现
module msg_expansion
	(
		clk_in,
		reset_n_in,
		message_in,
		start_in,
		index_j_in,
		word_p_out,
		word_out,
		msg_exp_finished_out
	);
	
`define	IDLE	2'b00
`define	WORKING	2'b01

input				clk_in;
input				reset_n_in;	
input	[511 : 0]	message_in;			
input				start_in;		
input	[5:0]		index_j_in;		

output	reg[31 : 0]	word_p_out;			
output	reg[31 : 0]	word_out;			
output				msg_exp_finished_out;

reg					working_en;
reg					msg_exp_finished_out;
reg		[1:0]		current_state,
					next_state;
reg		[31 : 0]	w0;
reg		[31 : 0]	w1;
reg		[31 : 0]	w2;
reg		[31 : 0]	w3;
reg		[31 : 0]	w4;
reg		[31 : 0]	w5;
reg		[31 : 0]	w6;
reg		[31 : 0]	w7;
reg		[31 : 0]	w8;
reg		[31 : 0]	w9;
reg		[31 : 0]	w10;
reg		[31 : 0]	w11;
reg		[31 : 0]	w12;
reg		[31 : 0]	w13;
reg		[31 : 0]	w14;
reg		[31 : 0]	w15;

wire	[31 : 0]	tmp_shift_15;	
wire	[31 : 0]	tmp_shift_7;	
wire	[31 : 0]	data_for_p1;
wire	[31 : 0]	data_after_p1;
wire	[31 : 0]	word_update;

assign	tmp_shift_15	=	{w13[31-15:0], w13[31:31-15+1]};
assign	tmp_shift_7		=	{w3[31-7:0],   w3[31:31-7+1]};
assign	data_for_p1		=	w0 ^ w7 ^ tmp_shift_15;
assign	data_after_p1	=	data_for_p1 ^ {data_for_p1[31-15:0], data_for_p1[31:31-15+1]} ^ {data_for_p1[31-23:0], data_for_p1[31:31-23+1]};
assign	word_update		=	data_after_p1 ^ tmp_shift_7 ^ w10;


always@(posedge clk_in)
	if(!reset_n_in)
		{w0, w1,  w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15}	<=	512'd0;
	else if(start_in)
		{w0, w1,  w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15}	<=	message_in;
	else if(working_en)
		{w0, w1,  w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15}	<=	{w1,  w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15, word_update};
	else
		{w0, w1,  w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15}	<=	{w0, w1,  w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15};	


always@(posedge clk_in)
	if(!reset_n_in)
		begin
			word_p_out	<=	32'd0;
			word_out	<=	32'd0;
		end
	else if(working_en)
		begin
			word_p_out	<=	w0 ^ w4;
			word_out	<=	w0;
		end
	else
		begin
			word_p_out	<=	word_p_out;
			word_out	<=	word_out;
		end
	
	
	
always@(posedge clk_in)					
	if(!reset_n_in)
		current_state	<=	`IDLE;
	else
		current_state	<=	next_state;
		
always@(*)
	begin	
		next_state	=	`IDLE;
		case(current_state)
			`IDLE:
					if(start_in)
						next_state = `WORKING;
					else
						next_state = `IDLE;

			`WORKING:
					if(index_j_in == 'd63)
						next_state = `IDLE;
					else
						next_state = `WORKING;
			default:
					next_state = `IDLE;
		endcase
	end
	
always@(posedge clk_in)
	if(!reset_n_in)
		begin
			working_en				<=	1'b0;
			msg_exp_finished_out	<=	1'b0;
		end
	else 
		begin
			
			if(next_state == `WORKING)
				working_en <= 1'b1;
			else
				working_en	<=	1'b0;	
			
			if(current_state == `WORKING && next_state == `IDLE)
				msg_exp_finished_out	<=	'd1;
			else
				msg_exp_finished_out	<=	'd0;
		end
		
		
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
2.3 压缩函数模块的FPGA实现
module compression_function
	(
		clk_in,
		reset_n_in,
		start_in,
		index_j_in,
		is_1st_msg_block_in,
		word_expanded_p_in,
		word_expanded_in,		
		data_after_cf_out
	);
	
`define	IDLE	2'b00
`define	LOAD	2'b01
`define	WORKING	2'b10	
	
input					clk_in;
input					reset_n_in;
input					start_in;
input	[5  : 0]		index_j_in;
input	[31 : 0]		word_expanded_p_in;
input	[31 : 0]		word_expanded_in;
input					is_1st_msg_block_in;

output	reg[255: 0]		data_after_cf_out;
reg						msg_cf_finished;

reg		[31 : 0]	reg_a;
reg		[31 : 0]	reg_b;
reg		[31 : 0]	reg_c;
reg		[31 : 0]	reg_d;
reg		[31 : 0]	reg_e;
reg		[31 : 0]	reg_f;
reg		[31 : 0]	reg_g;
reg		[31 : 0]	reg_h;

wire	[31 : 0]	tmp_for_ss1_0;
wire	[31 : 0]	TJ;
wire	[5  : 0]	J_mod;
wire	[31 : 0]	tmp_for_ss1_1;
wire	[31 : 0]	tmp_for_ss1_2;
wire	[31 : 0]	ss1;
wire	[31 : 0]	ss2;
wire	[31 : 0]	tmp_for_tt1_0;
wire	[31 : 0]	tmp_for_tt1_1;
wire	[31 : 0]	tt1;
wire	[31 : 0]	tmp_for_tt2_0;
wire	[31 : 0]	tmp_for_tt2_1;
wire	[31 : 0]	tt2;
wire	[31 : 0]	tt2_after_p0;


wire	[255:0]		data;

reg		[1:0]		current_state,
					next_state;
reg					working_en;	
reg					load_en;		
wire	[31:0]		tmp_a,
					tmp_b,
					tmp_c,
					tmp_d,
					tmp_e,
					tmp_f,
					tmp_g,
					tmp_h;
reg					reg_is_1st_msg_block2;
reg					reg_is_1st_msg_block;


always@(posedge clk_in)					
	if(!reset_n_in)
		reg_is_1st_msg_block2	<= 1'b0;
	else
		reg_is_1st_msg_block2	<=	is_1st_msg_block_in;
		
		
always@(posedge clk_in)					
	if(!reset_n_in)
		reg_is_1st_msg_block	<= 1'b0;
	else
		reg_is_1st_msg_block	<=	reg_is_1st_msg_block2;
				

assign	tmp_for_ss1_0	=	{reg_a[31-12:0], reg_a[31:31-12+1]} + reg_e;
assign	TJ				=	index_j_in < 16 ? 32'h79cc4519  : 32'h7a879d8a;
assign	J_mod			=	index_j_in < 6'd32 ? index_j_in	:  index_j_in - 6'd32;
assign	tmp_for_ss1_2	=	tmp_for_ss1_0 + tmp_for_ss1_1;
assign	ss1				=	{tmp_for_ss1_2[31 - 7 : 0], tmp_for_ss1_2[31 : 31 - 7 + 1]};
assign	ss2				=	ss1 ^ {reg_a[31 - 12 : 0], reg_a[31 : 31 - 12 + 1]};
assign	tmp_for_tt1_0	=	index_j_in < 16 ? reg_a ^ reg_b ^ reg_c : (reg_a & reg_b | reg_a & reg_c | reg_b & reg_c);
assign	tmp_for_tt1_1	=	reg_d + ss2 + word_expanded_p_in;
assign	tt1				=	tmp_for_tt1_0 + tmp_for_tt1_1;
assign	tmp_for_tt2_0	=	index_j_in < 16 ? reg_e ^ reg_f ^ reg_g : (reg_e & reg_f | ~reg_e & reg_g);
assign	tmp_for_tt2_1	=	reg_h + ss1 + word_expanded_in;
assign	tt2				=	tmp_for_tt2_0 + tmp_for_tt2_1;
assign	tt2_after_p0	=	tt2 ^ {tt2[31-9:0], tt2[31:31-9+1]} ^ {tt2[31-17:0], tt2[31:31-17+1]};


assign	is_1st_data_block	=	load_en == 1'b1 && index_j_in == 'd0;
assign	data	=	is_1st_data_block 
					? data_after_cf_out 
					: {reg_a,reg_b,reg_c,reg_d,reg_e,reg_f,reg_g,reg_h};
					
assign	{tmp_a, tmp_b, tmp_c, tmp_d, tmp_e, tmp_f, tmp_g, tmp_h} = data;


always@(posedge clk_in)
	if(!reset_n_in)
		begin
			reg_a	<=	'd0;
			reg_b	<=	'd0;
			reg_c	<=	'd0;
			reg_d	<=	'd0;
			reg_e	<=	'd0;
			reg_f	<=	'd0;
			reg_g	<=	'd0;
			reg_h	<=	'd0;
		end
	else if(load_en && reg_is_1st_msg_block)
		begin
			reg_a	<=	32'h7380166f;
			reg_b	<=	32'h4914b2b9;
			reg_c	<=	32'h172442d7;
			reg_d	<=	32'hda8a0600;
			reg_e	<=	32'ha96f30bc;
			reg_f	<=	32'h163138aa;
			reg_g	<=	32'he38dee4d;
			reg_h	<=	32'hb0fb0e4e;		
		end
	else if(load_en &&!reg_is_1st_msg_block)
		begin
			reg_a	<=	tmp_a;
			reg_b	<=	tmp_b;
			reg_c	<=	tmp_c;
			reg_d	<=	tmp_d;
			reg_e	<=	tmp_e;
			reg_f	<=	tmp_f;
			reg_g	<=	tmp_g;
			reg_h	<=	tmp_h;
		end	
	else if(working_en)
		begin
			reg_d	<=	reg_c;
			reg_c	<=	{reg_b[31 - 9 : 0], reg_b[31 : 31 - 9 + 1]};
			reg_b 	<=	reg_a;
			reg_a	<=	tt1;
			reg_h	<=	reg_g;
			reg_g	<=	{reg_f[31 - 19 : 0], reg_f[31 : 31 - 19 + 1]};
			reg_f	<=	reg_e;
			reg_e	<=	tt2_after_p0;
		end
	else
		begin
			reg_a	<=	reg_a;
			reg_b	<=	reg_b;
			reg_c	<=	reg_c;
			reg_d	<=	reg_d;
			reg_e	<=	reg_e;
			reg_f	<=	reg_f;
			reg_g	<=	reg_g;
			reg_h	<=	reg_h;
		end			


always@(posedge clk_in)
	if(!reset_n_in)
		data_after_cf_out	<=	'd0;
	else if(is_1st_data_block && reg_is_1st_msg_block)
		data_after_cf_out	<=	{32'h7380166f, 32'h4914b2b9, 32'h172442d7, 32'hda8a0600, 32'ha96f30bc, 32'h163138aa, 32'he38dee4d, 32'hb0fb0e4e};
	else if(msg_cf_finished == 1'b1)
		data_after_cf_out	<=	{reg_a,reg_b,reg_c,reg_d,reg_e,reg_f,reg_g,reg_h} ^ data_after_cf_out;
	else
		data_after_cf_out	<=	data_after_cf_out;
		

barrel_shifter u_barrel_shifter
	(
		.data_in(TJ),
		.shift_number_in(J_mod[4:0]),
		.data_after_shift_out(tmp_for_ss1_1)
	);


always@(posedge clk_in)					
	if(!reset_n_in)
		current_state	<=	`IDLE;
	else
		current_state	<=	next_state;
		
always@(*)
	begin	
		next_state	=	`IDLE;
		case(current_state)
			`IDLE:
					if(start_in)
						next_state = `LOAD;
					else
						next_state = `IDLE;
			`LOAD:
					next_state = `WORKING;
					
			`WORKING:
					if(index_j_in == 'd63)
						next_state = `IDLE;
					else
						next_state = `WORKING;
			default:
					next_state = `IDLE;
		endcase
	end
	
always@(posedge clk_in)
	if(!reset_n_in)
		begin
			working_en				<=	1'b0;
			msg_cf_finished	<=	1'b0;
		end
	else 
		begin
			
			if(current_state == `IDLE && next_state == `LOAD)
				load_en	<=	1'b1;
			else
				load_en	<=	1'b0;
			
			if(next_state == `WORKING)
				working_en <= 1'b1;
			else
				working_en	<=	1'b0;	
			
			if(current_state == `WORKING && next_state == `IDLE)
				msg_cf_finished	<=	'd1;
			else
				msg_cf_finished	<=	'd0;
		end
		endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
2.4 顶层模块的FPGA实现
module SM3_top
	(
		clk_in,
		reset_n_in,
		SM3_en_in,
		msg_in,
		msg_valid_in,
		is_last_word_in,
		last_word_byte_in,
		sm3_result_out,
		sm3_finished_out
	);
	
`define		IDLE		2'b00
`define		PADDING		2'b01
`define		ITERATION	2'b10	

localparam	WIDTH = 32;	

input					clk_in,
						reset_n_in,
						SM3_en_in;
input	[WIDTH - 1 : 0]	msg_in;	
input					msg_valid_in;
input					is_last_word_in;	
input	[1:0]			last_word_byte_in;	
output	[255 : 0]		sm3_result_out;		
output					sm3_finished_out;	

reg						padding_en,
						iteration_en;
reg						sm3_finished_out;
reg		[1:0]			current_state,
						next_state;		
reg		[5:0]			index_j;
wire					padding_1_block_finished;
wire	[511:0]			msg_padded;
wire					padding_all_finished;
wire	[31:0]			word_expanded_p;
wire	[31:0]			word_expanded;
wire					msg_exp_finished;
reg						is_last_block;
wire					is_1st_msg_block;

always@(posedge clk_in)
	if(!reset_n_in)
		is_last_block 	<=	1'b0;
	else if(padding_all_finished)	
		is_last_block	<=	1'b1;
	else if(SM3_en_in == 1'b0)
		is_last_block	<=	1'b0;
	else
		is_last_block	<=	is_last_block;

always@(posedge clk_in)					
	if(!reset_n_in)
		current_state	<=	`IDLE;
	else
		current_state	<=	next_state;
		
always@(*)
	begin	
		next_state	=	`IDLE;
		case(current_state)
			`IDLE:
				if(SM3_en_in == 1'b1 && is_last_block != 1'b1)	
					next_state = `PADDING;
				else
					next_state = `IDLE;
			`PADDING:
				if(padding_1_block_finished)
					next_state = `ITERATION;
				else
					next_state = `PADDING;
			`ITERATION:
				if(msg_exp_finished)
					next_state = `IDLE;
				else
					next_state = `ITERATION;
			default:
					next_state = `IDLE;
		endcase
	end

always@(posedge clk_in)
	if(!reset_n_in)
		begin
			padding_en			<=	1'b0;
			iteration_en		<=	1'b0;
			sm3_finished_out	<=	1'b0;
		end
	else
		begin

			if(next_state == `PADDING)
				padding_en		<=	1'b1;
			else
				padding_en		<=	1'b0;
			
			if(current_state == `ITERATION)
				iteration_en	<=	1'b1;
			else
				iteration_en	<=	1'b0;
			
			if(current_state == `ITERATION && next_state == `IDLE && is_last_block ==  1'b1)
				sm3_finished_out	<=	1'b1;
			else
				sm3_finished_out	<=	1'b0;								
		end

always@(posedge clk_in)
	if(!reset_n_in)
		index_j	<=	'd0;
	else if(iteration_en)
		index_j	<=	index_j	+	1'b1;
	else
		index_j	<=	'd0;

msg_padding #(WIDTH) U_pad
	(
		.clk_in(						clk_in),
		.reset_n_in(					reset_n_in),
		.SM3_en_in(						SM3_en_in),
		.padding_en_in(					padding_en),
		.msg_in(						msg_in),
		.msg_valid_in(					msg_valid_in),
		.is_last_word_in(				is_last_word_in),
		.last_word_byte_in(				last_word_byte_in),
		.is_1st_msg_block_out(			is_1st_msg_block),
		.msg_padded_out(				msg_padded),
		.padding_1_block_finished_out(	padding_1_block_finished),
		.padding_all_finished_out(		padding_all_finished)
	);
	
msg_expansion U_exp
	(
		.clk_in(						clk_in),
		.reset_n_in(					reset_n_in),
		.start_in(						padding_1_block_finished),
		.index_j_in(					index_j),
		.message_in(					msg_padded),
		.word_p_out(					word_expanded_p),
		.word_out(						word_expanded),
		.msg_exp_finished_out(			msg_exp_finished)
	);	

compression_function U_cf
	(
		.clk_in(						clk_in),
		.reset_n_in(					reset_n_in),
		.start_in(						padding_1_block_finished),
		.index_j_in(					index_j),
		.is_1st_msg_block_in(			is_1st_msg_block),
		.word_expanded_p_in(			word_expanded_p),
		.word_expanded_in(				word_expanded),		
		.data_after_cf_out(				sm3_result_out)
	);	
	
 
		
endmodule	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161

3.3 SM3哈希算法的modelsim仿真

在这里插入图片描述
在这里插入图片描述
如上方框中代表的是 数据的输入 以及最后SM3哈希算法的输出

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/139534
推荐阅读
相关标签
  

闽ICP备14008679号