在椭圆曲线的解点上找到一个循环子群E1,当E1的阶是足够大时,这个循环子群中的离散对数问题是困难的。设P和Q是是椭圆曲线上的两个解点,t为一正整数,且 1 < t < ∣ E 1 ∣ 1<t<\vert{E1}\vert 1<t<∣E1∣
对于给定的P和t,去解tP=Q是容易的,但若知P和Q,计算t则是及其困难的。这便是椭圆曲线解点群上的离散对数问题。简称ECDLP.
在SEC1的椭圆曲线密码标准中规定,一个椭圆曲线密码由以下六元组所描述:
T = < p , a , b , G , n , h > T=<p,a,b,G,n,h> T=<p,a,b,G,n,h>
其中:
-
p,为大于3的素数,确定了有限域GF§.
-
a,b 确定了椭圆曲线,且 a , b ∈ G F ( p ) a,b\in GF(p) a,b∈GF(p)
-
G 循环子群E1的生成元,
-
n 为素数,是生成元的阶,G和n确定了循环子群E1
-
h 余因子,它将交换群E与循环子群E1联系起来,计算方式:
h = ∣ E 1 ∣ n h=\frac{\vert E1\vert }{n} h=n∣E1∣
用户的私钥定义成一个随机数d:
d ∈ 1 , 2 , 3... n − 1 d\in 1,2,3... n-1 d∈1,2,3...n−1
用户的公开密钥定义为Q点:
Q = d G Q=dG Q=dG
SM2椭圆曲线公钥密码加密算法
注:相关标准可参考GB/T 0009-2012 或GB/T 0010-2012等
SM2推荐使用256位素数域GF§上的椭圆曲线:
y 2 = x 3 + a x + b y^2=x^3+ax+b y2=x3+ax+b
并对上述六元组都给出了固定值。
加密算法
私钥d为用户定义的随机数: d ∈ 1 , 2 , 3... n − 1 d\in 1,2,3... n-1 d∈1,2,3...n−1
用户的公钥定义为椭圆曲线上的P点:P=dG
其中G=G(x,y)是基点。
设用户A要把比特串明文M进行加密发送给用户B,M的长度为klen,加密计算过程为:
1、用随机数发生器产生随机数k, k ∈ ∣ 1 , 2 , . . . , n − 1 ∣ k\in \vert 1,2,...,n-1\vert k∈∣1,2,...,n−1∣
2、计算椭圆曲线点: C 1 = k G = ( x 1 , y 1 ) , 将 C 1 的数据表示为比特串 C_1=kG=(x_1,y_1),将C_1的数据表示为比特串 C1=kG=(x1,y1),将C1的数据表示为比特串
3、计算椭圆曲线点: S = h P B , 若 S 是无穷远点,则报错并退出 S=hP_B,若S是无穷远点,则报错并退出 S=hPB,若S是无穷远点,则报错并退出
4、计算椭圆曲线点: k P B = ( x 2 , y 2 ) , 将坐标 x 2 , y 2 的数据表示为比特串 kP_B=(x_2,y_2),将坐标x_2,y_2的数据表示为比特串 kPB=(x2,y2),将坐标x2,y2的数据表示为比特串
5、计算: t = K F D ( x 2 ∥ y 2 , k l e n ) , 若 t 为全 0 比特串,则返回步骤 1 t=KFD(x_2\Vert y_2,klen),若t为全0比特串,则返回步骤1 t=KFD(x2∥y2,klen),若t为全0比特串,则返回步骤1
6、计算: C 2 = M ⨁ t C_2=M\bigoplus t C2=M⨁t
7、计算: C 3 = H a s h ( x 2 ∥ M ∥ y 2 ) C_3=Hash(x_2\Vert M \Vert y_2) C3=Hash(x2∥M∥y2)
8、输出密文: C = C 1 ∥ C 2 ∥ C 3 C=C_1 \Vert C_2 \Vert C_3 C=C1∥C2∥C3
解密算法
用户B收到密文后,解密过程如下:
1、从C中取出比特串 C 1 C_1 C1,将 C 1 C_1 C1的数据表示为椭圆曲线上的点,验证 C 1 C_1 C1是否满足椭圆曲线方程,若不满足则报错并退出;
2、计算椭圆曲线点S=h C 1 C_1 C1,若S是无穷远点,则报错退出;
3、计算 d B C 1 = ( x 2 , y 2 ) d_BC_1=(x_2,y_2) dBC1=(x2,y2),将坐标 x 2 , y 2 x_2,y_2 x2,y2的数据表示为比特串;
4、计算 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为全0比特串,则报错退出;
5、从C中取出比特串 C 2 C_2 C2,j计算 M , = C 2 ⨁ t M^,=C_2\bigoplus t M,=C2⨁t;
6、计算 u = H a s h ( x 2 ∥ M , ∣ ∣ y 2 ) u=Hash(x_2\|M^,||y_2) u=Hash(x2∥M,∣∣y2),从C中取出比特串 C 3 C_3 C3,若 u ≠ C 3 u\neq C_3 u=C3,则报错并退出;
7、输出明文 M , M^, M,。
SM2椭圆曲线签名算法
A、求 Z A Z_A ZA值
签名者用户A具有长度为entlenA比特的标识 I D A ID_A IDA,记作 E N T L A ENTL_A ENTLA,是由整数entlenA转换而成的两个字节。在椭圆曲线数字签名算法中,签名者和验证者都需要用密码杂凑函数(Hash函数)球的用户A的杂凑值 Z A Z_A ZA
Z A = H 2 56 ( E N T L A ∥ I D A ∥ a ∥ b ∥ X G ∥ Y G ∥ X A ∥ y A ) Z_A=H_256(ENTL_A\| ID_A \| a\|b\|X_G\|Y_G\|X_A\|y_A) ZA=H256(ENTLA∥IDA∥a∥b∥XG∥YG∥XA∥yA)
其中, H v ( ) H_v() Hv()表示摘要长度为v比特的密码杂凑函数,在这里 H 256 ( ) H_{256}() H256()选用SM3,a、b为椭圆曲线的系数, x G 、 y G x_G、y_G xG、yG为基点G的坐标, x A 、 y A x_A、y_A xA、yA为用户A的公钥 P A P_A PA的坐标。
B、签名
假设待签名消息为M
1、置 M = Z A ∥ M M=Z_A\|M M=ZA∥M;
2、计算 e = H v ( M ) e=H_v(M) e=Hv(M),并将e的数据表示为整数;
3、用随机数发生器产生随机数 k ∈ [ 1 , n − 1 ] k\in [1,n-1] k∈[1,n−1];
4、计算椭圆曲线点 G A = ( x A , y A ) G_A=(x_A,y_A) GA=(xA,yA)=kG,并将 x A x_A xA的数据表示为整数;
5、计算 r = ( e + x A ) m o d n r=(e+x_A)mod\quad n r=(e+xA)modn,若r=0或r+k=0,则返回步骤3;
6、计算 s = ( ( 1 + d A ) − 1 . ( k − r d A ) ) m o d n s=({(1+d_A)}^{-1}.(k-rd_A))mod\quad n s=((1+dA)−1.(k−rdA))modn,若s=0则返回3;
7、将r、s的数据表示为字节串,消息M的签名为(r,s)。
C 、验签
为了检验收到的消息 M , M^, M,及其数字签名 ( r , , s , ) (r^,,s^,) (r,,s,),收信用户B应当执行:
1、检验 r , ∈ [ 1 , n − 1 ] r^,\in [1,n-1] r,∈[1,n−1]是否成立,若不成立则验证不通过;
2、检验是 s , ∈ [ 1 , n − 1 ] s^,\in [1,n-1] s,∈[1,n−1]是否成立,若不成立则验证不通过;
3、置 M , = Z A ∣ ∥ M , M^,=Z_A|\|M^, M,=ZA∣∥M,;
4、计算 e , = H v ( M , ) e^,=H_v(M^,) e,=Hv(M,),将 e , e^, e,的数据表示为整数;
5、将 r , , s , r^,,s^, r,,s,的数据表示为整数,计算 t = ( r , + s , ) m o d n t=(r^,+s^,)mod\quad n t=(r,+s,)modn,若t=0,则验证不通过;
6、计算椭圆曲线点 G A , = ( x A , + y A , ) = s , G + t P A {G_A}^,=({x_A}^,+{y_A}^,)=s^,G+tP_A GA,=(xA,+yA,)=s,G+tPA;
7、将 x A , {x_A}^, xA,的数据表示为整数,计算 R = ( e , + x A , ) m o d n R=(e^,+{x_A}^,)mod\quad n R=(e,+xA,)modn,检验 R = r , R=r^, R=r,是否成立,若成立则验证通过,否则,验证不通过。