package sdk import ( "PaymentCenter/app/third/paymentService/psbc/internal/gmutil/sm2/util" "crypto/elliptic" "encoding/binary" "math/big" ) type BaseSdk struct { } func NewBaseSdk() SDK { return &BaseSdk{} } func (b *BaseSdk) Kdf(c elliptic.Curve, x, y *big.Int, c2 []byte) error { data := elliptic.Marshal(c, x, y) ct := uint32(1) length := len(c2) end := (length + 31) / 32 result := make([]byte, 0) for i := 1; i <= end; i++ { bytes, err := b.sm3hash(data, b.uint32ToBytes(ct)) if err != nil { return err } result = append(result, bytes...) ct++ } last, err := b.sm3hash(data, b.uint32ToBytes(ct)) if err != nil { return err } if length%32 == 0 { result = append(result, last...) } else { result = append(result, last[:length%32]...) } for i := 0; i < length; i++ { c2[i] ^= result[i] } return nil } func (b *BaseSdk) CalculateHash(x *big.Int, c2 []byte, y *big.Int) []byte { digest := util.New() digest.Write(b.bigIntToByte(x)) digest.Write(c2) digest.Write(b.bigIntToByte(y)) result := digest.Sum(nil)[:32] return result } func (b *BaseSdk) GetZ(x *big.Int, y *big.Int, uid []byte) []byte { z := util.New() uidLen := len(uid) * 8 z.Write([]byte{byte((uidLen >> 8) & 0xFF)}) z.Write([]byte{byte(uidLen & 0xFF)}) z.Write(uid) sm2P256 := util.NewP256Sm2() z.Write(b.bigIntToByte(sm2P256.A)) z.Write(b.bigIntToByte(sm2P256.B)) z.Write(b.bigIntToByte(sm2P256.Gx)) z.Write(b.bigIntToByte(sm2P256.Gy)) z.Write(x.Bytes()) z.Write(y.Bytes()) return z.Sum(nil) } func (b *BaseSdk) GetE(z []byte, data []byte) *big.Int { e := util.New() e.Write(z) e.Write(data) return new(big.Int).SetBytes(e.Sum(nil)[:32]) } func (b *BaseSdk) uint32ToBytes(x uint32) []byte { var buf = make([]byte, 4) binary.BigEndian.PutUint32(buf, x) return buf } func (b *BaseSdk) sm3hash(sources ...[]byte) ([]byte, error) { bytes, err := util.JoinBytes(sources...) if err != nil { return nil, err } md := make([]byte, 32) h := util.New() h.Write(bytes) h.Sum(md[:0]) return md, nil } func (b *BaseSdk) 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 }