github.com/Hyperledger-TWGC/tjfoc-gm@v1.4.0/sm2/utils.go (about) 1 package sm2 2 3 import ( 4 "encoding/asn1" 5 "math/big" 6 ) 7 8 func Decompress(a []byte) *PublicKey { 9 var aa, xx, xx3 sm2P256FieldElement 10 11 P256Sm2() 12 x := new(big.Int).SetBytes(a[1:]) 13 curve := sm2P256 14 sm2P256FromBig(&xx, x) 15 sm2P256Square(&xx3, &xx) // x3 = x ^ 2 16 sm2P256Mul(&xx3, &xx3, &xx) // x3 = x ^ 2 * x 17 sm2P256Mul(&aa, &curve.a, &xx) // a = a * x 18 sm2P256Add(&xx3, &xx3, &aa) 19 sm2P256Add(&xx3, &xx3, &curve.b) 20 21 y2 := sm2P256ToBig(&xx3) 22 y := new(big.Int).ModSqrt(y2, sm2P256.P) 23 if getLastBit(y)+2 != uint(a[0]) { 24 y.Sub(sm2P256.P, y) 25 } 26 return &PublicKey{ 27 Curve: P256Sm2(), 28 X: x, 29 Y: y, 30 } 31 } 32 33 func Compress(a *PublicKey) []byte { 34 buf := []byte{} 35 yp := getLastBit(a.Y) 36 buf = append(buf, a.X.Bytes()...) 37 if n := len(a.X.Bytes()); n < 32 { 38 buf = append(zeroByteSlice()[:(32-n)], buf...) 39 } 40 buf = append([]byte{byte(yp + 2)}, buf...) 41 return buf 42 } 43 44 45 46 func SignDigitToSignData(r, s *big.Int) ([]byte, error) { 47 return asn1.Marshal(sm2Signature{r, s}) 48 } 49 50 func SignDataToSignDigit(sign []byte) (*big.Int, *big.Int, error) { 51 var sm2Sign sm2Signature 52 53 _, err := asn1.Unmarshal(sign, &sm2Sign) 54 if err != nil { 55 return nil, nil, err 56 } 57 return sm2Sign.R, sm2Sign.S, nil 58 } 59