Bootstrap

SHA-3算法的计算过程详解

SHA-3算法的计算过程详解

主要参考文档 SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions

1. 几个重要参数:

  • 存储状态 S S S的比特位宽为 b b b,其中 b ∈ 25 , 50 , 100 , 200 , 400 , 800 , 1600 b∈{25,50,100,200,400,800,1600} b25501002004008001600,可以写作 b = 25 × 2 l , l ∈ { 0 , 1 , ⋯ , 6 } b=25×2^l,l∈\left\{0,1,⋯ ,6\right\} b=25×2ll{016}
  • 存储状态 S S S可以分为比特率容量两部分,其比特位宽分别为 r r r c c c,很明显 b = r + c b=r+c b=r+c

2. 计算过程:

在这里插入图片描述

1. 填充:

在消息 M M M后加入 1 1 1、最少个数的 0 0 0 1 1 1,即: 100 ⋯ 001 100⋯001 100001,使填充后的消息长度是 r ( 0 ≤ r ≤ b ) r(0≤r≤b) r(0rb)的整数倍。加入的比特长度至少是 2 2 2比特,最多是 r + 1 r+1 r+1比特。
记填充后的消息为 P P P n = l e n ( P ) / r n=len(P)/r n=len(P)/r。即将 P P P分成 n n n段,记为 P = P 0 ∣ ∣ P 2 ∣ ∣ ⋯ ∣ ∣ P n − 1 ∣ ∣ P n ​ ​ P=P_0||P_2||\cdots ||P_{n-1}||P_{n}​​ P=P0P2Pn1Pn,每段长度为 r r r

2. 吸收阶段:

