Skip to main content

6. Computing the Message Digest (计算消息摘要)

每个安全散列函数应用于N个块的消息后的输出是散列量H(N). 对于SHA-224和SHA-256,H(i)可以被视为八个32位字,H(i)0, H(i)1, ... H(i)7. 对于SHA-384和SHA-512,它可以被视为八个64位字,H(i)0, H(i)1, ..., H(i)7.

如下所述,散列字被初始化,在处理每个消息块时被修改,最后在处理最后一个块后连接以产生输出. 对于SHA-256和SHA-512,所有H(N)变量都被连接,而SHA-224和SHA-384散列是通过在最终连接中省略一些来产生的.

6.1. SHA-224 and SHA-256 Initialization (SHA-224和SHA-256初始化)

对于SHA-224,初始散列值H(0)由以下32位字组成(十六进制):

H(0)0 = c1059ed8
H(0)1 = 367cd507
H(0)2 = 3070dd17
H(0)3 = f70e5939
H(0)4 = ffc00b31
H(0)5 = 68581511
H(0)6 = 64f98fa7
H(0)7 = befa4fa4

对于SHA-256,初始散列值H(0)由以下八个32位字组成(十六进制). 这些字是通过取前八个质数的平方根的小数部分的前32位获得的.

H(0)0 = 6a09e667
H(0)1 = bb67ae85
H(0)2 = 3c6ef372
H(0)3 = a54ff53a
H(0)4 = 510e527f
H(0)5 = 9b05688c
H(0)6 = 1f83d9ab
H(0)7 = 5be0cd19

6.2. SHA-224 and SHA-256 Processing (SHA-224和SHA-256处理)

SHA-224和SHA-256对消息块执行相同的处理,仅在H(0)的初始化方式以及它们产生最终输出的方式上有所不同. 它们可用于散列长度为L位的消息M,其中 0 <= L < 2^64. 该算法使用(1)包含64个32位字的消息调度,(2)八个32位的工作变量,以及(3)八个32位字的散列值.

消息调度的字标记为W0, W1, ..., W63. 八个工作变量标记为a, b, c, d, e, f, g和h. 散列值的字标记为H(i)0, H(i)1, ..., H(i)7,它将保存初始散列值H(0),被每个连续的中间散列值(在处理每个消息块后)H(i)替换,并在处理所有N个块后以最终散列值H(N)结束. 它们还使用两个临时字T1和T2.

输入消息按上面第4.1节所述进行填充,然后解析为512位块,这些块被视为由16个32位字M(i)0, M(i)1, ..., M(i)15组成. 然后对N个消息块中的每一个执行以下计算. 所有加法以模2^32执行.

对于i = 1到N

  1. 准备消息调度W (Prepare the message schedule W):
For t = 0 to 15
Wt = M(i)t
For t = 16 to 63
Wt = SSIG1(W(t-2)) + W(t-7) + SSIG0(W(t-15)) + W(t-16)
  1. 初始化工作变量 (Initialize the working variables):
a = H(i-1)0
b = H(i-1)1
c = H(i-1)2
d = H(i-1)3
e = H(i-1)4
f = H(i-1)5
g = H(i-1)6
h = H(i-1)7
  1. 执行主要散列计算 (Perform the main hash computation):
For t = 0 to 63
T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt
T2 = BSIG0(a) + MAJ(a,b,c)
h = g
g = f
f = e
e = d + T1
d = c
c = b
b = a
a = T1 + T2
  1. 计算中间散列值H(i) (Compute the intermediate hash value H(i)):
H(i)0 = a + H(i-1)0
H(i)1 = b + H(i-1)1
H(i)2 = c + H(i-1)2
H(i)3 = d + H(i-1)3
H(i)4 = e + H(i-1)4
H(i)5 = f + H(i-1)5
H(i)6 = g + H(i-1)6
H(i)7 = h + H(i-1)7

