voucher/internal/pkg/cmb/sm2/sdk/base.go

98 lines
2.0 KiB
Go

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
}