SHA-256算法及示例

news2024/12/25 1:52:47

1. 引言

SHA-256(安全哈希算法,FIPS 182-2)是密码学哈希函数,其摘要长度为256位。SHA-256为keyless哈希函数,即为MDC(Manipulation Detection Code)。【MAC消息认证码有key,不是keyless的。】

SHA-256哈希函数可定义为:

public static BigInteger hash(byte[] M)

其中:

  • 输入:消息 M M M为任意长度的字节数组。
  • 输出:在 [ 0 , 2 256 ) [0,2^{256}) [0,2256)范围的正整数,为消息 M M M的哈希值。

相关的测试用例有:【其中hash值以十六进制表示】
在这里插入图片描述

消息按block处理:

  • 每个block长度为512 = 16 x 32 位
  • 每个block需要64轮

2. 基本运算

SHA-256中的基本运算有:

  • 布尔运算:AND表示为 ∧ \wedge ,XOR表示为 ⊕ \oplus ,OR表示为 ∨ \vee
  • Bitwise complement(按位补码),表示为: ˉ \bar{} ˉ
  • 证明加法对 2 32 2^{32} 232求模运算,表示为 A + B A+B A+B

以上运算均是基于32位 words的(每个word对应32位)。binary words解析为以2为基的整数:

  • R o t R ( A , n ) RotR(A,n) RotR(A,n):表示将binary word A A A 循环右移 n n n位。
  • S h R ( A , n ) ShR(A,n) ShR(A,n):表示将binary word A A A 右移 n n n位。
  • A ∣ ∣ B A||B A∣∣B:表示将binary word A A A 和 binary word B B B 拼接在一起。

3. 函数和常量

SHA-256中使用的函数有:

  • C h ( X , Y , Z ) = ( X ∧ Y ) ⊕ ( X ˉ ∧ Z ) Ch(X, Y, Z) = (X\wedge Y)\oplus(\bar{X}\wedge Z) Ch(X,Y,Z)=(XY)(XˉZ)
  • M a j ( X , Y , Z ) = ( X ∧ Y ) ⊕ ( X ∧ Z ) ⊕ ( Y ∧ Z ) Maj(X,Y,Z)= (X\wedge Y)\oplus(X\wedge Z)\oplus(Y\wedge Z) Maj(X,Y,Z)=(XY)(XZ)(YZ)
  • ∑ 0 ( X ) = R o t R ( X , 2 ) ⊕ R o t R ( X , 13 ) ⊕ R o t R ( X , 22 ) \sum_0(X)=RotR(X,2)\oplus RotR(X,13)\oplus RotR(X,22) 0(X)=RotR(X,2)RotR(X,13)RotR(X,22)
  • ∑ 1 ( X ) = R o t R ( X , 6 ) ⊕ R o t R ( X , 11 ) ⊕ R o t R ( X , 25 ) \sum_1(X)=RotR(X,6)\oplus RotR(X,11)\oplus RotR(X,25) 1(X)=RotR(X,6)RotR(X,11)RotR(X,25)
  • σ 0 ( X ) = R o t R ( X , 7 ) ⊕ R o t R ( X , 18 ) ⊕ S h R ( X , 3 ) \sigma_0(X)=RotR(X,7)\oplus RotR(X,18)\oplus ShR(X,3) σ0(X)=RotR(X,7)RotR(X,18)ShR(X,3)
  • σ 1 ( X ) = R o t R ( X , 17 ) ⊕ R o t R ( X , 19 ) ⊕ S h R ( X , 10 ) \sigma_1(X)=RotR(X,17)\oplus RotR(X,19)\oplus ShR(X,10) σ1(X)=RotR(X,17)RotR(X,19)ShR(X,10)

SHA-256中每个block需要64轮,每一轮对应的64个constant words K 0 , K 1 , ⋯   , K 64 K_0,K_1,\cdots, K_{64} K0,K1,,K64为:

