步骤三:初始化缓冲区,将8个32比特的信息摘要分别进行初始化,初始数据如图所示。(8个32比特拼起来为256bit,这些数据会经过运算,最终的结果就是哈希值)
步骤4:对这些数据进行处理:
- 将数据M分为512bit的block,M0,M1,...,Mj ,....
- 对Mj连续的进行处理,一个接一个的处理
- 输入有,��:消息的一部分,32bit的word; �� :常量数组;H0到H7,当前的数据摘要
- 输出为新的H0到H7即数据摘要
接下来就是连续的进行数据处理,最开始A~H存储的就是原始的数据摘要初始值。然后处理512bit的block共64次。首先进行W消息区块处理,经过区块处理得到这一轮参与运算的32bit的Wt。计算方式如图所示,这里不详细讲解了。大家可以参考这篇文章:
�� 常量如图所示,因为有64轮运算,所以 �� 数组有64个元素,对应不同的轮次。
t从0遍历到63,通过第t轮此时的��和 �� 的共同参与,我们持续更新A~H的数据
在计算完64轮以后,我们就得到了最后的数据。上面的运算看起来唬人,其实用代码实现没那么复杂。每一步干什么实际上是非常清晰的,只不过有很多的符号,比较容易劝退,大家认真分析一下应该能够理解该算法。实际上就是对输入数据进行64轮的运算(这些运算都是位操作或逻辑运算或基本代数运算),这些运算首先要得到消息区块数据,然后由��和 ��持续的去更新A~H。
然后是模块的接口,可以看到仍然要求我们用状态机实现。根据指定的地址message_addr
读取数据,并将结果写回output_addr
,这些地址仍然是字地址。消息的大小是固定的20words(640bit)。也就是规定好了输入数据的大小。在运算完成以后将done信号拉高。
数据的组织形式如图所示,我才发现它这个地址是每个相隔1,然后每一个地址存32比特的数据。这样当然可以,但是现代数字系统地址组织形式一般不是这样的。这里还是按照它的课程要求来吧。
然后给了个提示。由于输入数据大小为640bits,所以实际上会形成2个block。对于第一个block,w[0]到w[15]是内存的前16个words。对于第二个block。前128比特存数据。然后存一个1,一直补0到1024-32bit。剩余的32bit存数据的长度32'd640。这里和之前说的数据组织形式其实是一样的,这里重复提醒了大家一下。大家按照这个方式将数据事先存于memory即可。
然后说明模块的时候和内存的时钟是同一时钟。
对于参与SHA256运算的K常数数组,使用parameter int sha256_k[0:63]的方式进行初始化。使用的时候直接选址即可。
然后告诉了大家怎么快速实现右旋转。它这里写错了,应该是{x[0],x[31:1]}。按照它那样成了左旋转了,或者说它的x[31]指的是最低位,跟Python一样。下面的位运算和代码倒是对的。
下节课给大家带来SHA256的状态机实现,其实也很简单。根据大家反馈情况,我决定要不要用别的高速方式实现SHA256算法。