gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/sm2soft/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 /* 10 sm2soft 是sm2的纯软实现,基于tjfoc国密算法库`tjfoc/gmsm`做了少量修改。 11 对应版权声明: thrid_licenses/github.com/tjfoc/gmsm/版权声明 12 */ 13 14 package sm2soft 15 16 // reference to ecdsa 17 import ( 18 "bytes" 19 "crypto" 20 "crypto/elliptic" 21 "crypto/rand" 22 "encoding/asn1" 23 "encoding/binary" 24 "errors" 25 "io" 26 "math/big" 27 28 "gitee.com/zhaochuninhefei/gmgo/sm3" 29 "golang.org/x/crypto/cryptobyte" 30 cbasn1 "golang.org/x/crypto/cryptobyte/asn1" 31 ) 32 33 var ( 34 defaultUid = []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38} 35 C1C3C2 = 0 36 C1C2C3 = 1 37 ) 38 39 // PublicKey SM2公钥结构体 40 type PublicKey struct { 41 elliptic.Curve // 椭圆曲线 42 X, Y *big.Int // 公钥座标 43 } 44 45 func (pub *PublicKey) Equal(x crypto.PublicKey) bool { 46 xx, ok := x.(*PublicKey) 47 if !ok { 48 return false 49 } 50 return pub.X.Cmp(xx.X) == 0 && pub.Y.Cmp(xx.Y) == 0 && 51 // Standard library Curve implementations are singletons, so this check 52 // will work for those. Other Curves might be equivalent even if not 53 // singletons, but there is no definitive way to check for that, and 54 // better to err on the side of safety. 55 pub.Curve == xx.Curve 56 } 57 58 // PrivateKey SM2私钥结构体 59 type PrivateKey struct { 60 PublicKey // 公钥 61 D *big.Int // 私钥,[1,n-1]区间的随机数 62 } 63 64 type sm2Cipher struct { 65 XCoordinate *big.Int 66 YCoordinate *big.Int 67 HASH []byte 68 CipherText []byte 69 } 70 71 // Public The SM2's private key contains the public key 72 func (priv *PrivateKey) Public() crypto.PublicKey { 73 return &priv.PublicKey 74 } 75 76 func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool { 77 xx, ok := x.(*PrivateKey) 78 if !ok { 79 return false 80 } 81 return priv.PublicKey.Equal(&xx.PublicKey) && priv.D.Cmp(xx.D) == 0 82 } 83 84 var errZeroParam = errors.New("zero parameter") 85 var one = new(big.Int).SetInt64(1) 86 var two = new(big.Int).SetInt64(2) 87 88 // sign format = 30 + len(z) + 02 + len(r) + r + 02 + len(s) + s, z being what follows its size, ie 02+len(r)+r+02+len(s)+s 89 90 // Sign 使用priv私钥对签名内容摘要做SM2签名,参数signer目前没有使用,但仍要求传入外部对明文消息做摘要的散列算法。 91 // 返回的签名为DER字节数组,对(r,s)做了asn1编码。 92 // - random : 随机数获取用, 如 rand.Reader 93 // - signContentDigest : 签名内容摘要(散列值) 94 // - signer : 外部对签名内容进行摘要计算使用的散列函数 95 //goland:noinspection GoUnusedParameter 96 func (priv *PrivateKey) Sign(random io.Reader, signContentDigest []byte, signer crypto.SignerOpts) ([]byte, error) { 97 r, s, err := Sm2Sign(priv, signContentDigest, nil, random) 98 if err != nil { 99 return nil, err 100 } 101 var b cryptobyte.Builder 102 b.AddASN1(cbasn1.SEQUENCE, func(b *cryptobyte.Builder) { 103 b.AddASN1BigInt(r) 104 b.AddASN1BigInt(s) 105 }) 106 return b.Bytes() 107 } 108 109 // SignASN1 使用私钥priv对一个hash值进行签名。 110 // 返回的签名为DER字节数组,对(r,s)做了asn1编码。 111 //goland:noinspection GoUnusedExportedFunction 112 func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte) ([]byte, error) { 113 return priv.Sign(rand, hash, nil) 114 } 115 116 // Verify 使用pub公钥对签名sig做验签。 117 // - signContentDigest : 签名内容摘要(散列值) 118 // - sig : 签名DER字节数组(对(r,s)做了asn1编码,因此会先做asn1解码) 119 func (pub *PublicKey) Verify(signContentDigest []byte, sig []byte) bool { 120 var ( 121 r, s = &big.Int{}, &big.Int{} 122 inner cryptobyte.String 123 ) 124 input := cryptobyte.String(sig) 125 if !input.ReadASN1(&inner, cbasn1.SEQUENCE) || 126 !input.Empty() || 127 !inner.ReadASN1Integer(r) || 128 !inner.ReadASN1Integer(s) || 129 !inner.Empty() { 130 return false 131 } 132 return Sm2Verify(pub, signContentDigest, defaultUid, r, s) 133 } 134 135 // VerifyASN1 使用公钥pub对hash和sig进行验签。 136 // - pub 公钥 137 // - hash 签名内容摘要(散列值) 138 // - sig 签名DER字节数组(对(r,s)做了asn1编码,因此会先做asn1解码) 139 //goland:noinspection GoUnusedExportedFunction 140 func VerifyASN1(pub *PublicKey, hash, sig []byte) bool { 141 return pub.Verify(hash, sig) 142 } 143 144 // Sm3Digest 对签名内容进行SM3摘要计算,摘要计算前混入sm2椭圆曲线部分参数与公钥并预散列一次。 145 func (pub *PublicKey) Sm3Digest(msg, uid []byte) ([]byte, error) { 146 if len(uid) == 0 { 147 uid = defaultUid 148 } 149 150 za, err := ZA(pub, uid) 151 if err != nil { 152 return nil, err 153 } 154 155 e, err := msgHash(za, msg) 156 if err != nil { 157 return nil, err 158 } 159 160 return e.Bytes(), nil 161 } 162 163 //****************************Encryption algorithm****************************// 164 165 // EncryptAsn1 sm2加密,C1C3C2,asn1编码 166 func (pub *PublicKey) EncryptAsn1(data []byte, random io.Reader) ([]byte, error) { 167 return EncryptAsn1(pub, data, random) 168 } 169 170 // DecryptAsn1 sm2解密,C1C3C2,asn1解码 171 func (priv *PrivateKey) DecryptAsn1(data []byte) ([]byte, error) { 172 return DecryptAsn1(priv, data) 173 } 174 175 //**************************Key agreement algorithm**************************// 176 177 // KeyExchangeB 协商第二部,用户B调用, 返回共享密钥k 178 func KeyExchangeB(klen int, ida, idb []byte, priB *PrivateKey, pubA *PublicKey, rpri *PrivateKey, rpubA *PublicKey) (k, s1, s2 []byte, err error) { 179 return keyExchange(klen, ida, idb, priB, pubA, rpri, rpubA, false) 180 } 181 182 // KeyExchangeA 协商第二部,用户A调用,返回共享密钥k 183 func KeyExchangeA(klen int, ida, idb []byte, priA *PrivateKey, pubB *PublicKey, rpri *PrivateKey, rpubB *PublicKey) (k, s1, s2 []byte, err error) { 184 return keyExchange(klen, ida, idb, priA, pubB, rpri, rpubB, true) 185 } 186 187 //****************************************************************************// 188 189 // Sm2Sign SM2签名 190 // - priv : 签名私钥 *sm2.PrivateKey 191 // - signContentDigest : 签名内容摘要(散列值) 192 // - uid : 内部混合摘要计算用uid, 长度16的字节数组,可以传 nil 193 // - random : 随机数获取用 194 func Sm2Sign(priv *PrivateKey, signContentDigest, uid []byte, random io.Reader) (r, s *big.Int, err error) { 195 // 对签名内容进行摘要计算 196 digest, err := priv.PublicKey.Sm3Digest(signContentDigest, uid) 197 if err != nil { 198 return nil, nil, err 199 } 200 e := new(big.Int).SetBytes(digest) 201 c := priv.PublicKey.Curve 202 N := c.Params().N 203 if N.Sign() == 0 { 204 return nil, nil, errZeroParam 205 } 206 var k *big.Int 207 // SM2签名实现 208 for { 209 for { 210 // 生成随机数k 211 k, err = randFieldElement(c, random) 212 if err != nil { 213 r = nil 214 return 215 } 216 // 计算P = k*G,返回值的x赋予了r 217 r, _ = priv.Curve.ScalarBaseMult(k.Bytes()) 218 // 计算 r = (e + P(x)) mod n 219 // e + P(x) 220 r.Add(r, e) 221 // (e + P(x)) mod n 222 r.Mod(r, N) 223 if r.Sign() != 0 { 224 if t := new(big.Int).Add(r, k); t.Cmp(N) != 0 { 225 break 226 } 227 } 228 229 } 230 // 计算 s = (((1 + d)^-1) (k-rd)) mod n 231 // rd 232 rD := new(big.Int).Mul(priv.D, r) 233 // k - rd 234 s = new(big.Int).Sub(k, rD) 235 // 1 + d 236 d1 := new(big.Int).Add(priv.D, one) 237 // (1 + d)^-1 238 d1Inv := new(big.Int).ModInverse(d1, N) 239 // ((1 + d)^-1) × (k-rd) 240 s.Mul(s, d1Inv) 241 // (((1 + d)^-1) (k-rd)) mod n 242 s.Mod(s, N) 243 if s.Sign() != 0 { 244 break 245 } 246 } 247 return 248 } 249 250 // Sm2Verify SM2验签 251 // - pub : 验签公钥, *sm2.PublicKey 252 // - signContentDigest : 签名内容摘要(散列值) 253 // - uid : 内部混合摘要计算用uid, 长度16的字节数组,可以传 nil 254 // - r, s : 签名 255 func Sm2Verify(pub *PublicKey, signContentDigest, uid []byte, r, s *big.Int) bool { 256 c := pub.Curve 257 N := c.Params().N 258 one := new(big.Int).SetInt64(1) 259 if r.Cmp(one) < 0 || s.Cmp(one) < 0 { 260 return false 261 } 262 if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 { 263 return false 264 } 265 if len(uid) == 0 { 266 uid = defaultUid 267 } 268 // 获取za: sm3(ENTLA || IDA || a || b || xG || yG || xA || yA) 269 za, err := ZA(pub, uid) 270 if err != nil { 271 return false 272 } 273 // 混合za与签名内容明文,并做sm3摘要 274 e, err := msgHash(za, signContentDigest) 275 if err != nil { 276 return false 277 } 278 // 计算 t = (r + s) mod n 279 t := new(big.Int).Add(r, s) 280 t.Mod(t, N) 281 if t.Sign() == 0 { 282 return false 283 } 284 var x *big.Int 285 // 计算 s*G 286 x1, y1 := c.ScalarBaseMult(s.Bytes()) 287 // 计算 t*pub 288 x2, y2 := c.ScalarMult(pub.X, pub.Y, t.Bytes()) 289 // 计算 s*G + t*pub 结果只要x轴座标 290 x, _ = c.Add(x1, y1, x2, y2) 291 // 计算 e + x 292 x.Add(x, e) 293 // 计算 R = (e + x) mod n 294 x.Mod(x, N) 295 // 判断 R == r 296 return x.Cmp(r) == 0 297 } 298 299 // Verify SM2验签 300 // - pub : 验签公钥, *sm2.PublicKey 301 // - hash : 签名内容摘要(散列值) 302 // - r, s : 签名 303 //goland:noinspection GoUnusedExportedFunction 304 func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { 305 return Sm2Verify(pub, hash, nil, r, s) 306 } 307 308 /* 309 za, err := ZA(pub, uid) 310 if err != nil { 311 return 312 } 313 e, err := msgHash(za, msg) 314 hash=e.getBytes() 315 */ 316 // 并非sm2验签 317 // func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool { 318 // c := pub.Curve 319 // N := c.Params().N 320 321 // if r.Sign() <= 0 || s.Sign() <= 0 { 322 // return false 323 // } 324 // if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 { 325 // return false 326 // } 327 328 // // 调整算法细节以实现SM2 329 // t := new(big.Int).Add(r, s) 330 // t.Mod(t, N) 331 // if t.Sign() == 0 { 332 // return false 333 // } 334 335 // var x *big.Int 336 // x1, y1 := c.ScalarBaseMult(s.Bytes()) 337 // x2, y2 := c.ScalarMult(pub.X, pub.Y, t.Bytes()) 338 // x, _ = c.Add(x1, y1, x2, y2) 339 340 // e := new(big.Int).SetBytes(hash) 341 // x.Add(x, e) 342 // x.Mod(x, N) 343 // return x.Cmp(r) == 0 344 // } 345 346 // Encrypt sm2非对称加密,支持C1C3C2(mode = 0)与C1C2C3(mode = 1)两种模式,默认使用C1C3C2模式。 347 // 不同的模式表示不同的密文结构,其中C1C2C3的意义: 348 // C1 : sm2椭圆曲线上的某个点,每次加密得到的点不一样 349 // C2 : 密文 350 // C3 : 明文加盐后的摘要 351 func Encrypt(pub *PublicKey, data []byte, random io.Reader, mode int) ([]byte, error) { 352 length := len(data) 353 for { 354 var c []byte 355 curve := pub.Curve 356 // 获取随机数k 357 k, err := randFieldElement(curve, random) 358 if err != nil { 359 return nil, err 360 } 361 // 计算点C1 = k*G ,因为k是随机数,所以C1每次加密都是随机的 362 x1, y1 := curve.ScalarBaseMult(k.Bytes()) 363 // 计算点(x2,y2) = k*pub,利用公钥计算出一个随机的点P 364 x2, y2 := curve.ScalarMult(pub.X, pub.Y, k.Bytes()) 365 x1Buf := x1.Bytes() 366 y1Buf := y1.Bytes() 367 x2Buf := x2.Bytes() 368 y2Buf := y2.Bytes() 369 // 填充满32个字节长度 370 if n := len(x1Buf); n < 32 { 371 x1Buf = append(zeroByteSlice()[:32-n], x1Buf...) 372 } 373 if n := len(y1Buf); n < 32 { 374 y1Buf = append(zeroByteSlice()[:32-n], y1Buf...) 375 } 376 if n := len(x2Buf); n < 32 { 377 x2Buf = append(zeroByteSlice()[:32-n], x2Buf...) 378 } 379 if n := len(y2Buf); n < 32 { 380 y2Buf = append(zeroByteSlice()[:32-n], y2Buf...) 381 } 382 // 填入C1(x) 383 c = append(c, x1Buf...) 384 // 填入C1(y) 385 c = append(c, y1Buf...) 386 387 // 计算C3 : 按 x2 data y2 的顺序混合数据并做sm3摘要 388 var tm []byte 389 tm = append(tm, x2Buf...) 390 tm = append(tm, data...) 391 tm = append(tm, y2Buf...) 392 h := sm3.Sm3Sum(tm) 393 // 填入C3 394 c = append(c, h...) 395 396 // 使用密钥派生函数kdf,基于P计算长度等于data长度的派生密钥 ct 397 ct, ok := kdf(length, x2Buf, y2Buf) 398 if !ok { 399 continue 400 } 401 // 填入ct 402 c = append(c, ct...) 403 // 利用ct对data进行异或加密,并覆盖c中对应内容 404 for i := 0; i < length; i++ { 405 c[96+i] ^= data[i] 406 } 407 408 // 此时c的内容是 c1c3c2,需要根据传入的参数mode判断是否需要重新排列。 409 switch mode { 410 case C1C3C2: 411 return append([]byte{0x04}, c...), nil 412 case C1C2C3: 413 // 如果是 C1C2C3 模式,那么需要将c切分后重新组装 414 c1 := make([]byte, 64) 415 c2 := make([]byte, len(c)-96) 416 c3 := make([]byte, 32) 417 // C1,即 x1Buf+y1Buf 418 copy(c1, c[:64]) 419 // C3,即 x2+data+y2混合后的SM3摘要 420 copy(c3, c[64:96]) 421 // C2,即 使用kdf派生出的密钥对data进行加密后的密文 422 copy(c2, c[96:]) 423 // 按C1C2C3的顺序组装结果 424 var ciphertext []byte 425 ciphertext = append(ciphertext, c1...) 426 ciphertext = append(ciphertext, c2...) 427 ciphertext = append(ciphertext, c3...) 428 return append([]byte{0x04}, ciphertext...), nil 429 default: 430 return append([]byte{0x04}, c...), nil 431 } 432 } 433 } 434 435 // Decrypt sm2非对称解密 436 func Decrypt(priv *PrivateKey, data []byte, mode int) ([]byte, error) { 437 switch mode { 438 case C1C3C2: 439 data = data[1:] 440 case C1C2C3: 441 // C1C2C3重新组装为 C1C3C2 442 data = data[1:] 443 c1 := make([]byte, 64) 444 c2 := make([]byte, len(data)-96) 445 c3 := make([]byte, 32) 446 copy(c1, data[:64]) //x1,y1 447 copy(c2, data[64:len(data)-32]) //密文 448 copy(c3, data[len(data)-32:]) //hash 449 var c []byte 450 c = append(c, c1...) 451 c = append(c, c3...) 452 c = append(c, c2...) 453 data = c 454 default: 455 data = data[1:] 456 } 457 length := len(data) - 96 458 curve := priv.Curve 459 // 取出C1的x和y 460 x := new(big.Int).SetBytes(data[:32]) 461 y := new(big.Int).SetBytes(data[32:64]) 462 // 根据C1计算 P = d*C1 463 x2, y2 := curve.ScalarMult(x, y, priv.D.Bytes()) 464 x2Buf := x2.Bytes() 465 y2Buf := y2.Bytes() 466 if n := len(x2Buf); n < 32 { 467 x2Buf = append(zeroByteSlice()[:32-n], x2Buf...) 468 } 469 if n := len(y2Buf); n < 32 { 470 y2Buf = append(zeroByteSlice()[:32-n], y2Buf...) 471 } 472 // 使用密钥派生函数kdf,基于P计算派生密钥 c 473 c, ok := kdf(length, x2Buf, y2Buf) 474 if !ok { 475 return nil, errors.New("decrypt: failed to decrypt") 476 } 477 // 使用派生密钥c对C2部分做异或计算解密 478 // 解密结果覆盖到c中,此时c即明文 479 for i := 0; i < length; i++ { 480 c[i] ^= data[i+96] 481 } 482 // 重新混合明文并计算摘要,与C3进行比较 483 var tm []byte 484 tm = append(tm, x2Buf...) 485 tm = append(tm, c...) 486 tm = append(tm, y2Buf...) 487 h := sm3.Sm3Sum(tm) 488 if !bytes.Equal(h, data[64:96]) { 489 return c, errors.New("decrypt: failed to decrypt") 490 } 491 return c, nil 492 } 493 494 // keyExchange 为SM2密钥交换算法的第二部和第三步复用部分,协商的双方均调用此函数计算共同的字节串 495 // klen: 密钥长度 496 // ida, idb: 协商双方的标识,ida为密钥协商算法发起方标识,idb为响应方标识 497 // pri: 函数调用者的密钥 498 // pub: 对方的公钥 499 // rpri: 函数调用者生成的临时SM2密钥 500 // rpub: 对方发来的临时SM2公钥 501 // thisIsA: 如果是A调用,文档中的协商第三步,设置为true,否则设置为false 502 // 返回 k 为klen长度的字节串 503 func keyExchange(klen int, ida, idb []byte, pri *PrivateKey, pub *PublicKey, rpri *PrivateKey, rpub *PublicKey, thisISA bool) (k, s1, s2 []byte, err error) { 504 curve := P256Sm2() 505 N := curve.Params().N 506 x2hat := keXHat(rpri.PublicKey.X) 507 x2rb := new(big.Int).Mul(x2hat, rpri.D) 508 tbt := new(big.Int).Add(pri.D, x2rb) 509 tb := new(big.Int).Mod(tbt, N) 510 if !curve.IsOnCurve(rpub.X, rpub.Y) { 511 err = errors.New("ra not on curve") 512 return 513 } 514 x1hat := keXHat(rpub.X) 515 ramx1, ramy1 := curve.ScalarMult(rpub.X, rpub.Y, x1hat.Bytes()) 516 vxt, vyt := curve.Add(pub.X, pub.Y, ramx1, ramy1) 517 518 vx, vy := curve.ScalarMult(vxt, vyt, tb.Bytes()) 519 pza := pub 520 if thisISA { 521 pza = &pri.PublicKey 522 } 523 za, err := ZA(pza, ida) 524 if err != nil { 525 return 526 } 527 zero := new(big.Int) 528 if vx.Cmp(zero) == 0 || vy.Cmp(zero) == 0 { 529 err = errors.New("v is infinite") 530 return 531 } 532 pzb := pub 533 if !thisISA { 534 pzb = &pri.PublicKey 535 } 536 zb, _ := ZA(pzb, idb) 537 k, ok := kdf(klen, vx.Bytes(), vy.Bytes(), za, zb) 538 if !ok { 539 err = errors.New("kdf: zero key") 540 return 541 } 542 h1 := BytesCombine(vx.Bytes(), za, zb, rpub.X.Bytes(), rpub.Y.Bytes(), rpri.X.Bytes(), rpri.Y.Bytes()) 543 if !thisISA { 544 h1 = BytesCombine(vx.Bytes(), za, zb, rpri.X.Bytes(), rpri.Y.Bytes(), rpub.X.Bytes(), rpub.Y.Bytes()) 545 } 546 hash := sm3.Sm3Sum(h1) 547 h2 := BytesCombine([]byte{0x02}, vy.Bytes(), hash) 548 S1 := sm3.Sm3Sum(h2) 549 h3 := BytesCombine([]byte{0x03}, vy.Bytes(), hash) 550 S2 := sm3.Sm3Sum(h3) 551 return k, S1, S2, nil 552 } 553 554 func msgHash(za, msg []byte) (*big.Int, error) { 555 e := sm3.New() 556 e.Write(za) 557 e.Write(msg) 558 return new(big.Int).SetBytes(e.Sum(nil)[:32]), nil 559 } 560 561 // ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA) 562 func ZA(pub *PublicKey, uid []byte) ([]byte, error) { 563 za := sm3.New() 564 uidLen := len(uid) 565 if uidLen >= 8192 { 566 return []byte{}, errors.New("SM2: uid too large") 567 } 568 Entla := uint16(8 * uidLen) 569 za.Write([]byte{byte((Entla >> 8) & 0xFF)}) 570 za.Write([]byte{byte(Entla & 0xFF)}) 571 if uidLen > 0 { 572 za.Write(uid) 573 } 574 za.Write(sm2P256ToBig(&sm2P256.a).Bytes()) 575 za.Write(sm2P256.B.Bytes()) 576 za.Write(sm2P256.Gx.Bytes()) 577 za.Write(sm2P256.Gy.Bytes()) 578 579 xBuf := pub.X.Bytes() 580 yBuf := pub.Y.Bytes() 581 if n := len(xBuf); n < 32 { 582 xBuf = append(zeroByteSlice()[:32-n], xBuf...) 583 } 584 if n := len(yBuf); n < 32 { 585 yBuf = append(zeroByteSlice()[:32-n], yBuf...) 586 } 587 za.Write(xBuf) 588 za.Write(yBuf) 589 return za.Sum(nil)[:32], nil 590 } 591 592 // 32byte 593 func zeroByteSlice() []byte { 594 return []byte{ 595 0, 0, 0, 0, 596 0, 0, 0, 0, 597 0, 0, 0, 0, 598 0, 0, 0, 0, 599 0, 0, 0, 0, 600 0, 0, 0, 0, 601 0, 0, 0, 0, 602 0, 0, 0, 0, 603 } 604 } 605 606 // EncryptAsn1 sm2加密,返回asn.1编码格式的密文内容 607 func EncryptAsn1(pub *PublicKey, data []byte, rand io.Reader) ([]byte, error) { 608 cipher, err := Encrypt(pub, data, rand, C1C3C2) 609 if err != nil { 610 return nil, err 611 } 612 return CipherMarshal(cipher) 613 } 614 615 // DecryptAsn1 sm2解密,解析asn.1编码格式的密文内容 616 func DecryptAsn1(pub *PrivateKey, data []byte) ([]byte, error) { 617 cipher, err := CipherUnmarshal(data) 618 if err != nil { 619 return nil, err 620 } 621 return Decrypt(pub, cipher, C1C3C2) 622 } 623 624 // CipherMarshal sm2密文转asn.1编码格式 625 // sm2密文结构如下: 626 // - x 627 // - y 628 // - hash 629 // - CipherText 630 func CipherMarshal(data []byte) ([]byte, error) { 631 data = data[1:] 632 x := new(big.Int).SetBytes(data[:32]) 633 y := new(big.Int).SetBytes(data[32:64]) 634 hash := data[64:96] 635 cipherText := data[96:] 636 return asn1.Marshal(sm2Cipher{x, y, hash, cipherText}) 637 } 638 639 // CipherUnmarshal sm2密文asn.1编码格式转C1|C3|C2拼接格式 640 func CipherUnmarshal(data []byte) ([]byte, error) { 641 var cipher sm2Cipher 642 _, err := asn1.Unmarshal(data, &cipher) 643 if err != nil { 644 return nil, err 645 } 646 x := cipher.XCoordinate.Bytes() 647 y := cipher.YCoordinate.Bytes() 648 hash := cipher.HASH 649 if err != nil { 650 return nil, err 651 } 652 cipherText := cipher.CipherText 653 if err != nil { 654 return nil, err 655 } 656 if n := len(x); n < 32 { 657 x = append(zeroByteSlice()[:32-n], x...) 658 } 659 if n := len(y); n < 32 { 660 y = append(zeroByteSlice()[:32-n], y...) 661 } 662 var c []byte 663 c = append(c, x...) // x分量 664 c = append(c, y...) // y分 665 c = append(c, hash...) // x分量 666 c = append(c, cipherText...) // y分 667 return append([]byte{0x04}, c...), nil 668 } 669 670 // keXHat 计算 x = 2^w + (x & (2^w-1)) 671 // 密钥协商算法辅助函数 672 func keXHat(x *big.Int) (xul *big.Int) { 673 buf := x.Bytes() 674 for i := 0; i < len(buf)-16; i++ { 675 buf[i] = 0 676 } 677 if len(buf) >= 16 { 678 c := buf[len(buf)-16] 679 buf[len(buf)-16] = c & 0x7f 680 } 681 682 r := new(big.Int).SetBytes(buf) 683 _2w := new(big.Int).SetBytes([]byte{ 684 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}) 686 return r.Add(r, _2w) 687 } 688 689 func BytesCombine(pBytes ...[]byte) []byte { 690 length := len(pBytes) 691 s := make([][]byte, length) 692 for index := 0; index < length; index++ { 693 s[index] = pBytes[index] 694 } 695 sep := []byte("") 696 return bytes.Join(s, sep) 697 } 698 699 func intToBytes(x int) []byte { 700 var buf = make([]byte, 4) 701 702 binary.BigEndian.PutUint32(buf, uint32(x)) 703 return buf 704 } 705 706 func kdf(length int, x ...[]byte) ([]byte, bool) { 707 var c []byte 708 709 ct := 1 710 h := sm3.New() 711 for i, j := 0, (length+31)/32; i < j; i++ { 712 h.Reset() 713 for _, xx := range x { 714 h.Write(xx) 715 } 716 h.Write(intToBytes(ct)) 717 hash := h.Sum(nil) 718 if i+1 == j && length%32 != 0 { 719 c = append(c, hash[:length%32]...) 720 } else { 721 c = append(c, hash...) 722 } 723 ct++ 724 } 725 for i := 0; i < length; i++ { 726 if c[i] != 0 { 727 return c, true 728 } 729 } 730 return c, false 731 } 732 733 // 选取一个位于[1~n-1]之间的随机数k,n是椭圆曲线的参数N 734 func randFieldElement(c elliptic.Curve, random io.Reader) (k *big.Int, err error) { 735 if random == nil { 736 random = rand.Reader //If there is no external trusted random source,please use rand.Reader to instead of it. 737 } 738 params := c.Params() 739 b := make([]byte, params.BitSize/8+8) 740 _, err = io.ReadFull(random, b) 741 if err != nil { 742 return 743 } 744 k = new(big.Int).SetBytes(b) 745 n := new(big.Int).Sub(params.N, one) 746 k.Mod(k, n) 747 k.Add(k, one) 748 return 749 } 750 751 // GenerateKey 基于P256Sm2曲线生成sm2的公私钥 752 func GenerateKey(random io.Reader) (*PrivateKey, error) { 753 c := P256Sm2() 754 if random == nil { 755 random = rand.Reader //If there is no external trusted random source,please use rand.Reader to instead of it. 756 } 757 params := c.Params() 758 b := make([]byte, params.BitSize/8+8) 759 _, err := io.ReadFull(random, b) 760 if err != nil { 761 return nil, err 762 } 763 // 生成随机数k 764 k := new(big.Int).SetBytes(b) 765 // n = N - 2 766 n := new(big.Int).Sub(params.N, two) 767 // k = k mod n 768 k.Mod(k, n) 769 // k = k + 1 770 k.Add(k, one) 771 priv := new(PrivateKey) 772 // 设置曲线 773 priv.PublicKey.Curve = c 774 // 设置私钥 775 priv.D = k 776 // 公钥 = k * G 777 priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes()) 778 779 return priv, nil 780 } 781 782 // ecdsa的实现中,使用zeroReader辅助生成一个cipher.StreamReader用作随机数生成的 rand io.Reader。 783 // sm2目前没有采用这种方式,所以这里将相关代码注释掉了。 784 785 // type zr struct { 786 // io.Reader 787 // } 788 789 // func (z *zr) Read(dst []byte) (n int, err error) { 790 // for i := range dst { 791 // dst[i] = 0 792 // } 793 // return len(dst), nil 794 // } 795 796 // var zeroReader = &zr{} 797 798 func getLastBit(a *big.Int) uint { 799 return a.Bit(0) 800 } 801 802 // Decrypt crypto.Decrypter 803 func (priv *PrivateKey) Decrypt(_ io.Reader, msg []byte, _ crypto.DecrypterOpts) (plaintext []byte, err error) { 804 return Decrypt(priv, msg, C1C3C2) 805 }