github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/sm2/sm2.go (about)

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