S i + 1 = f ( S i ⊕ ( P ​ i ​ ​ ∣ ∣ 0 ​ c ​ ​ ) ) S_{i+1}=f(S_{i}⊕(P​i​​ ∣∣0​^c​​ )) Si+1=f(Si(Pi0c))
在吸收阶段,首先将 S S S初始化为零,记初始状态为 S 0 S_{0} S0
每一轮运算中先将 P i P_i Pi后填充长度为 c c c 0 0 0,再与长度为 b b b S i S_i Si的进行异或运算,其结果 S i ′ S_i^{'} Si经过 f f f函数后作为下一轮的新状态 S i + 1 S_{i+1} Si+1,这过程一直重复到所有的输入都用完为止,即进行 n n n轮这样的运算。

在介绍 f f f函数之前,先要介绍一种存储结构的转换 S i ′ → A S_i^{'}→A SiA
在这里插入图片描述
在这里插入图片描述

S i ′ S_i^{'} Si是比特串,而状态 A A A可以表示为一个 5 × 5 × w 5×5×w 5×5×w的三维数组,其中 w = b / 25 w=b/25 w=b/25
状态数组中的每一位可以用 A [ x , y , z ] A[x,y,z] A[x,y,z]表示,则有 A [ i ] [   j ] [ k ] = S i ′ [ ( 5 j + i ) × w + k ] A[i][ j][k] =S_i^{'} [(5j + i) × w + k] A[i][j][k]=Si[(5j+i)×w+k] S i ′ S_i^{'} Si的下标索引采用小端模式,其中 i i i表示行, j j j表示列, k k k表示比特。转换的例子如下所示:
在这里插入图片描述
那么,如何将状态矩阵又转换成比特串呢?按照 L a n e ( i , j ) , P l a n e ( j ) Lane (i, j),Plane (j) Lane(i,j)Plane(j) S S S的顺序逐次转换;
L a n e ( i , j ) = A [ i , j , 0 ] ∣ ∣ A [ i , j , 1 ] ∣ ∣ A [ i , j , 2 ] ∣ ∣ … ∣ ∣ A [ i , j , w − 2 ] ∣ ∣ A [ i , j , w − 1 ] Lane (i, j) = A[i, j, 0] || A[i, j, 1] || A[i, j, 2] || … || A[i, j, w-2] || A[i, j, w-1] Lane(i,j)=A[i,j,0]A[i,j,1]A[i,j,2]A[i,j,w2]A[i,j,w1],其中 0 ≤ i < 5 , 0 ≤ j < 5 0 ≤ i < 5 ,0 ≤ j < 5 0i<5,0j<5
P l a n e ( j ) = L a n e ( 0 , j ) ∣ ∣ L a n e ( 1 , j ) ∣ ∣ L a n e ( 2 , j ) ∣ ∣ L a n e ( 3 , j ) ∣ ∣ L a n e ( 4 , j ) Plane (j) = Lane (0, j) || Lane (1, j) || Lane (2, j) || Lane (3, j) || Lane (4, j) Plane(j)=Lane(0,j)Lane(1,j)Lane(2,j)Lane(3,j)Lane(4,j),其中 0 ≤ j < 5 0 ≤ j < 5 0j<5
S = P l a n e ( 0 ) ∣ ∣ P l a n e ( 1 ) ∣ ∣ P l a n e ( 2 ) ∣ ∣ P l a n e ( 3 ) ∣ ∣ P l a n e ( 4 ) S = Plane (0) || Plane (1) || Plane (2) || Plane (3) || Plane (4) S=Plane(0)Plane(1)Plane(2)Plane(3)Plane(4)
同样来举个例子吧;
在这里插入图片描述
SHA-3 标准中共有 5 个映射函数,可以对状态数组 A A A进行不同的排列,下面简要进行介绍。

θ ( A ) θ(A) θ(A) 0 ≤ x < 5 , 0 ≤ y < 5 , a n d 0 ≤ z < w 0 ≤ x < 5, 0 ≤ y < 5, and 0 ≤ z < w 0x<5,0y<5,and0z<w

C [ x , z ] = A [ x , 0 , z ] ⊕ A [ x , 1 , z ] ⊕ A [ x , 2 , z ] ⊕ A [ x , 3 , z ] ⊕ A [ x , 4 , z ] C[x, z] = A[x, 0, z] ⊕ A[x, 1, z] ⊕ A[x, 2, z] ⊕ A[x, 3, z] ⊕ A[x, 4, z] C[x,z]=A[x,0,z]A[x,1,z]A[x,2,z]A[x,3,z]A[x,4,z]
D [ x , z ] = C [ ( x − 1 ) m o d   5 , z ] ⊕ C [ ( x + 1 ) m o d   5 , ( z – 1 ) m o d   w ] D[x, z] = C[(x-1) mod \ 5, z] ⊕ C[(x+1) mod \ 5, (z – 1) mod\ w] D[x,z]=C[(x1)mod 5,z]C[(x+1)mod 5,(z1)mod w]
A ′ [ x , y , z ] = A [ x , y , z ] ⊕ D [ x , z ] A′[x, y, z] = A[x, y, z] ⊕ D[x, z] A[x,y,z]=A[x,y,z]D[x,z]
从图形上来看,就是计算某一比特对应两列的奇偶校验值,再与该比特异或的过程。
在这里插入图片描述

ρ ( A ) ρ(A) ρ(A)对25个 L a n e Lane Lane进行循环移位:
在这里插入图片描述在这里插入图片描述
对于不同 L a n e Lane Lane的偏移量是可以预计算的,计算结果如下:
在这里插入图片描述
从状态矩阵上来看,图形如下所示,注意是循环移位:
在这里插入图片描述
π ( A ) π(A) π(A)对25个 S l i c e Slice Slice进行固定的换位:
在这里插入图片描述
从状态矩阵来看,效果如下所示,注意中间点 ( x , y ) = ( 0 , 0 ) (x,y)=(0,0) (x,y)=(0,0)
在这里插入图片描述

χ ( A ) χ(A) χ(A) 沿 r o w row row进行比特组合:
在这里插入图片描述
从状态矩阵来看,效果如下所示,注意这是对于 x x x的:
在这里插入图片描述

ι ( A , i r ​ ​ ) ι(A,i_r​​) ι(A,ir)修改 L a n e ( 0 , 0 ) Lane(0,0) Lane(0,0)中的某些比特,其他24个 L a n e ( 0 , 0 ) Lane(0,0) Lane(0,0)则不受影响:
在这里插入图片描述
R C [ z ] RC[z] RC[z]开始被初始化为 w w w比特的全 0 0 0,然后对某些比特进行修改,修改后的比特来自于 r c ( t ) rc(t) rc(t)函数。
r c ( t ) rc(t) rc(t)函数的定义如下,类似于一个反馈移位寄存器,运算结果为 1 1 1比特, j + 7 i r j+7i_r j+7ir是反馈移位寄存器动作的次数。
在这里插入图片描述
介绍完5个映射函数,就可以得到轮函数 R n d ( A , i r ) Rnd(A, i_r) Rnd(A,ir)了;
在这里插入图片描述
定义完 R n d ( A , i r ) Rnd(A, i_r) Rnd(A,ir),进一步定义 K e c c a k − p [ b , n r ] Keccak-p[b,n_r] Keccakp[b,nr]函数, K e c c a k − p [ b , n r ] Keccak-p[b,n_r] Keccakp[b,nr]是对状态矩阵 A A A进行多次 R n d ( A , i r ) Rnd(A, i_r) Rnd(A,ir)迭代, i r i_r ir作为索引,取不同的值;
在这里插入图片描述
K e c c a k − p [ b , n r ] Keccak-p[b,n_r] Keccakp[b,nr]中的 n r n_r nr是可以取任意正整数的,SHA-3算法中的 f f f函数实际上是 K e c c a k − p [ b , n r ] Keccak-p[b,n_r] Keccakp[b,nr]的一种特殊化,即 n r = 12 + 2 l n_r=12+2l nr=12+2l
在这里插入图片描述

3. 挤压阶段:

在这里插入图片描述
挤压阶段和吸收阶段用的是相同的 f f f函数。吸收阶段每一个 f f f函数之后,将状态矩阵 A A A转化成 S S S,吸收 r r r比特的消息。挤压阶段则每一个 f f f函数之后,生成 r r r比特的摘要。将生成的摘要进行拼接,直到生成摘要的长度大于需要的摘要长度时,进行截断。 T r u n c d Trunc_d Truncd表示取字符串的前 d d d比特。

4. 总结一下:

在这里插入图片描述
在这里插入图片描述

3. 需要注意的地方:

  • K e c c a k − p [ b , n r ] Keccak-p[b,n_r] Keccakp[b,nr] K e c c a k − f [ b ] Keccak-f[b] Keccakf[b] K e c c a k [ c ] ( N , d ) Keccak{[c]}(N, d) Keccak[c](N,d)三者的区别需要注意,否则不太容易理解文档中所描述的东西;
    K e c c a k − p [ b , n r ] Keccak-p[b,n_r] Keccakp[b,nr]是广义的置换函数, n r n_r nr是可以取任意正整数的;
    SHA-3算法中的 f f f函数实际上是 K e c c a k − p [ b , n r ] Keccak-p[b,n_r] Keccakp[b,nr]的一种特殊化,即 n r = 12 + 2 l n_r=12+2l nr=12+2l,记为 K e c c a k − f [ b ] Keccak-f[b] Keccakf[b]
    K e c c a k [ c ] ( N , d ) Keccak{[c]}(N, d) Keccak[c](N,d)则可以认为是整体的这种海绵结构,包括吸收和挤压阶段,其中 b = 1600 b=1600 b=1600 c = 1600 − r c=1600-r c=1600r S P O N G E SPONGE SPONGE的三个参数分别为 f f f函数、填充规则和 r r r取值,填充规则用正则表达式表示。
    在这里插入图片描述
    K e c c a k [ c ] ( N , d ) Keccak{[c]}(N, d) Keccak[c](N,d)进一步进行限制,则可以定义为SHA-3算法,其中容量 c c c取摘要长度 d d d的两倍;SHA-3在调用 K e c c a k [ c ] ( N , d ) Keccak{[c]}(N, d) Keccak[c](N,d)函数时,需要对消息进行填充01。
    在这里插入图片描述
;