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