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 // ↑↑↑↑↑↑↑↑↑↑ 非对称加解密 ↑↑↑↑↑↑↑↑↑↑