0x428a2f98 0x71374491 0xb5c0fbcf 0xe9b5dba5 0x3956c25b 0x59f111f1 0x923f82a4 0xab1c5ed5
0xd807aa98 0x12835b01 0x243185be 0x550c7dc3 0x72be5d74 0x80deb1fe 0x9bdc06a7 0xc19bf174
0xe49b69c1 0xefbe4786 0x0fc19dc6 0x240ca1cc 0x2de92c6f 0x4a7484aa 0x5cb0a9dc 0x76f988da
0x983e5152 0xa831c66d 0xb00327c8 0xbf597fc7 0xc6e00bf3 0xd5a79147 0x06ca6351 0x14292967
0x27b70a85 0x2e1b2138 0x4d2c6dfc 0x53380d13 0x650a7354 0x766a0abb 0x81c2c92e 0x92722c85
0xa2bfe8a1 0xa81a664b 0xc24b8b70 0xc76c51a3 0xd192e819 0xd6990624 0xf40e3585 0x106aa070
0x19a4c116 0x1e376c08 0x2748774c 0x34b0bcb5 0x391c0cb3 0x4ed8aa4a 0x5b9cca4f 0x682e6ff3
0x748f82ee 0x78a5636f 0x84c87814 0x8cc70208 0x90befffa 0xa4506ceb 0xbef9a3f7 0xc67178f2

这些常量是对自然数中前64个素数(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97…)的立方根的小数部分取前32bit而来。

4. 填充

假设消息长度可 以64位整数表示,为确保消息长度为512位的整数倍,需做如下填充:

  • 1)附加bit 1。
  • 2)附加 k k k个bit 0, k k k取值为使得 l + 1 + k ≡ 448 m o d    512 l+1+k\equiv 448 \mod 512 l+1+k448mod512的最小正整数,其中 l l l为初始消息位长度。
  • 3)初始消息长度 l < 2 64 l<2^{64} l<264以正好64位big-endian表示,将这64位附加到2)之后。

消息通常需要填充。即使消息初始长度已是512的整数倍,也需要填充。

5. block分解

SHA-256中每个block M ∈ { 0 , 1 } 512 M\in\{0,1\}^{512} M{0,1}512,对应64个words(每个word为32位)的构建方式为:

  • 前16个words为:将 M M M按512位block切分为16个32位words:
    M = W 1 ∣ ∣ W 2 ∣ ∣ ⋯ ∣ ∣ W 15 ∣ ∣ W 16 M=W_1||W_2||\cdots||W_{15}||W_{16} M=W1∣∣W2∣∣∣∣W15∣∣W16
  • 剩下48个words按如下公式构建:
    W i = σ 1 ( W i − 2 ) + W i − 7 + σ 0 ( W i − 15 ) + W i − 16 , 17 ≤ i ≤ 64 W_i=\sigma_1(W_{i-2})+W_{i-7}+\sigma_0(W_{i-15})+W_{i-16},17\leq i \leq 64 Wi=σ1(Wi2)+Wi7+σ0(Wi15)+Wi16,17i64

6. 哈希计算(压缩函数)

哈希计算,本质为SHA256压缩函数:

  • consumes the previous 32-byte digest and a 64-byte block of the padded input。

