gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/sm2soft/sm2.go (about)

     1  // Copyright (c) 2022 zhaochun
     2  // core-gm is licensed under Mulan PSL v2.
     3  // You can use this software according to the terms and conditions of the Mulan PSL v2.
     4  // You may obtain a copy of Mulan PSL v2 at:
     5  //          http://license.coscl.org.cn/MulanPSL2
     6  // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
     7  // See the Mulan PSL v2 for more details.
     8  
     9  /*
    10  sm2soft 是sm2的纯软实现,基于tjfoc国密算法库`tjfoc/gmsm`做了少量修改。
    11  对应版权声明: thrid_licenses/github.com/tjfoc/gmsm/版权声明
    12  */
    13  
    14  package sm2soft
    15  
    16  // reference to ecdsa
    17  import (
    18  	"bytes"
    19  	"crypto"
    20  	"crypto/elliptic"
    21  	"crypto/rand"
    22  	"encoding/asn1"
    23  	"encoding/binary"
    24  	"errors"
    25  	"io"
    26  	"math/big"
    27  
    28  	"gitee.com/ks-custle/core-gm/sm3"
    29  	"golang.org/x/crypto/cryptobyte"
    30  	cbasn1 "golang.org/x/crypto/cryptobyte/asn1"
    31  )
    32  
    33  var (
    34  	defaultUid = []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}
    35  	C1C3C2     = 0
    36  	C1C2C3     = 1
    37  )
    38  
    39  // PublicKey SM2公钥结构体
    40  type PublicKey struct {
    41  	elliptic.Curve          // 椭圆曲线
    42  	X, Y           *big.Int // 公钥座标
    43  }
    44  
    45  func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
    46  	xx, ok := x.(*PublicKey)
    47  	if !ok {
    48  		return false
    49  	}
    50  	return pub.X.Cmp(xx.X) == 0 && pub.Y.Cmp(xx.Y) == 0 &&
    51  		// Standard library Curve implementations are singletons, so this check
    52  		// will work for those. Other Curves might be equivalent even if not
    53  		// singletons, but there is no definitive way to check for that, and
    54  		// better to err on the side of safety.
    55  		pub.Curve == xx.Curve
    56  }
    57  
    58  // PrivateKey SM2私钥结构体
    59  type PrivateKey struct {
    60  	PublicKey          // 公钥
    61  	D         *big.Int // 私钥,[1,n-1]区间的随机数
    62  }
    63  
    64  type sm2Cipher struct {
    65  	XCoordinate *big.Int
    66  	YCoordinate *big.Int
    67  	HASH        []byte
    68  	CipherText  []byte
    69  }
    70  
    71  // Public The SM2's private key contains the public key
    72  func (priv *PrivateKey) Public() crypto.PublicKey {
    73  	return &priv.PublicKey
    74  }
    75  
    76  func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
    77  	xx, ok := x.(*PrivateKey)
    78  	if !ok {
    79  		return false
    80  	}
    81  	return priv.PublicKey.Equal(&xx.PublicKey) && priv.D.Cmp(xx.D) == 0
    82  }
    83  
    84  var errZeroParam = errors.New("zero parameter")
    85  var one = new(big.Int).SetInt64(1)
    86  var two = new(big.Int).SetInt64(2)
    87  
    88  // sign format = 30 + len(z) + 02 + len(r) + r + 02 + len(s) + s, z being what follows its size, ie 02+len(r)+r+02+len(s)+s
    89  
    90  // Sign 使用priv私钥对签名内容摘要做SM2签名,参数signer目前没有使用,但仍要求传入外部对明文消息做摘要的散列算法。
    91  // 返回的签名为DER字节数组,对(r,s)做了asn1编码。
    92  //   - random : 随机数获取用, 如 rand.Reader
    93  //   - signContentDigest : 签名内容摘要(散列值)
    94  //   - signer : 外部对签名内容进行摘要计算使用的散列函数
    95  //
    96  //goland:noinspection GoUnusedParameter
    97  func (priv *PrivateKey) Sign(random io.Reader, signContentDigest []byte, signer crypto.SignerOpts) ([]byte, error) {
    98  	r, s, err := Sm2Sign(priv, signContentDigest, nil, random)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  	var b cryptobyte.Builder
   103  	b.AddASN1(cbasn1.SEQUENCE, func(b *cryptobyte.Builder) {
   104  		b.AddASN1BigInt(r)
   105  		b.AddASN1BigInt(s)
   106  	})
   107  	return b.Bytes()
   108  }
   109  
   110  // SignASN1 使用私钥priv对一个hash值进行签名。
   111  // 返回的签名为DER字节数组,对(r,s)做了asn1编码。
   112  //
   113  //goland:noinspection GoUnusedExportedFunction
   114  func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
   115  	return priv.Sign(rand, hash, nil)
   116  }
   117  
   118  // Verify 使用pub公钥对签名sig做验签。
   119  //   - signContentDigest : 签名内容摘要(散列值)
   120  //   - sig : 签名DER字节数组(对(r,s)做了asn1编码,因此会先做asn1解码)
   121  func (pub *PublicKey) Verify(signContentDigest []byte, sig []byte) bool {
   122  	var (
   123  		r, s  = &big.Int{}, &big.Int{}
   124  		inner cryptobyte.String
   125  	)
   126  	input := cryptobyte.String(sig)
   127  	if !input.ReadASN1(&inner, cbasn1.SEQUENCE) ||
   128  		!input.Empty() ||
   129  		!inner.ReadASN1Integer(r) ||
   130  		!inner.ReadASN1Integer(s) ||
   131  		!inner.Empty() {
   132  		return false
   133  	}
   134  	return Sm2Verify(pub, signContentDigest, defaultUid, r, s)
   135  }
   136  
   137  // VerifyASN1 使用公钥pub对hash和sig进行验签。
   138  //   - pub 公钥
   139  //   - hash 签名内容摘要(散列值)
   140  //   - sig 签名DER字节数组(对(r,s)做了asn1编码,因此会先做asn1解码)
   141  //
   142  //goland:noinspection GoUnusedExportedFunction
   143  func VerifyASN1(pub *PublicKey, hash, sig []byte) bool {
   144  	return pub.Verify(hash, sig)
   145  }
   146  
   147  // Sm3Digest 对签名内容进行SM3摘要计算,摘要计算前混入sm2椭圆曲线部分参数与公钥并预散列一次。
   148  func (pub *PublicKey) Sm3Digest(msg, uid []byte) ([]byte, error) {
   149  	if len(uid) == 0 {
   150  		uid = defaultUid
   151  	}
   152  
   153  	za, err := ZA(pub, uid)
   154  	if err != nil {
   155  		return nil, err
   156  	}
   157  
   158  	e, err := msgHash(za, msg)
   159  	if err != nil {
   160  		return nil, err
   161  	}
   162  
   163  	return e.Bytes(), nil
   164  }
   165  
   166  //****************************Encryption algorithm****************************//
   167  
   168  // EncryptAsn1 sm2加密,C1C3C2,asn1编码
   169  func (pub *PublicKey) EncryptAsn1(data []byte, random io.Reader) ([]byte, error) {
   170  	return EncryptAsn1(pub, data, random)
   171  }
   172  
   173  // DecryptAsn1 sm2解密,C1C3C2,asn1解码
   174  func (priv *PrivateKey) DecryptAsn1(data []byte) ([]byte, error) {
   175  	return DecryptAsn1(priv, data)
   176  }
   177  
   178  //**************************Key agreement algorithm**************************//
   179  
   180  // KeyExchangeB 协商第二部,用户B调用, 返回共享密钥k
   181  func KeyExchangeB(klen int, ida, idb []byte, priB *PrivateKey, pubA *PublicKey, rpri *PrivateKey, rpubA *PublicKey) (k, s1, s2 []byte, err error) {
   182  	return keyExchange(klen, ida, idb, priB, pubA, rpri, rpubA, false)
   183  }
   184  
   185  // KeyExchangeA 协商第二部,用户A调用,返回共享密钥k
   186  func KeyExchangeA(klen int, ida, idb []byte, priA *PrivateKey, pubB *PublicKey, rpri *PrivateKey, rpubB *PublicKey) (k, s1, s2 []byte, err error) {
   187  	return keyExchange(klen, ida, idb, priA, pubB, rpri, rpubB, true)
   188  }
   189  
   190  //****************************************************************************//
   191  
   192  // Sm2Sign SM2签名
   193  //   - priv : 签名私钥 *sm2.PrivateKey
   194  //   - signContentDigest : 签名内容摘要(散列值)
   195  //   - uid : 内部混合摘要计算用uid, 长度16的字节数组,可以传 nil
   196  //   - random : 随机数获取用
   197  func Sm2Sign(priv *PrivateKey, signContentDigest, uid []byte, random io.Reader) (r, s *big.Int, err error) {
   198  	// 对签名内容进行摘要计算
   199  	digest, err := priv.PublicKey.Sm3Digest(signContentDigest, uid)
   200  	if err != nil {
   201  		return nil, nil, err
   202  	}
   203  	e := new(big.Int).SetBytes(digest)
   204  	c := priv.PublicKey.Curve
   205  	N := c.Params().N
   206  	if N.Sign() == 0 {
   207  		return nil, nil, errZeroParam
   208  	}
   209  	var k *big.Int
   210  	// SM2签名实现
   211  	for {
   212  		for {
   213  			// 生成随机数k
   214  			k, err = randFieldElement(c, random)
   215  			if err != nil {
   216  				r = nil
   217  				return
   218  			}
   219  			// 计算P = k*G,返回值的x赋予了r
   220  			r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
   221  			// 计算 r = (e + P(x)) mod n
   222  			// e + P(x)
   223  			r.Add(r, e)
   224  			// (e + P(x)) mod n
   225  			r.Mod(r, N)
   226  			if r.Sign() != 0 {
   227  				if t := new(big.Int).Add(r, k); t.Cmp(N) != 0 {
   228  					break
   229  				}
   230  			}
   231  
   232  		}
   233  		// 计算 s = (((1 + d)^-1) (k-rd)) mod n
   234  		// rd
   235  		rD := new(big.Int).Mul(priv.D, r)
   236  		// k - rd
   237  		s = new(big.Int).Sub(k, rD)
   238  		// 1 + d
   239  		d1 := new(big.Int).Add(priv.D, one)
   240  		// (1 + d)^-1
   241  		d1Inv := new(big.Int).ModInverse(d1, N)
   242  		// ((1 + d)^-1) × (k-rd)
   243  		s.Mul(s, d1Inv)
   244  		// (((1 + d)^-1) (k-rd)) mod n
   245  		s.Mod(s, N)
   246  		if s.Sign() != 0 {
   247  			break
   248  		}
   249  	}
   250  	return
   251  }
   252  
   253  // Sm2Verify SM2验签
   254  //   - pub : 验签公钥, *sm2.PublicKey
   255  //   - signContentDigest : 签名内容摘要(散列值)
   256  //   - uid : 内部混合摘要计算用uid, 长度16的字节数组,可以传 nil
   257  //   - r, s : 签名
   258  func Sm2Verify(pub *PublicKey, signContentDigest, uid []byte, r, s *big.Int) bool {
   259  	c := pub.Curve
   260  	N := c.Params().N
   261  	one := new(big.Int).SetInt64(1)
   262  	if r.Cmp(one) < 0 || s.Cmp(one) < 0 {
   263  		return false
   264  	}
   265  	if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
   266  		return false
   267  	}
   268  	if len(uid) == 0 {
   269  		uid = defaultUid
   270  	}
   271  	// 获取za: sm3(ENTLA || IDA || a || b || xG || yG || xA || yA)
   272  	za, err := ZA(pub, uid)
   273  	if err != nil {
   274  		return false
   275  	}
   276  	// 混合za与签名内容明文,并做sm3摘要
   277  	e, err := msgHash(za, signContentDigest)
   278  	if err != nil {
   279  		return false
   280  	}
   281  	// 计算 t = (r + s) mod n
   282  	t := new(big.Int).Add(r, s)
   283  	t.Mod(t, N)
   284  	if t.Sign() == 0 {
   285  		return false
   286  	}
   287  	var x *big.Int
   288  	// 计算 s*G
   289  	x1, y1 := c.ScalarBaseMult(s.Bytes())
   290  	// 计算 t*pub
   291  	x2, y2 := c.ScalarMult(pub.X, pub.Y, t.Bytes())
   292  	// 计算 s*G + t*pub 结果只要x轴座标
   293  	x, _ = c.Add(x1, y1, x2, y2)
   294  	// 计算 e + x
   295  	x.Add(x, e)
   296  	// 计算 R = (e + x) mod n
   297  	x.Mod(x, N)
   298  	// 判断 R == r
   299  	return x.Cmp(r) == 0
   300  }
   301  
   302  // Verify SM2验签
   303  //   - pub : 验签公钥, *sm2.PublicKey
   304  //   - hash : 签名内容摘要(散列值)
   305  //   - r, s : 签名
   306  //
   307  //goland:noinspection GoUnusedExportedFunction
   308  func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
   309  	return Sm2Verify(pub, hash, nil, r, s)
   310  }
   311  
   312  /*
   313      za, err := ZA(pub, uid)
   314  	if err != nil {
   315  		return
   316  	}
   317  	e, err := msgHash(za, msg)
   318  	hash=e.getBytes()
   319  */
   320  // 并非sm2验签
   321  // func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
   322  // 	c := pub.Curve
   323  // 	N := c.Params().N
   324  
   325  // 	if r.Sign() <= 0 || s.Sign() <= 0 {
   326  // 		return false
   327  // 	}
   328  // 	if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
   329  // 		return false
   330  // 	}
   331  
   332  // 	// 调整算法细节以实现SM2
   333  // 	t := new(big.Int).Add(r, s)
   334  // 	t.Mod(t, N)
   335  // 	if t.Sign() == 0 {
   336  // 		return false
   337  // 	}
   338  
   339  // 	var x *big.Int
   340  // 	x1, y1 := c.ScalarBaseMult(s.Bytes())
   341  // 	x2, y2 := c.ScalarMult(pub.X, pub.Y, t.Bytes())
   342  // 	x, _ = c.Add(x1, y1, x2, y2)
   343  
   344  // 	e := new(big.Int).SetBytes(hash)
   345  // 	x.Add(x, e)
   346  // 	x.Mod(x, N)
   347  // 	return x.Cmp(r) == 0
   348  // }
   349  
   350  // Encrypt sm2非对称加密,支持C1C3C2(mode = 0)与C1C2C3(mode = 1)两种模式,默认使用C1C3C2模式。
   351  // 不同的模式表示不同的密文结构,其中C1C2C3的意义:
   352  // C1 : sm2椭圆曲线上的某个点,每次加密得到的点不一样
   353  // C2 : 密文
   354  // C3 : 明文加盐后的摘要
   355  func Encrypt(pub *PublicKey, data []byte, random io.Reader, mode int) ([]byte, error) {
   356  	length := len(data)
   357  	for {
   358  		var c []byte
   359  		curve := pub.Curve
   360  		// 获取随机数k
   361  		k, err := randFieldElement(curve, random)
   362  		if err != nil {
   363  			return nil, err
   364  		}
   365  		// 计算点C1 = k*G ,因为k是随机数,所以C1每次加密都是随机的
   366  		x1, y1 := curve.ScalarBaseMult(k.Bytes())
   367  		// 计算点(x2,y2) = k*pub,利用公钥计算出一个随机的点P
   368  		x2, y2 := curve.ScalarMult(pub.X, pub.Y, k.Bytes())
   369  		x1Buf := x1.Bytes()
   370  		y1Buf := y1.Bytes()
   371  		x2Buf := x2.Bytes()
   372  		y2Buf := y2.Bytes()
   373  		// 填充满32个字节长度
   374  		if n := len(x1Buf); n < 32 {
   375  			x1Buf = append(zeroByteSlice()[:32-n], x1Buf...)
   376  		}
   377  		if n := len(y1Buf); n < 32 {
   378  			y1Buf = append(zeroByteSlice()[:32-n], y1Buf...)
   379  		}
   380  		if n := len(x2Buf); n < 32 {
   381  			x2Buf = append(zeroByteSlice()[:32-n], x2Buf...)
   382  		}
   383  		if n := len(y2Buf); n < 32 {
   384  			y2Buf = append(zeroByteSlice()[:32-n], y2Buf...)
   385  		}
   386  		// 填入C1(x)
   387  		c = append(c, x1Buf...)
   388  		// 填入C1(y)
   389  		c = append(c, y1Buf...)
   390  
   391  		// 计算C3 : 按 x2 data y2 的顺序混合数据并做sm3摘要
   392  		var tm []byte
   393  		tm = append(tm, x2Buf...)
   394  		tm = append(tm, data...)
   395  		tm = append(tm, y2Buf...)
   396  		h := sm3.Sm3Sum(tm)
   397  		// 填入C3
   398  		c = append(c, h...)
   399  
   400  		// 使用密钥派生函数kdf,基于P计算长度等于data长度的派生密钥 ct
   401  		ct, ok := kdf(length, x2Buf, y2Buf)
   402  		if !ok {
   403  			continue
   404  		}
   405  		// 填入ct
   406  		c = append(c, ct...)
   407  		// 利用ct对data进行异或加密,并覆盖c中对应内容
   408  		for i := 0; i < length; i++ {
   409  			c[96+i] ^= data[i]
   410  		}
   411  
   412  		// 此时c的内容是 c1c3c2,需要根据传入的参数mode判断是否需要重新排列。
   413  		switch mode {
   414  		case C1C3C2:
   415  			return append([]byte{0x04}, c...), nil
   416  		case C1C2C3:
   417  			// 如果是 C1C2C3 模式,那么需要将c切分后重新组装
   418  			c1 := make([]byte, 64)
   419  			c2 := make([]byte, len(c)-96)
   420  			c3 := make([]byte, 32)
   421  			// C1,即 x1Buf+y1Buf
   422  			copy(c1, c[:64])
   423  			// C3,即 x2+data+y2混合后的SM3摘要
   424  			copy(c3, c[64:96])
   425  			// C2,即 使用kdf派生出的密钥对data进行加密后的密文
   426  			copy(c2, c[96:])
   427  			// 按C1C2C3的顺序组装结果
   428  			var ciphertext []byte
   429  			ciphertext = append(ciphertext, c1...)
   430  			ciphertext = append(ciphertext, c2...)
   431  			ciphertext = append(ciphertext, c3...)
   432  			return append([]byte{0x04}, ciphertext...), nil
   433  		default:
   434  			return append([]byte{0x04}, c...), nil
   435  		}
   436  	}
   437  }
   438  
   439  // Decrypt sm2非对称解密
   440  func Decrypt(priv *PrivateKey, data []byte, mode int) ([]byte, error) {
   441  	switch mode {
   442  	case C1C3C2:
   443  		data = data[1:]
   444  	case C1C2C3:
   445  		// C1C2C3重新组装为 C1C3C2
   446  		data = data[1:]
   447  		c1 := make([]byte, 64)
   448  		c2 := make([]byte, len(data)-96)
   449  		c3 := make([]byte, 32)
   450  		copy(c1, data[:64])             //x1,y1
   451  		copy(c2, data[64:len(data)-32]) //密文
   452  		copy(c3, data[len(data)-32:])   //hash
   453  		var c []byte
   454  		c = append(c, c1...)
   455  		c = append(c, c3...)
   456  		c = append(c, c2...)
   457  		data = c
   458  	default:
   459  		data = data[1:]
   460  	}
   461  	length := len(data) - 96
   462  	curve := priv.Curve
   463  	// 取出C1的x和y
   464  	x := new(big.Int).SetBytes(data[:32])
   465  	y := new(big.Int).SetBytes(data[32:64])
   466  	// 根据C1计算 P = d*C1
   467  	x2, y2 := curve.ScalarMult(x, y, priv.D.Bytes())
   468  	x2Buf := x2.Bytes()
   469  	y2Buf := y2.Bytes()
   470  	if n := len(x2Buf); n < 32 {
   471  		x2Buf = append(zeroByteSlice()[:32-n], x2Buf...)
   472  	}
   473  	if n := len(y2Buf); n < 32 {
   474  		y2Buf = append(zeroByteSlice()[:32-n], y2Buf...)
   475  	}
   476  	// 使用密钥派生函数kdf,基于P计算派生密钥 c
   477  	c, ok := kdf(length, x2Buf, y2Buf)
   478  	if !ok {
   479  		return nil, errors.New("decrypt: failed to decrypt")
   480  	}
   481  	// 使用派生密钥c对C2部分做异或计算解密
   482  	// 解密结果覆盖到c中,此时c即明文
   483  	for i := 0; i < length; i++ {
   484  		c[i] ^= data[i+96]
   485  	}
   486  	// 重新混合明文并计算摘要,与C3进行比较
   487  	var tm []byte
   488  	tm = append(tm, x2Buf...)
   489  	tm = append(tm, c...)
   490  	tm = append(tm, y2Buf...)
   491  	h := sm3.Sm3Sum(tm)
   492  	if !bytes.Equal(h, data[64:96]) {
   493  		return c, errors.New("decrypt: failed to decrypt")
   494  	}
   495  	return c, nil
   496  }
   497  
   498  // keyExchange 为SM2密钥交换算法的第二部和第三步复用部分,协商的双方均调用此函数计算共同的字节串
   499  // klen: 密钥长度
   500  // ida, idb: 协商双方的标识,ida为密钥协商算法发起方标识,idb为响应方标识
   501  // pri: 函数调用者的密钥
   502  // pub: 对方的公钥
   503  // rpri: 函数调用者生成的临时SM2密钥
   504  // rpub: 对方发来的临时SM2公钥
   505  // thisIsA: 如果是A调用,文档中的协商第三步,设置为true,否则设置为false
   506  // 返回 k 为klen长度的字节串
   507  func keyExchange(klen int, ida, idb []byte, pri *PrivateKey, pub *PublicKey, rpri *PrivateKey, rpub *PublicKey, thisISA bool) (k, s1, s2 []byte, err error) {
   508  	curve := P256Sm2()
   509  	N := curve.Params().N
   510  	x2hat := keXHat(rpri.PublicKey.X)
   511  	x2rb := new(big.Int).Mul(x2hat, rpri.D)
   512  	tbt := new(big.Int).Add(pri.D, x2rb)
   513  	tb := new(big.Int).Mod(tbt, N)
   514  	if !curve.IsOnCurve(rpub.X, rpub.Y) {
   515  		err = errors.New("ra not on curve")
   516  		return
   517  	}
   518  	x1hat := keXHat(rpub.X)
   519  	ramx1, ramy1 := curve.ScalarMult(rpub.X, rpub.Y, x1hat.Bytes())
   520  	vxt, vyt := curve.Add(pub.X, pub.Y, ramx1, ramy1)
   521  
   522  	vx, vy := curve.ScalarMult(vxt, vyt, tb.Bytes())
   523  	pza := pub
   524  	if thisISA {
   525  		pza = &pri.PublicKey
   526  	}
   527  	za, err := ZA(pza, ida)
   528  	if err != nil {
   529  		return
   530  	}
   531  	zero := new(big.Int)
   532  	if vx.Cmp(zero) == 0 || vy.Cmp(zero) == 0 {
   533  		err = errors.New("v is infinite")
   534  		return
   535  	}
   536  	pzb := pub
   537  	if !thisISA {
   538  		pzb = &pri.PublicKey
   539  	}
   540  	zb, _ := ZA(pzb, idb)
   541  	k, ok := kdf(klen, vx.Bytes(), vy.Bytes(), za, zb)
   542  	if !ok {
   543  		err = errors.New("kdf: zero key")
   544  		return
   545  	}
   546  	h1 := BytesCombine(vx.Bytes(), za, zb, rpub.X.Bytes(), rpub.Y.Bytes(), rpri.X.Bytes(), rpri.Y.Bytes())
   547  	if !thisISA {
   548  		h1 = BytesCombine(vx.Bytes(), za, zb, rpri.X.Bytes(), rpri.Y.Bytes(), rpub.X.Bytes(), rpub.Y.Bytes())
   549  	}
   550  	hash := sm3.Sm3Sum(h1)
   551  	h2 := BytesCombine([]byte{0x02}, vy.Bytes(), hash)
   552  	S1 := sm3.Sm3Sum(h2)
   553  	h3 := BytesCombine([]byte{0x03}, vy.Bytes(), hash)
   554  	S2 := sm3.Sm3Sum(h3)
   555  	return k, S1, S2, nil
   556  }
   557  
   558  func msgHash(za, msg []byte) (*big.Int, error) {
   559  	e := sm3.New()
   560  	e.Write(za)
   561  	e.Write(msg)
   562  	return new(big.Int).SetBytes(e.Sum(nil)[:32]), nil
   563  }
   564  
   565  // ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA)
   566  func ZA(pub *PublicKey, uid []byte) ([]byte, error) {
   567  	za := sm3.New()
   568  	uidLen := len(uid)
   569  	if uidLen >= 8192 {
   570  		return []byte{}, errors.New("SM2: uid too large")
   571  	}
   572  	Entla := uint16(8 * uidLen)
   573  	za.Write([]byte{byte((Entla >> 8) & 0xFF)})
   574  	za.Write([]byte{byte(Entla & 0xFF)})
   575  	if uidLen > 0 {
   576  		za.Write(uid)
   577  	}
   578  	za.Write(sm2P256ToBig(&sm2P256.a).Bytes())
   579  	za.Write(sm2P256.B.Bytes())
   580  	za.Write(sm2P256.Gx.Bytes())
   581  	za.Write(sm2P256.Gy.Bytes())
   582  
   583  	xBuf := pub.X.Bytes()
   584  	yBuf := pub.Y.Bytes()
   585  	if n := len(xBuf); n < 32 {
   586  		xBuf = append(zeroByteSlice()[:32-n], xBuf...)
   587  	}
   588  	if n := len(yBuf); n < 32 {
   589  		yBuf = append(zeroByteSlice()[:32-n], yBuf...)
   590  	}
   591  	za.Write(xBuf)
   592  	za.Write(yBuf)
   593  	return za.Sum(nil)[:32], nil
   594  }
   595  
   596  // 32byte
   597  func zeroByteSlice() []byte {
   598  	return []byte{
   599  		0, 0, 0, 0,
   600  		0, 0, 0, 0,
   601  		0, 0, 0, 0,
   602  		0, 0, 0, 0,
   603  		0, 0, 0, 0,
   604  		0, 0, 0, 0,
   605  		0, 0, 0, 0,
   606  		0, 0, 0, 0,
   607  	}
   608  }
   609  
   610  // EncryptAsn1 sm2加密,返回asn.1编码格式的密文内容
   611  func EncryptAsn1(pub *PublicKey, data []byte, rand io.Reader) ([]byte, error) {
   612  	cipher, err := Encrypt(pub, data, rand, C1C3C2)
   613  	if err != nil {
   614  		return nil, err
   615  	}
   616  	return CipherMarshal(cipher)
   617  }
   618  
   619  // DecryptAsn1 sm2解密,解析asn.1编码格式的密文内容
   620  func DecryptAsn1(pub *PrivateKey, data []byte) ([]byte, error) {
   621  	cipher, err := CipherUnmarshal(data)
   622  	if err != nil {
   623  		return nil, err
   624  	}
   625  	return Decrypt(pub, cipher, C1C3C2)
   626  }
   627  
   628  // CipherMarshal sm2密文转asn.1编码格式
   629  //
   630  //	sm2密文结构如下:
   631  //	- x
   632  //	- y
   633  //	- hash
   634  //	- CipherText
   635  func CipherMarshal(data []byte) ([]byte, error) {
   636  	data = data[1:]
   637  	x := new(big.Int).SetBytes(data[:32])
   638  	y := new(big.Int).SetBytes(data[32:64])
   639  	hash := data[64:96]
   640  	cipherText := data[96:]
   641  	return asn1.Marshal(sm2Cipher{x, y, hash, cipherText})
   642  }
   643  
   644  // CipherUnmarshal sm2密文asn.1编码格式转C1|C3|C2拼接格式
   645  func CipherUnmarshal(data []byte) ([]byte, error) {
   646  	var cipher sm2Cipher
   647  	_, err := asn1.Unmarshal(data, &cipher)
   648  	if err != nil {
   649  		return nil, err
   650  	}
   651  	x := cipher.XCoordinate.Bytes()
   652  	y := cipher.YCoordinate.Bytes()
   653  	hash := cipher.HASH
   654  	if err != nil {
   655  		return nil, err
   656  	}
   657  	cipherText := cipher.CipherText
   658  	if err != nil {
   659  		return nil, err
   660  	}
   661  	if n := len(x); n < 32 {
   662  		x = append(zeroByteSlice()[:32-n], x...)
   663  	}
   664  	if n := len(y); n < 32 {
   665  		y = append(zeroByteSlice()[:32-n], y...)
   666  	}
   667  	var c []byte
   668  	c = append(c, x...)          // x分量
   669  	c = append(c, y...)          // y分
   670  	c = append(c, hash...)       // x分量
   671  	c = append(c, cipherText...) // y分
   672  	return append([]byte{0x04}, c...), nil
   673  }
   674  
   675  // keXHat 计算 x = 2^w + (x & (2^w-1))
   676  // 密钥协商算法辅助函数
   677  func keXHat(x *big.Int) (xul *big.Int) {
   678  	buf := x.Bytes()
   679  	for i := 0; i < len(buf)-16; i++ {
   680  		buf[i] = 0
   681  	}
   682  	if len(buf) >= 16 {
   683  		c := buf[len(buf)-16]
   684  		buf[len(buf)-16] = c & 0x7f
   685  	}
   686  
   687  	r := new(big.Int).SetBytes(buf)
   688  	_2w := new(big.Int).SetBytes([]byte{
   689  		0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   690  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
   691  	return r.Add(r, _2w)
   692  }
   693  
   694  func BytesCombine(pBytes ...[]byte) []byte {
   695  	length := len(pBytes)
   696  	s := make([][]byte, length)
   697  	for index := 0; index < length; index++ {
   698  		s[index] = pBytes[index]
   699  	}
   700  	sep := []byte("")
   701  	return bytes.Join(s, sep)
   702  }
   703  
   704  func intToBytes(x int) []byte {
   705  	var buf = make([]byte, 4)
   706  
   707  	binary.BigEndian.PutUint32(buf, uint32(x))
   708  	return buf
   709  }
   710  
   711  func kdf(length int, x ...[]byte) ([]byte, bool) {
   712  	var c []byte
   713  
   714  	ct := 1
   715  	h := sm3.New()
   716  	for i, j := 0, (length+31)/32; i < j; i++ {
   717  		h.Reset()
   718  		for _, xx := range x {
   719  			h.Write(xx)
   720  		}
   721  		h.Write(intToBytes(ct))
   722  		hash := h.Sum(nil)
   723  		if i+1 == j && length%32 != 0 {
   724  			c = append(c, hash[:length%32]...)
   725  		} else {
   726  			c = append(c, hash...)
   727  		}
   728  		ct++
   729  	}
   730  	for i := 0; i < length; i++ {
   731  		if c[i] != 0 {
   732  			return c, true
   733  		}
   734  	}
   735  	return c, false
   736  }
   737  
   738  // 选取一个位于[1~n-1]之间的随机数k,n是椭圆曲线的参数N
   739  func randFieldElement(c elliptic.Curve, random io.Reader) (k *big.Int, err error) {
   740  	if random == nil {
   741  		random = rand.Reader //If there is no external trusted random source,please use rand.Reader to instead of it.
   742  	}
   743  	params := c.Params()
   744  	b := make([]byte, params.BitSize/8+8)
   745  	_, err = io.ReadFull(random, b)
   746  	if err != nil {
   747  		return
   748  	}
   749  	k = new(big.Int).SetBytes(b)
   750  	n := new(big.Int).Sub(params.N, one)
   751  	k.Mod(k, n)
   752  	k.Add(k, one)
   753  	return
   754  }
   755  
   756  // GenerateKey 基于P256Sm2曲线生成sm2的公私钥
   757  func GenerateKey(random io.Reader) (*PrivateKey, error) {
   758  	c := P256Sm2()
   759  	if random == nil {
   760  		random = rand.Reader //If there is no external trusted random source,please use rand.Reader to instead of it.
   761  	}
   762  	params := c.Params()
   763  	b := make([]byte, params.BitSize/8+8)
   764  	_, err := io.ReadFull(random, b)
   765  	if err != nil {
   766  		return nil, err
   767  	}
   768  	// 生成随机数k
   769  	k := new(big.Int).SetBytes(b)
   770  	// n = N - 2
   771  	n := new(big.Int).Sub(params.N, two)
   772  	// k = k mod n
   773  	k.Mod(k, n)
   774  	// k = k + 1
   775  	k.Add(k, one)
   776  	priv := new(PrivateKey)
   777  	// 设置曲线
   778  	priv.PublicKey.Curve = c
   779  	// 设置私钥
   780  	priv.D = k
   781  	// 公钥 = k * G
   782  	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
   783  
   784  	return priv, nil
   785  }
   786  
   787  // ecdsa的实现中,使用zeroReader辅助生成一个cipher.StreamReader用作随机数生成的 rand io.Reader。
   788  // sm2目前没有采用这种方式,所以这里将相关代码注释掉了。
   789  
   790  // type zr struct {
   791  // 	io.Reader
   792  // }
   793  
   794  // func (z *zr) Read(dst []byte) (n int, err error) {
   795  // 	for i := range dst {
   796  // 		dst[i] = 0
   797  // 	}
   798  // 	return len(dst), nil
   799  // }
   800  
   801  // var zeroReader = &zr{}
   802  
   803  func getLastBit(a *big.Int) uint {
   804  	return a.Bit(0)
   805  }
   806  
   807  // Decrypt crypto.Decrypter
   808  func (priv *PrivateKey) Decrypt(_ io.Reader, msg []byte, _ crypto.DecrypterOpts) (plaintext []byte, err error) {
   809  	return Decrypt(priv, msg, C1C3C2)
   810  }