starcrypto/asymm/sm9.go

237 lines
6.4 KiB
Go

package asymm
import (
"crypto/rand"
"encoding/pem"
"errors"
gmsm3 "github.com/emmansun/gmsm/sm3"
gmsm9 "github.com/emmansun/gmsm/sm9"
)
const (
SM9SignHID byte = 0x01
SM9EncryptHID byte = 0x03
)
func GenerateSM9SignMasterKey() (*gmsm9.SignMasterPrivateKey, *gmsm9.SignMasterPublicKey, error) {
priv, err := gmsm9.GenerateSignMasterKey(rand.Reader)
if err != nil {
return nil, nil, err
}
return priv, priv.PublicKey(), nil
}
func GenerateSM9EncryptMasterKey() (*gmsm9.EncryptMasterPrivateKey, *gmsm9.EncryptMasterPublicKey, error) {
priv, err := gmsm9.GenerateEncryptMasterKey(rand.Reader)
if err != nil {
return nil, nil, err
}
return priv, priv.PublicKey(), nil
}
func GenerateSM9SignUserKey(master *gmsm9.SignMasterPrivateKey, uid []byte, hid byte) (*gmsm9.SignPrivateKey, error) {
if master == nil {
return nil, errors.New("sm9 sign master key is nil")
}
if hid == 0 {
hid = SM9SignHID
}
return master.GenerateUserKey(uid, hid)
}
func GenerateSM9EncryptUserKey(master *gmsm9.EncryptMasterPrivateKey, uid []byte, hid byte) (*gmsm9.EncryptPrivateKey, error) {
if master == nil {
return nil, errors.New("sm9 encrypt master key is nil")
}
if hid == 0 {
hid = SM9EncryptHID
}
return master.GenerateUserKey(uid, hid)
}
func EncodeSM9SignMasterPrivateKey(key *gmsm9.SignMasterPrivateKey) ([]byte, error) {
if key == nil {
return nil, errors.New("sm9 sign master private key is nil")
}
der, err := key.MarshalASN1()
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{Type: "SM9 SIGN MASTER PRIVATE KEY", Bytes: der}), nil
}
func DecodeSM9SignMasterPrivateKey(data []byte) (*gmsm9.SignMasterPrivateKey, error) {
der, err := pemOrDER(data)
if err != nil {
return nil, err
}
return gmsm9.UnmarshalSignMasterPrivateKeyASN1(der)
}
func EncodeSM9SignMasterPublicKey(key *gmsm9.SignMasterPublicKey) ([]byte, error) {
if key == nil {
return nil, errors.New("sm9 sign master public key is nil")
}
der, err := key.MarshalASN1()
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{Type: "SM9 SIGN MASTER PUBLIC KEY", Bytes: der}), nil
}
func DecodeSM9SignMasterPublicKey(data []byte) (*gmsm9.SignMasterPublicKey, error) {
der, err := pemOrDER(data)
if err != nil {
return nil, err
}
return gmsm9.UnmarshalSignMasterPublicKeyASN1(der)
}
func EncodeSM9SignPrivateKey(key *gmsm9.SignPrivateKey) ([]byte, error) {
if key == nil {
return nil, errors.New("sm9 sign private key is nil")
}
der, err := key.MarshalASN1()
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{Type: "SM9 SIGN PRIVATE KEY", Bytes: der}), nil
}
func DecodeSM9SignPrivateKey(data []byte) (*gmsm9.SignPrivateKey, error) {
der, err := pemOrDER(data)
if err != nil {
return nil, err
}
return gmsm9.UnmarshalSignPrivateKeyASN1(der)
}
func EncodeSM9EncryptMasterPrivateKey(key *gmsm9.EncryptMasterPrivateKey) ([]byte, error) {
if key == nil {
return nil, errors.New("sm9 encrypt master private key is nil")
}
der, err := key.MarshalASN1()
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{Type: "SM9 ENCRYPT MASTER PRIVATE KEY", Bytes: der}), nil
}
func DecodeSM9EncryptMasterPrivateKey(data []byte) (*gmsm9.EncryptMasterPrivateKey, error) {
der, err := pemOrDER(data)
if err != nil {
return nil, err
}
return gmsm9.UnmarshalEncryptMasterPrivateKeyASN1(der)
}
func EncodeSM9EncryptMasterPublicKey(key *gmsm9.EncryptMasterPublicKey) ([]byte, error) {
if key == nil {
return nil, errors.New("sm9 encrypt master public key is nil")
}
der, err := key.MarshalASN1()
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{Type: "SM9 ENCRYPT MASTER PUBLIC KEY", Bytes: der}), nil
}
func DecodeSM9EncryptMasterPublicKey(data []byte) (*gmsm9.EncryptMasterPublicKey, error) {
der, err := pemOrDER(data)
if err != nil {
return nil, err
}
return gmsm9.UnmarshalEncryptMasterPublicKeyASN1(der)
}
func EncodeSM9EncryptPrivateKey(key *gmsm9.EncryptPrivateKey) ([]byte, error) {
if key == nil {
return nil, errors.New("sm9 encrypt private key is nil")
}
der, err := key.MarshalASN1()
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{Type: "SM9 ENCRYPT PRIVATE KEY", Bytes: der}), nil
}
func DecodeSM9EncryptPrivateKey(data []byte) (*gmsm9.EncryptPrivateKey, error) {
der, err := pemOrDER(data)
if err != nil {
return nil, err
}
return gmsm9.UnmarshalEncryptPrivateKeyASN1(der)
}
func SM9SignHashASN1(priv *gmsm9.SignPrivateKey, hash []byte) ([]byte, error) {
if priv == nil {
return nil, errors.New("sm9 sign private key is nil")
}
return gmsm9.SignASN1(rand.Reader, priv, hash)
}
func SM9SignASN1(priv *gmsm9.SignPrivateKey, message []byte) ([]byte, error) {
sum := gmsm3.Sum(message)
return SM9SignHashASN1(priv, sum[:])
}
func SM9VerifyHashASN1(pub *gmsm9.SignMasterPublicKey, uid []byte, hid byte, hash, sig []byte) bool {
if pub == nil {
return false
}
if hid == 0 {
hid = SM9SignHID
}
return gmsm9.VerifyASN1(pub, uid, hid, hash, sig)
}
func SM9VerifyASN1(pub *gmsm9.SignMasterPublicKey, uid []byte, hid byte, message, sig []byte) bool {
sum := gmsm3.Sum(message)
return SM9VerifyHashASN1(pub, uid, hid, sum[:], sig)
}
func SM9Encrypt(pub *gmsm9.EncryptMasterPublicKey, uid []byte, hid byte, plaintext []byte) ([]byte, error) {
if pub == nil {
return nil, errors.New("sm9 encrypt master public key is nil")
}
if hid == 0 {
hid = SM9EncryptHID
}
return gmsm9.Encrypt(rand.Reader, pub, uid, hid, plaintext, gmsm9.SM4CBCEncrypterOpts)
}
func SM9Decrypt(priv *gmsm9.EncryptPrivateKey, uid, ciphertext []byte) ([]byte, error) {
if priv == nil {
return nil, errors.New("sm9 encrypt private key is nil")
}
return gmsm9.Decrypt(priv, uid, ciphertext, gmsm9.SM4CBCEncrypterOpts)
}
func SM9EncryptASN1(pub *gmsm9.EncryptMasterPublicKey, uid []byte, hid byte, plaintext []byte) ([]byte, error) {
if pub == nil {
return nil, errors.New("sm9 encrypt master public key is nil")
}
if hid == 0 {
hid = SM9EncryptHID
}
return gmsm9.EncryptASN1(rand.Reader, pub, uid, hid, plaintext, gmsm9.SM4CBCEncrypterOpts)
}
func SM9DecryptASN1(priv *gmsm9.EncryptPrivateKey, uid, ciphertext []byte) ([]byte, error) {
if priv == nil {
return nil, errors.New("sm9 encrypt private key is nil")
}
return gmsm9.DecryptASN1(priv, uid, ciphertext)
}
func pemOrDER(data []byte) ([]byte, error) {
if len(data) == 0 {
return nil, errors.New("empty key data")
}
if blk, _ := pem.Decode(data); blk != nil {
return blk.Bytes, nil
}
return data, nil
}