SHA-256哈希计算步骤为:

  • 1)设置8个固定的32bit变量 I V IV IV作为SHA-256哈希计算初始值:
    H 1 ( 0 ) = 0 x 6 a 09 e 667    H 2 ( 0 ) = 0 x b b 67 a e 85    H 3 ( 0 ) = 0 x 3 c 6 e f 372    H 4 ( 0 ) = 0 x a 54 f f 53 a H_1^{(0)}=0x6a09e667\ \ H_2^{(0)}=0xbb67ae85 \ \ H_3^{(0)}=0x3c6ef372 \ \ H_4^{(0)}=0xa54ff53a H1(0)=0x6a09e667  H2(0)=0xbb67ae85  H3(0)=0x3c6ef372  H4(0)=0xa54ff53a
    H 5 ( 0 ) = 0 x 510 e 527 f    H 6 ( 0 ) = 0 x 9 b 05688 c    H 7 ( 0 ) = 0 x 1 f 83 d 9 a b    H 8 ( 0 ) = 0 x 5 b e 0 c d 19 H_5^{(0)}=0x510e527f\ \ H_6^{(0)}=0x9b05688c \ \ H_7^{(0)}=0x1f83d9ab \ \ H_8^{(0)}=0x5be0cd19 H5(0)=0x510e527f  H6(0)=0x9b05688c  H7(0)=0x1f83d9ab  H8(0)=0x5be0cd19
    这些初始值是对自然数中前8个素数(2,3,5,7,11,13,17,19)的平方根的小数部分取前32bit而来。如, 2 = 0.414213562373095048 \sqrt{2}=0.414213562373095048 2 =0.414213562373095048,而 0.414213562373095048 ≈ 6 × 1 6 − 1 + a × 1 6 − 2 + 0 × 1 6 − 3 ⋯ 0.414213562373095048\approx 6\times 16^{-1}+a\times 16^{-2}+0\times 16^{-3}\cdots 0.4142135623730950486×161+a×162+0×163,于是素数 2 2 2的平方根的小数部分取前32bit就对应为0x6a09e667。

  • 2)对于每个blocks M ( 1 ) , M ( 2 ) , ⋯   , M ( N ) M^{(1)},M^{(2)},\cdots,M^{(N)} M(1),M(2),,M(N),均按如下方式处理:
    For  t = 1  to  N \text{For } t=1 \text{ to } N For t=1 to N

    • 2.1)根据上面“5. block分解”,为 M ( t ) M^{(t)} M(t)构建64个words W i W_i Wi
    • 2.2)设置: ( a , b , c , d , e , f , g , h ) = ( H 1 ( t − 1 ) , H 2 ( t − 1 ) , H 3 ( t − 1 ) , H 4 ( t − 1 ) , H 5 ( t − 1 ) , H 6 ( t − 1 ) , H 7 ( t − 1 ) , H 8 ( t − 1 ) ) (a,b,c,d,e,f,g,h)=(H_1^{(t-1)},H_2^{(t-1)},H_3^{(t-1)},H_4^{(t-1)},H_5^{(t-1)},H_6^{(t-1)},H_7^{(t-1)},H_8^{(t-1)}) (a,b,c,d,e,f,g,h)=(H1(t1),H2(t1),H3(t1),H4(t1),H5(t1),H6(t1),H7(t1),H8(t1))
    • 2.3)做64轮如下运算:
      For  i = 1  to  64 \text{For } i=1 \text{ to } 64 For i=1 to 64
           T 1 = h + ∑ 1 ( e ) + C h ( e , f , g ) + K i \ \ \ \ T_1=h+\sum_1(e)+Ch(e,f,g)+K_i     T1=h+1(e)+Ch(e,f,g)+Ki
           T 2 = ∑ 0 ( a ) + M a j ( a , b , c ) \ \ \ \ T_2=\sum_0(a)+Maj(a,b,c)     T2=0(a)+Maj(a,b,c)
           h = g \ \ \ \ h=g     h=g
           g = f \ \ \ \ g=f     g=f
           f = e \ \ \ \ f=e     f=e
           e = d + T 1 \ \ \ \ e=d+T_1     e=d+T1
           d = c \ \ \ \ d=c     d=c
           c = b \ \ \ \ c=b     c=b
           b = a \ \ \ \ b=a     b=a
           a = T 1 + T 2 \ \ \ \ a=T_1+T_2     a=T1+T2
      End for  i \text{End for } i End for i
    • 2.4)计算 H j ( t ) H_j^{(t)} Hj(t)的新值:【 j j j 的取值为1~8 】
      H 1 ( t ) = H 1 ( t − 1 ) + a H_1^{(t)}=H_1^{(t-1)}+a H1(t)=H1(t1)+a
      H 2 ( t ) = H 2 ( t − 1 ) + b H_2^{(t)}=H_2^{(t-1)}+b H2(t)=H2(t1)+b
      H 3 ( t ) = H 3 ( t − 1 ) + c H_3^{(t)}=H_3^{(t-1)}+c H3(t)=H3(t1)+c
      H 4 ( t ) = H 4 ( t − 1 ) + d H_4^{(t)}=H_4^{(t-1)}+d H4(t)=H4(t1)+d
      H 5 ( t ) = H 5 ( t − 1 ) + e H_5^{(t)}=H_5^{(t-1)}+e H5(t)=H5(t1)+e
      H 6 ( t ) = H 6 ( t − 1 ) + f H_6^{(t)}=H_6^{(t-1)}+f H6(t)=H6(t1)+f
      H 7 ( t ) = H 7 ( t − 1 ) + g H_7^{(t)}=H_7^{(t-1)}+g H7(t)=H7(t1)+g
      H 8 ( t ) = H 8 ( t − 1 ) + h H_8^{(t)}=H_8^{(t-1)}+h H8(t)=H8(t1)+h

    End for  t \text{End for } t End for t

  • 3)当处理完最后一个block之后,将 H j ( N ) H_j^{(N)} Hj(N)变量拼接在一起,即为消息的哈希值:
    H = H 1 ( N ) ∣ ∣ H 2 ( N ) ∣ ∣ H 3 ( N ) ∣ ∣ H 4 ( N ) ∣ ∣ H 5 ( N ) ∣ ∣ H 6 ( N ) ∣ ∣ H 7 ( N ) ∣ ∣ H 8 ( N ) H=H_1^{(N)}||H_2^{(N)}||H_3^{(N)}||H_4^{(N)}||H_5^{(N)}||H_6^{(N)}||H_7^{(N)}||H_8^{(N)} H=H1(N)∣∣H2(N)∣∣H3(N)∣∣H4(N)∣∣H5(N)∣∣H6(N)∣∣H7(N)∣∣H8(N)

