1、sha-1算法
SHA1是一种密码散列函数,主要适用于数字签名标准里面定义的数字签名算法。对于长度小于2^64位的消息,SHA1会产生一个160位的消息摘要。当接收到消息的时候,这个消息摘要可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产生不同的消息摘要,
1 | sha1算法流程 |
1.1 消息填充
对于任意长度的明文,首先需要对明文添加位数,使明文总长度为对 512 取模为 448 位。在明文后的第一个添加位是 1 ,其余都是 0 。然后将原始明文的长度以64位表示,附加于前面已添加过位的明文后,此时的明文长度正好是512位的倍数。明文长度从低位开始填充。
1 | 原始消息 01100001 01100010 01100011 |
1.2 分组与扩展
经过添加位数处理的明文,其长度正好为512位的整数倍,然后按512位的长度进行分组(block),可以划分成L份明文分组,用Y0,Y1,……YL-1表示这些明文分组。对于每个512位的明文分组,将其再分成16份子明文分组(sub-block),每份子明文分组为32位,用M[k](k=0,1,...,15)表示。之后将这16份子明文分组扩充到80份子明文分组,记为W[t](t=0,1,...,79),扩充的方法如下。
1.3 摘要运算
1 | H0 = 0x67452301 |
其中ft为逻辑公式,Kt为常数
2、硬件设计
2.1 整体

| 信号 | 输入/输出 |
|---|---|
| clk | 输入 |
| rst_n | 输入 |
| data_in[63:0] | 输入 |
| valid_in | 输入 |
| hash[159:0] | 输出 |
| valid_out | 输出 |
| in_ready | 输出 |

2.2 消息填充
消息填充分为以下几种情况
1 | 原始消息 1000000 length |
| 信号 | 输入 / 输出 |
|---|---|
| data_in[63:0] | 输入 |
| valid_in | 输入 |
| out_ready | 输入 |
| valid_out | 输出 |
| data_pad[63:0] | 输出 |
| last_block | 输出 |

2.3 摘要计算
| 信号 | 输入 / 输出 |
|---|---|
| data_in[63:0] | 输入 |
| valid_in | 输入 |
| last_block | 输入 |
| in_ready | 输出 |
| pad_in_ready, | 输出 |
| hash[159:0] | 输出 |
| valid_out | 输出 |

3、验证
主要验证不同长度的消息能否正常计算摘要信息
1 | 63、64、65、127、128、129、447、448、449、511、512、513、1023、1024、1025、2014、2048、2049、随机 |
4、遇到的报错
1 | UVM_FATAL /home/tools/synopsys/vcs/vcs-mx/O-2018.09-SP2/etc/uvm-1.2/base/uvm_phase.svh(1493) @ 9200: reporter [PH_TIMEOUT] Default timeout of 9200 hit, indicating a probable testbench issue |