国密SM2算法

1 前言

比原链的智能合约支持国密算法的函数。SM2是国密标准的椭圆曲线加密算法,遵循以下SM2国家标准:

  • GB/T 32918.1-2016
  • GB/T 32918.2-2016
  • GB/T 32918.3-2016
  • GB/T 32918.4-2016
  • GB/T 32918.5-2017
  • GB/T 35275-2017
  • GB/T 35276-2017

椭圆曲线算法那公钥密码所基于的曲线性质:椭圆曲线多倍点运算构成一个单向函数。在多倍点运算中,已知多倍点与基点,求解倍数的问题称为椭圆曲线离散对数问题。对于一般椭圆曲线的离散对数问题,目前只存在指数级计算复杂度的求解方法。与大数分解问题及有限域上离散对数问题相比,椭圆曲线离散对数问题的求解难度要大得多。因此,在相同安全程度要求下,椭圆曲线密码较其他公钥密码所需的秘钥规模要小得多。

数字签名算法由一个签名者对数据产生数字签名,并由一个验证者验证签名的可靠性。每个签名者都有一个公钥和一个私钥,其中私钥用于产生签名,验证者用签名者的公钥验证签名。在签名的生成过程之前,要用密码杂凑算法对 Z A Z_A ZA 和待签消息 M M M 进行压缩;在验证过程之前,要用密码杂凑算法对 Z A Z_A ZA 和待签消息 M M M 进行同样的压缩。

2 基础参数

SM2的曲线方程为 y 2 = x 3 + a x + b \displaystyle y^2 = x^3 + ax + b y2=x3+ax+b ,其中:

  • a a a0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC
  • b b b0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93
  • p p p0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF

私钥长度:32字节。

公钥长度:SM2非压缩公钥格式字节串长度为65字节,压缩格式长度为33字节,若公钥y坐标最后一位为0,则首字节为0x02,否则为0x03。非压缩格式公钥首字节为0x04

签名长度:64字节。

3 密钥对生成

SM2密钥生成是指生成SM2算法的密钥对的过程,该密钥对包括私钥和与之对应的公钥。

  • 输入:无
  • 输出:
    • k:SM2PrivateKey,SM2私钥
    • Q:SM2PublicKey,SM2公钥
  1. 用随机数发生器产生整数 d ∈ [ 1 , n − 2 ] \displaystyle d\in[1,n-2] d[1,n2]
  2. G G G 为基点,计算点 P = ( x P , y P ) = [ d ] G \displaystyle P=(x_P,y_P)=[d]G P=(xP,yP)=[d]G

则私钥是 d d d,公钥为 P P P

4 签名算法

4.1 预处理1

预处理1是指使用签名方的用户身份标识和签名方公钥,通过运算得到Z值的过程。Z值用于预处理2。

  • 输入:
    • ID:字符串,用户身份标识
    • Q:SM2PublicKey,用户的公钥
  • 输出:
    • Z:字节串,预处理1的输出
  • 计算公式: Z = S M 3 ( E N T L ∣ ∣ I D ∣ ∣ a ∣ ∣ b ∣ ∣ x G ∣ ∣ y G ∣ ∣ x A ∣ ∣ y A ) Z=SM3(ENTL||ID||a||b||x_G||y_G||x_A||y_A) Z=SM3(ENTLIDabxGyGxAyA)
  • 参数说明:
    • E N T L ENTL ENTL:为由2个字节标识的ID的比特长度;
    • I D ID ID:为用户身份标识。无特殊约定的情况下,用户身份标识ID的长度为16字节,其默认值从左至右依次为:0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38。
    • a , b a,b a,b:为系统曲线参数;
    • x G ,   y G \displaystyle x_G,\ y_G xG, yG 为基点;
    • x A ,   y A \displaystyle x_A,\ y_A xA, yA 为用户的公钥。

4.2 预处理2

预处理2是指使用Z值和待签名消息,通过SM3运算得到杂凑值H的过程。杂凑值H用于SM2数字签名。

  • 输入:
    • Z:字节串,预处理2的输入
    • M:字节串,待签名消息
  • 输出:
    • H:字节串,杂凑值
  • 计算公式: H = S M 3 ( Z ∣ ∣ M ) \displaystyle H=SM3(Z||M) H=SM3(ZM)

4.3 生成签名

SM2签名是指使用预处理2的结果和签名者的私钥,通过签名计算得到签名结果的过程。

  • 输入:
    • d:SM2PrivateKey,签名者私钥
    • H:字节串,预处理2的结果
  • 输出:
    • sign:SM2Signature,签名值