7. SHA-256示例

以对“hello world”进行SHA-256计算为例:

  • 1)STEP 1:预处理。预处理后的长度为512bit的整数倍。

    • 1.1)将“hello world”转换为二进制表示为:【即消息原始长度为88bit】
      01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111
      01110010 01101100 01100100
      
    • 1.2)附加单个bit 1:
      01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111
      01110010 01101100 01100100 1
      
    • 1.3)附加 k k k个bit 0, k k k取值为使得 l + 1 + k ≡ 448 m o d    512 l+1+k\equiv 448 \mod 512 l+1+k448mod512的最小正整数,其中 l l l为初始消息位长度。
      01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111
      01110010 01101100 01100100 10000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      
    • 1.4)初始消息长度 l < 2 64 l<2^{64} l<264以正好64位big-endian表示,将这64位附加到1.3)之后。此处“hello world”二进制表示长度为 l = 88 = 1011000 l=88=1011000 l=88=1011000
      01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111
      01110010 01101100 01100100 10000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      00000000 00000000 00000000 00000000 00000000 00000000 00000000 01011000
      
      至此,后续STEP的输入即为512bit的整数倍。
  • 2)STEP 2:初始化哈希值。

    h0 := 0x6a09e667
    h1 := 0xbb67ae85
    h2 := 0x3c6ef372
    h3 := 0xa54ff53a
    h4 := 0x510e527f
    h5 := 0x9b05688c
    h6 := 0x1f83d9ab
    h7 := 0x5be0cd19
    
  • 3)STEP 3:初始化Round常量。

    0x428a2f98 0x71374491 0xb5c0fbcf 0xe9b5dba5 0x3956c25b 0x59f111f1 0x923f82a4 0xab1c5ed5
    0xd807aa98 0x12835b01 0x243185be 0x550c7dc3 0x72be5d74 0x80deb1fe 0x9bdc06a7 0xc19bf174
    0xe49b69c1 0xefbe4786 0x0fc19dc6 0x240ca1cc 0x2de92c6f 0x4a7484aa 0x5cb0a9dc 0x76f988da
    0x983e5152 0xa831c66d 0xb00327c8 0xbf597fc7 0xc6e00bf3 0xd5a79147 0x06ca6351 0x14292967
    0x27b70a85 0x2e1b2138 0x4d2c6dfc 0x53380d13 0x650a7354 0x766a0abb 0x81c2c92e 0x92722c85
    0xa2bfe8a1 0xa81a664b 0xc24b8b70 0xc76c51a3 0xd192e819 0xd6990624 0xf40e3585 0x106aa070
    0x19a4c116 0x1e376c08 0x2748774c 0x34b0bcb5 0x391c0cb3 0x4ed8aa4a 0x5b9cca4f 0x682e6ff3
    0x748f82ee 0x78a5636f 0x84c87814 0x8cc70208 0x90befffa 0xa4506ceb 0xbef9a3f7 0xc67178f2
    
  • 4)STEP 4:Block Loop(或又名Chunk Loop)。将输入拆分为以512 bit为单位的block。由于本例中“hello world”太短,对应为1个block。 对每个block,做如下STEP操作。

  • 5)STEP 5:block分解。

    • 5.1) 前16个words为:将 M M M按512位block切分为16个32位words:
      01101000011001010110110001101100 01101111001000000111011101101111
      01110010011011000110010010000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000001011000
      
    • 5.2)剩下48个words按如下公式构建:
      W i = σ 1 ( W i − 2 ) + W i − 7 + σ 0 ( W i − 15 ) + W i − 16 , 17 ≤ i ≤ 64 W_i=\sigma_1(W_{i-2})+W_{i-7}+\sigma_0(W_{i-15})+W_{i-16},17\leq i \leq 64 Wi=σ1(Wi2)+Wi7+σ0(Wi15)+Wi16,17i64
      01101000011001010110110001101100 01101111001000000111011101101111
      01110010011011000110010010000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000001011000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      00000000000000000000000000000000 00000000000000000000000000000000
      ...
      ...
      00000000000000000000000000000000 00000000000000000000000000000000
      

    最终整个64个words( W W W)为:

    01101000011001010110110001101100 01101111001000000111011101101111
    01110010011011000110010010000000 00000000000000000000000000000000
    00000000000000000000000000000000 00000000000000000000000000000000
    00000000000000000000000000000000 00000000000000000000000000000000
    00000000000000000000000000000000 00000000000000000000000000000000
    00000000000000000000000000000000 00000000000000000000000000000000
    00000000000000000000000000000000 00000000000000000000000000000000
    00000000000000000000000000000000 00000000000000000000000001011000
    00110111010001110000001000110111 10000110110100001100000000110001
    11010011101111010001000100001011 01111000001111110100011110000010
    00101010100100000111110011101101 01001011001011110111110011001001
    00110001111000011001010001011101 10001001001101100100100101100100
    01111111011110100000011011011010 11000001011110011010100100111010
    10111011111010001111011001010101 00001100000110101110001111100110
    10110000111111100000110101111101 01011111011011100101010110010011
    00000000100010011001101101010010 00000111111100011100101010010100
    00111011010111111110010111010110 01101000011001010110001011100110
    11001000010011100000101010011110 00000110101011111001101100100101
    10010010111011110110010011010111 01100011111110010101111001011010
    11100011000101100110011111010111 10000100001110111101111000010110
    11101110111011001010100001011011 10100000010011111111001000100001
    11111001000110001010110110111000 00010100101010001001001000011001
    00010000100001000101001100011101 01100000100100111110000011001101
    10000011000000110101111111101001 11010101101011100111100100111000
    00111001001111110000010110101101 11111011010010110001101111101111
    11101011011101011111111100101001 01101010001101101001010100110100
    00100010111111001001110011011000 10101001011101000000110100101011
    01100000110011110011100010000101 11000100101011001001100000111010
    00010001010000101111110110101101 10110000101100000001110111011001
    10011000111100001100001101101111 01110010000101111011100000011110
    10100010110101000110011110011010 00000001000011111001100101111011
    11111100000101110100111100001010 11000010110000101110101100010110
    
  • 6)STEP 6:压缩。按上面“6. 哈希计算”做64轮运算之后,有:

    a = 4F434152 = 01001111010000110100000101010010
    b = D7E58F83 = 11010111111001011000111110000011
    c = 68BF5F65 = 01101000101111110101111101100101
    d = 352DB6C0 = 00110101001011011011011011000000
    e = 73769D64 = 01110011011101101001110101100100
    f = DF4E1862 = 11011111010011100001100001100010
    g = 71051E01 = 01110001000001010001111000000001
    h = 870F00D0 = 10000111000011110000000011010000
    
  • 7)STEP 7:修正final值。按上面“6. 哈希计算”中“2.4)计算 H j ( t ) H_j^{(t)} Hj(t)的新值”,有:

    h0 = h0 + a = 10111001010011010010011110111001
    h1 = h1 + b = 10010011010011010011111000001000
    h2 = h2 + c = 10100101001011100101001011010111
    h3 = h3 + d = 11011010011111011010101111111010
    h4 = h4 + e = 11000100100001001110111111100011
    h5 = h5 + f = 01111010010100111000000011101110
    h6 = h6 + g = 10010000100010001111011110101100
    h7 = h7 + h = 11100010111011111100110111101001
    
  • 8)STEP 8:拼接最终哈希值:

    digest = h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7
           = B94D27B9934D3E08A52E52D7DA7DABFAC484EFE37A5380EE9088F7ACE2EFCDE9
    

