PaymentCenter/app/third/paymentService/psbc/internal/gmutil/sm2/sdk/base.go

117 lines
2.5 KiB
Go

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
}