SM2椭圆曲线公钥密码算法
简介:
SM2 是中国国家密码管理局颁布的中国商用公钥密码标准算法,它是一组椭圆曲线密码算法,其中包含加解密算法、数宇签名算法。
SM2 算法与与国际标准的 ECC 算法比较:
(1) ECC 算法通常采用 NIST 等国际机构建议的曲线及参数,而 SM2 算法的参数需要利用一定的算法产生。而由于算法中加入了用户特异性的曲线参数
、基点、用户的公钥点信息,故使得 SM2 算法的安全性明显提高。
(2) 在 ECC 算法中,用户可以选择 MD5 或 SHA-1 等国际通用的哈希算法。而 SM2算法中则使用 SM3 哈希算法,SM3 算法输出为 256 比特,其安全性
与SHA-256 算法基本相当。
SM2 算法分为基于素数域和基于二元扩域两种。本节仅介绍基于素数域的 SM2 算法。
基本参数:
基于素数域的SM2算法参数如下:
具体含义:
A
,
B
:
A,B:
A,B:使用公钥密码系统的两个用户。
a
,
b
:
a,b:
a,b:
F
q
Fq
Fq 中的元素,它们定义
F
q
Fq
Fq上的一条椭圆曲线
E
E
E。
d
B
:
d_B:
dB:用户
B
B
B 的私钥。
E
(
F
q
)
:
F
q
E(Fq):Fq
E(Fq):Fq上椭圆曲线
E
E
E 的所有有理点(包括无穷远点
O
O
O)组成的集合。
F
q
:
Fq:
Fq:包含
q
q
q 个元素的有限域。
G
:
G:
G:椭圆曲线的一个基点,其阶为素数。
H
a
s
h
(
)
:
Hash( ):
Hash():密码杂凑函数。
H
v
(
)
:
Hv( ):
Hv():消息摘要长度为
v
v
v 比特的密码杂凑函数。
K
D
F
(
)
:
KDF( ):
KDF():密钥派生函数。
M
:
M :
M:待加密的消息。
M
′:
M′:
M′:解密得到的消息。
n
:
n:
n:基点
G
G
G 的阶(
n
n
n 是 #
E
(
F
q
)
E(Fq)
E(Fq)的素因子)。
O
:
O:
O:椭圆曲线上的一个特殊点,称为无穷远点或零点,是椭圆曲线加法群的单位元。
P
B
:
P_B:
PB:用户
B
B
B 的公钥。
q
:
q:
q:有限域
F
q
Fq
Fq 中元素的数目。
x
∥
y
:
x
x∥y:x
x∥y:x 与
y
y
y 的拼接,其中
x
x
x、
y
y
y 可以是比特串或字节串。
[
k
]
P
:
[k]P:
[k]P:椭圆曲线上点
P
P
P 的
k
k
k 倍点,即
[
k
]
P
=
P
+
P
+
⋅
⋅
⋅
+
P
[k]P= P + P + · · · + P
[k]P=P+P+⋅⋅⋅+P,一共
k
k
k 个
P
P
P,
k
k
k 是正整数。
[
x
,
y
]
:
[x,y]:
[x,y]:大于或等于
x
x
x 且小于或等于
y
y
y 的整数的集合。
⌈
x
⌉
:
⌈x⌉:
⌈x⌉:顶函数,大于或等于x的最小整数。例如
⌈
7
⌉
=
7
⌈7⌉=7
⌈7⌉=7,
⌈
8.3
⌉
=
9
⌈8.3⌉=9
⌈8.3⌉=9。
⌊
x
⌋
:
⌊x⌋:
⌊x⌋:底函数,小于或等于x的最大整数。例如
⌊
7
⌋
=
7
⌊7⌋=7
⌊7⌋=7,
⌊
8.3
⌋
=
8
⌊8.3⌋=8
⌊8.3⌋=8。
#
E
(
F
q
)
:
E
(
F
q
)
E(Fq):E(Fq)
E(Fq):E(Fq)上点的数目,称为椭圆曲线
E
(
F
q
)
E(Fq)
E(Fq) 的阶。
密钥产生:
设接收方为
B
B
B,
B
B
B 的秘密钥取为 {1,2,···,n-1} 中的一个随机数
d
B
d_B
dB,记为
d
B
d_B
dB←
R
_R
R{1,2,···,n-1},其中
n
n
n 是基点
G
G
G 的阶。
B
B
B 的公开钥取为椭圆曲线上的点:
P
B
P_B
PB =
[
d
B
]
[d_B]
[dB]G
其中
G
G
G =
G
(
x
,
y
)
G(x,y)
G(x,y)是基点。
加密算法及流程:
设
A
A
A 需要发送的消息为比特串
M
M
M,
k
l
e
n
klen
klen 为
M
M
M 的比特长度。
为了对明文
M
M
M 进行加密,作为加密者的用户
A
A
A 应实现以下运算步骤:
A
1
:
A1:
A1:用随机数发生器产生随机数
k
∈
[
1
,
n
−
1
]
;
k∈[1,n-1];
k∈[1,n−1];
A
2
:
A2:
A2:计算椭圆曲线点
C
1
=
[
k
]
G
=
(
x
1
,
y
1
)
C_1=[k]G =(x_1,y_1)
C1=[k]G=(x1,y1),将
C
1
C_1
C1 的数据类型转换为比特串;
A
3
:
A3:
A3:计算椭圆曲线点
S
=
[
h
]
S=[h]
S=[h]
P
B
P_B
PB,若
S
S
S 是无穷远点,则报错并退出;
A
4
:
A4:
A4:计算椭圆曲线点
[
k
]
P
B
=
(
x
2
,
y
2
)
[k]P_B=(x_2,y_2)
[k]PB=(x2,y2),将坐标
x
2
x_2
x2、
y
2
y_2
y2 的数据类型转换为比特串;
A
5
:
A5:
A5:计算
t
=
K
D
F
(
x
2
∥
y
2
,
k
l
e
n
)
t=KDF(x_2 ∥ y_2,klen)
t=KDF(x2∥y2,klen),若
t
t
t 为全
0
0
0 比特串,则返回
A
1
A1
A1 ;
A
6
:
A6:
A6:计算
C
2
=
M
⊕
t
;
C_2 = M ⊕ t;
C2=M⊕t;
A
7
:
A7:
A7:计算
C
3
=
H
a
s
h
(
x
2
∥
M
∥
y
2
)
;
C_3 = Hash(x_2 ∥ M ∥ y_2);
C3=Hash(x2∥M∥y2);
A
8
:
A8:
A8:输出密文
C
=
C
1
∥
C
2
∥
C
3
。
C = C_1 ∥ C_2 ∥ C_3。
C=C1∥C2∥C3。
下图就是SM2加密算法的流程图:
解密算法及流程:
设
k
l
e
n
klen
klen 为密文中
C
2
C_2
C2 的比特长度。
为了对密文
C
=
C
1
∥
C
2
∥
C
3
C=C_1 ∥ C_2 ∥ C_3
C=C1∥C2∥C3 进行解密,作为解密者的用户
B
B
B 应实现以下运算步骤:
B
1
:
B1:
B1:从
C
C
C 中取出比特串
C
1
C_1
C1,将
C
1
C_1
C1的数据类型转换为椭圆曲线上的点,验证
C
1
C_1
C1 是否满足椭圆曲线方程,若不满足则报错并退出;
B
2
:
B2:
B2:计算椭圆曲线点
S
=
[
h
]
C
1
S=[h]C_1
S=[h]C1,若
S
S
S 是无穷远点,则报错并退出;
B
3
:
B3:
B3:计算
[
d
B
]
C
1
=
(
x
2
,
y
2
)
[d_B]C_1=(x_2,y_2)
[dB]C1=(x2,y2),将坐标
x
2
、
y
2
x_2、y_2
x2、y2 的数据类型转换为比特串;
B
4
:
B4:
B4:计算
t
=
K
D
F
(
x
2
∥
y
2
,
k
l
e
n
)
t=KDF(x_2 ∥ y_2,klen)
t=KDF(x2∥y2,klen),若
t
t
t 为全
0
0
0 比特串,则报错并退出;
B
5
:
B5:
B5:从
C
C
C 中取出比特串
C
2
C_2
C2,计算
M
′
=
C
2
⊕
t
M′ = C_2 ⊕ t
M′=C2⊕t;
B
6
:
B6:
B6:计算
u
=
H
a
s
h
(
x
2
∥
M
′∥
y
2
)
u = Hash(x_2 ∥ M′ ∥ y_2)
u=Hash(x2∥M′∥y2),从
C
C
C 中取出比特串
C
3
C_3
C3,若
u
u
u ̸=
C
3
C_3
C3,则报错并退出;
B
7
:
B7:
B7:输出明文
M
′
M′
M′。
下图就是SM2解密算法的流程图:
解密的正确性: 因为
P
B
=
[
d
B
]
G
,
C
1
=
[
k
]
G
=
(
x
1
,
y
1
)
P_B=[d_B]G,C_1=[k]G=(x_1,y_1)
PB=[dB]G,C1=[k]G=(x1,y1),由解密算法的第(3)步可得
[
d
B
]
C
1
=
[
d
B
]
[
k
]
G
=
[
k
]
(
[
d
B
]
G
)
=
[
k
]
P
B
=
(
x
2
,
y
2
)
[d_B]C_1 = [d_B][k]G = [k]([d_B]G) = [k]P_B = (x_2,y_2)
[dB]C1=[dB][k]G=[k]([dB]G)=[k]PB=(x2,y2)
所以解密算法第(4)步得到的
t
t
t 与加密算法第(5)步得到的相等,由
C
,
t
C,t
C,t,便得到明文
M
M
M。