设待签名的消息为M,为了获取消息M的数字签名 ( r , s ) (r,s) (r,s),作为签名者的用户A应实现以下运算步骤:

  1. M ‾ = Z A ∣ ∣ M \displaystyle \overline{M}=Z_A||M M=ZAM ;
  2. 计算 e = H v ( M ‾ ) \displaystyle e=H_v(\overline{M}) e=Hv(M) ,将 e e e 的数据类型转化为整数;
  3. 用随机数发生器产生随机数 k ∈ [ 1 , n − 1 ] \displaystyle k\in[1,n-1] k[1,n1]
  4. 计算椭圆曲线点 ( x 1 , y 1 ) = [ k ] G \displaystyle (x_1,y_1)=[k]G (x1,y1)=[k]G ,将 x 1 \displaystyle x_1 x1 的数据类型转化为整数;
  5. 计算 r = ( e + x 1 ) m o d   n \displaystyle r=(e+x_1) mod \ n r=(e+x1)mod n ,若 r = 0 r = 0 r=0 r + k = n r + k = n r+k=n 则返回第3步;
  6. 计算 s = ( ( 1 + d A ) − 1 ⋅ ( k − r ⋅ d A ) ) m o d   n \displaystyle s=((1+d_A)^{-1}\cdot (k-r \cdot d_A)) mod\ n s=((1+dA)1(krdA))mod n ,若 s = 0 s=0 s=0 则返回第3步;
  7. r , s r, s r,s 转化为字节串。

消息M的签名为 ( r , s ) (r, s) (r,s)

4.4 签名验证

SM2签名验证是指使用预处理2的结果、签名值和签名者的公钥,通过验签计算确定签名是否通过验证的过程。

  • 输入:
    • H:字节串,预处理2的结果
    • sign:SM2Signature,签名值
    • Q:PublicKey,签名者的公钥
  • 输出:为真表示验证通过,为假表示验证不通过。

为了检验收到的消息 M及其数字签名 ( r , s ) (r, s) (r,s),作为验证者的用户B应实现以下运算步骤:

  1. 检验 r ∈ [ 1 , n − 1 ] \displaystyle r\in[1,n-1] r[1,n1] 是否成立,若不成立则验证不通过;
  2. 检验 s ∈ [ 1 , n − 1 ] \displaystyle s\in[1,n-1] s[1,n1] 是否成立,若不成立则验证不通过;
  3. M ‾ = Z A ∣ ∣ M \displaystyle \overline{M}=Z_A||M M=ZAM ;
  4. 计算 e = H v ( M ‾ ) \displaystyle e=H_v(\overline{M}) e=Hv(M) ,将 e e e的数据类型转化为整数;
  5. r , s r,s r,s 的数据类型转化为整数,计算 t = ( r + s ) m o d   n \displaystyle t=(r+s) mod \ n t=(r+s)mod n ,若 t = 0 t=0 t=0,则验证不通过;
  6. 计算椭圆曲线点 ( x 1 , y 1 ) = [ s ] G + [ t ] P A \displaystyle (x_1,y_1)=[s]G+[t]P_A (x1,y1)=[s]G+[t]PA
  7. x 1 \displaystyle x_1 x1 的数据类型转化为整数,计算 R = ( e + x 1 ) m o d   n \displaystyle R=(e+x_1) mod \ n R=(e+x1)mod n ,检验 R = r R=r R=r 是否成立,若成立则验证通过;否则验证不通过。

4.5 签名验证原理

[ s ] G + [ t ] P A = s G + ( r + s ) P A = s G + ( r + s ) d A G = s G + s d A G + r d A G = ( 1 + d A ) s G + r d A G = ( 1 + d A ) ( 1 + d A ) − 1 ( k − r d A ) G + r d A G = ( k − r d A ) G + r d A G = k G − r d A G + r d A G = k G = ( x 1 , y 1 ) \displaystyle \begin{aligned} [s]G+[t]P_A &=sG+(r+s)P_A\\ &=sG+(r+s)d_AG\\ &=sG+s d_AG+rd_AG\\ &=(1+d_A)sG+rd_AG\\ &=(1+d_A)(1+d_A)^{-1}(k-rd_A)G+rd_AG\\ &=(k-rd_A)G+rd_AG\\ &=kG-rd_AG+rd_AG\\ &=kG\\ &=(x_1,y_1) \end{aligned} [s]G+[t]PA=sG+(r+s)PA=sG+(r+s)dAG=sG+sdAG+rdAG=(1+dA)sG+rdAG=(1+dA)(1+dA)1(krdA)G+rdAG=(krdA)G+rdAG=kGrdAG+rdAG=kG=(x1,y1)

5 参考资料

  • 19
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值