在对消息中的所有块按顺序执行上述计算后,计算最终输出. 对于SHA-256,这是所有H(N)0, H(N)1到H(N)7的连接. 对于SHA-224,这是H(N)0, H(N)1到H(N)6的连接.

6.3. SHA-384 and SHA-512 Initialization (SHA-384和SHA-512初始化)

对于SHA-384,初始散列值H(0)由以下八个64位字组成(十六进制). 这些字是通过取第9到第16个质数的平方根的小数部分的前64位获得的.

H(0)0 = cbbb9d5dc1059ed8
H(0)1 = 629a292a367cd507
H(0)2 = 9159015a3070dd17
H(0)3 = 152fecd8f70e5939
H(0)4 = 67332667ffc00b31
H(0)5 = 8eb44a8768581511
H(0)6 = db0c2e0d64f98fa7
H(0)7 = 47b5481dbefa4fa4

对于SHA-512,初始散列值H(0)由以下八个64位字组成(十六进制). 这些字是通过取前八个质数的平方根的小数部分的前64位获得的.

H(0)0 = 6a09e667f3bcc908
H(0)1 = bb67ae8584caa73b
H(0)2 = 3c6ef372fe94f82b
H(0)3 = a54ff53a5f1d36f1
H(0)4 = 510e527fade682d1
H(0)5 = 9b05688c2b3e6c1f
H(0)6 = 1f83d9abfb41bd6b
H(0)7 = 5be0cd19137e2179

6.4. SHA-384 and SHA-512 Processing (SHA-384和SHA-512处理)

SHA-384和SHA-512对消息块执行相同的处理,仅在H(0)的初始化方式以及它们产生最终输出的方式上有所不同. 它们可用于散列长度为L位的消息M,其中 0 <= L < 2^128. 该算法使用(1)包含80个64位字的消息调度,(2)八个64位的工作变量,以及(3)八个64位字的散列值.

消息调度的字标记为W0, W1, ..., W79. 八个工作变量标记为a, b, c, d, e, f, g和h. 散列值的字标记为H(i)0, H(i)1, ..., H(i)7,它将保存初始散列值H(0),被每个连续的中间散列值(在处理每个消息块后)H(i)替换,并在处理所有N个块后以最终散列值H(N)结束.

输入消息按上面第4.2节所述进行填充,然后解析为1024位块,这些块被视为由16个64位字M(i)0, M(i)1, ..., M(i)15组成. 然后对N个消息块中的每一个执行以下计算. 所有加法以模2^64执行.

对于i = 1到N

  1. 准备消息调度W (Prepare the message schedule W):
For t = 0 to 15
Wt = M(i)t
For t = 16 to 79
Wt = SSIG1(W(t-2)) + W(t-7) + SSIG0(W(t-15)) + W(t-16)
  1. 初始化工作变量 (Initialize the working variables):
a = H(i-1)0
b = H(i-1)1
c = H(i-1)2
d = H(i-1)3
e = H(i-1)4
f = H(i-1)5
g = H(i-1)6
h = H(i-1)7
  1. 执行主要散列计算 (Perform the main hash computation):
For t = 0 to 79
T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt
T2 = BSIG0(a) + MAJ(a,b,c)
h = g
g = f
f = e
e = d + T1
d = c
c = b
b = a
a = T1 + T2
  1. 计算中间散列值H(i) (Compute the intermediate hash value H(i)):
H(i)0 = a + H(i-1)0
H(i)1 = b + H(i-1)1
H(i)2 = c + H(i-1)2
H(i)3 = d + H(i-1)3
H(i)4 = e + H(i-1)4
H(i)5 = f + H(i-1)5
H(i)6 = g + H(i-1)6
H(i)7 = h + H(i-1)7

在对消息中的所有块按顺序执行上述计算后,计算最终输出. 对于SHA-512,这是所有H(N)0, H(N)1到H(N)7的连接. 对于SHA-384,这是H(N)0, H(N)1到H(N)5的连接.