github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/sm2soft/utils.go (about) 1 // Copyright 2022 s1ren@github.com/hxx258456. 2 3 /* 4 sm2soft 是sm2的纯软实现,基于tjfoc国密算法库`tjfoc/gmsm`做了少量修改。 5 对应版权声明: thrid_licenses/github.com/tjfoc/gmsm/版权声明 6 */ 7 8 package sm2soft 9 10 import ( 11 "encoding/asn1" 12 "math/big" 13 ) 14 15 func Decompress(a []byte) *PublicKey { 16 var aa, xx, xx3 sm2P256FieldElement 17 18 P256Sm2() 19 x := new(big.Int).SetBytes(a[1:]) 20 curve := sm2P256 21 sm2P256FromBig(&xx, x) 22 sm2P256Square(&xx3, &xx) // x3 = x ^ 2 23 sm2P256Mul(&xx3, &xx3, &xx) // x3 = x ^ 2 * x 24 sm2P256Mul(&aa, &curve.a, &xx) // a = a * x 25 sm2P256Add(&xx3, &xx3, &aa) 26 sm2P256Add(&xx3, &xx3, &curve.b) 27 28 y2 := sm2P256ToBig(&xx3) 29 y := new(big.Int).ModSqrt(y2, sm2P256.P) 30 if getLastBit(y) != uint(a[0]) { 31 y.Sub(sm2P256.P, y) 32 } 33 return &PublicKey{ 34 Curve: P256Sm2(), 35 X: x, 36 Y: y, 37 } 38 } 39 40 func Compress(a *PublicKey) []byte { 41 buf := []byte{} 42 yp := getLastBit(a.Y) 43 buf = append(buf, a.X.Bytes()...) 44 if n := len(a.X.Bytes()); n < 32 { 45 buf = append(zeroByteSlice()[:(32-n)], buf...) 46 } 47 buf = append([]byte{byte(yp)}, buf...) 48 return buf 49 } 50 51 type sm2Signature struct { 52 R, S *big.Int 53 } 54 55 func SignDigitToSignData(r, s *big.Int) ([]byte, error) { 56 return asn1.Marshal(sm2Signature{r, s}) 57 } 58 59 func SignDataToSignDigit(sign []byte) (*big.Int, *big.Int, error) { 60 var sm2Sign sm2Signature 61 62 _, err := asn1.Unmarshal(sign, &sm2Sign) 63 if err != nil { 64 return nil, nil, err 65 } 66 return sm2Sign.R, sm2Sign.S, nil 67 }