SM2 - 密钥交换协议
符号
A,B:使用公钥密码系统的两个用户。
\(a,b\):\(F_q\)中的元素,他们定义\(F_q\)上的一条椭圆曲线\(E\)。
\(d_A\):用户A的私钥。
\(d_B\):用户B的私钥。
\(E(F_q )\):\(F_q\)上椭圆曲线\(E\)的所有有理点(包括无穷远点\(O\))组成的集合。
\(F_q\):包含\(q\)个元素的有限域。
\(G\):椭圆曲线的一个基点,其阶为素数。
\(Hash()\):密码杂凑函数。
\(H_v()\):消息摘要长度为\(v\)比特的密码杂凑函数。
\(h\):余因子,\(h=♯E(F_q ) ⁄n\),其中\(n\)是基点\(G\)的阶。
\(ID_A,ID_B\):用户A和用户B的可辩别标识。
\(K,K_A,K_B\):密钥交换协议商定的共享秘密密钥。
\(KDF()\):密钥派生函数。
\(\mbox{mod }n\):模\(n\)元素。例如,\(23\mbox{ mod }7=2\)。
\(n\):基点\(G\)的阶(\(n\)是\(♯E(F_q )\)的素因子)。
\(O\):椭圆曲线上的一个特殊点,称为无穷远点或零点,是椭圆曲线加法群的单位元。
\(P_A\):用户A的公钥。
\(P_B\):用户B的公钥。
\(q\):有限域\(F_q\)中元素的数目。
\(r_A\):密钥交换中用户A产生的临时密钥值。
\(r_B\):密钥交换中用户B产生的临时密钥值。
\(x‖y\):\(x\)与\(y\)的拼接,其中\(x\)和\(y\)是比特串或字节串。
\(Z_A\):关于用户A的可辨识标识、部分椭圆曲线系统参数和用户A公钥的杂凑值。
\(Z_B\):关于用户B的可辨识标识、部分椭圆曲线系统参数和用户B公钥的杂凑值。
\(♯E(F_q )\):\(E(F_q )\)上点的数目,称为椭圆曲线\(E(F_q )\)的阶。
\([k]P\):椭圆曲线上点\(P\)的\(k\)倍点,即:\(\lbrack k\rbrack P = \underset{k\text{个}}{\underbrace{P + P + \cdots + P}}\),其中\(k\)是正整数。
\([x,y]\):大于或等于\(x\)且小于或等于\(y\)的整数的集合。
\(⌈x⌉\):顶函数,大于或等于\(x\)的最小整数。例如,\(⌈7⌉=7\),\(⌈8.3⌉=9\)。
\(⌊x⌋\):底函数,小于或等于\(y\)的最大整数。例如,\(⌊7⌋=7\),\(⌊8.3⌋=8\)。
\(\&\):两个整数的按比特与运算。
用户密码对
用户A的密钥对包括其私钥\(d_A\)和公钥\(P_A=[d_A ]G=(x_A,y_A )\),用户B的密钥对包括其私钥\(d_B\)和公钥\(P_B=[d_B ]G=(x_B,y_B )\)。
密钥派生函数
设密码杂凑函数为\(H_v ()\),其输出是长度为\(v\)比特的杂凑值。
密钥派生函数\(KDF(Z,klen)\):
输入:比特串\(Z\),整数\(klen\)(表示要获得的密钥数据的比特长度,要求该值小于\((2^{32}-1)v\))。
输出:长度为\(klen\)的密钥数据比特串\(K\)。
- 初始化一个32比特构成的计数器\(ct=\mbox{0x}00000001\);
- 对\(i\)从\(1\)到\(⌈klen⁄v⌉\)执行:
2.1. 计算\(Ha_i=H_v(Z‖ct)\);
2.2. \(ct++\); - 若\(klen⁄v\)是整数,令\(Ha!_{⌈klen⁄v⌉}=Ha_{⌈klen⁄v⌉}\),否则令\(Ha!_{⌈klen⁄v⌉}\)为\(Ha_{⌈klen⁄v⌉}\)最左边的\((klen-(v×⌊klen⁄v⌋))\)比特;
- 令\(K=Ha_1 ‖Ha_2 ‖⋯‖Ha_{⌈klen⁄v⌉-1} ‖Ha!_{⌈klen⁄v⌉}\)。
用户其他信息
用户A具有长度为\(entlen_A\)比特的可辨识标识\(ID_A\),记\(ENTL_A\)是由整数\(entlen_A\)转换而成的两个字节;用户B具有长度为\(entlen_B\)比特的可辨识标识\(ID_B\),记\(ENTL_B\)是由整数\(entlen_B\)转换而成的两个字节。将椭圆曲线方程参数\(a\)、\(b\)、\(G\)的坐标\(x_G\)、\(y_G\)和\(P_A\)的坐标\(x_A\)、\(y_A\)的数据类型转换为比特串,\(Z_A=H_{256}(ENTL_A ‖ID_A ‖a‖b‖x_G ‖y_G ‖x_A ‖y_A )\);将椭圆曲线方程参数\(a\)、\(b\)、\(G\)的坐标\(x_G\)、\(y_G\)和\(P_B\)的坐标\(x_B\)、\(y_B\)的数据类型转换为比特串,\(Z_B=H_{256}(ENTL_B ‖ID_B ‖a‖b‖x_G ‖y_G ‖x_B ‖y_B )\)。
密钥交换协议
设用户A和B协商获得密钥数据的长度为\(klen\)比特,用户A为发起方,用户B为响应方。
用户A和B双方为了获得相同的密钥,应实现如下运算步骤:
记\(w=⌈⌈log_2n ⌉⁄2⌉-1\)。
用户A:
A1. 用随机数发生器产生随机数\(r_A∈[1,n-1]\);
A2. 计算椭圆曲线点\(R_A=[r_A ]G=(x_1,y_1 )\);
A3. 将\(R_A\)发送给用户B;
用户B:
B1. 用随机数发生器产生随机数\(r_B∈[1,n-1]\);
B2. 计算椭圆曲线点\(R_B=[r_B ]G=(x_2,y_2 )\);
B3. 从\(R_B\)中取出域元素\(x_2\),计算\(\bar{x}_2=2^w+(x_2\&(2^w-1))\);
B4. 计算\(t_B=(d_B+\bar{x}_2⋅r_B )\mbox{ mod }n\);
B5. 验证\(R_A\)是否满足椭圆曲线方程,若不满足则协商失败;否则从\(R_A\)中取出域元素\(x_1\),计算\(\bar{x}_1=2^w+(x_1\&(2^w-1))\);
B6. 计算椭圆曲线点\(V=[h⋅t_B ](P_A+[\bar{x}_1] R_A )=(x_V,y_V )\),若\(V\)是无穷远点,则B协商失败;否则将\(x_V\)、\(y_V\)的数据类型转换为比特串;
B7. 计算\(K_B=KDF(x_V ‖y_V ‖Z_A ‖Z_B,klen)\);
B8. (选项)将\(R_A\)的坐标\(x_1\)、\(y_1\)和\(R_B\)的坐标\(x_2\)、\(y_2\)的数据类型转换为比特串,计算\(S_B=Hash(\mbox{0x}02‖y_V ‖Hash(x_V ‖Z_A ‖Z_B ‖x_1 ‖y_1 ‖x_2 ‖y_2 ) )\);
B9. 将\(R_B\)、(选项\(S_B\))发送给用户A;
用户A:
A4. 从\(R_A\)中取出域元素\(x_1\),计算\(\bar{x}_1=2^w+(x_1\&(2^w-1))\);
A5. 计算\(t_A=(d_A+\bar{x}_1⋅r_A )\mbox{ mod }n\);
A6. 验证\(R_B\)是否满足椭圆曲线方程,若不满足则协商失败;否则从\(R_B\)中取出域元素\(x_2\),计算\(\bar{x}_2=2^w+(x_2\&(2^w-1))\);
A7. 计算椭圆曲线点\(U=[h⋅t_A ](P_B+[\bar{x}_2] R_B )=(x_U,y_U )\),若\(U\)是无穷远点,则A协商失败;否则将\(x_U\)、\(y_U\)的数据类型转换为比特串;
A8. 计算\(K_A=KDF(x_U ‖y_U ‖Z_A ‖Z_B,klen)\);
A9. (选项)将\(R_A\)的坐标\(x_1\)、\(y_1\)和\(R_B\)的坐标\(x_2\)、\(y_2\)的数据类型转换为比特串,计算\(S_1=Hash(\mbox{0x}02‖y_U ‖Hash(x_U ‖Z_A ‖Z_B ‖x_1 ‖y_1 ‖x_2 ‖y_2 ) )\),并检验\(S_1=S_B\)是否成立,若等式不成立则从B到A的密钥确认失败;
A10. (选项)计算\(S_A=Hash(\mbox{0x}03‖y_U ‖Hash(x_U ‖Z_A ‖Z_B ‖x_1 ‖y_1 ‖x_2 ‖y_2 ) )\),并将\(S_A\)发送给用户B。
用户B:
B10. (选项)计算\(S_2=Hash(\mbox{0x}03‖y_V ‖Hash(x_V ‖Z_A ‖Z_B ‖x_1 ‖y_1 ‖x_2 ‖y_2 ) )\),并检验\(S_2=S_A\)是否成立,若等式不成立则从A到B的密钥确认失败。
注:在步骤B6、A7中计算获得的\(V\)、\(U\)分别满足如下公式:
参考
GM/T 0003.3—2012