参考文献:
- [BDP+13] Bertoni G, Daemen J, Peeters M, et al. Keccak[C]//Advances in Cryptology–EUROCRYPT 2013: 32nd Annual International Conference on the Theory and Applications of Cryptographic Techniques, Athens, Greece, May 26-30, 2013. Proceedings 32. Springer Berlin Heidelberg, 2013: 313-314.
- [FIPS 202] Dworkin M J. SHA-3 standard: Permutation-based hash and extendable-output functions[J]. 2015.
- [NIST SP 800-185] Kelsey J, Chang S, Perlner R. SHA-3 derived functions: cSHAKE, KMAC, TupleHash, and ParallelHash[J]. NIST special publication, 2016, 800: 185.
- 官网 Team Keccak,源码 eXtended Keccak Code Package
2012年10月2日,Keccak 被选为 NIST(National Institute of Standards and Technology)散列函数竞赛的胜利者,成为了 FIPS 202 标准。SHA-3 并不是要取代 SHA-2,因为 SHA-2 并没有出现明显的弱点。由于对 MD5 和 SHA-1 出现成功的破解,NIST 感觉需要一个与之前算法不同的、可替换的加密散列算法,也就是 SHA-3。出于适应不同应用的考虑,NIST SP 800-185 基于 FIPS 202 设计了一些派生函数。
置换函数
K E C C A K − p [ b , n r ] KECCAK-p[b,n_r] KECCAK−p[b,nr] 置换函数,这里的 n r n_r nr 是轮数(round), 而 b ∈ { 25 , 50 , 100 , 200 , 400 , 800 , 1600 } b \in \{25,50,100,200,400,800,1600\} b∈{25,50,100,200,400,800,1600} 是宽度(width)
状态 state 是大小 5 × 5 × w 5 \times 5 \times w 5×5×w 的三维数组,它的两维的子数组叫做 sheets, planes, slices,一维子数组叫做 rows, columns, lanes.
K
E
C
C
A
K
−
p
[
b
,
n
r
]
KECCAK-p[b,n_r]
KECCAK−p[b,nr] 包括
n
r
n_r
nr 次迭代,每次迭代中对状态数组
A
A
A 依次执行
θ
,
ρ
,
π
,
χ
,
ι
\theta,\rho,\pi,\chi,\iota
θ,ρ,π,χ,ι 变换,
R
n
d
(
A
,
i
r
)
=
ι
(
χ
(
π
(
ρ
(
θ
(
A
)
)
)
)
,
i
r
)
Rnd(A,i_r) = \iota(\chi(\pi(\rho(\theta(A)))),i_r)
Rnd(A,ir)=ι(χ(π(ρ(θ(A)))),ir)
具体的各个变换本人没有探究,读者感兴趣可以自行查看 SHA-3 标准文档。
另外定义
K
E
C
C
A
K
−
f
[
b
]
=
K
E
C
C
A
K
−
p
[
b
,
12
+
2
l
]
KECCAK-f[b] = KECCAK-p[b,12+2l]
KECCAK−f[b]=KECCAK−p[b,12+2l]
特别地, K E C C A K − f [ 1600 ] = K E C C A K − p [ 1600 , 24 ] KECCAK-f[1600] = KECCAK-p[1600,24] KECCAK−f[1600]=KECCAK−p[1600,24]
海绵结构
海绵结构(sponge construction)包括吸收(sbsorbing)和挤压(squeezing)两个步骤,定义为 S P O N G E [ f , p a d , r ] ( N , d ) SPONGE[f,pad,r](N,d) SPONGE[f,pad,r](N,d),
- 固定长度的置换函数 f f f
- 比率(rate) r < b r < b r<b,而 c = b − r c = b-r c=b−r 叫做容量(capacity)
- 填充规则 p a d pad pad
- 输入的比特流 N N N
- 输出的比特长度 d d d
如图所示,在吸收阶段,输入比特流 N N N 做填充后被分成 r r r 长的若干块,与链接变量异或后作为置换函数的输入;在挤压阶段,每次直接将链接变量作为输入,将输出的链接变量截取 r r r 比特作为一个输出块(block);最后,截取 d d d 比特的前缀作为最终的输出。
KECCAK 是一族
K
E
C
C
A
K
−
f
[
b
]
KECCAK-f[b]
KECCAK−f[b] 置换下的海绵结构,填充规则使用
p
a
d
1
0
∗
1
pad10^*1
pad10∗1(即填充
1
∥
0
⋯
0
∥
1
1\|0\cdots0\|1
1∥0⋯0∥1 比特串)。它的
b
b
b 可以从
{
25
,
50
,
100
,
200
,
400
,
800
,
1600
}
\{25,50,100,200,400,800,1600\}
{25,50,100,200,400,800,1600} 中任意选择,如果设置
b
=
1600
b=1600
b=1600 那么有:
K
E
C
C
A
K
[
c
]
(
N
,
d
)
=
S
P
O
N
G
E
[
K
E
C
C
A
K
−
p
[
1600
,
24
]
,
p
a
d
1
0
∗
1
,
1600
−
c
]
(
N
,
d
)
KECCAK[c](N,d) = SPONGE[KECCAK-p[1600,24],\,\, pad10^*1,\,\, 1600-c](N,d)
KECCAK[c](N,d)=SPONGE[KECCAK−p[1600,24],pad10∗1,1600−c](N,d)
Hash & XOF
密码学哈希函数(cryptographic hash functions):SHA3-224
, SHA3-256
, SHA3-384
, SHA3-512
.
使用 KECCAK 函数,并设置 c = 2 d c=2d c=2d,再设置 N = M ∥ 01 N=M\|01 N=M∥01(两比特后缀),
- SHA3-224 ( M ) = K E C C A K [ 448 ] ( M ∥ 01 , 224 ) \text{SHA3-224}(M) = KECCAK[448](M\|01,224) SHA3-224(M)=KECCAK[448](M∥01,224),摘要的长度为 224 224 224 比特
- SHA3-256 ( M ) = K E C C A K [ 512 ] ( M ∥ 01 , 256 ) \text{SHA3-256}(M) = KECCAK[512](M\|01,256) SHA3-256(M)=KECCAK[512](M∥01,256),摘要的长度为 256 256 256 比特
- SHA3-384 ( M ) = K E C C A K [ 768 ] ( M ∥ 01 , 384 ) \text{SHA3-384}(M) = KECCAK[768](M\|01,384) SHA3-384(M)=KECCAK[768](M∥01,384),摘要的长度为 384 384 384 比特
- SHA3-512 ( M ) = K E C C A K [ 1024 ] ( M ∥ 01 , 512 ) \text{SHA3-512}(M) = KECCAK[1024](M\|01,512) SHA3-512(M)=KECCAK[1024](M∥01,512),摘要的长度为 512 512 512 比特
可扩展输出函数(extendable-output functions, XOF):SHAKE128
, SHAKE256
.
使用 KECCAK 函数,并设置 N = M ∥ 1111 N=M\|1111 N=M∥1111(四比特后缀),
- SHAKE128 ( M , d ) = K E C C A K [ 256 ] ( M ∥ 1111 , d ) \text{SHAKE128}(M,d) = KECCAK[256](M\|1111,d) SHAKE128(M,d)=KECCAK[256](M∥1111,d),参数为 b = 1600 , c = 256 b=1600,c=256 b=1600,c=256,每个输出的 block 长度为 r = 1344 r=1344 r=1344 比特
- SHAKE256 ( M , d ) = K E C C A K [ 512 ] ( M ∥ 1111 , d ) \text{SHAKE256}(M,d) = KECCAK[512](M\|1111,d) SHAKE256(M,d)=KECCAK[512](M∥1111,d),参数为 b = 1600 , c = 512 b=1600,c=512 b=1600,c=512,每个输出的 block 长度为 r = 1088 r=1088 r=1088 比特
Security
在公钥密码中,人们使用 SHA 系列和 SHAKE 系列作为 RO 实例。公钥密码的安全强度不会超过所使用 RO 实例的安全强度。目前还不存在超过 256-bit 安全强度的 RO 实例。
Derived Functions
NIST SP 800-185 标准定义了一些 FIPS 202 的派生函数,
- cSHAKE(customizable variant of the SHAKE),所谓 “定制化” 指的是:用户可以自定义 customization strings 作为额外输入,不同的 customization strings 对应的 Shake 函数将会是相互独立的。后续的三个派生函数都以 cSHAKE 作为基础。
- KMAC(KECCAK Message Authentication Code),包含一个任意长度的密钥串,用途是 PRF 或者 Keyed Hash。
- TupleHash,它将不同的字符串元组(包括空串)映射到无关的哈希值,这里的 “不同” 也包含了不同元组的各分量级联相同的情况。
- ParallelHash,用于高效处理 input 的长度很大的场景(并行计算可用时),它将 input 划分为长度 B B B 的分组,先分别哈希,然后将这些哈希值组合输入到 cSHAKE 作为哈希结果。
这四种派生函数的都以 cSHAKE 调用作为结束(with Arbitrary-Length Output),因此都可以作为 XOF 使用。