gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/sm2/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  package sm2
    10  
    11  /*
    12  sm2/sm2.go sm2国密算法实现,包括签名验签与非对称加解密
    13  
    14  为*sm2.PrivateKey绑定方法:
    15  Public
    16  Equal
    17  SignWithZA
    18  Sign
    19  DecryptAsn1
    20  Decrypt
    21  
    22  为*sm2.PublicKey绑定方法:
    23  Equal
    24  Verify
    25  EncryptAsn1
    26  Encrypt
    27  
    28  提供函数:
    29  P256Sm2
    30  GenerateKey
    31  IsSM2PublicKey
    32  NewSM2SignerOption
    33  DefaultSM2SignerOption
    34  SignASN1WithOpts
    35  SignASN1
    36  Sign
    37  Sm2Sign
    38  SignWithZA
    39  SignAfterZA
    40  VerifyASN1
    41  VerifyASN1WithoutZA
    42  Verify
    43  Sm2Verify
    44  VerifyWithZA
    45  CalculateZA
    46  Encrypt
    47  Decrypt
    48  EncryptDefault
    49  EncryptAsn1
    50  DecryptDefault
    51  DecryptAsn1
    52  ASN1Ciphertext2Plain
    53  PlainCiphertext2ASN1
    54  AdjustCiphertextSplicingOrder
    55  NewPlainEncrypterOpts
    56  NewPlainDecrypterOpts
    57  
    58  */
    59  
    60  // Further references:
    61  //   [NSA]: Suite B implementer's guide to FIPS 186-3
    62  //     http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.182.4503&rep=rep1&type=pdf
    63  //   [SECG]: SECG, SEC1
    64  //     http://www.secg.org/sec1-v2.pdf
    65  //   [GM/T]: SM2 GB/T 32918.2-2016, GB/T 32918.4-2016
    66  //
    67  
    68  import (
    69  	"crypto"
    70  	"crypto/aes"
    71  	"crypto/cipher"
    72  	"crypto/elliptic"
    73  	"crypto/sha512"
    74  	"encoding/binary"
    75  	"errors"
    76  	"fmt"
    77  	"gitee.com/zhaochuninhefei/gmgo/ecbase"
    78  	"gitee.com/zhaochuninhefei/zcgolog/zclog"
    79  	"io"
    80  	"math/big"
    81  	"strings"
    82  	"sync"
    83  
    84  	"gitee.com/zhaochuninhefei/gmgo/sm3"
    85  	"golang.org/x/crypto/cryptobyte"
    86  	"golang.org/x/crypto/cryptobyte/asn1"
    87  )
    88  
    89  // PublicKey SM2公钥结构体
    90  type PublicKey struct {
    91  	elliptic.Curve          // 椭圆曲线
    92  	X, Y           *big.Int // 公钥座标
    93  }
    94  
    95  func (pub *PublicKey) Equal(x crypto.PublicKey) bool {
    96  	xx, ok := x.(*PublicKey)
    97  	if !ok {
    98  		return false
    99  	}
   100  	return pub.X.Cmp(xx.X) == 0 && pub.Y.Cmp(xx.Y) == 0 &&
   101  		// Standard library Curve implementations are singletons, so this check
   102  		// will work for those. Other Curves might be equivalent even if not
   103  		// singletons, but there is no definitive way to check for that, and
   104  		// better to err on the side of safety.
   105  		pub.Curve == xx.Curve
   106  }
   107  
   108  // PrivateKey SM2私钥结构体
   109  type PrivateKey struct {
   110  	PublicKey          // 公钥
   111  	D         *big.Int // 私钥,[1,n-1]区间的随机数
   112  }
   113  
   114  // Public The SM2's private key contains the public key
   115  func (priv *PrivateKey) Public() crypto.PublicKey {
   116  	return &priv.PublicKey
   117  }
   118  
   119  func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
   120  	xx, ok := x.(*PrivateKey)
   121  	if !ok {
   122  		return false
   123  	}
   124  	return priv.PublicKey.Equal(&xx.PublicKey) && priv.D.Cmp(xx.D) == 0
   125  }
   126  
   127  var (
   128  	one      = new(big.Int).SetInt64(1)
   129  	initonce sync.Once
   130  )
   131  
   132  // P256Sm2 获取sm2p256曲线
   133  // P256Sm2 init and return the singleton.
   134  func P256Sm2() elliptic.Curve {
   135  	initonce.Do(initP256)
   136  	return p256
   137  }
   138  
   139  // 选取一个位于[1~n-1]之间的随机数k,n是椭圆曲线的参数N
   140  // randFieldElement returns a random element of the order of the given
   141  // curve using the procedure given in FIPS 186-4, Appendix B.5.1.
   142  func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
   143  	params := c.Params()
   144  	b := make([]byte, params.BitSize/8+8) // (N + 64) / 8 = (256 + 64) / 8
   145  	_, err = io.ReadFull(rand, b)
   146  	if err != nil {
   147  		return
   148  	}
   149  
   150  	k = new(big.Int).SetBytes(b) // 5.Convert returned_bits to the (non-negtive) integrer c
   151  	n := new(big.Int).Sub(params.N, one)
   152  	k.Mod(k, n)
   153  	k.Add(k, one) // 6. k = (c mod (n-1)) + 1, here n = params.N
   154  	return
   155  }
   156  
   157  // GenerateKey 生成sm2的公私钥对
   158  // GenerateKey generates a public and private key pair.
   159  func GenerateKey(rand io.Reader) (*PrivateKey, error) {
   160  	c := P256Sm2()
   161  	// 生成随机数k
   162  	k, err := randFieldElement(c, rand)
   163  	if err != nil {
   164  		return nil, err
   165  	}
   166  	priv := new(PrivateKey)
   167  	// 设置曲线为sm2p256
   168  	priv.PublicKey.Curve = c
   169  	// 设置私钥为随机数k
   170  	priv.D = k
   171  	// 计算公钥座标 k*G
   172  	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
   173  	return priv, nil
   174  }
   175  
   176  var errZeroParam = errors.New("zero parameter")
   177  
   178  // IsSM2PublicKey check if given public key is a SM2 public key or not
   179  //goland:noinspection GoUnusedExportedFunction
   180  func IsSM2PublicKey(publicKey interface{}) bool {
   181  	pub, ok := publicKey.(*PublicKey)
   182  	return ok && strings.EqualFold(P256Sm2().Params().Name, pub.Curve.Params().Name)
   183  }
   184  
   185  // ↓↓↓↓↓↓↓↓↓↓ 签名与验签 ↓↓↓↓↓↓↓↓↓↓
   186  
   187  var defaultUID = []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}
   188  
   189  //// directSigning is a standard Hash value that signals that no pre-hashing
   190  //// should be performed.
   191  //var directSigning crypto.Hash = 0
   192  
   193  // SM2SignerOption sm2签名参数
   194  // SM2SignerOption implements crypto.SignerOpts interface.
   195  // It is specific for SM2, used in private key's Sign method.
   196  //goland:noinspection GoNameStartsWithPackageName
   197  type SM2SignerOption struct {
   198  	ecbase.EcSignerOpts
   199  
   200  	// ZA计算用唯一标识符,只在ForceZA为true时使用。
   201  	UID []byte
   202  	// 是否强制使用国密签名标准,即对签名内容进行ZA混合散列后再签名。
   203  	// 该值为true则代表进行ZA混合散列。
   204  	ForceZA bool
   205  }
   206  
   207  // NewSM2SignerOption 生成一个新的sm2签名参数
   208  //  forceZA为true而uid为空时,使用defaultUID
   209  func NewSM2SignerOption(forceZA bool, uid []byte) *SM2SignerOption {
   210  	opt := &SM2SignerOption{
   211  		// sm2签名不能做low-s处理,因为sm2的验签算法会对s值做额外检查,s高低值不能混用
   212  		EcSignerOpts: ecbase.CreateEcSignerOpts(0, false),
   213  		UID:          uid,
   214  		ForceZA:      forceZA,
   215  	}
   216  	if forceZA && len(uid) == 0 {
   217  		// ForceGMSign为true而uid为空时,使用defaultUID
   218  		opt.UID = defaultUID
   219  	}
   220  	return opt
   221  }
   222  
   223  // DefaultSM2SignerOption 生成一个默认的sm2签名参数
   224  func DefaultSM2SignerOption() *SM2SignerOption {
   225  	return &SM2SignerOption{
   226  		// sm2签名不能做low-s处理,因为sm2的验签算法会对s值做额外检查,s高低值不能混用
   227  		EcSignerOpts: ecbase.CreateEcSignerOpts(0, false),
   228  		UID:          defaultUID,
   229  		ForceZA:      true,
   230  	}
   231  }
   232  
   233  //// HashFunc 为sm2.SM2SignerOption实现crypto.SignerOpts接口
   234  //func (*SM2SignerOption) HashFunc() crypto.Hash {
   235  //	return directSigning
   236  //}
   237  
   238  // Signer SM2 special signer
   239  type Signer interface {
   240  	SignWithZA(rand io.Reader, uid, msg []byte) ([]byte, error)
   241  }
   242  
   243  // SignWithZA 为sm2.PrivateKey实现SignWithZA方法。
   244  //  该方法强制对msg做ZA混合散列,签名使用low-s值
   245  func (priv *PrivateKey) SignWithZA(rand io.Reader, uid, msg []byte) ([]byte, error) {
   246  	return priv.Sign(rand, msg, NewSM2SignerOption(true, uid))
   247  }
   248  
   249  // SignASN1WithOpts SignASN1使用私钥priv对签名摘要hash进行签名,并将签名转为asn1格式字节数组。
   250  //  是否对hash做ZA混合散列取决于opts类型是否*sm2.SM2SignerOption且opts.ForceGMSign为true。
   251  //  如果opts传nil,则对hash做ZA混合散列。
   252  //goland:noinspection GoUnusedExportedFunction
   253  func SignASN1WithOpts(rand io.Reader, priv *PrivateKey, hash []byte, opts crypto.SignerOpts) ([]byte, error) {
   254  	return priv.Sign(rand, hash, opts)
   255  }
   256  
   257  // SignASN1 SignASN1使用私钥priv对签名摘要hash进行签名,并将签名转为asn1格式字节数组。
   258  //  会对hash做ZA混合散列。
   259  func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) {
   260  	return priv.Sign(rand, hash, nil)
   261  }
   262  
   263  // Sign 为sm2.PrivateKey实现Sign方法。
   264  //  如果opts类型是*sm2.SM2SignerOption且opts.ForceGMSign为true,或opts传nil,
   265  // 则将对digest进行ZA混合散列后再对其进行签名。
   266  func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
   267  	zclog.Debugf("sm2priv.Sign digest长度: %d", len(digest))
   268  	var r, s *big.Int
   269  	var err error
   270  	if opts == nil {
   271  		opts = DefaultSM2SignerOption()
   272  	}
   273  	if sm2Opts, ok := opts.(*SM2SignerOption); ok {
   274  		// 传入的opts是SM2SignerOption类型时,根据设置决定是否进行ZA混合散列
   275  		if sm2Opts.ForceZA {
   276  			zclog.Debugln("sm2priv.Sign内部执行ZA混合散列")
   277  			// 执行ZA混合散列
   278  			r, s, err = SignWithZA(rand, priv, sm2Opts.UID, digest)
   279  		} else {
   280  			zclog.Debugln("sm2priv.Sign内部不执行ZA混合散列")
   281  			// 不执行ZA混合散列
   282  			r, s, err = SignAfterZA(rand, priv, digest)
   283  		}
   284  	} else {
   285  		zclog.Debugln("sm2priv.Sign内部执行ZA混合散列")
   286  		// 传入的opts不是SM2SignerOption类型时,执行ZA混合散列
   287  		r, s, err = SignWithZA(rand, priv, defaultUID, digest)
   288  	}
   289  	if err != nil {
   290  		return nil, err
   291  	}
   292  	//utils.PrintStack("sm2priv.Sign打印调用栈")
   293  	// 将签名结果(r,s)转为asn1格式字节数组
   294  	return ecbase.MarshalECSignature(r, s)
   295  	//var b cryptobyte.Builder
   296  	//b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
   297  	//	b.AddASN1BigInt(r)
   298  	//	b.AddASN1BigInt(s)
   299  	//})
   300  	//return b.Bytes()
   301  }
   302  
   303  // Sign Sign使用私钥priv对签名摘要hash进行签名,并将签名转为asn1格式字节数组。
   304  //  会对hash做ZA混合散列。
   305  func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
   306  	zclog.Debugf("sm2.Sign内部执行ZA混合散列, 传入hash长度: %d", len(hash))
   307  	//utils.PrintStack("sm2.Sign打印调用栈")
   308  	r, s, err = SignWithZA(rand, priv, defaultUID, hash)
   309  	return
   310  }
   311  
   312  // Sm2Sign Sm2Sign使用私钥priv对签名摘要hash进行签名,并将签名转为asn1格式字节数组。
   313  //  会对hash做ZA混合散列。
   314  //goland:noinspection GoUnusedExportedFunction,GoNameStartsWithPackageName,GoUnusedParameter
   315  func Sm2Sign(priv *PrivateKey, msg, uid []byte, random io.Reader) (r, s *big.Int, err error) {
   316  	//utils.PrintStack("sm2.Sm2Sign打印调用栈")
   317  	zclog.Debugf("sm2.Sm2Sign内部执行ZA混合散列, 传入msg长度: %d", len(msg))
   318  	r, s, err = SignWithZA(random, priv, defaultUID, msg)
   319  	return
   320  }
   321  
   322  // SignWithZA 对msg做ZA混合散列后再对得到的校验和进行签名。
   323  //  混合散列使用sm3
   324  // SignWithZA follow sm2 dsa standards for hash part, compliance with GB/T 32918.2-2016.
   325  func SignWithZA(rand io.Reader, priv *PrivateKey, uid, msg []byte) (r, s *big.Int, err error) {
   326  	if len(uid) == 0 {
   327  		uid = defaultUID
   328  	}
   329  	// 计算ZA
   330  	za, err := calculateZA(&priv.PublicKey, uid)
   331  	if err != nil {
   332  		return nil, nil, err
   333  	}
   334  	// 混入ZA
   335  	md := sm3.New()
   336  	md.Write(za)
   337  	md.Write(msg)
   338  	// 对混入了ZA的签名内容做散列,对得到的校验和进行签名
   339  	return SignAfterZA(rand, priv, md.Sum(nil))
   340  }
   341  
   342  // SignAfterZA sm2签名函数
   343  //   1.内部不对签名内容hash进行混入ZA的散列处理。
   344  //   2.内部会根据rand与hash使用aes生成一个后续签名生成随机数用的csprng,即本函数在签名时获取随机数时不是直接使用rand。
   345  func SignAfterZA(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
   346  	// 为避免获取相同的随机数?
   347  	maybeReadByte(rand)
   348  
   349  	// ↓↓↓↓↓ 计算 csprng 用于签名时的随机数获取 begin ↓↓↓↓↓
   350  	// We use SDK's nouce generation implementation here.
   351  	// This implementation derives the nonce from an AES-CTR CSPRNG keyed by:
   352  	//    SHA2-512(priv.D || entropy || hash)[:32]
   353  	// The CSPRNG key is indifferentiable from a random oracle as shown in
   354  	// [Coron], the AES-CTR stream is indifferentiable from a random oracle
   355  	// under standard cryptographic assumptions (see [Larsson] for examples).
   356  	// [Coron]: https://cs.nyu.edu/~dodis/ps/merkle.pdf
   357  	// [Larsson]: https://web.archive.org/web/20040719170906/https://www.nada.kth.se/kurser/kth/2D1441/semteo03/lecturenotes/assump.pdf
   358  	// Get 256 bits of entropy from rand.
   359  	entropy := make([]byte, 32)
   360  	_, err = io.ReadFull(rand, entropy)
   361  	if err != nil {
   362  		return
   363  	}
   364  	// Initialize an SHA-512 hash context; digest ...
   365  	md := sha512.New()
   366  	md.Write(priv.D.Bytes()) // the private key,
   367  	md.Write(entropy)        // the entropy,
   368  	md.Write(hash)           // and the input hash;
   369  	key := md.Sum(nil)[:32]  // and compute ChopMD-256(SHA-512),
   370  	// which is an indifferentiable MAC.
   371  	// Create an AES-CTR instance to use as a CSPRNG.
   372  	block, err := aes.NewCipher(key)
   373  	if err != nil {
   374  		return nil, nil, err
   375  	}
   376  	// Create a CSPRNG that xors a stream of zeros with
   377  	// the output of the AES-CTR instance.
   378  	csprng := cipher.StreamReader{
   379  		R: zeroReader,
   380  		S: cipher.NewCTR(block, []byte(aesIV)),
   381  	}
   382  	// ↑↑↑↑↑ 计算 csprng 用于签名时的随机数获取 end ↑↑↑↑↑
   383  
   384  	return signGeneric(priv, &csprng, hash)
   385  }
   386  
   387  // sm2签名的具体实现
   388  func signGeneric(priv *PrivateKey, csprng *cipher.StreamReader, hash []byte) (r, s *big.Int, err error) {
   389  	// 获取私钥对应曲线
   390  	c := priv.PublicKey.Curve
   391  	N := c.Params().N
   392  	if N.Sign() == 0 {
   393  		return nil, nil, errZeroParam
   394  	}
   395  	var k *big.Int
   396  	e := hashToInt(hash, c)
   397  	for {
   398  		for {
   399  			// 1.生成随机数k,注意这里使用的不是random而是前面计算出来的csprng
   400  			k, err = randFieldElement(c, csprng)
   401  			if err != nil {
   402  				r = nil
   403  				return
   404  			}
   405  			// 2.计算P = k*G,即(x, y) = k*G,返回值的x座标赋予r
   406  			r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
   407  			// 3.计算 r = (e + P(x)) mod n
   408  			r.Add(r, e) // e + P(x)
   409  			r.Mod(r, N) //  (e + P(x)) mod n
   410  			if r.Sign() != 0 {
   411  				t := new(big.Int).Add(r, k)
   412  				// 步骤1,2,3得到的 r 与 k 满足条件才能跳出循环
   413  				if t.Cmp(N) != 0 { // if r != 0 && (r + k) != N then ok
   414  					break
   415  				}
   416  			}
   417  		}
   418  		// 4. 计算 s = (((1 + d)^-1) (k-rd)) mod n
   419  		s = new(big.Int).Mul(priv.D, r)      // r×d
   420  		s = new(big.Int).Sub(k, s)           // k - rd
   421  		dp1 := new(big.Int).Add(priv.D, one) // 1 + d
   422  		var dp1Inv *big.Int                  // (1 + d)^-1
   423  		if in, ok := priv.Curve.(invertible); ok {
   424  			// fmt.Println("sm2hard/sm2.go signGeneric 利用硬件加速")
   425  			// 如果平台cpu是amd64或arm64架构,则利用cpu硬件实现快速的 (1 + d)^-1 运算
   426  			dp1Inv = in.Inverse(dp1)
   427  		} else {
   428  			// fmt.Println("sm2hard/sm2.go signGeneric 没有利用硬件加速")
   429  			// 纯软实现的 (1 + d)^-1 运算
   430  			dp1Inv = fermatInverse(dp1, N) // N != 0
   431  		}
   432  		s.Mul(s, dp1Inv) // ((1 + d)^-1) × (k-rd)
   433  		s.Mod(s, N)      // (((1 + d)^-1) (k-rd)) mod n
   434  		if s.Sign() != 0 {
   435  			break
   436  		}
   437  	}
   438  
   439  	return
   440  }
   441  
   442  // Verify sm2公钥验签
   443  //  对msg做ZA混合散列
   444  func (pub *PublicKey) Verify(msg []byte, sig []byte) bool {
   445  	zclog.Debugf("sm2Pub.Verify内部固定使用ZA散列, 接收msg长度: %d", len(msg))
   446  	return VerifyASN1(pub, msg, sig)
   447  }
   448  
   449  // EcVerify 实现`ecbase.EcVerifier`接口
   450  //  根据opts决定是否需要做ZA混合散列,默认做
   451  func (pub *PublicKey) EcVerify(msg []byte, sig []byte, opts ecbase.EcSignerOpts) (bool, error) {
   452  	zclog.Debugf("sm2Pub.EcVerify 接收msg长度: %d", len(msg))
   453  	if opts == nil {
   454  		opts = DefaultSM2SignerOption()
   455  	}
   456  	withZA := false
   457  	if sm2Opts, ok := opts.(*SM2SignerOption); ok {
   458  		withZA = sm2Opts.ForceZA
   459  	} else {
   460  		// 传入的不是SM2SignerOption的话,默认做ZA混合散列
   461  		withZA = true
   462  	}
   463  	valid := false
   464  	if withZA {
   465  		zclog.Debugln("在sm2的EcVerify中执行有ZA混合散列的验签")
   466  		valid = VerifyASN1(pub, msg, sig)
   467  	} else {
   468  		zclog.Debugln("在sm2的EcVerify中执行没有ZA混合散列的验签")
   469  		valid = VerifyASN1WithoutZA(pub, msg, sig)
   470  	}
   471  	if !valid {
   472  		zclog.ErrorStack("sm2验签失败")
   473  		return valid, errors.New("sm2验签失败")
   474  	}
   475  	return valid, nil
   476  }
   477  
   478  // VerifyASN1 VerifyASN1将asn1格式字节数组的签名转为(r,s)在调用sm2的验签函数。
   479  //  对msg做ZA混合散列
   480  func VerifyASN1(pub *PublicKey, msg, sig []byte) bool {
   481  	//var (
   482  	//	r, s  = &big.Int{}, &big.Int{}
   483  	//	inner cryptobyte.String
   484  	//)
   485  	//input := cryptobyte.String(sig)
   486  	//if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
   487  	//	!input.Empty() ||
   488  	//	!inner.ReadASN1Integer(r) ||
   489  	//	!inner.ReadASN1Integer(s) ||
   490  	//	!inner.Empty() {
   491  	//	return false
   492  	//}
   493  	r, s, err := ecbase.UnmarshalECSignature(sig)
   494  	if err != nil {
   495  		zclog.Debugf("ecbase.UnmarshalECSignature 失败: %s", err.Error())
   496  		return false
   497  	}
   498  	return VerifyWithZA(pub, nil, msg, r, s)
   499  }
   500  
   501  // VerifyASN1WithoutZA 将asn1格式字节数组的签名转为(r,s),再做验签。
   502  // 不对hash再做ZA混合散列。
   503  //goland:noinspection GoUnusedExportedFunction
   504  func VerifyASN1WithoutZA(pub *PublicKey, hash, sig []byte) bool {
   505  	//var (
   506  	//	r, s  = &big.Int{}, &big.Int{}
   507  	//	inner cryptobyte.String
   508  	//)
   509  	//input := cryptobyte.String(sig)
   510  	//if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
   511  	//	!input.Empty() ||
   512  	//	!inner.ReadASN1Integer(r) ||
   513  	//	!inner.ReadASN1Integer(s) ||
   514  	//	!inner.Empty() {
   515  	//	return false
   516  	//}
   517  	r, s, err := ecbase.UnmarshalECSignature(sig)
   518  	if err != nil {
   519  		return false
   520  	}
   521  	return verifyGeneric(pub, hash, r, s)
   522  }
   523  
   524  // Verify sm2验签
   525  //  对msg做ZA混合散列
   526  //goland:noinspection GoUnusedExportedFunction
   527  func Verify(pub *PublicKey, msg []byte, r, s *big.Int) bool {
   528  	return VerifyWithZA(pub, nil, msg, r, s)
   529  }
   530  
   531  // Sm2Verify sm2验签
   532  //  对msg做ZA混合散列
   533  //goland:noinspection GoUnusedExportedFunction,GoNameStartsWithPackageName
   534  func Sm2Verify(pub *PublicKey, msg, uid []byte, r, s *big.Int) bool {
   535  	return VerifyWithZA(pub, uid, msg, r, s)
   536  }
   537  
   538  // VerifyWithZA 将对msg进行ZA混合散列后再进行验签。
   539  func VerifyWithZA(pub *PublicKey, uid, msg []byte, r, s *big.Int) bool {
   540  	if len(uid) == 0 {
   541  		uid = defaultUID
   542  	}
   543  	// 对消息进行ZA混合散列
   544  	za, err := calculateZA(pub, uid)
   545  	if err != nil {
   546  		zclog.Debugf("calculateZA失败: %s", err.Error())
   547  		return false
   548  	}
   549  	md := sm3.New()
   550  	md.Write(za)
   551  	md.Write(msg)
   552  	return verifyGeneric(pub, md.Sum(nil), r, s)
   553  }
   554  
   555  // sm2验签的具体实现。
   556  //  如果有ZA混合散列,则在调用该函数之前处理。
   557  func verifyGeneric(pub *PublicKey, hash []byte, r, s *big.Int) bool {
   558  	// 获取公钥对应曲线及其参数N
   559  	c := pub.Curve
   560  	N := c.Params().N
   561  	// 检查签名(r,s)是否在(0, N)区间
   562  	if r.Sign() <= 0 || s.Sign() <= 0 {
   563  		zclog.Debugln("r.Sign() <= 0 || s.Sign() <= 0")
   564  		return false
   565  	}
   566  	if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
   567  		zclog.Debugln("r.Cmp(N) >= 0 || s.Cmp(N) >= 0")
   568  		return false
   569  	}
   570  	e := hashToInt(hash, c)
   571  	// 1.计算 t = (r + s) mod n
   572  	t := new(big.Int).Add(r, s)
   573  	t.Mod(t, N)
   574  	if t.Sign() == 0 {
   575  		zclog.Debugln("t.Sign() == 0")
   576  		return false
   577  	}
   578  	var x *big.Int
   579  	if opt, ok := c.(combinedMult); ok {
   580  		// fmt.Println("sm2hard/sm2.go verifyGeneric 利用硬件加速")
   581  		// 如果cpu是amd64或arm64架构,则使用快速计算实现步骤2~4
   582  		x, _ = opt.CombinedMult(pub.X, pub.Y, s.Bytes(), t.Bytes())
   583  	} else {
   584  		// fmt.Println("sm2hard/sm2.go verifyGeneric 没有利用硬件加速")
   585  		// 2.计算 s*G
   586  		x1, y1 := c.ScalarBaseMult(s.Bytes())
   587  		// 3.计算 t*pub
   588  		x2, y2 := c.ScalarMult(pub.X, pub.Y, t.Bytes())
   589  		// 4.计算 s*G + t*pub 结果只要x轴座标
   590  		x, _ = c.Add(x1, y1, x2, y2)
   591  	}
   592  	// 计算 e + x
   593  	x.Add(x, e)
   594  	// 计算 R = (e + x) mod n
   595  	x.Mod(x, N)
   596  	// 判断 R == r
   597  	if x.Cmp(r) == 0 {
   598  		return true
   599  	} else {
   600  		zclog.Debugln("x.Cmp(r) != 0")
   601  		return false
   602  	}
   603  	//return x.Cmp(r) == 0
   604  }
   605  
   606  // CalculateZA ZA计算。
   607  //  SM2签名与验签之前,先对签名内容做一次混入ZA的散列。
   608  //  ZA的值是根据公钥与uid计算出来的。
   609  //  CalculateZA ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA).
   610  //  Compliance with GB/T 32918.2-2016 5.5
   611  //goland:noinspection GoUnusedExportedFunction
   612  func CalculateZA(pub *PublicKey, uid []byte) ([]byte, error) {
   613  	return calculateZA(pub, uid)
   614  }
   615  
   616  // ZA计算。
   617  //  SM2签名与验签之前,先对签名内容做一次混入ZA的散列。
   618  //  ZA的值是根据公钥与uid计算出来的。
   619  //  calculateZA ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA)
   620  //  Compliance with GB/T 32918.2-2016 5.5
   621  func calculateZA(pub *PublicKey, uid []byte) ([]byte, error) {
   622  	uidLen := len(uid)
   623  	if uidLen >= 0x2000 {
   624  		return nil, errors.New("the uid is too long")
   625  	}
   626  	entla := uint16(uidLen) << 3
   627  	md := sm3.New()
   628  	md.Write([]byte{byte(entla >> 8), byte(entla)})
   629  	if uidLen > 0 {
   630  		md.Write(uid)
   631  	}
   632  	a := new(big.Int).Sub(pub.Params().P, big.NewInt(3))
   633  	md.Write(toBytes(pub.Curve, a))
   634  	md.Write(toBytes(pub.Curve, pub.Params().B))
   635  	md.Write(toBytes(pub.Curve, pub.Params().Gx))
   636  	md.Write(toBytes(pub.Curve, pub.Params().Gy))
   637  	md.Write(toBytes(pub.Curve, pub.X))
   638  	md.Write(toBytes(pub.Curve, pub.Y))
   639  	return md.Sum(nil), nil
   640  }
   641  
   642  // hashToInt converts a hash value to an integer. Per FIPS 186-4, Section 6.4,
   643  // we use the left-most bits of the hash to match the bit-length of the order of
   644  // the curve. This also performs Step 5 of SEC 1, Version 2.0, Section 4.1.3.
   645  func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
   646  	orderBits := c.Params().N.BitLen()
   647  	orderBytes := (orderBits + 7) / 8
   648  	if len(hash) > orderBytes {
   649  		hash = hash[:orderBytes]
   650  	}
   651  
   652  	ret := new(big.Int).SetBytes(hash)
   653  	excess := len(hash)*8 - orderBits
   654  	if excess > 0 {
   655  		ret.Rsh(ret, uint(excess))
   656  	}
   657  	return ret
   658  }
   659  
   660  type zr struct {
   661  	io.Reader
   662  }
   663  
   664  // Read replaces the contents of dst with zeros.
   665  func (z *zr) Read(dst []byte) (n int, err error) {
   666  	for i := range dst {
   667  		dst[i] = 0
   668  	}
   669  	return len(dst), nil
   670  }
   671  
   672  var zeroReader = &zr{}
   673  
   674  // A invertible implements fast inverse in GF(N).
   675  type invertible interface {
   676  	// Inverse mod Params().N 的倒数运算
   677  	// Inverse returns the inverse of k mod Params().N.
   678  	Inverse(k *big.Int) *big.Int
   679  }
   680  
   681  // fermatInverse 使用费马方法(取幂模 P - 2,根据欧拉定理)计算 GF(P) 中 k 的倒数。
   682  //
   683  // fermatInverse calculates the inverse of k in GF(P) using Fermat's method
   684  // (exponentiation modulo P - 2, per Euler's theorem). This has better
   685  // constant-time properties than Euclid's method (implemented in
   686  // math/big.Int.ModInverse and FIPS 186-4, Appendix C.1) although math/big
   687  // itself isn't strictly constant-time so it's not perfect.
   688  func fermatInverse(k, N *big.Int) *big.Int {
   689  	two := big.NewInt(2)
   690  	nMinus2 := new(big.Int).Sub(N, two)
   691  	return new(big.Int).Exp(k, nMinus2, N)
   692  }
   693  
   694  // combineMult 实现了快速组合乘法以进行验证。需要平台对应架构CPU的硬件支持。
   695  // A combinedMult implements fast combined multiplication for verification.
   696  type combinedMult interface {
   697  	// CombinedMult 返回 [s1]G + [s2]P,其中 G 是生成器。
   698  	//  需要平台对应架构CPU的硬件支持。
   699  	// CombinedMult returns [s1]G + [s2]P where G is the generator.
   700  	CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int)
   701  }
   702  
   703  const (
   704  	aesIV = "IV for ECDSA CTR"
   705  )
   706  
   707  // ↑↑↑↑↑↑↑↑↑↑ 签名与验签 ↑↑↑↑↑↑↑↑↑↑
   708  
   709  // ↓↓↓↓↓↓↓↓↓↓ 非对称加解密 ↓↓↓↓↓↓↓↓↓↓
   710  
   711  // EncryptAsn1 sm2公钥加密, C1C3C2, C1不压缩, C3C2做ASN1转码
   712  func (pub *PublicKey) EncryptAsn1(data []byte, random io.Reader) ([]byte, error) {
   713  	return EncryptAsn1(pub, data, random)
   714  }
   715  
   716  // DecryptAsn1 sm2私钥解密, C1C3C2, C1不压缩, C3C2做ASN1转码
   717  func (priv *PrivateKey) DecryptAsn1(data []byte) ([]byte, error) {
   718  	return DecryptAsn1(priv, data)
   719  }
   720  
   721  // Encrypt sm2公钥加密
   722  //  opts传nil代表默认模式: C1C3C2, C1不压缩, C3C2不做ASN1转码
   723  func (pub *PublicKey) Encrypt(rand io.Reader, msg []byte, opts *EncrypterOpts) (ciphertext []byte, err error) {
   724  	return encryptGeneric(rand, pub, msg, opts)
   725  }
   726  
   727  // Decrypt sm2私钥解密
   728  //  opts传nil代表C1C3C2模式
   729  //goland:noinspection GoUnusedParameter
   730  func (priv *PrivateKey) Decrypt(rand io.Reader, msg []byte, opts *DecrypterOpts) (plaintext []byte, err error) {
   731  	return decryptGeneric(priv, msg, opts)
   732  }
   733  
   734  // Encrypt sm2公钥加密
   735  //  opts传nil代表默认模式: C1C3C2, C1不压缩, C3C2不做ASN1转码
   736  func Encrypt(pub *PublicKey, data []byte, random io.Reader, opts *EncrypterOpts) ([]byte, error) {
   737  	return encryptGeneric(random, pub, data, opts)
   738  }
   739  
   740  // Decrypt sm2私钥解密
   741  //  opts传nil代表C1C3C2模式
   742  func Decrypt(priv *PrivateKey, data []byte, opts *DecrypterOpts) ([]byte, error) {
   743  	return decryptGeneric(priv, data, opts)
   744  }
   745  
   746  // EncryptDefault sm2公钥加密
   747  //  默认模式: C1C3C2, C1不压缩, C3C2不做ASN1转码
   748  //goland:noinspection GoUnusedExportedFunction
   749  func EncryptDefault(pub *PublicKey, data []byte, random io.Reader) ([]byte, error) {
   750  	return encryptGeneric(random, pub, data, nil)
   751  }
   752  
   753  // EncryptAsn1 sm2公钥加密
   754  //  默认模式: C1C3C2, C1不压缩, C3C2做ASN1转码
   755  func EncryptAsn1(pub *PublicKey, data []byte, random io.Reader) ([]byte, error) {
   756  	return encryptGeneric(random, pub, data, ASN1EncrypterOpts)
   757  }
   758  
   759  // DecryptDefault sm2私钥解密, C1C3C2模式
   760  //goland:noinspection GoUnusedExportedFunction
   761  func DecryptDefault(priv *PrivateKey, ciphertext []byte) ([]byte, error) {
   762  	return decryptGeneric(priv, ciphertext, nil)
   763  }
   764  
   765  // DecryptAsn1 sm2私钥解密, C1C3C2, C3C2做ASN1转码
   766  func DecryptAsn1(priv *PrivateKey, ciphertext []byte) ([]byte, error) {
   767  	return decryptGeneric(priv, ciphertext, ASN1DecrypterOpts)
   768  }
   769  
   770  // encryptGeneric sm2公钥加密实现
   771  //  opts传nil代表默认模式: C1C3C2, C1不压缩, C3C2不做ASN1转码
   772  //  参考: GB/T 32918.4-2016 chapter 6
   773  func encryptGeneric(random io.Reader, pub *PublicKey, msg []byte, opts *EncrypterOpts) ([]byte, error) {
   774  	// 获取公钥对应曲线
   775  	curve := pub.Curve
   776  	msgLen := len(msg)
   777  	if msgLen == 0 {
   778  		return nil, nil
   779  	}
   780  	if opts == nil {
   781  		// 默认C1C3C2, C1不压缩, C3C2不做ASN1转码
   782  		opts = defaultEncrypterOpts
   783  	}
   784  	// 检查公钥坐标
   785  	if pub.X.Sign() == 0 && pub.Y.Sign() == 0 {
   786  		return nil, errors.New("SM2: invalid public key")
   787  	}
   788  	for {
   789  		// 1.获取随机数k
   790  		k, err := randFieldElement(curve, random)
   791  		if err != nil {
   792  			return nil, err
   793  		}
   794  		// 2.计算C1 = k*G ,C1是曲线上的一个点,坐标为(x1, y1)。
   795  		// 因为k是随机数,所以C1每次加密都是随机的
   796  		x1, y1 := curve.ScalarBaseMult(k.Bytes())
   797  		// 3.计算点(x2,y2) = k*pub,利用公钥计算出一个随机点(x2,y2)
   798  		x2, y2 := curve.ScalarMult(pub.X, pub.Y, k.Bytes())
   799  		var kdfCount = 0
   800  		// 4.使用密钥派生函数kdf,基于P计算长度等于data长度的派生密钥 t=KDF(x2||y2, klen)
   801  		t, success := kdf(append(toBytes(curve, x2), toBytes(curve, y2)...), msgLen)
   802  		if !success {
   803  			kdfCount++
   804  			if kdfCount > maxRetryLimit {
   805  				return nil, fmt.Errorf("SM2: A5, failed to calculate valid t, tried %v times", kdfCount)
   806  			}
   807  			continue
   808  		}
   809  		// 5.计算C2, 利用派生密钥t对data进行异或加密
   810  		c2 := make([]byte, msgLen)
   811  		for i := 0; i < msgLen; i++ {
   812  			c2[i] = msg[i] ^ t[i]
   813  		}
   814  		// 6.计算C3, 按照 (x2||msg||y2) 的顺序混合数据并做sm3摘要
   815  		c3 := calculateC3(curve, x2, y2, msg)
   816  		// 7.根据参数将C1,C2,C3拼接成加密结果
   817  		// c1字节数组 : 根据加密参数中的座标序列化模式,对c1进行序列化转为字节数组
   818  		c1 := opts.PointMarshalMode.mashal(curve, x1, y1)
   819  		// 如果C2C3不做ASN1转码,则直接在这里拼接加密结果
   820  		// 在 GB/T 32918.4-2016 中只看到直接拼接C2C3的,并没有对C3C2做ASN1转码的描述
   821  		if opts.CiphertextEncoding == ENCODING_PLAIN {
   822  			switch opts.CiphertextSplicingOrder {
   823  			case C1C3C2:
   824  				return append(append(c1, c3...), c2...), nil
   825  			case C1C2C3:
   826  				return append(append(c1, c2...), c3...), nil
   827  			}
   828  		}
   829  		// C2C3做ASN1转码时,只支持C1C3C2模式且C1不压缩
   830  		return mashalASN1Ciphertext(x1, y1, c2, c3)
   831  	}
   832  }
   833  
   834  // sm2私钥解密
   835  //  参考: GB/T 32918.4-2016 chapter 7.
   836  func decryptGeneric(priv *PrivateKey, ciphertext []byte, opts *DecrypterOpts) ([]byte, error) {
   837  	// 默认拼接顺序C1C3C2
   838  	splicingOrder := C1C3C2
   839  	if opts != nil {
   840  		// C3C2做了ASN1转码时,按照对应规则读取C1C3C2并做sm2私钥解密
   841  		if opts.CiphertextEncoding == ENCODING_ASN1 {
   842  			return decryptASN1(priv, ciphertext)
   843  		}
   844  		// 不是固定的ASN1模式时,设置传入的拼接模式
   845  		splicingOrder = opts.CipherTextSplicingOrder
   846  	}
   847  	// 判断密文是否做过ASN1转码
   848  	if ciphertext[0] == 0x30 {
   849  		return decryptASN1(priv, ciphertext)
   850  	}
   851  	ciphertextLen := len(ciphertext)
   852  	if ciphertextLen <= 1+(priv.Params().BitSize/8)+sm3.Size {
   853  		return nil, errors.New("SM2: invalid ciphertext length")
   854  	}
   855  	curve := priv.Curve
   856  	// 获取C1坐标,以及C1结束位置
   857  	x1, y1, c1End, err := bytes2Point(curve, ciphertext)
   858  	if err != nil {
   859  		return nil, err
   860  	}
   861  
   862  	// 根据拼接顺序取出C2C3
   863  	var c2, c3 []byte
   864  	if splicingOrder == C1C3C2 {
   865  		c2 = ciphertext[c1End+sm3.Size:]
   866  		c3 = ciphertext[c1End : c1End+sm3.Size]
   867  	} else {
   868  		c2 = ciphertext[c1End : ciphertextLen-sm3.Size]
   869  		c3 = ciphertext[ciphertextLen-sm3.Size:]
   870  	}
   871  	// 执行sm2私钥解密逻辑
   872  	return rawDecrypt(priv, x1, y1, c2, c3)
   873  }
   874  
   875  // 按照C1C3C2顺序, C1未压缩, C3C2做了ASN1转码的规则进行sm2私钥解密
   876  func decryptASN1(priv *PrivateKey, ciphertext []byte) ([]byte, error) {
   877  	x1, y1, c2, c3, err := unmarshalASN1Ciphertext(ciphertext)
   878  	if err != nil {
   879  		return nil, err
   880  	}
   881  	return rawDecrypt(priv, x1, y1, c2, c3)
   882  }
   883  
   884  // 按照C1C3C2顺序, C1未压缩, C3C2做了ASN1转码的规则读取C1,C2,C3
   885  func unmarshalASN1Ciphertext(ciphertext []byte) (*big.Int, *big.Int, []byte, []byte, error) {
   886  	var (
   887  		x1, y1 = &big.Int{}, &big.Int{}
   888  		c2, c3 []byte
   889  		inner  cryptobyte.String
   890  	)
   891  	input := cryptobyte.String(ciphertext)
   892  	if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
   893  		!input.Empty() ||
   894  		!inner.ReadASN1Integer(x1) ||
   895  		!inner.ReadASN1Integer(y1) ||
   896  		!inner.ReadASN1Bytes(&c3, asn1.OCTET_STRING) ||
   897  		!inner.ReadASN1Bytes(&c2, asn1.OCTET_STRING) ||
   898  		!inner.Empty() {
   899  		return nil, nil, nil, nil, errors.New("SM2: invalid asn1 format ciphertext")
   900  	}
   901  	return x1, y1, c2, c3, nil
   902  }
   903  
   904  // sm2私钥解密实现逻辑
   905  func rawDecrypt(priv *PrivateKey, x1, y1 *big.Int, c2, c3 []byte) ([]byte, error) {
   906  	// 获取私钥对应曲线
   907  	curve := priv.Curve
   908  	// 根据C1计算随机点 (x2,y2) = c1 * D
   909  	x2, y2 := curve.ScalarMult(x1, y1, priv.D.Bytes())
   910  	msgLen := len(c2)
   911  	// 派生密钥
   912  	t, success := kdf(append(toBytes(curve, x2), toBytes(curve, y2)...), msgLen)
   913  	if !success {
   914  		return nil, errors.New("SM2: invalid cipher text")
   915  	}
   916  	// 再对c2做异或运算,恢复msg
   917  	msg := make([]byte, msgLen)
   918  	for i := 0; i < msgLen; i++ {
   919  		msg[i] = c2[i] ^ t[i]
   920  	}
   921  	// 重新计算C3并比较
   922  	u := calculateC3(curve, x2, y2, msg)
   923  	for i := 0; i < sm3.Size; i++ {
   924  		if c3[i] != u[i] {
   925  			return nil, errors.New("SM2: invalid hash value")
   926  		}
   927  	}
   928  	return msg, nil
   929  }
   930  
   931  // ASN1Ciphertext2Plain sm2加密结果去除ASN1转码
   932  // ASN1Ciphertext2Plain utility method to convert ASN.1 encoding ciphertext to plain encoding format
   933  func ASN1Ciphertext2Plain(ciphertext []byte, opts *EncrypterOpts) ([]byte, error) {
   934  	if opts == nil {
   935  		opts = defaultEncrypterOpts
   936  	}
   937  	x1, y1, c2, c3, err := unmarshalASN1Ciphertext(ciphertext)
   938  	if err != nil {
   939  		return nil, err
   940  	}
   941  	curve := P256Sm2()
   942  	c1 := opts.PointMarshalMode.mashal(curve, x1, y1)
   943  	if opts.CiphertextSplicingOrder == C1C3C2 {
   944  		// c1 || c3 || c2
   945  		return append(append(c1, c3...), c2...), nil
   946  	}
   947  	// c1 || c2 || c3
   948  	return append(append(c1, c2...), c3...), nil
   949  }
   950  
   951  // PlainCiphertext2ASN1 sm2加密结果改为ASN1转码
   952  // PlainCiphertext2ASN1 utility method to convert plain encoding ciphertext to ASN.1 encoding format
   953  func PlainCiphertext2ASN1(ciphertext []byte, from ciphertextSplicingOrder) ([]byte, error) {
   954  	if ciphertext[0] == 0x30 {
   955  		return nil, errors.New("SM2: invalid plain encoding ciphertext")
   956  	}
   957  	curve := P256Sm2()
   958  	ciphertextLen := len(ciphertext)
   959  	if ciphertextLen <= 1+(curve.Params().BitSize/8)+sm3.Size {
   960  		return nil, errors.New("SM2: invalid ciphertext length")
   961  	}
   962  	// get C1, and check C1
   963  	x1, y1, c3Start, err := bytes2Point(curve, ciphertext)
   964  	if err != nil {
   965  		return nil, err
   966  	}
   967  
   968  	var c2, c3 []byte
   969  
   970  	if from == C1C3C2 {
   971  		c2 = ciphertext[c3Start+sm3.Size:]
   972  		c3 = ciphertext[c3Start : c3Start+sm3.Size]
   973  	} else {
   974  		c2 = ciphertext[c3Start : ciphertextLen-sm3.Size]
   975  		c3 = ciphertext[ciphertextLen-sm3.Size:]
   976  	}
   977  	return mashalASN1Ciphertext(x1, y1, c2, c3)
   978  }
   979  
   980  // AdjustCiphertextSplicingOrder 修改sm2加密结果的C2C3拼接顺序
   981  // AdjustCiphertextSplicingOrder utility method to change c2 c3 order
   982  func AdjustCiphertextSplicingOrder(ciphertext []byte, from, to ciphertextSplicingOrder) ([]byte, error) {
   983  	curve := P256Sm2()
   984  	if from == to {
   985  		return ciphertext, nil
   986  	}
   987  	ciphertextLen := len(ciphertext)
   988  	if ciphertextLen <= 1+(curve.Params().BitSize/8)+sm3.Size {
   989  		return nil, errors.New("SM2: invalid ciphertext length")
   990  	}
   991  	// 检查C1并获取C1结束位置
   992  	_, _, c1End, err := bytes2Point(curve, ciphertext)
   993  	if err != nil {
   994  		return nil, err
   995  	}
   996  	var c1, c2, c3 []byte
   997  	c1 = ciphertext[:c1End]
   998  	if from == C1C3C2 {
   999  		c2 = ciphertext[c1End+sm3.Size:]
  1000  		c3 = ciphertext[c1End : c1End+sm3.Size]
  1001  	} else {
  1002  		c2 = ciphertext[c1End : ciphertextLen-sm3.Size]
  1003  		c3 = ciphertext[ciphertextLen-sm3.Size:]
  1004  	}
  1005  	result := make([]byte, ciphertextLen)
  1006  	copy(result, c1)
  1007  	if to == C1C3C2 {
  1008  		// c1 || c3 || c2
  1009  		copy(result[c1End:], c3)
  1010  		copy(result[c1End+sm3.Size:], c2)
  1011  	} else {
  1012  		// c1 || c2 || c3
  1013  		copy(result[c1End:], c2)
  1014  		copy(result[ciphertextLen-sm3.Size:], c3)
  1015  	}
  1016  	return result, nil
  1017  }
  1018  
  1019  // 计算C3 : sm3hash(x2||msg||y2)
  1020  func calculateC3(curve elliptic.Curve, x2, y2 *big.Int, msg []byte) []byte {
  1021  	md := sm3.New()
  1022  	md.Write(toBytes(curve, x2))
  1023  	md.Write(msg)
  1024  	md.Write(toBytes(curve, y2))
  1025  	return md.Sum(nil)
  1026  }
  1027  
  1028  // 对C3C2做ASN1格式转码,并将加密啊结果拼接为C1C3C2模式,且C1不压缩
  1029  func mashalASN1Ciphertext(x1, y1 *big.Int, c2, c3 []byte) ([]byte, error) {
  1030  	var b cryptobyte.Builder
  1031  	b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
  1032  		b.AddASN1BigInt(x1)
  1033  		b.AddASN1BigInt(y1)
  1034  		b.AddASN1OctetString(c3)
  1035  		b.AddASN1OctetString(c2)
  1036  	})
  1037  	return b.Bytes()
  1038  }
  1039  
  1040  // // EncryptASN1 sm2 encrypt and output ASN.1 result, compliance with GB/T 32918.4-2016.
  1041  // func EncryptASN1(random io.Reader, pub *ecdsa.PublicKey, msg []byte) ([]byte, error) {
  1042  // 	return Encrypt(random, pub, msg, ASN1EncrypterOpts)
  1043  // }
  1044  
  1045  const maxRetryLimit = 100
  1046  
  1047  // 密钥派生函数
  1048  // kdf key derivation function, compliance with GB/T 32918.4-2016 5.4.3.
  1049  func kdf(z []byte, len int) ([]byte, bool) {
  1050  	// limit := (len + sm3.Size - 1) >> sm3.SizeBitSize
  1051  	limit := (len + sm3.Size - 1) >> 5
  1052  	hasher := sm3.New()
  1053  	var countBytes [4]byte
  1054  	var ct uint32 = 1
  1055  	k := make([]byte, len+sm3.Size-1)
  1056  	for i := 0; i < limit; i++ {
  1057  		binary.BigEndian.PutUint32(countBytes[:], ct)
  1058  		hasher.Write(z)
  1059  		hasher.Write(countBytes[:])
  1060  		copy(k[i*sm3.Size:], hasher.Sum(nil))
  1061  		ct++
  1062  		hasher.Reset()
  1063  	}
  1064  	for i := 0; i < len; i++ {
  1065  		if k[i] != 0 {
  1066  			return k[:len], true
  1067  		}
  1068  	}
  1069  	return k, false
  1070  }
  1071  
  1072  const (
  1073  	uncompressed byte = 0x04
  1074  	compressed02 byte = 0x02
  1075  	compressed03 byte = 0x03
  1076  	mixed06      byte = 0x06
  1077  	mixed07      byte = 0x07
  1078  )
  1079  
  1080  // C1序列化模式
  1081  type pointMarshalMode byte
  1082  
  1083  const (
  1084  	// MarshalUncompressed C1不压缩序列化
  1085  	// MarshalUncompressed uncompressed mashal mode
  1086  	MarshalUncompressed pointMarshalMode = iota
  1087  	// MarshalCompressed C1压缩序列化
  1088  	// MarshalCompressed compressed mashal mode
  1089  	MarshalCompressed
  1090  	// MarshalMixed C1混合序列化
  1091  	// MarshalMixed mixed mashal mode
  1092  	MarshalMixed
  1093  )
  1094  
  1095  // sm2 C1C2C3拼接顺序
  1096  type ciphertextSplicingOrder byte
  1097  
  1098  const (
  1099  	// C1C3C2 默认使用 C1C3C2
  1100  	C1C3C2 ciphertextSplicingOrder = iota
  1101  	C1C2C3
  1102  )
  1103  
  1104  // sm2 C2C3转码规则
  1105  type ciphertextEncoding byte
  1106  
  1107  //goland:noinspection GoSnakeCaseUsage
  1108  const (
  1109  	// ENCODING_PLAIN 平文,即不对C2C3做ASN1转码
  1110  	ENCODING_PLAIN ciphertextEncoding = iota
  1111  	// ENCODING_ASN1 ASN1,即对C2C3做ASN1转码
  1112  	ENCODING_ASN1
  1113  )
  1114  
  1115  // EncrypterOpts 加密参数
  1116  // EncrypterOpts encryption options
  1117  type EncrypterOpts struct {
  1118  	// C2C3转码规则
  1119  	CiphertextEncoding ciphertextEncoding
  1120  	// C1序列化模式
  1121  	PointMarshalMode pointMarshalMode
  1122  	// C1C2C3拼接模式
  1123  	CiphertextSplicingOrder ciphertextSplicingOrder
  1124  }
  1125  
  1126  // DecrypterOpts 解密参数
  1127  // DecrypterOpts decryption options
  1128  type DecrypterOpts struct {
  1129  	// 转码规则
  1130  	CiphertextEncoding ciphertextEncoding
  1131  	// 拼接模式
  1132  	CipherTextSplicingOrder ciphertextSplicingOrder
  1133  }
  1134  
  1135  // NewPlainEncrypterOpts 生成不做ASN1转码的sm2加密参数
  1136  func NewPlainEncrypterOpts(marhsalMode pointMarshalMode, splicingOrder ciphertextSplicingOrder) *EncrypterOpts {
  1137  	return &EncrypterOpts{ENCODING_PLAIN, marhsalMode, splicingOrder}
  1138  }
  1139  
  1140  // NewPlainDecrypterOpts 生成不做ASN1转码的sm2解密参数
  1141  func NewPlainDecrypterOpts(splicingOrder ciphertextSplicingOrder) *DecrypterOpts {
  1142  	return &DecrypterOpts{ENCODING_PLAIN, splicingOrder}
  1143  }
  1144  
  1145  // 曲线座标序列化, 用于C1的序列化计算
  1146  func (mode pointMarshalMode) mashal(curve elliptic.Curve, x, y *big.Int) []byte {
  1147  	switch mode {
  1148  	case MarshalCompressed:
  1149  		// C1压缩序列化
  1150  		return point2CompressedBytes(curve, x, y)
  1151  	case MarshalMixed:
  1152  		// C1混合序列化
  1153  		return point2MixedBytes(curve, x, y)
  1154  	default:
  1155  		// C1完整序列化
  1156  		return point2UncompressedBytes(curve, x, y)
  1157  	}
  1158  }
  1159  
  1160  // 默认加密参数: C1C3C2, C1不压缩, C3C2不做ASN1转码
  1161  var defaultEncrypterOpts = &EncrypterOpts{ENCODING_PLAIN, MarshalUncompressed, C1C3C2}
  1162  
  1163  // ASN1EncrypterOpts ASN1转码加密参数: C1C3C2, C1不压缩, C3C2做ASN1转码
  1164  var ASN1EncrypterOpts = &EncrypterOpts{ENCODING_ASN1, MarshalUncompressed, C1C3C2}
  1165  
  1166  // ASN1DecrypterOpts ASN1转码解密参数: C1C3C2, C3C2做ASN1转码
  1167  var ASN1DecrypterOpts = &DecrypterOpts{ENCODING_ASN1, C1C3C2}
  1168  
  1169  // ↑↑↑↑↑↑↑↑↑↑ 非对称加解密 ↑↑↑↑↑↑↑↑↑↑