Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
108 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
--- | ||
layout: post | ||
title: "SM3密码杂凑算法" | ||
date: 2021-10-05 23:59:12 | ||
categories: [算法] | ||
excerpt_separator: <!--more--> | ||
--- | ||
SM3密码杂凑算法 | ||
<!--more--> | ||
|
||
## 1. 填充 | ||
|
||
假设消息m 的长度为l 比特。首先将比特“1”添加到消息的末尾,再添加k 个“0”,k是满足l + 1 + k ≡ 448mod512 的最小的非负整数。然后再添加一个64位比特串,该比特串是长度l的二进制表示。 | ||
|
||
其中将bit转byte有$448bit = 56byte$,$512bit = 64byte$。 | ||
$l + 1 + k \equiv 448 mod 512$ 等于 $l + 1 + k \equiv 56 mod 64$ | ||
若$a \equiv b \mod p$,则对于任意的c,都有$(a + c) \equiv (b + c) \mod p$。 | ||
$$k \equiv (56 - 1 - l) \mod 64 \qquad 0 \le k \le 63$$ | ||
|
||
```go | ||
// 填充go语言实现 | ||
// 1 byte end marker :: 0-63 padding bytes :: 8 byte length | ||
tmp := [1 + 63 + 8]byte{0x80} | ||
pad := (55 - len) % 64 // calculate number of padding bytes | ||
binary.BigEndian.PutUint64(tmp[1+pad:], len<<3) // append length in bits | ||
Write(tmp[:1+pad+8]) | ||
``` | ||
|
||
## 2. 迭代过程 | ||
|
||
将填充后的消息m′按512比特进行分组:m′ = B(0)B (1)· · · B(n−1)。 | ||
|
||
```go | ||
for i := 0; i <= len(p)-BlockSize; i += BlockSize { | ||
// eliminate bounds checks on p | ||
q := p[i:] | ||
q = q[:BlockSize:BlockSize] | ||
} | ||
``` | ||
|
||
## 3. 消息扩展 | ||
|
||
* a) 将消息分组B(i)划分为16个字W0, W1, · · ·, W15。 | ||
```go | ||
for j := 0; j < 16; j++ { | ||
w0[j] = binary.BigEndian.Uint32(q[4*j : 4*(j+1)]) | ||
} | ||
``` | ||
|
||
* b) | ||
$ | ||
FOR \quad j=16 \quad TO \quad 67 \\ | ||
\qquad W_j ← P1(W_{j−16} ⊕ W_{j−9} ⊕ (W_{j−3} ≪ 15)) ⊕ (W_{j−13} ≪ 7) ⊕ W_{j−6} \\ | ||
ENDFOR | ||
$ | ||
```go | ||
for j := 16; j < 68; j++ { | ||
w0[j] = P1(w0[j-16]^w0[j-9]^bits.RotateLeft32(w0[j-3], 15)) ^ bits.RotateLeft32(w0[j-13], 7) ^ w0[j-6] | ||
} | ||
``` | ||
|
||
* c) | ||
$ | ||
FOR \quad j=0 \quad TO \quad 63 \\ | ||
\qquad W'_j = W_j ⊕ W_{j+4} \\ | ||
ENDFOR | ||
$ | ||
|
||
```go | ||
for j := 0; j < 64; j++ { | ||
w1[j] = w0[j] ^ w0[j+4] | ||
} | ||
``` | ||
|
||
## 4. 压缩函数 | ||
|
||
```go | ||
A, B, C, D, E, F, G, H := a, b, c, d, e, f, g, h | ||
for j := 0; j < 16; j++ { | ||
SS1 := bits.RotateLeft32(bits.RotateLeft32(A, 12)+E+bits.RotateLeft32(0x79cc4519, j), 7) | ||
SS2 := SS1 ^ bits.RotateLeft32(A, 12) | ||
TT1 := FF0(A, B, C) + D + SS2 + w1[j] | ||
TT2 := GG0(E, F, G) + H + SS1 + w0[j] | ||
D = C | ||
C = bits.RotateLeft32(B, 9) | ||
B = A | ||
A = TT1 | ||
H = G | ||
G = bits.RotateLeft32(F, 19) | ||
F = E | ||
E = P0(TT2) | ||
} | ||
for j := 16; j < 64; j++ { | ||
SS1 := bits.RotateLeft32(bits.RotateLeft32(A, 12)+E+bits.RotateLeft32(0x7a879d8a, j), 7) | ||
SS2 := SS1 ^ bits.RotateLeft32(A, 12) | ||
TT1 := FF1(A, B, C) + D + SS2 + w1[j] | ||
TT2 := GG1(E, F, G) + H + SS1 + w0[j] | ||
D = C | ||
C = bits.RotateLeft32(B, 9) | ||
B = A | ||
A = TT1 | ||
H = G | ||
G = bits.RotateLeft32(F, 19) | ||
F = E | ||
E = P0(TT2) | ||
} | ||
a, b, c, d, e, f, g, h = a^A, b^B, c^C, d^D, e^E, f^F, g^G, h^H | ||
``` |