package sm2 import ( "encoding/asn1" "math/big" ) func Decompress(a []byte) *PublicKey { var aa, xx, xx3 sm2P256FieldElement P256Sm2() x := new(big.Int).SetBytes(a[1:]) curve := sm2P256 sm2P256FromBig(&xx, x) sm2P256Square(&xx3, &xx) // x3 = x ^ 2 sm2P256Mul(&xx3, &xx3, &xx) // x3 = x ^ 2 * x sm2P256Mul(&aa, &curve.a, &xx) // a = a * x sm2P256Add(&xx3, &xx3, &aa) sm2P256Add(&xx3, &xx3, &curve.b) y2 := sm2P256ToBig(&xx3) y := new(big.Int).ModSqrt(y2, sm2P256.P) if getLastBit(y)!= uint(a[0]) { y.Sub(sm2P256.P, y) } return &PublicKey{ Curve: P256Sm2(), X: x, Y: y, } } func Compress(a *PublicKey) []byte { buf := []byte{} yp := getLastBit(a.Y) buf = append(buf, a.X.Bytes()...) if n := len(a.X.Bytes()); n < 32 { buf = append(zeroByteSlice()[:(32-n)], buf...) } buf = append([]byte{byte(yp)}, buf...) return buf } func SignDigitToSignData(r, s *big.Int) ([]byte, error) { return asn1.Marshal(sm2Signature{r, s}) } func SignDataToSignDigit(sign []byte) (*big.Int, *big.Int, error) { var sm2Sign sm2Signature _, err := asn1.Unmarshal(sign, &sm2Sign) if err != nil { return nil, nil, err } return sm2Sign.R, sm2Sign.S, nil }