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