package sdk import ( "crypto/elliptic" "encoding/binary" "math/big" "voucher/internal/pkg/cmb/sm2/util" ) 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(util.BigIntToByte(x)) digest.Write(c2) digest.Write(util.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(util.BigIntToByte(sm2P256.A)) z.Write(util.BigIntToByte(sm2P256.B)) z.Write(util.BigIntToByte(sm2P256.Gx)) z.Write(util.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 }