utils.go raw

   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)!= 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)}, 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  
  60