[原]国密SM2算法
版权声明:本文为博主原创文章,转载请注明来源!获取更新内容请关注我的开源项目:https://github.com/zcc0721/MasterBlockchain https://blog.csdn.net/u013137970/article/details/84573200
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
椭圆曲线算法那公钥密码所基于的曲线性质:椭圆曲线多倍点运算构成一个单向函数。在多倍点运算中,已知多倍点与基点,求解倍数的问题称为椭圆曲线离散对数问题。对于一般椭圆曲线的离散对数问题,目前只存在指数级计算复杂度的求解方法。与大数分解问题及有限域上离散对数问题相比,椭圆曲线离散对数问题的求解难度要大得多。因此,在相同安全程度要求下,椭圆曲线密码较其他公钥密码所需的秘钥规模要小得多。
数字签名算法由一个签名者对数据产生数字签名,并由一个验证者验证签名的可靠性。每个签名者都有一个公钥和一个私钥,其中私钥用于产生签名,验证者用签名者的公钥验证签名。在签名的生成过程之前,要用密码杂凑算法对 和待签消息 进行压缩;在验证过程之前,要用密码杂凑算法对 和待签消息 进行同样的压缩。
2 基础参数
SM2的曲线方程为 ,其中:
- :
0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC - :
0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93 - :
0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF
私钥长度:32字节。
公钥长度:SM2非压缩公钥格式字节串长度为65字节,压缩格式长度为33字节,若公钥y坐标最后一位为0,则首字节为0x02,否则为0x03。非压缩格式公钥首字节为0x04。
签名长度:64字节。
3 密钥对生成
SM2密钥生成是指生成SM2算法的密钥对的过程,该密钥对包括私钥和与之对应的公钥。
- 输入:无
- 输出:
- k:SM2PrivateKey,SM2私钥
- Q:SM2PublicKey,SM2公钥
- 用随机数发生器产生整数 ;
- 为基点,计算点 。
则私钥是,公钥为。
4 签名算法
4.1 预处理1
预处理1是指使用签名方的用户身份标识和签名方公钥,通过运算得到Z值的过程。Z值用于预处理2。
- 输入:
- ID:字符串,用户身份标识
- Q:SM2PublicKey,用户的公钥
- 输出:
- Z:字节串,预处理1的输出
- 计算公式:
- 参数说明:
- :为由2个字节标识的ID的比特长度;
- :为用户身份标识。无特殊约定的情况下,用户身份标识ID的长度为16字节,其默认值从左至右依次为:0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38。
- :为系统曲线参数;
- 为基点;
- 为用户的公钥。
4.2 预处理2
预处理2是指使用Z值和待签名消息,通过SM3运算得到杂凑值H的过程。杂凑值H用于SM2数字签名。
- 输入:
- Z:字节串,预处理2的输入
- M:字节串,待签名消息
- 输出:
- H:字节串,杂凑值
- 计算公式:
4.3 生成签名
SM2签名是指使用预处理2的结果和签名者的私钥,通过签名计算得到签名结果的过程。
- 输入:
- d:SM2PrivateKey,签名者私钥
- H:字节串,预处理2的结果
- 输出:
- sign:SM2Signature,签名值
设待签名的消息为M,为了获取消息M的数字签名 ,作为签名者的用户A应实现以下运算步骤:
- 置 ;
- 计算 ,将 的数据类型转化为整数;
- 用随机数发生器产生随机数 ;
- 计算椭圆曲线点 ,将 的数据类型转化为整数;
- 计算 ,若 或 则返回第3步;
- 计算 ,若 则返回第3步;
- 将 转化为字节串。
消息M的签名为。
4.4 签名验证
SM2签名验证是指使用预处理2的结果、签名值和签名者的公钥,通过验签计算确定签名是否通过验证的过程。
- 输入:
- H:字节串,预处理2的结果
- sign:SM2Signature,签名值
- Q:PublicKey,签名者的公钥
- 输出:为真表示验证通过,为假表示验证不通过。
为了检验收到的消息 M及其数字签名,作为验证者的用户B应实现以下运算步骤:
- 检验 是否成立,若不成立则验证不通过;
- 检验 是否成立,若不成立则验证不通过;
- 置 ;
- 计算 ,将的数据类型转化为整数;
- 将 的数据类型转化为整数,计算 ,若 ,则验证不通过;
- 计算椭圆曲线点 ;
- 将 的数据类型转化为整数,计算 ,检验 是否成立,若成立则验证通过;否则验证不通过。
4.5 签名验证原理
5 参考资料
https://blog.csdn.net/u013137970/article/details/84573200

![[原]智能合约编写实例](http://www.memleaking.com/wp-content/uploads/2018/07/e58e9fe699bae883bde59088e7baa6e7bc96e58699e5ae9ee4be8b.png)
