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