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  }