gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/sm2soft/sm2.go (about)

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