package util import ( "bytes" "encoding/hex" "fmt" "math/big" "voucher/internal/pkg/cmb/sm2/model" ) func BigIntToByte(n *big.Int) []byte { byteArray := n.Bytes() // If the bytes is not a multiple of 32, pad with zero bytes. byteArrLen := len(byteArray) KeyBytes := 32 if byteArrLen == KeyBytes { return byteArray } byteArray = append(make([]byte, KeyBytes-byteArrLen), byteArray...) // If the most significant byte's most significant bit is set, // prepend a 0 byte to the slice to avoid being interpreted as a negative number. if (byteArray[0] & 0x80) != 0 { byteArray = append([]byte{0}, byteArray...) } return byteArray } func JoinBytes(params ...[]byte) ([]byte, error) { var buffer bytes.Buffer for i := 0; i < len(params); i++ { _, err := buffer.Write(params[i]) if err != nil { return nil, err } } return buffer.Bytes(), nil } func HexToPrivateKey(d []byte) (*model.PrivateKey, error) { k := new(big.Int).SetBytes(d) c := NewP256Sm2() params := c.Params() n := new(big.Int).Sub(params.N, model.One) if k.Cmp(n) >= 0 { return nil, fmt.Errorf("privateKey is overflow") } pri := &model.PrivateKey{ PublicKey: &model.PublicKey{}, D: nil, } pri.PublicKey.Curve = c pri.D = k pri.PublicKey.X, pri.PublicKey.Y = c.ScalarBaseMult(k.Bytes()) return pri, nil } func HexToPublicKey(d []byte) (*model.PublicKey, error) { if len(d) == 65 && d[0] == byte(0x04) { d = d[1:] } if len(d) != 64 { return nil, fmt.Errorf("publicKey is not 64 bytes: %d", len(d)) } pub := new(model.PublicKey) pub.Curve = NewP256Sm2() pub.X = new(big.Int).SetBytes(d[:32]) pub.Y = new(big.Int).SetBytes(d[32:]) return pub, nil } func PrivateKeyToHex(key *model.PrivateKey) string { return key.D.Text(16) } func PublicKeyToHex(key *model.PublicKey) string { x := key.X.Bytes() y := key.Y.Bytes() if n := len(x); n < 32 { x = append(zeroByteSlice()[:32-n], x...) } if n := len(y); n < 32 { y = append(zeroByteSlice()[:32-n], y...) } var c []byte c = append(c, x...) c = append(c, y...) c = append([]byte{0x04}, c...) return hex.EncodeToString(c) } // 32byte func zeroByteSlice() []byte { return []byte{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } } func HexToSignature(hexStr string) (s model.Signature, err error) { signData, err := hex.DecodeString(hexStr) if err != nil { return } rBy := make([]byte, 33) copy(rBy[1:], signData[:32]) rBy[0] = 0x00 s.R = new(big.Int).SetBytes(rBy) sBy := make([]byte, 33) copy(sBy[1:], signData[32:64]) sBy[0] = 0x00 s.S = new(big.Int).SetBytes(sBy) return }