在这里插入图片描述

SHA-256伪代码为:

Note 1: All variables are 32 bit unsigned integers and addition is calculated modulo 232
Note 2: For each round, there is one round constant k[i] and one entry in the message schedule array w[i], 0 ≤ i ≤ 63
Note 3: The compression function uses 8 working variables, a through h
Note 4: Big-endian convention is used when expressing the constants in this pseudocode,
    and when parsing message block data from bytes to words, for example,
    the first word of the input message "abc" after padding is 0x61626380

Initialize hash values:
(first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
h0 := 0x6a09e667
h1 := 0xbb67ae85
h2 := 0x3c6ef372
h3 := 0xa54ff53a
h4 := 0x510e527f
h5 := 0x9b05688c
h6 := 0x1f83d9ab
h7 := 0x5be0cd19

Initialize array of round constants:
(first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311):
k[0..63] :=
   0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
   0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
   0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
   0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
   0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
   0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
   0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
   0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2

Pre-processing (Padding):
begin with the original message of length L bits
append a single '1' bit
append K '0' bits, where K is the minimum number >= 0 such that L + 1 + K + 64 is a multiple of 512
append L as a 64-bit big-endian integer, making the total post-processed length a multiple of 512 bits

Process the message in successive 512-bit chunks:
break message into 512-bit chunks
for each chunk
    create a 64-entry message schedule array w[0..63] of 32-bit words
    (The initial values in w[0..63] don't matter, so many implementations zero them here)
    copy chunk into first 16 words w[0..15] of the message schedule array

    Extend the first 16 words into the remaining 48 words w[16..63] of the message schedule array:
    for i from 16 to 63
        s0 := (w[i-15] rightrotate  7) xor (w[i-15] rightrotate 18) xor (w[i-15] rightshift  3)
        s1 := (w[i- 2] rightrotate 17) xor (w[i- 2] rightrotate 19) xor (w[i- 2] rightshift 10)
        w[i] := w[i-16] + s0 + w[i-7] + s1

    Initialize working variables to current hash value:
    a := h0
    b := h1
    c := h2
    d := h3
    e := h4
    f := h5
    g := h6
    h := h7

    Compression function main loop:
    for i from 0 to 63
        S1 := (e rightrotate 6) xor (e rightrotate 11) xor (e rightrotate 25)
        ch := (e and f) xor ((not e) and g)
        temp1 := h + S1 + ch + k[i] + w[i]
        S0 := (a rightrotate 2) xor (a rightrotate 13) xor (a rightrotate 22)
        maj := (a and b) xor (a and c) xor (b and c)
        temp2 := S0 + maj
 
        h := g
        g := f
        f := e
        e := d + temp1
        d := c
        c := b
        b := a
        a := temp1 + temp2

    Add the compressed chunk to the current hash value:
    h0 := h0 + a
    h1 := h1 + b
    h2 := h2 + c
    h3 := h3 + d
    h4 := h4 + e
    h5 := h5 + f
    h6 := h6 + g
    h7 := h7 + h

Produce the final hash value (big-endian):
digest := hash := h0 append h1 append h2 append h3 append h4 append h5 append h6 append h7

参考资料

[1] The cryptographic hash function SHA-256
[2] WHAT IS SHA-256?
[3] Descriptions of SHA-256, SHA-384, and SHA-512

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/707901.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据库】外键的作用

前言 说到外键&#xff0c;一般就会牵扯出约束。不谈约束&#xff0c;起始外键就是一个普通的字段&#xff08;Column&#xff09;&#xff0c;起到一个关联的作用。 先把约束放一边&#xff0c;看看外键有哪些作用。 建立表中记录的一对一的关系 学生表&#xff1a; 手机表…

C++引用计数

文章目录 1. 什么是引用计数2. 引用计数的实现3. 示例代码 1. 什么是引用计数 引用计数&#xff08;reference count&#xff09;的核心思想是使用一个计数器来标识当前指针指向的对象被多少类的对象所使用&#xff08;即记录指针指向对象被引用的次数&#xff09;。它允许有多…

Linux--查找文件指令:find

语法&#xff1a; find pathname -name 文件名 示例&#xff1a; 从根目录下开始查找名字中带file.txt文件的路径

C++思维导图以及作业

定义一个命名空间Myspace&#xff0c;包含以下函数&#xff1a;将一个字符串中的所有单词进行反转&#xff0c;并输出反转后的结果。例如&#xff0c;输入字符串为"Hello World"&#xff0c;输出结果为"olleH dlroW"&#xff0c;并在主函数内测试该函数。 …

战略书籍排行榜前五名

战略管理对企业的重要性不言而喻。有效的战略管理可以帮助企业确定未来的方向和目标、制定长期发展规划、提高企业的竞争力和获得市场份额。本文推荐的这5本优秀的战略管理类书籍&#xff0c;每一本都有其独特的思想和实践价值&#xff0c;值得企业管理者借鉴和学习。 战略书籍…

Leetcode---351周赛

周赛题目 2748. 美丽下标对的数目 2749. 得到整数零需要执行的最少操作数 2750. 将数组划分成若干好子数组的方式 2751. 机器人碰撞 一、美丽下标对的数目 这题没什么好说的&#xff0c;按照题目的要求直接暴力求解&#xff0c;代码如下 bool gcd(int x,int y){if(x1||y1)…

vue父子组件之间相互控制传值,子组件使用$parent直接控制父组件的值

父子组件之间相互控制传值&#xff0c;子组件控制父组件的值 需求概述 父组件在提交表单后&#xff0c;弹框进行提示&#xff0c;子组件是一个弹框。 vue版本 v2.x 实现原理 在父组件内建立控制器isShowModal&#xff0c;使用v-if来控制子组件的显示与隐藏。在子组件通过…

DAY39——动态规划part2

1.考虑障碍在起点和终点的特殊状况&#xff0c;可直接返回0 2.判断是否存在障碍物&#xff1a;初始化时需要设置障碍物后的坐标为0

常见存储引擎

TiKV 简介 TiKV 是一个分布式事务型的键值数据库&#xff0c;提供了满足 ACID 约束的分布式事务接口&#xff0c;并且通过Raft协议保证了多副本数据一致性以及高可用。TiKV 作为 TiDB 的存储层&#xff0c;为用户写入 TiDB 的数据提供了持久化以及读写服务&#xff0c;同时还存…

Spring BeanFactory FactoryBean的区别?

文章目录 前言一、BeanFactory二、FactoryBean 前言 面试中被问到过Spring BeanFactory FactoryBean的区别&#xff1f;当时没答上来&#xff0c;感觉这就是一个文字游戏&#xff0c;后面仔细的了解了一下&#xff0c;分享给大家。 一、BeanFactory 在 Spring 中最核心的就是…

GDB 断点管理

1、b 设置断点 usage 1: b 函数名 usage 2: b 文件名:行号 2、rb 函数名关键字 &#xff1a; 所有带有这个关键字的函数名都设置为断点 (gdb) rb dkauth Breakpoint 7 at 0x34187ae0: file /home/jintao/cvf/apps/cvf/services/dkauth/src/dkauth.c, line 58. void dkauth_…

Python之花舞盛宴:探索列表与元组之美与妙用

前言 在Python编程世界中&#xff0c;列表和元组是两个最常用的数据结构之一。无论是初学者还是经验丰富的开发者&#xff0c;对于这两个数据类型的掌握都至关重要。 列表和元组都是用于存储多个值的容器&#xff0c;但它们在性质和特性上有所不同。列表是可变的&#xff0c;…

VMIC-pci-5565反射内存的优势

优势&#xff1a; &#xff08;1&#xff09;实现远程互连的能力 随着仿真实验复杂度的提高&#xff0c;需要多楼宇多试验室间设备的远程互连&#xff0c;通过单模光纤及光纤HUB将远距离的试验室设备进行连接&#xff0c;单模光纤支持的传输距离可达20km。对于距离300m以内的试…

免费搭建一个有脾气的聊天机器人,1行Python代码就够了!

大家好&#xff0c;这里是程序员晚枫。 之前在小破站&#xff1a;Python自动化办公社区给大家免费分享了用Python制作一个wx机器人&#xff0c;1行代码人人可用&#xff0c;很多人还想要免费的智能聊天功能。 今天终于开发出来了&#xff0c;让我们一起看一下&#xff0c;如何…

第四课—大学英语四六级备考—听力专项

Key Words 1.monarch n.君主政治 非常抱歉误解了您的问题。以下是关于"monarch"这两个意义的常见用法、造句和固定搭配的例子&#xff1a; 1. Monarch&#xff08;君主&#xff09;&#xff1a; - 造句&#xff1a; - The monarch of the country made an…

爆文:硬件工程师如何零基础入门?

大家好&#xff0c;我是记得诚。 最近老是有读者问我学习路线&#xff0c;之前其实写过一篇文章&#xff1a; 硬件工程师如何零基础入门&#xff1f;&#xff08;点击阅读&#xff09; 觉得很有必要再发一遍&#xff0c;这篇文章&#xff0c;在全网也算爆文了。 在CSDN有65…

SpringBoot项目中PageHelper给子查询做分页

目录 1.起因 2.sql改进 3.改造pagehelper 4.新的问题 方案一 方案二 方案三(终极) 5.附上pagehelper官方使用指南 1.起因 项目中有个查询非常慢,查询第一页都很慢, sql为一张大表A left join了许多张基础数据表(小表), select * from A left join b on xxx left join…

安全、环保的随身“数据库”——体验希捷锦系列移动硬盘

移动硬盘不属于那种技术更新换代快、差异化明显的产品&#xff0c;因此消费者在选购时关注的点无外乎容量、价格、外观、传输速度以及数据安全等方面。希捷新推出的锦系列移动硬盘&#xff0c;就聚焦数据安全&#xff0c;同时在选材上贯彻了环保理念&#xff0c;设计方面也值得…

Linux限制用户使用特权-限制su

Linux下&#xff0c;允许普通用户通过su命令切换到root身份进行操作。 相对于直接使用root登录操作&#xff0c;这钟方法要安全些。但仍存在安全隐患。 缩小特权使用用户的范围&#xff0c;无疑是更安全的做法。 Linux提供了这样的设置。 编辑/etc/pam.d/su文件&#xff0c…

ai绘画工具有免费的吗?3款ai画图工具分享

在ai绘画工具问世之后&#xff0c;我试验了各种软件&#xff0c;有的功能太过简单&#xff0c;无法满足我对创作的要求&#xff1b;有的则要求我花费大额费用才能享受完整的功能。这让我在探索过程中一度怀疑是否真的有免费软件能够满足我的需求。 然而功夫不负有心人&#xf…