gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/sm2soft/utils.go (about)

     1  // Copyright (c) 2022 zhaochun
     2  // core-gm is licensed under Mulan PSL v2.
     3  // You can use this software according to the terms and conditions of the Mulan PSL v2.
     4  // You may obtain a copy of Mulan PSL v2 at:
     5  //          http://license.coscl.org.cn/MulanPSL2
     6  // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
     7  // See the Mulan PSL v2 for more details.
     8  
     9  /*
    10  sm2soft 是sm2的纯软实现,基于tjfoc国密算法库`tjfoc/gmsm`做了少量修改。
    11  对应版权声明: thrid_licenses/github.com/tjfoc/gmsm/版权声明
    12  */
    13  
    14  package sm2soft
    15  
    16  import (
    17  	"encoding/asn1"
    18  	"math/big"
    19  )
    20  
    21  func Decompress(a []byte) *PublicKey {
    22  	var aa, xx, xx3 sm2P256FieldElement
    23  
    24  	P256Sm2()
    25  	x := new(big.Int).SetBytes(a[1:])
    26  	curve := sm2P256
    27  	sm2P256FromBig(&xx, x)
    28  	sm2P256Square(&xx3, &xx)       // x3 = x ^ 2
    29  	sm2P256Mul(&xx3, &xx3, &xx)    // x3 = x ^ 2 * x
    30  	sm2P256Mul(&aa, &curve.a, &xx) // a = a * x
    31  	sm2P256Add(&xx3, &xx3, &aa)
    32  	sm2P256Add(&xx3, &xx3, &curve.b)
    33  
    34  	y2 := sm2P256ToBig(&xx3)
    35  	y := new(big.Int).ModSqrt(y2, sm2P256.P)
    36  	if getLastBit(y) != uint(a[0]) {
    37  		y.Sub(sm2P256.P, y)
    38  	}
    39  	return &PublicKey{
    40  		Curve: P256Sm2(),
    41  		X:     x,
    42  		Y:     y,
    43  	}
    44  }
    45  
    46  func Compress(a *PublicKey) []byte {
    47  	buf := []byte{}
    48  	yp := getLastBit(a.Y)
    49  	buf = append(buf, a.X.Bytes()...)
    50  	if n := len(a.X.Bytes()); n < 32 {
    51  		buf = append(zeroByteSlice()[:(32-n)], buf...)
    52  	}
    53  	buf = append([]byte{byte(yp)}, buf...)
    54  	return buf
    55  }
    56  
    57  type sm2Signature struct {
    58  	R, S *big.Int
    59  }
    60  
    61  func SignDigitToSignData(r, s *big.Int) ([]byte, error) {
    62  	return asn1.Marshal(sm2Signature{r, s})
    63  }
    64  
    65  func SignDataToSignDigit(sign []byte) (*big.Int, *big.Int, error) {
    66  	var sm2Sign sm2Signature
    67  
    68  	_, err := asn1.Unmarshal(sign, &sm2Sign)
    69  	if err != nil {
    70  		return nil, nil, err
    71  	}
    72  	return sm2Sign.R, sm2Sign.S, nil
    73  }